qemu_command.c 490.2 KB
Newer Older
1 2 3
/*
 * qemu_command.c: QEMU command generation
 *
4
 * Copyright (C) 2006-2015 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_command.h"
27
#include "qemu_hostdev.h"
28 29
#include "qemu_capabilities.h"
#include "cpu/cpu.h"
30
#include "dirname.h"
31
#include "passfd.h"
32
#include "viralloc.h"
33
#include "virlog.h"
34
#include "virarch.h"
35
#include "virerror.h"
E
Eric Blake 已提交
36
#include "virfile.h"
37
#include "virnetdev.h"
38
#include "virnetdevbridge.h"
39
#include "virstring.h"
40
#include "virtime.h"
41
#include "viruuid.h"
42 43
#include "c-ctype.h"
#include "domain_nwfilter.h"
44
#include "domain_addr.h"
45
#include "domain_audit.h"
M
Michal Novotny 已提交
46
#include "domain_conf.h"
47
#include "netdev_bandwidth_conf.h"
48
#include "snapshot_conf.h"
49
#include "storage_conf.h"
50
#include "secret_conf.h"
51
#include "network/bridge_driver.h"
52
#include "virnetdevtap.h"
53
#include "base64.h"
54
#include "device_conf.h"
55
#include "virstoragefile.h"
56
#include "virtpm.h"
57
#include "virscsi.h"
58
#include "virnuma.h"
59 60 61
#if defined(__linux__)
# include <linux/capability.h>
#endif
62 63 64 65 66 67

#include <sys/stat.h>
#include <fcntl.h>

#define VIR_FROM_THIS VIR_FROM_QEMU

68 69
VIR_LOG_INIT("qemu.qemu_command");

70 71 72 73
#define VIO_ADDR_NET 0x1000ul
#define VIO_ADDR_SCSI 0x2000ul
#define VIO_ADDR_SERIAL 0x30000000ul
#define VIO_ADDR_NVRAM 0x3000ul
74 75 76 77 78 79 80 81 82 83

VIR_ENUM_DECL(virDomainDiskQEMUBus)
VIR_ENUM_IMPL(virDomainDiskQEMUBus, VIR_DOMAIN_DISK_BUS_LAST,
              "ide",
              "floppy",
              "scsi",
              "virtio",
              "xen",
              "usb",
              "uml",
84 85
              "sata",
              "sd")
86 87 88 89 90 91 92 93


VIR_ENUM_DECL(qemuDiskCacheV2)

VIR_ENUM_IMPL(qemuDiskCacheV2, VIR_DOMAIN_DISK_CACHE_LAST,
              "default",
              "none",
              "writethrough",
94
              "writeback",
95 96
              "directsync",
              "unsafe");
97 98 99 100 101 102 103 104 105

VIR_ENUM_DECL(qemuVideo)

VIR_ENUM_IMPL(qemuVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
              "std",
              "cirrus",
              "vmware",
              "", /* no arg needed for xen */
              "", /* don't support vbox */
106
              "qxl",
M
Marc-André Lureau 已提交
107 108
              "", /* don't support parallels */
              "" /* no need for virtio */);
109

110 111 112 113 114 115 116 117
VIR_ENUM_DECL(qemuDeviceVideo)

VIR_ENUM_IMPL(qemuDeviceVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
              "VGA",
              "cirrus-vga",
              "vmware-svga",
              "", /* no device for xen */
              "", /* don't support vbox */
118
              "qxl-vga",
M
Marc-André Lureau 已提交
119 120
              "", /* don't support parallels */
              "virtio-vga");
121

122 123 124 125 126 127
VIR_ENUM_DECL(qemuSoundCodec)

VIR_ENUM_IMPL(qemuSoundCodec, VIR_DOMAIN_SOUND_CODEC_TYPE_LAST,
              "hda-duplex",
              "hda-micro");

128 129 130 131 132 133 134 135 136 137 138
VIR_ENUM_DECL(qemuControllerModelUSB)

VIR_ENUM_IMPL(qemuControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST,
              "piix3-usb-uhci",
              "piix4-usb-uhci",
              "usb-ehci",
              "ich9-usb-ehci1",
              "ich9-usb-uhci1",
              "ich9-usb-uhci2",
              "ich9-usb-uhci3",
              "vt82c686b-usb-uhci",
G
Gerd Hoffmann 已提交
139
              "pci-ohci",
140 141
              "nec-usb-xhci",
              "none");
142

143 144 145 146
VIR_ENUM_DECL(qemuDomainFSDriver)
VIR_ENUM_IMPL(qemuDomainFSDriver, VIR_DOMAIN_FS_DRIVER_TYPE_LAST,
              "local",
              "local",
147
              "handle",
148
              NULL,
D
Dmitry Guryanov 已提交
149
              NULL,
150
              NULL);
151

152 153 154 155 156
VIR_ENUM_DECL(qemuNumaPolicy)
VIR_ENUM_IMPL(qemuNumaPolicy, VIR_DOMAIN_NUMATUNE_MEM_LAST,
              "bind",
              "preferred",
              "interleave");
157

158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
/**
 * qemuVirCommandGetFDSet:
 * @cmd: the command to modify
 * @fd: fd to reassign to the child
 *
 * Get the parameters for the QEMU -add-fd command line option
 * for the given file descriptor. The file descriptor must previously
 * have been 'transferred' in a virCommandPassFD() call.
 * This function for example returns "set=10,fd=20".
 */
static char *
qemuVirCommandGetFDSet(virCommandPtr cmd, int fd)
{
    char *result = NULL;
    int idx = virCommandPassFDGetFDIndex(cmd, fd);

    if (idx >= 0) {
        ignore_value(virAsprintf(&result, "set=%d,fd=%d", idx, fd));
    } else {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("file descriptor %d has not been transferred"), fd);
    }

    return result;
}

/**
 * qemuVirCommandGetDevSet:
 * @cmd: the command to modify
 * @fd: fd to reassign to the child
 *
 * Get the parameters for the QEMU path= parameter where a file
 * descriptor is accessed via a file descriptor set, for example
 * /dev/fdset/10. The file descriptor must previously have been
 * 'transferred' in a virCommandPassFD() call.
 */
static char *
qemuVirCommandGetDevSet(virCommandPtr cmd, int fd)
{
    char *result = NULL;
    int idx = virCommandPassFDGetFDIndex(cmd, fd);

    if (idx >= 0) {
        ignore_value(virAsprintf(&result, "/dev/fdset/%d", idx));
    } else {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("file descriptor %d has not been transferred"), fd);
    }
    return result;
}


210 211
/**
 * qemuPhysIfaceConnect:
212
 * @def: the definition of the VM (needed by 802.1Qbh and audit)
213
 * @driver: pointer to the driver instance
W
Wang Rui 已提交
214
 * @net: pointer to the VM's interface description with direct device type
215 216
 * @tapfd: array of file descriptor return value for the new device
 * @tapfdSize: number of file descriptors in @tapfd
M
Michael Wood 已提交
217
 * @vmop: VM operation type
218
 *
219
 * Returns 0 on success or -1 in case of error.
220 221
 */
int
222
qemuPhysIfaceConnect(virDomainDefPtr def,
223
                     virQEMUDriverPtr driver,
224
                     virDomainNetDefPtr net,
225 226
                     int *tapfd,
                     size_t tapfdSize,
227
                     virNetDevVPortProfileOp vmop)
228
{
229
    int ret = -1;
230
    char *res_ifname = NULL;
231
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
232
    unsigned int macvlan_create_flags = VIR_NETDEV_MACVLAN_CREATE_WITH_TAP;
233

234
    if (net->model && STREQ(net->model, "virtio"))
235
        macvlan_create_flags |= VIR_NETDEV_MACVLAN_VNET_HDR;
236

237 238 239 240 241 242 243 244
    if (virNetDevMacVLanCreateWithVPortProfile(net->ifname,
                                               &net->mac,
                                               virDomainNetGetActualDirectDev(net),
                                               virDomainNetGetActualDirectMode(net),
                                               def->uuid,
                                               virDomainNetGetActualVirtPortProfile(net),
                                               &res_ifname,
                                               vmop, cfg->stateDir,
245
                                               tapfd, tapfdSize,
246
                                               macvlan_create_flags) < 0)
247
        goto cleanup;
248

249 250 251 252
    virDomainAuditNetDevice(def, net, res_ifname, true);
    VIR_FREE(net->ifname);
    net->ifname = res_ifname;
    ret = 0;
253

254 255 256 257 258
 cleanup:
    if (ret < 0) {
        while (tapfdSize--)
            VIR_FORCE_CLOSE(tapfd[tapfdSize]);
    }
259
    virObjectUnref(cfg);
260
    return ret;
261 262 263
}


264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
/**
 * qemuCreateInBridgePortWithHelper:
 * @cfg: the configuration object in which the helper name is looked up
 * @brname: the bridge name
 * @ifname: the returned interface name
 * @macaddr: the returned MAC address
 * @tapfd: file descriptor return value for the new tap device
 * @flags: OR of virNetDevTapCreateFlags:

 *   VIR_NETDEV_TAP_CREATE_VNET_HDR
 *     - Enable IFF_VNET_HDR on the tap device
 *
 * This function creates a new tap device on a bridge using an external
 * helper.  The final name for the bridge will be stored in @ifname.
 *
 * Returns 0 in case of success or -1 on failure
 */
static int qemuCreateInBridgePortWithHelper(virQEMUDriverConfigPtr cfg,
                                            const char *brname,
                                            char **ifname,
                                            int *tapfd,
                                            unsigned int flags)
{
    virCommandPtr cmd;
288
    char *errbuf = NULL, *cmdstr = NULL;
289 290 291 292 293 294 295 296 297 298
    int pair[2] = { -1, -1 };

    if ((flags & ~VIR_NETDEV_TAP_CREATE_VNET_HDR) != VIR_NETDEV_TAP_CREATE_IFUP)
        return -1;

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) < 0) {
        virReportSystemError(errno, "%s", _("failed to create socket"));
        return -1;
    }

299 300 301 302 303 304
    if (!virFileIsExecutable(cfg->bridgeHelperName)) {
        virReportSystemError(errno, _("'%s' is not a suitable bridge helper"),
                             cfg->bridgeHelperName);
        return -1;
    }

305 306 307 308 309
    cmd = virCommandNew(cfg->bridgeHelperName);
    if (flags & VIR_NETDEV_TAP_CREATE_VNET_HDR)
        virCommandAddArgFormat(cmd, "--use-vnet");
    virCommandAddArgFormat(cmd, "--br=%s", brname);
    virCommandAddArgFormat(cmd, "--fd=%d", pair[1]);
310 311
    virCommandSetErrorBuffer(cmd, &errbuf);
    virCommandDoAsyncIO(cmd);
312 313
    virCommandPassFD(cmd, pair[1],
                     VIR_COMMAND_PASS_FD_CLOSE_PARENT);
314 315 316 317 318 319 320 321 322 323 324 325
    virCommandClearCaps(cmd);
#ifdef CAP_NET_ADMIN
    virCommandAllowCap(cmd, CAP_NET_ADMIN);
#endif
    if (virCommandRunAsync(cmd, NULL) < 0) {
        *tapfd = -1;
        goto cleanup;
    }

    do {
        *tapfd = recvfd(pair[0], 0);
    } while (*tapfd < 0 && errno == EINTR);
326

327
    if (*tapfd < 0) {
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
        char ebuf[1024];
        char *errstr = NULL;

        if (!(cmdstr = virCommandToString(cmd)))
            goto cleanup;
        virCommandAbort(cmd);

        if (errbuf && *errbuf &&
            virAsprintf(&errstr, "\nstderr=%s", errbuf) < 0)
            goto cleanup;

        virReportError(VIR_ERR_INTERNAL_ERROR,
            _("%s: failed to communicate with bridge helper: %s%s"),
            cmdstr, virStrerror(errno, ebuf, sizeof(ebuf)),
            errstr ? errstr : "");
        VIR_FREE(errstr);
344 345 346 347
        goto cleanup;
    }

    if (virNetDevTapGetName(*tapfd, ifname) < 0 ||
348
        virCommandWait(cmd, NULL) < 0) {
349 350 351 352
        VIR_FORCE_CLOSE(*tapfd);
        *tapfd = -1;
    }

353
 cleanup:
354 355
    VIR_FREE(cmdstr);
    VIR_FREE(errbuf);
356 357 358 359 360
    virCommandFree(cmd);
    VIR_FORCE_CLOSE(pair[0]);
    return *tapfd < 0 ? -1 : 0;
}

361 362 363 364 365
/* qemuNetworkIfaceConnect - *only* called if actualType is
 * VIR_DOMAIN_NET_TYPE_NETWORK or VIR_DOMAIN_NET_TYPE_BRIDGE (i.e. if
 * the connection is made with a tap device connecting to a bridge
 * device)
 */
366
int
367
qemuNetworkIfaceConnect(virDomainDefPtr def,
368
                        virQEMUDriverPtr driver,
369
                        virDomainNetDefPtr net,
370
                        int *tapfd,
371
                        size_t *tapfdSize)
372
{
373
    const char *brname;
374
    int ret = -1;
375
    unsigned int tap_create_flags = VIR_NETDEV_TAP_CREATE_IFUP;
E
Eric Blake 已提交
376
    bool template_ifname = false;
377
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
378 379
    const char *tunpath = "/dev/net/tun";

380
    if (net->backend.tap) {
381
        tunpath = net->backend.tap;
382
        if (!(virQEMUDriverIsPrivileged(driver))) {
383 384 385 386 387
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("cannot use custom tap device in session mode"));
            goto cleanup;
        }
    }
388

389 390 391
    if (!(brname = virDomainNetGetActualBridgeName(net))) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing bridge name"));
        goto cleanup;
392 393 394
    }

    if (!net->ifname ||
E
Eric Blake 已提交
395
        STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) ||
396 397
        strchr(net->ifname, '%')) {
        VIR_FREE(net->ifname);
398
        if (VIR_STRDUP(net->ifname, VIR_NET_GENERATED_PREFIX "%d") < 0)
399
            goto cleanup;
400
        /* avoid exposing vnet%d in getXMLDesc or error outputs */
E
Eric Blake 已提交
401
        template_ifname = true;
402 403
    }

404
    if (net->model && STREQ(net->model, "virtio"))
405
        tap_create_flags |= VIR_NETDEV_TAP_CREATE_VNET_HDR;
406

407
    if (virQEMUDriverIsPrivileged(driver)) {
408
        if (virNetDevTapCreateInBridgePort(brname, &net->ifname, &net->mac,
409
                                           def->uuid, tunpath, tapfd, *tapfdSize,
410 411 412
                                           virDomainNetGetActualVirtPortProfile(net),
                                           virDomainNetGetActualVlan(net),
                                           tap_create_flags) < 0) {
413
            virDomainAuditNetDevice(def, net, tunpath, false);
414 415
            goto cleanup;
        }
416 417 418 419 420
        if (virDomainNetGetActualBridgeMACTableManager(net)
            == VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_LIBVIRT) {
            /* libvirt is managing the FDB of the bridge this device
             * is attaching to, so we need to turn off learning and
             * unicast_flood on the device to prevent the kernel from
421 422 423
             * adding any FDB entries for it. We will add add an fdb
             * entry ourselves (during qemuInterfaceStartDevices(),
             * using the MAC address from the interface config.
424 425 426 427 428 429
             */
            if (virNetDevBridgePortSetLearning(brname, net->ifname, false) < 0)
                goto cleanup;
            if (virNetDevBridgePortSetUnicastFlood(brname, net->ifname, false) < 0)
                goto cleanup;
        }
430 431 432 433
    } else {
        if (qemuCreateInBridgePortWithHelper(cfg, brname,
                                             &net->ifname,
                                             tapfd, tap_create_flags) < 0) {
434
            virDomainAuditNetDevice(def, net, tunpath, false);
435 436 437 438 439 440 441
            goto cleanup;
        }
        /* qemuCreateInBridgePortWithHelper can only create a single FD */
        if (*tapfdSize > 1) {
            VIR_WARN("Ignoring multiqueue network request");
            *tapfdSize = 1;
        }
442 443
    }

444
    virDomainAuditNetDevice(def, net, tunpath, true);
445 446

    if (cfg->macFilter &&
447 448 449 450
        ebtablesAddForwardAllowIn(driver->ebtables,
                                  net->ifname,
                                  &net->mac) < 0)
        goto cleanup;
451

452
    if (net->filter &&
453
        virDomainConfNWFilterInstantiate(def->uuid, net) < 0) {
454
        goto cleanup;
455 456
    }

457 458
    ret = 0;

459
 cleanup:
460
    if (ret < 0) {
461
        size_t i;
462
        for (i = 0; i < *tapfdSize && tapfd[i] >= 0; i++)
463 464 465 466
            VIR_FORCE_CLOSE(tapfd[i]);
        if (template_ifname)
            VIR_FREE(net->ifname);
    }
467
    virObjectUnref(cfg);
468

469
    return ret;
470 471
}

472
static bool
473 474 475
qemuDomainSupportsNicdev(virDomainDefPtr def,
                         virQEMUCapsPtr qemuCaps,
                         virDomainNetDefPtr net)
476 477 478 479
{
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
        return false;

480
    /* non-virtio ARM nics require legacy -net nic */
481 482
    if (((def->os.arch == VIR_ARCH_ARMV7L) ||
        (def->os.arch == VIR_ARCH_AARCH64)) &&
483 484
        net->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO &&
        net->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
485 486 487 488 489 490
        return false;

    return true;
}

static bool
491 492 493
qemuDomainSupportsNetdev(virDomainDefPtr def,
                         virQEMUCapsPtr qemuCaps,
                         virDomainNetDefPtr net)
494
{
495
    if (!qemuDomainSupportsNicdev(def, qemuCaps, net))
496 497 498
        return false;
    return virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV);
}
499

500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610

static int
qemuBuildObjectCommandLinePropsInternal(const char *key,
                                        const virJSONValue *value,
                                        virBufferPtr buf,
                                        bool nested)
{
    virJSONValuePtr elem;
    virBitmapPtr bitmap = NULL;
    ssize_t pos = -1;
    ssize_t end;
    size_t i;

    switch ((virJSONType) value->type) {
    case VIR_JSON_TYPE_STRING:
        virBufferAsprintf(buf, ",%s=%s", key, value->data.string);
        break;

    case VIR_JSON_TYPE_NUMBER:
        virBufferAsprintf(buf, ",%s=%s", key, value->data.number);
        break;

    case VIR_JSON_TYPE_BOOLEAN:
        if (value->data.boolean)
            virBufferAsprintf(buf, ",%s=yes", key);
        else
            virBufferAsprintf(buf, ",%s=no", key);

        break;

    case VIR_JSON_TYPE_ARRAY:
        if (nested) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("nested -object property arrays are not supported"));
            return -1;
        }

        if (virJSONValueGetArrayAsBitmap(value, &bitmap) == 0) {
            while ((pos = virBitmapNextSetBit(bitmap, pos)) > -1) {
                if ((end = virBitmapNextClearBit(bitmap, pos)) < 0)
                    end = virBitmapLastSetBit(bitmap) + 1;

                if (end - 1 > pos) {
                    virBufferAsprintf(buf, ",%s=%zd-%zd", key, pos, end - 1);
                    pos = end;
                } else {
                    virBufferAsprintf(buf, ",%s=%zd", key, pos);
                }
            }
        } else {
            /* fallback, treat the array as a non-bitmap, adding the key
             * for each member */
            for (i = 0; i < virJSONValueArraySize(value); i++) {
                elem = virJSONValueArrayGet((virJSONValuePtr)value, i);

                /* recurse to avoid duplicating code */
                if (qemuBuildObjectCommandLinePropsInternal(key, elem, buf,
                                                            true) < 0)
                    return -1;
            }
        }
        break;

    case VIR_JSON_TYPE_OBJECT:
    case VIR_JSON_TYPE_NULL:
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("NULL and OBJECT JSON types can't be converted to "
                         "commandline string"));
        return -1;
    }

    virBitmapFree(bitmap);
    return 0;
}


static int
qemuBuildObjectCommandLineProps(const char *key,
                                const virJSONValue *value,
                                void *opaque)
{
    return qemuBuildObjectCommandLinePropsInternal(key, value, opaque, false);
}


char *
qemuBuildObjectCommandlineFromJSON(const char *type,
                                   const char *alias,
                                   virJSONValuePtr props)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    char *ret = NULL;

    virBufferAsprintf(&buf, "%s,id=%s", type, alias);

    if (virJSONValueObjectForeachKeyValue(props,
                                          qemuBuildObjectCommandLineProps,
                                          &buf) < 0)
        goto cleanup;

    if (virBufferCheckError(&buf) < 0)
        goto cleanup;

    ret = virBufferContentAndReset(&buf);

 cleanup:
    virBufferFreeAndReset(&buf);
    return ret;
}


611 612 613 614 615 616 617 618 619 620 621 622 623 624 625
/**
 * qemuOpenVhostNet:
 * @def: domain definition
 * @net: network definition
 * @qemuCaps: qemu binary capabilities
 * @vhostfd: array of opened vhost-net device
 * @vhostfdSize: number of file descriptors in @vhostfd array
 *
 * Open vhost-net, multiple times - if requested.
 * In case, no vhost-net is needed, @vhostfdSize is set to 0
 * and 0 is returned.
 *
 * Returns: 0 on success
 *         -1 on failure
 */
626
int
627 628
qemuOpenVhostNet(virDomainDefPtr def,
                 virDomainNetDefPtr net,
629
                 virQEMUCapsPtr qemuCaps,
630
                 int *vhostfd,
631
                 size_t *vhostfdSize)
632
{
633
    size_t i;
634 635 636 637
    const char *vhostnet_path = net->backend.vhost;

    if (!vhostnet_path)
        vhostnet_path = "/dev/vhost-net";
638

639 640 641 642
    /* If running a plain QEMU guest, or
     * if the config says explicitly to not use vhost, return now*/
    if (def->virtType != VIR_DOMAIN_VIRT_KVM ||
        net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_QEMU) {
643 644
        *vhostfdSize = 0;
        return 0;
645 646 647 648 649
    }

    /* If qemu doesn't support vhost-net mode (including the -netdev command
     * option), don't try to open the device.
     */
650
    if (!(virQEMUCapsGet(qemuCaps, QEMU_CAPS_VHOST_NET) &&
651
          qemuDomainSupportsNetdev(def, qemuCaps, net))) {
652
        if (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST) {
653 654 655
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("vhost-net is not supported with "
                                   "this QEMU binary"));
656 657
            return -1;
        }
658
        *vhostfdSize = 0;
659 660
        return 0;
    }
661

662 663
    /* If the nic model isn't virtio, don't try to open. */
    if (!(net->model && STREQ(net->model, "virtio"))) {
664
        if (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST) {
665 666 667
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("vhost-net is only supported for "
                                   "virtio network interfaces"));
668 669
            return -1;
        }
670
        *vhostfdSize = 0;
671 672 673
        return 0;
    }

674
    for (i = 0; i < *vhostfdSize; i++) {
675
        vhostfd[i] = open(vhostnet_path, O_RDWR);
676

677 678 679 680
        /* If the config says explicitly to use vhost and we couldn't open it,
         * report an error.
         */
        if (vhostfd[i] < 0) {
681
            virDomainAuditNetDevice(def, net, vhostnet_path, false);
682 683 684 685 686 687
            if (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("vhost-net was requested for an interface, "
                                       "but is unavailable"));
                goto error;
            }
688
            VIR_WARN("Unable to open vhost-net. Opened so far %zu, requested %zu",
689 690 691
                     i, *vhostfdSize);
            *vhostfdSize = i;
            break;
692
        }
693
    }
694
    virDomainAuditNetDevice(def, net, vhostnet_path, *vhostfdSize);
695
    return 0;
696

697
 error:
698 699 700 701
    while (i--)
        VIR_FORCE_CLOSE(vhostfd[i]);

    return -1;
702 703
}

704

705 706 707 708
int
qemuNetworkPrepareDevices(virDomainDefPtr def)
{
    int ret = -1;
709
    size_t i;
710

711 712
    for (i = 0; i < def->nnets; i++) {
        virDomainNetDefPtr net = def->nets[i];
713 714 715 716 717 718
        int actualType;

        /* If appropriate, grab a physical device from the configured
         * network's pool of devices, or resolve bridge device name
         * to the one defined in the network definition.
         */
719
        if (networkAllocateActualDevice(def, net) < 0)
720 721 722 723 724 725 726 727 728 729 730 731 732
            goto cleanup;

        actualType = virDomainNetGetActualType(net);
        if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV &&
            net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
            /* Each type='hostdev' network device must also have a
             * corresponding entry in the hostdevs array. For netdevs
             * that are hardcoded as type='hostdev', this is already
             * done by the parser, but for those allocated from a
             * network / determined at runtime, we need to do it
             * separately.
             */
            virDomainHostdevDefPtr hostdev = virDomainNetGetActualHostdev(net);
733
            virDomainHostdevSubsysPCIPtr pcisrc = &hostdev->source.subsys.u.pci;
734 735 736 737 738 739

            if (virDomainHostdevFind(def, hostdev, NULL) >= 0) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("PCI device %04x:%02x:%02x.%x "
                                 "allocated from network %s is already "
                                 "in use by domain %s"),
740 741 742
                               pcisrc->addr.domain, pcisrc->addr.bus,
                               pcisrc->addr.slot, pcisrc->addr.function,
                               net->data.network.name, def->name);
743 744
                goto cleanup;
            }
745
            if (virDomainHostdevInsert(def, hostdev) < 0)
746 747 748 749
                goto cleanup;
        }
    }
    ret = 0;
750
 cleanup:
751 752
    return ret;
}
753

754
static int qemuDomainDeviceAliasIndex(const virDomainDeviceInfo *info,
755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777
                                      const char *prefix)
{
    int idx;

    if (!info->alias)
        return -1;
    if (!STRPREFIX(info->alias, prefix))
        return -1;

    if (virStrToLong_i(info->alias + strlen(prefix), NULL, 10, &idx) < 0)
        return -1;

    return idx;
}


int qemuDomainNetVLAN(virDomainNetDefPtr def)
{
    return qemuDomainDeviceAliasIndex(&def->info, "net");
}


char *qemuDeviceDriveHostAlias(virDomainDiskDefPtr disk,
778
                               virQEMUCapsPtr qemuCaps)
779 780 781
{
    char *ret;

782
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
783 784
        ignore_value(virAsprintf(&ret, "%s%s", QEMU_DRIVE_HOST_PREFIX,
                                 disk->info.alias));
785
    } else {
786
        ignore_value(VIR_STRDUP(ret, disk->info.alias));
787 788 789 790 791 792 793 794 795 796
    }
    return ret;
}


/* Names used before -drive supported the id= option */
static int qemuAssignDeviceDiskAliasFixed(virDomainDiskDefPtr disk)
{
    int busid, devid;
    int ret;
797
    char *dev_name;
798 799

    if (virDiskNameToBusDeviceIndex(disk, &busid, &devid) < 0) {
800 801 802
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot convert disk '%s' to bus/device index"),
                       disk->dst);
803 804 805 806 807
        return -1;
    }

    switch (disk->bus) {
    case VIR_DOMAIN_DISK_BUS_IDE:
808
        if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK)
809
            ret = virAsprintf(&dev_name, "ide%d-hd%d", busid, devid);
810
        else
811
            ret = virAsprintf(&dev_name, "ide%d-cd%d", busid, devid);
812 813 814
        break;
    case VIR_DOMAIN_DISK_BUS_SCSI:
        if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK)
815
            ret = virAsprintf(&dev_name, "scsi%d-hd%d", busid, devid);
816
        else
817
            ret = virAsprintf(&dev_name, "scsi%d-cd%d", busid, devid);
818 819
        break;
    case VIR_DOMAIN_DISK_BUS_FDC:
820
        ret = virAsprintf(&dev_name, "floppy%d", devid);
821 822
        break;
    case VIR_DOMAIN_DISK_BUS_VIRTIO:
823
        ret = virAsprintf(&dev_name, "virtio%d", devid);
824 825
        break;
    case VIR_DOMAIN_DISK_BUS_XEN:
826
        ret = virAsprintf(&dev_name, "xenblk%d", devid);
827
        break;
828 829 830
    case VIR_DOMAIN_DISK_BUS_SD:
        ret = virAsprintf(&dev_name, "sd%d", devid);
        break;
831 832 833
    case VIR_DOMAIN_DISK_BUS_USB:
        ret = virAsprintf(&dev_name, "usb%d", devid);
        break;
834
    default:
835 836 837
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Unsupported disk name mapping for bus '%s'"),
                       virDomainDiskBusTypeToString(disk->bus));
838 839 840
        return -1;
    }

841
    if (ret == -1)
842 843
        return -1;

844
    disk->info.alias = dev_name;
845 846 847 848

    return 0;
}

849
static int
850
qemuSetSCSIControllerModel(virDomainDefPtr def,
851
                           virQEMUCapsPtr qemuCaps,
852
                           int *model)
853 854 855 856
{
    if (*model > 0) {
        switch (*model) {
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC:
857
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_LSI)) {
858 859
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("This QEMU doesn't support "
860
                                 "the LSI 53C895A SCSI controller"));
861 862 863 864
                return -1;
            }
            break;
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI:
865
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_SCSI)) {
866 867 868 869 870 871 872 873 874
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("This QEMU doesn't support "
                                 "virtio scsi controller"));
                return -1;
            }
            break;
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI:
            /*TODO: need checking work here if necessary */
            break;
875 876 877 878 879 880 881 882
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1078:
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_MEGASAS)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("This QEMU doesn't support "
                                 "the LSI SAS1078 controller"));
                return -1;
            }
            break;
883 884 885 886 887 888
        default:
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("Unsupported controller model: %s"),
                           virDomainControllerModelSCSITypeToString(*model));
            return -1;
        }
889
    } else {
890
        if (ARCH_IS_PPC64(def->os.arch) &&
891
            STRPREFIX(def->os.machine, "pseries")) {
892
            *model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI;
893
        } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_LSI)) {
894
            *model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC;
895 896
        } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_SCSI)) {
            *model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI;
897 898 899 900 901
        } else {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Unable to determine model for scsi controller"));
            return -1;
        }
902
    }
903 904

    return 0;
905
}
906 907

/* Our custom -drive naming scheme used with id= */
908 909
static int
qemuAssignDeviceDiskAliasCustom(virDomainDefPtr def,
910
                                virDomainDiskDefPtr disk,
911
                                virQEMUCapsPtr qemuCaps)
912 913
{
    const char *prefix = virDomainDiskBusTypeToString(disk->bus);
914 915
    int controllerModel = -1;

916
    if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
917 918
        if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
            controllerModel =
H
Han Cheng 已提交
919 920
                virDomainDeviceFindControllerModel(def, &disk->info,
                                                   VIR_DOMAIN_CONTROLLER_TYPE_SCSI);
921

922
            if ((qemuSetSCSIControllerModel(def, qemuCaps, &controllerModel)) < 0)
923 924
                return -1;
        }
925 926 927 928 929 930 931

        if (disk->bus != VIR_DOMAIN_DISK_BUS_SCSI ||
            controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) {
            if (virAsprintf(&disk->info.alias, "%s%d-%d-%d", prefix,
                            disk->info.addr.drive.controller,
                            disk->info.addr.drive.bus,
                            disk->info.addr.drive.unit) < 0)
932
                return -1;
933 934 935 936 937 938
        } else {
            if (virAsprintf(&disk->info.alias, "%s%d-%d-%d-%d", prefix,
                            disk->info.addr.drive.controller,
                            disk->info.addr.drive.bus,
                            disk->info.addr.drive.target,
                            disk->info.addr.drive.unit) < 0)
939
                return -1;
940
        }
941 942 943
    } else {
        int idx = virDiskNameToIndex(disk->dst);
        if (virAsprintf(&disk->info.alias, "%s-disk%d", prefix, idx) < 0)
944
            return -1;
945 946 947 948 949 950 951
    }

    return 0;
}


int
952 953
qemuAssignDeviceDiskAlias(virDomainDefPtr vmdef,
                          virDomainDiskDefPtr def,
954
                          virQEMUCapsPtr qemuCaps)
955
{
956 957 958 959
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
        return qemuAssignDeviceDiskAliasCustom(vmdef, def, qemuCaps);
    else
        return qemuAssignDeviceDiskAliasFixed(def);
960 961 962 963 964 965 966
}


int
qemuAssignDeviceNetAlias(virDomainDefPtr def, virDomainNetDefPtr net, int idx)
{
    if (idx == -1) {
967
        size_t i;
968
        idx = 0;
969
        for (i = 0; i < def->nnets; i++) {
970
            int thisidx;
971

972 973
            if (virDomainNetGetActualType(def->nets[i])
                == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
974 975 976
                /* type='hostdev' interfaces have a hostdev%d alias */
               continue;
            }
977
            if ((thisidx = qemuDomainDeviceAliasIndex(&def->nets[i]->info, "net")) < 0) {
978 979
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("Unable to determine device index for network device"));
980 981 982 983 984 985 986
                return -1;
            }
            if (thisidx >= idx)
                idx = thisidx + 1;
        }
    }

987 988 989
    if (virAsprintf(&net->info.alias, "net%d", idx) < 0)
        return -1;
    return 0;
990 991 992 993 994 995 996
}


int
qemuAssignDeviceHostdevAlias(virDomainDefPtr def, virDomainHostdevDefPtr hostdev, int idx)
{
    if (idx == -1) {
997
        size_t i;
998
        idx = 0;
999
        for (i = 0; i < def->nhostdevs; i++) {
1000
            int thisidx;
1001
            if ((thisidx = qemuDomainDeviceAliasIndex(def->hostdevs[i]->info, "hostdev")) < 0) {
1002 1003
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("Unable to determine device index for hostdev device"));
1004 1005 1006 1007 1008 1009 1010
                return -1;
            }
            if (thisidx >= idx)
                idx = thisidx + 1;
        }
    }

1011
    if (virAsprintf(&hostdev->info->alias, "hostdev%d", idx) < 0)
1012 1013 1014 1015 1016 1017
        return -1;

    return 0;
}


1018 1019 1020 1021
int
qemuAssignDeviceRedirdevAlias(virDomainDefPtr def, virDomainRedirdevDefPtr redirdev, int idx)
{
    if (idx == -1) {
1022
        size_t i;
1023
        idx = 0;
1024
        for (i = 0; i < def->nredirdevs; i++) {
1025 1026
            int thisidx;
            if ((thisidx = qemuDomainDeviceAliasIndex(&def->redirdevs[i]->info, "redir")) < 0) {
1027 1028
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("Unable to determine device index for redirected device"));
1029 1030 1031 1032 1033 1034 1035
                return -1;
            }
            if (thisidx >= idx)
                idx = thisidx + 1;
        }
    }

1036 1037 1038
    if (virAsprintf(&redirdev->info.alias, "redir%d", idx) < 0)
        return -1;
    return 0;
1039 1040 1041
}


1042
int
1043 1044 1045
qemuAssignDeviceControllerAlias(virDomainDefPtr domainDef,
                                virQEMUCapsPtr qemuCaps,
                                virDomainControllerDefPtr controller)
1046 1047 1048
{
    const char *prefix = virDomainControllerTypeToString(controller->type);

1049
    if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) {
1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
        if (!virQEMUCapsHasPCIMultiBus(qemuCaps, domainDef)) {
            /* qemus that don't support multiple PCI buses have
             * hardcoded the name of their single PCI controller as
             * "pci".
             */
            return VIR_STRDUP(controller->info.alias, "pci");
        } else if (controller->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) {
            /* The pcie-root controller on Q35 machinetypes uses a
             * different naming convention ("pcie.0"), because it is
             * hardcoded that way in qemu.
             */
1061
            return virAsprintf(&controller->info.alias, "pcie.%d", controller->idx);
1062 1063 1064 1065 1066 1067 1068
        }
        /* All other PCI controllers use the consistent "pci.%u"
         * (including the hardcoded pci-root controller on
         * multibus-capable qemus).
         */
        return virAsprintf(&controller->info.alias, "pci.%d", controller->idx);
    } else if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE) {
1069 1070 1071
        /* for any machine based on e.g. I440FX or G3Beige, the
         * first (and currently only) IDE controller is an integrated
         * controller hardcoded with id "ide"
1072
         */
1073 1074
        if (qemuDomainMachineHasBuiltinIDE(domainDef) &&
            controller->idx == 0)
1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
            return VIR_STRDUP(controller->info.alias, "ide");
    } else if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SATA) {
        /* for any Q35 machine, the first SATA controller is the
         * integrated one, and it too is hardcoded with id "ide"
         */
        if (qemuDomainMachineIsQ35(domainDef) && controller->idx == 0)
            return VIR_STRDUP(controller->info.alias, "ide");
    } else if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) {
        /* first USB device is "usb", others are normal "usb%d" */
        if (controller->idx == 0)
            return VIR_STRDUP(controller->info.alias, "usb");
1086
    }
1087 1088 1089
    /* all other controllers use the default ${type}${index} naming
     * scheme for alias/id.
     */
1090
    return virAsprintf(&controller->info.alias, "%s%d", prefix, controller->idx);
1091 1092
}

1093 1094 1095 1096 1097
static ssize_t
qemuGetNextChrDevIndex(virDomainDefPtr def,
                       virDomainChrDefPtr chr,
                       const char *prefix)
{
1098 1099
    const virDomainChrDef **arrPtr;
    size_t cnt;
1100 1101 1102 1103 1104 1105 1106
    size_t i;
    ssize_t idx = 0;
    const char *prefix2 = NULL;

    if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE)
        prefix2 = "serial";

1107
    virDomainChrGetDomainPtrs(def, chr->deviceType, &arrPtr, &cnt);
1108

1109
    for (i = 0; i < cnt; i++) {
1110
        ssize_t thisidx;
1111
        if (((thisidx = qemuDomainDeviceAliasIndex(&arrPtr[i]->info, prefix)) < 0) &&
1112
            (prefix2 &&
1113
             (thisidx = qemuDomainDeviceAliasIndex(&arrPtr[i]->info, prefix2)) < 0)) {
1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Unable to determine device index for character device"));
            return -1;
        }
        if (thisidx >= idx)
            idx = thisidx + 1;
    }

    return idx;
}


1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136
int
qemuAssignDeviceRNGAlias(virDomainRNGDefPtr rng,
                         size_t idx)
{
    if (virAsprintf(&rng->info.alias, "rng%zu", idx) < 0)
        return -1;

    return 0;
}


1137
int
1138
qemuAssignDeviceChrAlias(virDomainDefPtr def,
1139 1140 1141 1142 1143
                         virDomainChrDefPtr chr,
                         ssize_t idx)
{
    const char *prefix = NULL;

1144
    switch ((virDomainChrDeviceType) chr->deviceType) {
1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164
    case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL:
        prefix = "parallel";
        break;

    case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL:
        prefix = "serial";
        break;

    case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE:
        prefix = "console";
        break;

    case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL:
        prefix = "channel";
        break;

    case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST:
        return -1;
    }

1165 1166 1167
    if (idx == -1 && (idx = qemuGetNextChrDevIndex(def, chr, prefix)) < 0)
        return -1;

1168 1169
    return virAsprintf(&chr->info.alias, "%s%zd", prefix, idx);
}
1170

1171
int
1172
qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
1173
{
1174
    size_t i;
1175

1176
    for (i = 0; i < def->ndisks; i++) {
1177
        if (qemuAssignDeviceDiskAlias(def, def->disks[i], qemuCaps) < 0)
1178 1179
            return -1;
    }
1180 1181 1182 1183 1184 1185 1186 1187
    for (i = 0; i < def->nnets; i++) {
        /* type='hostdev' interfaces are also on the hostdevs list,
         * and will have their alias assigned with other hostdevs.
         */
        if (virDomainNetGetActualType(def->nets[i])
            != VIR_DOMAIN_NET_TYPE_HOSTDEV &&
            qemuAssignDeviceNetAlias(def, def->nets[i], i) < 0) {
            return -1;
1188 1189 1190
        }
    }

1191
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
1192 1193
        return 0;

1194
    for (i = 0; i < def->nfss; i++) {
1195
        if (virAsprintf(&def->fss[i]->info.alias, "fs%zu", i) < 0)
1196
            return -1;
1197
    }
1198
    for (i = 0; i < def->nsounds; i++) {
1199
        if (virAsprintf(&def->sounds[i]->info.alias, "sound%zu", i) < 0)
1200
            return -1;
1201
    }
1202
    for (i = 0; i < def->nhostdevs; i++) {
1203 1204 1205
        if (qemuAssignDeviceHostdevAlias(def, def->hostdevs[i], i) < 0)
            return -1;
    }
1206
    for (i = 0; i < def->nredirdevs; i++) {
1207 1208 1209
        if (qemuAssignDeviceRedirdevAlias(def, def->redirdevs[i], i) < 0)
            return -1;
    }
1210
    for (i = 0; i < def->nvideos; i++) {
1211
        if (virAsprintf(&def->videos[i]->info.alias, "video%zu", i) < 0)
1212
            return -1;
1213
    }
1214
    for (i = 0; i < def->ncontrollers; i++) {
1215
        if (qemuAssignDeviceControllerAlias(def, qemuCaps, def->controllers[i]) < 0)
1216 1217
            return -1;
    }
1218
    for (i = 0; i < def->ninputs; i++) {
1219
        if (virAsprintf(&def->inputs[i]->info.alias, "input%zu", i) < 0)
1220
            return -1;
1221
    }
1222
    for (i = 0; i < def->nparallels; i++) {
1223
        if (qemuAssignDeviceChrAlias(def, def->parallels[i], i) < 0)
1224
            return -1;
1225
    }
1226
    for (i = 0; i < def->nserials; i++) {
1227
        if (qemuAssignDeviceChrAlias(def, def->serials[i], i) < 0)
1228
            return -1;
1229
    }
1230
    for (i = 0; i < def->nchannels; i++) {
1231
        if (qemuAssignDeviceChrAlias(def, def->channels[i], i) < 0)
1232
            return -1;
1233
    }
1234
    for (i = 0; i < def->nconsoles; i++) {
1235
        if (qemuAssignDeviceChrAlias(def, def->consoles[i], i) < 0)
1236
            return -1;
E
Eric Blake 已提交
1237
    }
1238
    for (i = 0; i < def->nhubs; i++) {
1239
        if (virAsprintf(&def->hubs[i]->info.alias, "hub%zu", i) < 0)
1240
            return -1;
M
Marc-André Lureau 已提交
1241
    }
1242 1243 1244 1245
    for (i = 0; i < def->nshmems; i++) {
        if (virAsprintf(&def->shmems[i]->info.alias, "shmem%zu", i) < 0)
            return -1;
    }
1246
    for (i = 0; i < def->nsmartcards; i++) {
1247
        if (virAsprintf(&def->smartcards[i]->info.alias, "smartcard%zu", i) < 0)
1248
            return -1;
1249 1250 1251
    }
    if (def->watchdog) {
        if (virAsprintf(&def->watchdog->info.alias, "watchdog%d", 0) < 0)
1252
            return -1;
1253 1254 1255
    }
    if (def->memballoon) {
        if (virAsprintf(&def->memballoon->info.alias, "balloon%d", 0) < 0)
1256
            return -1;
1257
    }
1258
    for (i = 0; i < def->nrngs; i++) {
1259
        if (qemuAssignDeviceRNGAlias(def->rngs[i], i) < 0)
1260
            return -1;
1261
    }
1262 1263
    if (def->tpm) {
        if (virAsprintf(&def->tpm->info.alias, "tpm%d", 0) < 0)
1264
            return -1;
1265
    }
1266 1267 1268 1269
    for (i = 0; i < def->nmems; i++) {
        if (virAsprintf(&def->mems[i]->info.alias, "dimm%zu", i) < 0)
            return -1;
    }
1270 1271 1272 1273

    return 0;
}

1274

1275
static void
1276
qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def,
1277
                                     virDomainDeviceAddressType type)
1278 1279 1280
{
    /*
       declare address-less virtio devices to be of address type 'type'
1281 1282
       disks, networks, consoles, controllers, memballoon and rng in this
       order
1283
       if type is ccw filesystem devices are declared to be of address type ccw
1284
    */
1285
    size_t i;
1286

1287
    for (i = 0; i < def->ndisks; i++) {
1288 1289 1290 1291 1292
        if (def->disks[i]->bus == VIR_DOMAIN_DISK_BUS_VIRTIO &&
            def->disks[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            def->disks[i]->info.type = type;
    }

1293
    for (i = 0; i < def->nnets; i++) {
E
Eric Blake 已提交
1294
        if (STREQ(def->nets[i]->model, "virtio") &&
1295
            def->nets[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
1296
            def->nets[i]->info.type = type;
1297
        }
1298 1299
    }

1300 1301 1302 1303 1304 1305
    for (i = 0; i < def->ninputs; i++) {
        if (def->inputs[i]->bus == VIR_DOMAIN_DISK_BUS_VIRTIO &&
            def->inputs[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            def->inputs[i]->info.type = type;
    }

1306
    for (i = 0; i < def->ncontrollers; i++) {
1307 1308 1309 1310
        if ((def->controllers[i]->type ==
             VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL ||
             def->controllers[i]->type ==
             VIR_DOMAIN_CONTROLLER_TYPE_SCSI) &&
1311 1312 1313 1314 1315
            def->controllers[i]->info.type ==
            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            def->controllers[i]->info.type = type;
    }

1316 1317 1318 1319
    if (def->memballoon &&
        def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO &&
        def->memballoon->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
        def->memballoon->info.type = type;
1320

1321 1322 1323 1324 1325
    for (i = 0; i < def->nrngs; i++) {
        if (def->rngs[i]->model == VIR_DOMAIN_RNG_MODEL_VIRTIO &&
            def->rngs[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            def->rngs[i]->info.type = type;
    }
1326 1327 1328 1329 1330 1331 1332

    if (type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
        for (i = 0; i < def->nfss; i++) {
            if (def->fss[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
                def->fss[i]->info.type = type;
        }
    }
1333 1334
}

1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345

/*
 * Three steps populating CCW devnos
 * 1. Allocate empty address set
 * 2. Gather addresses with explicit devno
 * 3. Assign defaults to the rest
 */
static int
qemuDomainAssignS390Addresses(virDomainDefPtr def,
                              virQEMUCapsPtr qemuCaps,
                              virDomainObjPtr obj)
1346
{
1347
    int ret = -1;
J
Ján Tomko 已提交
1348
    virDomainCCWAddressSetPtr addrs = NULL;
1349 1350
    qemuDomainObjPrivatePtr priv = NULL;

1351
    if (qemuDomainMachineIsS390CCW(def) &&
1352
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
1353
        qemuDomainPrimeVirtioDeviceAddresses(
1354 1355
            def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW);

J
Ján Tomko 已提交
1356
        if (!(addrs = virDomainCCWAddressSetCreate()))
1357 1358
            goto cleanup;

J
Ján Tomko 已提交
1359
        if (virDomainDeviceInfoIterate(def, virDomainCCWAddressValidate,
1360 1361 1362
                                       addrs) < 0)
            goto cleanup;

J
Ján Tomko 已提交
1363
        if (virDomainDeviceInfoIterate(def, virDomainCCWAddressAllocate,
1364 1365 1366 1367
                                       addrs) < 0)
            goto cleanup;
    } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390)) {
        /* deal with legacy virtio-s390 */
1368
        qemuDomainPrimeVirtioDeviceAddresses(
1369
            def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390);
1370 1371 1372 1373 1374 1375
    }

    if (obj && obj->privateData) {
        priv = obj->privateData;
        if (addrs) {
            /* if this is the live domain object, we persist the CCW addresses*/
J
Ján Tomko 已提交
1376
            virDomainCCWAddressSetFree(priv->ccwaddrs);
1377 1378 1379 1380 1381 1382 1383 1384 1385
            priv->persistentAddrs = 1;
            priv->ccwaddrs = addrs;
            addrs = NULL;
        } else {
            priv->persistentAddrs = 0;
        }
    }
    ret = 0;

1386
 cleanup:
J
Ján Tomko 已提交
1387
    virDomainCCWAddressSetFree(addrs);
1388 1389

    return ret;
1390
}
1391

1392 1393 1394 1395
static int
qemuDomainAssignARMVirtioMMIOAddresses(virDomainDefPtr def,
                                       virQEMUCapsPtr qemuCaps)
{
1396 1397
    if (((def->os.arch == VIR_ARCH_ARMV7L) ||
        (def->os.arch == VIR_ARCH_AARCH64)) &&
1398
        (STRPREFIX(def->os.machine, "vexpress-") ||
1399 1400
            STREQ(def->os.machine, "virt") ||
            STRPREFIX(def->os.machine, "virt-")) &&
1401 1402 1403 1404 1405 1406
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_MMIO)) {
        qemuDomainPrimeVirtioDeviceAddresses(
            def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO);
    }
    return 0;
}
1407

1408 1409
static int
qemuSpaprVIOFindByReg(virDomainDefPtr def ATTRIBUTE_UNUSED,
1410
                      virDomainDeviceDefPtr device ATTRIBUTE_UNUSED,
1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431
                      virDomainDeviceInfoPtr info, void *opaque)
{
    virDomainDeviceInfoPtr target = opaque;

    if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO)
        return 0;

    /* Match a dev that has a reg, is not us, and has a matching reg */
    if (info->addr.spaprvio.has_reg && info != target &&
        info->addr.spaprvio.reg == target->addr.spaprvio.reg)
        /* Has to be < 0 so virDomainDeviceInfoIterate() will exit */
        return -1;

    return 0;
}

static int
qemuAssignSpaprVIOAddress(virDomainDefPtr def, virDomainDeviceInfoPtr info,
                          unsigned long long default_reg)
{
    bool user_reg;
1432
    int ret;
1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443

    if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO)
        return 0;

    /* Check if the user has assigned the reg already, if so use it */
    user_reg = info->addr.spaprvio.has_reg;
    if (!user_reg) {
        info->addr.spaprvio.reg = default_reg;
        info->addr.spaprvio.has_reg = true;
    }

1444 1445
    ret = virDomainDeviceInfoIterate(def, qemuSpaprVIOFindByReg, info);
    while (ret != 0) {
1446
        if (user_reg) {
1447 1448 1449
            virReportError(VIR_ERR_XML_ERROR,
                           _("spapr-vio address %#llx already in use"),
                           info->addr.spaprvio.reg);
1450 1451 1452 1453 1454
            return -EEXIST;
        }

        /* We assigned the reg, so try a new value */
        info->addr.spaprvio.reg += 0x1000;
1455
        ret = virDomainDeviceInfoIterate(def, qemuSpaprVIOFindByReg, info);
1456 1457 1458 1459 1460
    }

    return 0;
}

1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487

static int
qemuDomainAssignVirtioSerialAddresses(virDomainDefPtr def,
                                      virDomainObjPtr obj)
{
    int ret = -1;
    size_t i;
    virDomainVirtioSerialAddrSetPtr addrs = NULL;
    qemuDomainObjPrivatePtr priv = NULL;

    if (!(addrs = virDomainVirtioSerialAddrSetCreate()))
        goto cleanup;

    if (virDomainVirtioSerialAddrSetAddControllers(addrs, def) < 0)
        goto cleanup;

    if (virDomainDeviceInfoIterate(def, virDomainVirtioSerialAddrReserve,
                                   addrs) < 0)
        goto cleanup;

    VIR_DEBUG("Finished reserving existing ports");

    for (i = 0; i < def->nconsoles; i++) {
        virDomainChrDefPtr chr = def->consoles[i];
        if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
            chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO &&
            !virDomainVirtioSerialAddrIsComplete(&chr->info) &&
J
Ján Tomko 已提交
1488
            virDomainVirtioSerialAddrAutoAssign(def, addrs, &chr->info, true) < 0)
1489 1490 1491 1492 1493 1494 1495 1496
            goto cleanup;
    }

    for (i = 0; i < def->nchannels; i++) {
        virDomainChrDefPtr chr = def->channels[i];
        if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
            chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO &&
            !virDomainVirtioSerialAddrIsComplete(&chr->info) &&
J
Ján Tomko 已提交
1497
            virDomainVirtioSerialAddrAutoAssign(def, addrs, &chr->info, false) < 0)
1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516
            goto cleanup;
    }

    if (obj && obj->privateData) {
        priv = obj->privateData;
        /* if this is the live domain object, we persist the addresses */
        virDomainVirtioSerialAddrSetFree(priv->vioserialaddrs);
        priv->persistentAddrs = 1;
        priv->vioserialaddrs = addrs;
        addrs = NULL;
    }
    ret = 0;

 cleanup:
    virDomainVirtioSerialAddrSetFree(addrs);
    return ret;
}


1517
int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
1518
                                      virQEMUCapsPtr qemuCaps)
1519
{
1520 1521
    size_t i;
    int ret = -1;
1522
    int model;
1523 1524 1525

    /* Default values match QEMU. See spapr_(llan|vscsi|vty).c */

1526
    for (i = 0; i < def->nnets; i++) {
1527 1528 1529
        if (def->nets[i]->model &&
            STREQ(def->nets[i]->model, "spapr-vlan"))
            def->nets[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
1530
        if (qemuAssignSpaprVIOAddress(def, &def->nets[i]->info,
1531
                                      VIO_ADDR_NET) < 0)
1532
            goto cleanup;
1533 1534
    }

1535
    for (i = 0; i < def->ncontrollers; i++) {
1536
        model = def->controllers[i]->model;
1537
        if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
1538
            if (qemuSetSCSIControllerModel(def, qemuCaps, &model) < 0)
1539 1540 1541
                goto cleanup;
        }

1542
        if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI &&
1543
            def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
1544
            def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
1545
        if (qemuAssignSpaprVIOAddress(def, &def->controllers[i]->info,
1546
                                      VIO_ADDR_SCSI) < 0)
1547
            goto cleanup;
1548 1549
    }

1550
    for (i = 0; i < def->nserials; i++) {
1551
        if (def->serials[i]->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
1552
            ARCH_IS_PPC64(def->os.arch) &&
1553
            STRPREFIX(def->os.machine, "pseries"))
1554
            def->serials[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
1555
        if (qemuAssignSpaprVIOAddress(def, &def->serials[i]->info,
1556 1557 1558 1559 1560
                                      VIO_ADDR_SERIAL) < 0)
            goto cleanup;
    }

    if (def->nvram) {
1561
        if (ARCH_IS_PPC64(def->os.arch) &&
1562
            STRPREFIX(def->os.machine, "pseries"))
1563 1564 1565
            def->nvram->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
        if (qemuAssignSpaprVIOAddress(def, &def->nvram->info,
                                      VIO_ADDR_NVRAM) < 0)
1566
            goto cleanup;
1567 1568 1569 1570
    }

    /* No other devices are currently supported on spapr-vio */

1571
    ret = 0;
1572

1573
 cleanup:
1574
    return ret;
1575
}
1576 1577


1578 1579 1580 1581 1582
static int
qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
                      virDomainDeviceDefPtr device,
                      virDomainDeviceInfoPtr info,
                      void *opaque)
1583
{
1584
    virDomainPCIAddressSetPtr addrs = opaque;
1585
    int ret = -1;
1586
    virDevicePCIAddressPtr addr = &info->addr.pci;
1587
    bool entireSlot;
1588
    /* flags may be changed from default below */
1589 1590
    virDomainPCIConnectFlags flags = (VIR_PCI_CONNECT_HOTPLUGGABLE |
                                      VIR_PCI_CONNECT_TYPE_PCI);
1591

1592 1593 1594 1595 1596 1597 1598
    if ((info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
        || ((device->type == VIR_DOMAIN_DEVICE_HOSTDEV) &&
            (device->data.hostdev->parent.type != VIR_DOMAIN_DEVICE_NONE))) {
        /* If a hostdev has a parent, its info will be a part of the
         * parent, and will have its address collected during the scan
         * of the parent's device type.
        */
1599
        return 0;
1600
    }
1601

1602 1603 1604
    /* Change flags according to differing requirements of different
     * devices.
     */
1605 1606 1607 1608 1609 1610 1611 1612 1613
    switch (device->type) {
    case VIR_DOMAIN_DEVICE_CONTROLLER:
        switch (device->data.controller->type) {
        case  VIR_DOMAIN_CONTROLLER_TYPE_PCI:
            switch (device->data.controller->model) {
            case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
                /* pci-bridge needs a PCI slot, but it isn't
                 * hot-pluggable, so it doesn't need a hot-pluggable slot.
                 */
1614
                flags = VIR_PCI_CONNECT_TYPE_PCI;
1615 1616 1617 1618 1619
                break;
            case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
                /* pci-bridge needs a PCIe slot, but it isn't
                 * hot-pluggable, so it doesn't need a hot-pluggable slot.
                 */
1620
                flags = VIR_PCI_CONNECT_TYPE_PCIE;
1621
                break;
1622 1623 1624 1625 1626 1627
            case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT:
                /* pcie-root-port can only connect to pcie-root, isn't
                 * hot-pluggable
                 */
                flags = VIR_PCI_CONNECT_TYPE_PCIE_ROOT;
                break;
1628 1629 1630 1631 1632 1633
            case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT:
                /* pcie-switch can only connect to a true
                 * pcie bus, and can't be hot-plugged.
                 */
                flags = VIR_PCI_CONNECT_TYPE_PCIE_PORT;
                break;
1634 1635 1636 1637 1638 1639
            case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT:
                /* pcie-switch-downstream-port can only connect to a
                 * pcie-switch-upstream-port, and can't be hot-plugged.
                 */
                flags = VIR_PCI_CONNECT_TYPE_PCIE_SWITCH;
                break;
1640 1641 1642
            default:
                break;
            }
1643
            break;
1644 1645 1646 1647

        case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
            /* SATA controllers aren't hot-plugged, and can be put in
             * either a PCI or PCIe slot
1648
             */
1649
            flags = VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE;
1650
            break;
1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662

        case VIR_DOMAIN_CONTROLLER_TYPE_USB:
           /* allow UHCI and EHCI controllers to be manually placed on
            * the PCIe bus (but don't put them there automatically)
            */
           switch (device->data.controller->model) {
           case VIR_DOMAIN_CONTROLLER_MODEL_USB_EHCI:
           case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1:
           case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI1:
           case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI2:
           case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI3:
           case VIR_DOMAIN_CONTROLLER_MODEL_USB_VT82C686B_UHCI:
1663
              flags = VIR_PCI_CONNECT_TYPE_PCI;
1664 1665 1666 1667 1668
              break;
           case VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI:
              /* should this be PCIE-only? Or do we need to allow PCI
               * for backward compatibility?
               */
1669
              flags = VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE;
1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682
              break;
           case VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI:
           case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI:
           case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX4_UHCI:
              /* Allow these for PCI only */
              break;
           }
        }
        break;

    case VIR_DOMAIN_DEVICE_SOUND:
        switch (device->data.sound->model) {
        case VIR_DOMAIN_SOUND_MODEL_ICH6:
1683
        case VIR_DOMAIN_SOUND_MODEL_ICH9:
1684
            flags = VIR_PCI_CONNECT_TYPE_PCI;
1685
            break;
1686
        }
1687
        break;
1688

1689 1690 1691 1692
    case VIR_DOMAIN_DEVICE_VIDEO:
        /* video cards aren't hot-plugged, and can be put in either a
         * PCI or PCIe slot
         */
1693
        flags = VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE;
1694 1695
        break;
    }
1696

1697 1698 1699 1700 1701 1702
    /* Ignore implicit controllers on slot 0:0:1.0:
     * implicit IDE controller on 0:0:1.1 (no qemu command line)
     * implicit USB controller on 0:0:1.2 (-usb)
     *
     * If the machine does have a PCI bus, they will get reserved
     * in qemuAssignDevicePCISlots().
1703 1704 1705 1706 1707
     */

    /* These are the IDE and USB controllers in the PIIX3, hardcoded
     * to bus 0 slot 1.  They cannot be attached to a PCIe slot, only
     * PCI.
1708 1709 1710 1711
     */
    if (device->type == VIR_DOMAIN_DEVICE_CONTROLLER && addr->domain == 0 &&
        addr->bus == 0 && addr->slot == 1) {
        virDomainControllerDefPtr cont = device->data.controller;
1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724

        if ((cont->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE && cont->idx == 0 &&
             addr->function == 1) ||
            (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_USB && cont->idx == 0 &&
             (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI ||
              cont->model == -1) && addr->function == 2)) {
            /* Note the check for nbuses > 0 - if there are no PCI
             * buses, we skip this check. This is a quirk required for
             * some machinetypes such as s390, which pretend to have a
             * PCI bus for long enough to generate the "-usb" on the
             * commandline, but that don't really care if a PCI bus
             * actually exists. */
            if (addrs->nbuses > 0 &&
1725
                !(addrs->buses[0].flags & VIR_PCI_CONNECT_TYPE_PCI)) {
1726 1727 1728 1729 1730 1731 1732 1733
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("Bus 0 must be PCI for integrated PIIX3 "
                                 "USB or IDE controllers"));
                return -1;
            } else {
                return 0;
            }
        }
1734 1735
    }

1736
    entireSlot = (addr->function == 0 &&
J
Ján Tomko 已提交
1737
                  addr->multi != VIR_TRISTATE_SWITCH_ON);
1738

1739 1740
    if (virDomainPCIAddressReserveAddr(addrs, addr, flags,
                                       entireSlot, true) < 0)
1741
        goto cleanup;
1742

1743
    ret = 0;
1744
 cleanup:
1745
    return ret;
1746 1747
}

1748
static bool
1749
qemuDomainSupportsPCI(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
1750
{
1751
    if ((def->os.arch != VIR_ARCH_ARMV7L) && (def->os.arch != VIR_ARCH_AARCH64))
1752 1753 1754 1755 1756
        return true;

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

1757 1758 1759 1760 1761
    if ((STREQ(def->os.machine, "virt") ||
         STRPREFIX(def->os.machine, "virt-")) &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_GPEX))
        return true;

1762 1763
    return false;
}
1764

1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776
static bool
qemuDomainPCIBusFullyReserved(virDomainPCIAddressBusPtr bus)
{
    size_t i;

    for (i = bus->minSlot; i <= bus->maxSlot; i++)
        if (!bus->slots[i])
            return false;

    return true;
}

1777

1778
int qemuDomainAssignAddresses(virDomainDefPtr def,
1779
                              virQEMUCapsPtr qemuCaps,
1780
                              virDomainObjPtr obj)
1781
{
1782 1783
    int rc;

1784 1785 1786 1787
    rc = qemuDomainAssignVirtioSerialAddresses(def, obj);
    if (rc)
        return rc;

1788
    rc = qemuDomainAssignSpaprVIOAddresses(def, qemuCaps);
1789 1790 1791
    if (rc)
        return rc;

1792 1793 1794
    rc = qemuDomainAssignS390Addresses(def, qemuCaps, obj);
    if (rc)
        return rc;
1795

1796 1797 1798 1799
    rc = qemuDomainAssignARMVirtioMMIOAddresses(def, qemuCaps);
    if (rc)
        return rc;

1800
    return qemuDomainAssignPCIAddresses(def, qemuCaps, obj);
1801
}
1802

1803

1804
virDomainPCIAddressSetPtr
1805 1806 1807
qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
                              unsigned int nbuses,
                              bool dryRun)
1808
{
1809
    virDomainPCIAddressSetPtr addrs;
1810
    size_t i;
1811

1812 1813
    if ((addrs = virDomainPCIAddressSetAlloc(nbuses)) == NULL)
        return NULL;
1814

1815
    addrs->nbuses = nbuses;
1816
    addrs->dryRun = dryRun;
1817

1818 1819 1820 1821 1822 1823 1824 1825
    /* As a safety measure, set default model='pci-root' for first pci
     * controller and 'pci-bridge' for all subsequent. After setting
     * those defaults, then scan the config and set the actual model
     * for all addrs[idx]->bus that already have a corresponding
     * controller in the config.
     *
     */
    if (nbuses > 0)
1826 1827
        virDomainPCIAddressBusSetModel(&addrs->buses[0],
                                       VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT);
1828
    for (i = 1; i < nbuses; i++) {
1829 1830
        virDomainPCIAddressBusSetModel(&addrs->buses[i],
                                       VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE);
1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845
    }

    for (i = 0; i < def->ncontrollers; i++) {
        size_t idx = def->controllers[i]->idx;

        if (def->controllers[i]->type != VIR_DOMAIN_CONTROLLER_TYPE_PCI)
            continue;

        if (idx >= addrs->nbuses) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Inappropriate new pci controller index %zu "
                             "not found in addrs"), idx);
            goto error;
        }

1846 1847
        if (virDomainPCIAddressBusSetModel(&addrs->buses[idx],
                                           def->controllers[i]->model) < 0)
1848 1849
            goto error;
        }
1850

1851 1852 1853 1854 1855
    if (virDomainDeviceInfoIterate(def, qemuCollectPCIAddress, addrs) < 0)
        goto error;

    return addrs;

1856
 error:
1857
    virDomainPCIAddressSetFree(addrs);
1858 1859 1860
    return NULL;
}

1861

1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872
void
qemuDomainReleaseDeviceAddress(virDomainObjPtr vm,
                               virDomainDeviceInfoPtr info,
                               const char *devstr)
{
    qemuDomainObjPrivatePtr priv = vm->privateData;

    if (!devstr)
        devstr = info->alias;

    if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW &&
1873
        qemuDomainMachineIsS390CCW(vm->def) &&
1874
        virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW) &&
J
Ján Tomko 已提交
1875
        virDomainCCWAddressReleaseAddr(priv->ccwaddrs, info) < 0)
1876 1877 1878 1879
        VIR_WARN("Unable to release CCW address on %s",
                 NULLSTR(devstr));
    else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
             virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
1880 1881
             virDomainPCIAddressReleaseSlot(priv->pciaddrs,
                                            &info->addr.pci) < 0)
1882 1883
        VIR_WARN("Unable to release PCI address on %s",
                 NULLSTR(devstr));
1884 1885 1886 1887
    if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL &&
        virDomainVirtioSerialAddrRelease(priv->vioserialaddrs, info) < 0)
        VIR_WARN("Unable to release virtio-serial address on %s",
                 NULLSTR(devstr));
1888 1889 1890
}


1891 1892 1893 1894 1895 1896 1897
#define IS_USB2_CONTROLLER(ctrl) \
    (((ctrl)->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) && \
     ((ctrl)->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1 || \
      (ctrl)->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI1 || \
      (ctrl)->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI2 || \
      (ctrl)->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI3))

1898 1899 1900 1901

static int
qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
                                virQEMUCapsPtr qemuCaps,
1902
                                virDomainPCIAddressSetPtr addrs)
1903
{
1904
    int ret = -1;
1905
    size_t i;
1906
    virDevicePCIAddress tmp_addr;
1907
    bool qemuDeviceVideoUsable = virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
1908
    char *addrStr = NULL;
1909
    virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI;
1910

1911
    /* Verify that first IDE and USB controllers (if any) is on the PIIX3, fn 1 */
1912
    for (i = 0; i < def->ncontrollers; i++) {
1913 1914 1915 1916 1917 1918 1919 1920
        /* First IDE controller lives on the PIIX3 at slot=1, function=1 */
        if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE &&
            def->controllers[i]->idx == 0) {
            if (def->controllers[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
                if (def->controllers[i]->info.addr.pci.domain != 0 ||
                    def->controllers[i]->info.addr.pci.bus != 0 ||
                    def->controllers[i]->info.addr.pci.slot != 1 ||
                    def->controllers[i]->info.addr.pci.function != 1) {
1921 1922
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("Primary IDE controller must have PCI address 0:0:1.1"));
1923
                    goto cleanup;
1924 1925 1926 1927 1928 1929 1930 1931
                }
            } else {
                def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
                def->controllers[i]->info.addr.pci.domain = 0;
                def->controllers[i]->info.addr.pci.bus = 0;
                def->controllers[i]->info.addr.pci.slot = 1;
                def->controllers[i]->info.addr.pci.function = 1;
            }
1932 1933
        } else if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
                   def->controllers[i]->idx == 0 &&
1934 1935
                   (def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI ||
                    def->controllers[i]->model == -1)) {
1936 1937 1938 1939 1940
            if (def->controllers[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
                if (def->controllers[i]->info.addr.pci.domain != 0 ||
                    def->controllers[i]->info.addr.pci.bus != 0 ||
                    def->controllers[i]->info.addr.pci.slot != 1 ||
                    def->controllers[i]->info.addr.pci.function != 2) {
1941 1942
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("PIIX3 USB controller must have PCI address 0:0:1.2"));
1943
                    goto cleanup;
1944 1945 1946 1947 1948 1949 1950 1951
                }
            } else {
                def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
                def->controllers[i]->info.addr.pci.domain = 0;
                def->controllers[i]->info.addr.pci.bus = 0;
                def->controllers[i]->info.addr.pci.slot = 1;
                def->controllers[i]->info.addr.pci.function = 2;
            }
1952 1953 1954 1955 1956 1957
        }
    }

    /* PIIX3 (ISA bridge, IDE controller, something else unknown, USB controller)
     * hardcoded slot=1, multifunction device
     */
1958 1959 1960
    if (addrs->nbuses) {
        memset(&tmp_addr, 0, sizeof(tmp_addr));
        tmp_addr.slot = 1;
1961
        if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0)
1962
            goto cleanup;
W
Wen Congyang 已提交
1963
    }
1964 1965

    if (def->nvideos > 0) {
1966 1967 1968 1969 1970 1971
        /* Because the PIIX3 integrated IDE/USB controllers are
         * already at slot 1, when qemu looks for the first free slot
         * to place the VGA controller (which is always the first
         * device added after integrated devices), it *always* ends up
         * at slot 2.
         */
1972 1973
        virDomainVideoDefPtr primaryVideo = def->videos[0];
        if (primaryVideo->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
1974 1975 1976
            memset(&tmp_addr, 0, sizeof(tmp_addr));
            tmp_addr.slot = 2;

1977
            if (!(addrStr = virDomainPCIAddressAsString(&tmp_addr)))
1978
                goto cleanup;
1979 1980
            if (!virDomainPCIAddressValidate(addrs, &tmp_addr,
                                             addrStr, flags, false))
1981
                goto cleanup;
1982

1983
            if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
1984
                if (qemuDeviceVideoUsable) {
1985 1986 1987
                    if (virDomainPCIAddressReserveNextSlot(addrs,
                                                           &primaryVideo->info,
                                                           flags) < 0)
1988
                        goto cleanup;
1989 1990 1991 1992
                } else {
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("PCI address 0:0:2.0 is in use, "
                                     "QEMU needs it for primary video"));
1993
                    goto cleanup;
1994
                }
1995
            } else {
1996
                if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0)
1997 1998 1999
                    goto cleanup;
                primaryVideo->info.addr.pci = tmp_addr;
                primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
2000 2001 2002 2003 2004 2005
            }
        } else if (!qemuDeviceVideoUsable) {
            if (primaryVideo->info.addr.pci.domain != 0 ||
                primaryVideo->info.addr.pci.bus != 0 ||
                primaryVideo->info.addr.pci.slot != 2 ||
                primaryVideo->info.addr.pci.function != 0) {
2006 2007
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("Primary video card must have PCI address 0:0:2.0"));
2008
                goto cleanup;
2009
            }
2010
            /* If TYPE == PCI, then qemuCollectPCIAddress() function
2011
             * has already reserved the address, so we must skip */
2012
        }
2013
    } else if (addrs->nbuses && !qemuDeviceVideoUsable) {
2014 2015
        memset(&tmp_addr, 0, sizeof(tmp_addr));
        tmp_addr.slot = 2;
2016

2017
        if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
2018 2019 2020
            VIR_DEBUG("PCI address 0:0:2.0 in use, future addition of a video"
                      " device will not be possible without manual"
                      " intervention");
2021
        } else if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0) {
2022
            goto cleanup;
2023 2024
        }
    }
2025
    ret = 0;
2026
 cleanup:
2027 2028
    VIR_FREE(addrStr);
    return ret;
2029 2030 2031
}


2032 2033 2034
static int
qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
                                    virQEMUCapsPtr qemuCaps,
2035
                                    virDomainPCIAddressSetPtr addrs)
2036
{
2037
    int ret = -1;
2038 2039 2040
    size_t i;
    virDevicePCIAddress tmp_addr;
    bool qemuDeviceVideoUsable = virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
2041
    char *addrStr = NULL;
2042
    virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPE_PCIE;
2043 2044

    for (i = 0; i < def->ncontrollers; i++) {
2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066
        switch (def->controllers[i]->type) {
        case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
            /* Verify that the first SATA controller is at 00:1F.2 the
             * q35 machine type *always* has a SATA controller at this
             * address.
             */
            if (def->controllers[i]->idx == 0) {
                if (def->controllers[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
                    if (def->controllers[i]->info.addr.pci.domain != 0 ||
                        def->controllers[i]->info.addr.pci.bus != 0 ||
                        def->controllers[i]->info.addr.pci.slot != 0x1F ||
                        def->controllers[i]->info.addr.pci.function != 2) {
                        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                       _("Primary SATA controller must have PCI address 0:0:1f.2"));
                        goto cleanup;
                    }
                } else {
                    def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
                    def->controllers[i]->info.addr.pci.domain = 0;
                    def->controllers[i]->info.addr.pci.bus = 0;
                    def->controllers[i]->info.addr.pci.slot = 0x1F;
                    def->controllers[i]->info.addr.pci.function = 2;
2067 2068
                }
            }
2069
            break;
2070 2071 2072 2073 2074 2075 2076 2077 2078 2079

        case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
            if (def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE &&
                def->controllers[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
                /* Try to assign this bridge to 00:1E.0 (because that
                * is its standard location on real hardware) unless
                * it's already taken, but don't insist on it.
                */
                memset(&tmp_addr, 0, sizeof(tmp_addr));
                tmp_addr.slot = 0x1E;
2080 2081 2082
                if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
                    if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr,
                                                       flags, true, false) < 0)
2083 2084 2085 2086 2087 2088 2089 2090 2091
                        goto cleanup;
                    def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
                    def->controllers[i]->info.addr.pci.domain = 0;
                    def->controllers[i]->info.addr.pci.bus = 0;
                    def->controllers[i]->info.addr.pci.slot = 0x1E;
                    def->controllers[i]->info.addr.pci.function = 0;
                }
            }
            break;
2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104
        }
    }

    /* Reserve slot 0x1F function 0 (ISA bridge, not in config model)
     * and function 3 (SMBus, also not (yet) in config model). As with
     * the SATA controller, these devices are always present in a q35
     * machine; there is no way to not have them.
     */
    if (addrs->nbuses) {
        memset(&tmp_addr, 0, sizeof(tmp_addr));
        tmp_addr.slot = 0x1F;
        tmp_addr.function = 0;
        tmp_addr.multi = 1;
2105 2106
        if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,
                                           false, false) < 0)
2107
           goto cleanup;
2108 2109
        tmp_addr.function = 3;
        tmp_addr.multi = 0;
2110 2111
        if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,
                                           false, false) < 0)
2112
           goto cleanup;
2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123
    }

    if (def->nvideos > 0) {
        /* NB: unlike the pc machinetypes, on q35 machinetypes the
         * integrated devices are at slot 0x1f, so when qemu looks for
         * the first free lot for the first VGA, it will always be at
         * slot 1 (which was used up by the integrated PIIX3 devices
         * on pc machinetypes).
         */
        virDomainVideoDefPtr primaryVideo = def->videos[0];
        if (primaryVideo->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
2124 2125 2126
            memset(&tmp_addr, 0, sizeof(tmp_addr));
            tmp_addr.slot = 1;

2127
            if (!(addrStr = virDomainPCIAddressAsString(&tmp_addr)))
2128
                goto cleanup;
2129 2130
            if (!virDomainPCIAddressValidate(addrs, &tmp_addr,
                                             addrStr, flags, false))
2131
                goto cleanup;
2132

2133
            if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
2134
                if (qemuDeviceVideoUsable) {
2135 2136 2137
                    if (virDomainPCIAddressReserveNextSlot(addrs,
                                                           &primaryVideo->info,
                                                           flags) < 0)
2138
                        goto cleanup;
2139 2140 2141 2142
                } else {
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("PCI address 0:0:1.0 is in use, "
                                     "QEMU needs it for primary video"));
2143
                    goto cleanup;
2144
                }
2145
            } else {
2146
                if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0)
2147 2148 2149
                    goto cleanup;
                primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
                primaryVideo->info.addr.pci = tmp_addr;
2150 2151 2152 2153 2154 2155 2156 2157
            }
        } else if (!qemuDeviceVideoUsable) {
            if (primaryVideo->info.addr.pci.domain != 0 ||
                primaryVideo->info.addr.pci.bus != 0 ||
                primaryVideo->info.addr.pci.slot != 1 ||
                primaryVideo->info.addr.pci.function != 0) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("Primary video card must have PCI address 0:0:1.0"));
2158
                goto cleanup;
2159
            }
2160
            /* If TYPE == PCI, then qemuCollectPCIAddress() function
2161 2162 2163 2164 2165 2166
             * has already reserved the address, so we must skip */
        }
    } else if (addrs->nbuses && !qemuDeviceVideoUsable) {
        memset(&tmp_addr, 0, sizeof(tmp_addr));
        tmp_addr.slot = 1;

2167
        if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
2168 2169 2170 2171
            VIR_DEBUG("PCI address 0:0:1.0 in use, future addition of a video"
                      " device will not be possible without manual"
                      " intervention");
            virResetLastError();
2172
        } else if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0) {
2173
            goto cleanup;
2174 2175
        }
    }
2176
    ret = 0;
2177
 cleanup:
2178 2179
    VIR_FREE(addrStr);
    return ret;
2180 2181
}

2182 2183 2184 2185 2186
static int
qemuValidateDevicePCISlotsChipsets(virDomainDefPtr def,
                                   virQEMUCapsPtr qemuCaps,
                                   virDomainPCIAddressSetPtr addrs)
{
2187
    if (qemuDomainMachineIsI440FX(def) &&
2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198
        qemuValidateDevicePCISlotsPIIX3(def, qemuCaps, addrs) < 0) {
        return -1;
    }

    if (qemuDomainMachineIsQ35(def) &&
        qemuDomainValidateDevicePCISlotsQ35(def, qemuCaps, addrs) < 0) {
        return -1;
    }

    return 0;
}
2199

2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213
int
qemuDomainAssignPCIAddresses(virDomainDefPtr def,
                             virQEMUCapsPtr qemuCaps,
                             virDomainObjPtr obj)
{
    int ret = -1;
    virDomainPCIAddressSetPtr addrs = NULL;
    qemuDomainObjPrivatePtr priv = NULL;

    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
        int max_idx = -1;
        int nbuses = 0;
        size_t i;
        int rv;
2214 2215
        bool buses_reserved = true;

2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233
        virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPE_PCI;

        for (i = 0; i < def->ncontrollers; i++) {
            if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) {
                if ((int) def->controllers[i]->idx > max_idx)
                    max_idx = def->controllers[i]->idx;
            }
        }

        nbuses = max_idx + 1;

        if (nbuses > 0 &&
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCI_BRIDGE)) {
            virDomainDeviceInfo info;

            /* 1st pass to figure out how many PCI bridges we need */
            if (!(addrs = qemuDomainPCIAddressSetCreate(def, nbuses, true)))
                goto cleanup;
2234 2235 2236 2237

            if (qemuValidateDevicePCISlotsChipsets(def, qemuCaps, addrs) < 0)
                goto cleanup;

2238
            for (i = 0; i < addrs->nbuses; i++) {
2239 2240
                if (!qemuDomainPCIBusFullyReserved(&addrs->buses[i]))
                    buses_reserved = false;
2241 2242
            }

2243 2244 2245 2246 2247 2248 2249
            /* Reserve 1 extra slot for a (potential) bridge only if buses
             * are not fully reserved yet
             */
            if (!buses_reserved &&
                virDomainPCIAddressReserveNextSlot(addrs, &info, flags) < 0)
                goto cleanup;

2250
            if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0)
2251 2252
                goto cleanup;

2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278
            for (i = 1; i < addrs->nbuses; i++) {
                virDomainPCIAddressBusPtr bus = &addrs->buses[i];

                if ((rv = virDomainDefMaybeAddController(
                         def, VIR_DOMAIN_CONTROLLER_TYPE_PCI,
                         i, bus->model)) < 0)
                    goto cleanup;
                /* If we added a new bridge, we will need one more address */
                if (rv > 0 &&
                    virDomainPCIAddressReserveNextSlot(addrs, &info, flags) < 0)
                    goto cleanup;
            }
            nbuses = addrs->nbuses;
            virDomainPCIAddressSetFree(addrs);
            addrs = NULL;

        } else if (max_idx > 0) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("PCI bridges are not supported "
                             "by this QEMU binary"));
            goto cleanup;
        }

        if (!(addrs = qemuDomainPCIAddressSetCreate(def, nbuses, false)))
            goto cleanup;

2279
        if (qemuDomainSupportsPCI(def, qemuCaps)) {
2280 2281 2282
            if (qemuValidateDevicePCISlotsChipsets(def, qemuCaps, addrs) < 0)
                goto cleanup;

2283
            if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0)
2284
                goto cleanup;
2285 2286

            for (i = 0; i < def->ncontrollers; i++) {
2287 2288 2289
                virDomainControllerDefPtr cont = def->controllers[i];
                int idx = cont->idx;
                virDevicePCIAddressPtr addr;
2290
                virDomainPCIControllerOptsPtr options;
2291 2292 2293 2294 2295

                if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_PCI)
                    continue;

                addr = &cont->info.addr.pci;
2296 2297 2298 2299 2300 2301 2302 2303 2304 2305
                options = &cont->opts.pciopts;

                /* set defaults for any other auto-generated config
                 * options for this controller that haven't been
                 * specified in config.
                 */
                switch ((virDomainControllerModelPCI)cont->model) {
                case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
                    if (options->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE)
                        options->modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCI_BRIDGE;
2306 2307
                    if (options->chassisNr == -1)
                        options->chassisNr = cont->idx;
2308 2309 2310 2311 2312
                    break;
                case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
                    if (options->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE)
                        options->modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_I82801B11_BRIDGE;
                    break;
2313
                case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT:
2314 2315 2316 2317 2318 2319 2320
                    if (options->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE)
                        options->modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_IOH3420;
                    if (options->chassis == -1)
                       options->chassis = cont->idx;
                    if (options->port == -1)
                       options->port = (addr->slot << 3) + addr->function;
                    break;
2321
                case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT:
2322 2323 2324
                    if (options->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE)
                        options->modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_X3130_UPSTREAM;
                    break;
2325
                case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT:
2326 2327 2328 2329 2330 2331 2332
                    if (options->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE)
                        options->modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_XIO3130_DOWNSTREAM;
                    if (options->chassis == -1)
                       options->chassis = cont->idx;
                    if (options->port == -1)
                       options->port = addr->slot;
                    break;
2333 2334 2335 2336 2337 2338
                case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
                case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
                case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST:
                    break;
                }

2339 2340 2341
                /* check if every PCI bridge controller's ID is greater than
                 * the bus it is placed onto
                 */
2342 2343
                if (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE &&
                    idx <= addr->bus) {
2344 2345 2346 2347
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("failed to create PCI bridge "
                                     "on bus %d: too many devices with fixed "
                                     "addresses"),
2348
                                   addr->bus);
2349 2350 2351
                    goto cleanup;
                }
            }
2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376
        }
    }

    if (obj && obj->privateData) {
        priv = obj->privateData;
        if (addrs) {
            /* if this is the live domain object, we persist the PCI addresses*/
            virDomainPCIAddressSetFree(priv->pciaddrs);
            priv->persistentAddrs = 1;
            priv->pciaddrs = addrs;
            addrs = NULL;
        } else {
            priv->persistentAddrs = 0;
        }
    }

    ret = 0;

 cleanup:
    virDomainPCIAddressSetFree(addrs);

    return ret;
}


2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393
/*
 * This assigns static PCI slots to all configured devices.
 * The ordering here is chosen to match the ordering used
 * with old QEMU < 0.12, so that if a user updates a QEMU
 * host from old QEMU to QEMU >= 0.12, their guests should
 * get PCI addresses in the same order as before.
 *
 * NB, if they previously hotplugged devices then all bets
 * are off. Hotplug for old QEMU was unfixably broken wrt
 * to stable PCI addressing.
 *
 * Order is:
 *
 *  - Host bridge (slot 0)
 *  - PIIX3 ISA bridge, IDE controller, something else unknown, USB controller (slot 1)
 *  - Video (slot 2)
 *
2394 2395 2396
 *  - These integrated devices were already added by
 *    qemuValidateDevicePCISlotsChipsets invoked right before this function
 *
2397 2398 2399 2400 2401 2402 2403 2404
 * Incrementally assign slots from 3 onwards:
 *
 *  - Net
 *  - Sound
 *  - SCSI controllers
 *  - VirtIO block
 *  - VirtIO balloon
 *  - Host device passthrough
2405
 *  - Watchdog
M
Michal Privoznik 已提交
2406
 *  - pci serial devices
2407 2408 2409 2410 2411 2412 2413 2414
 *
 * Prior to this function being invoked, qemuCollectPCIAddress() will have
 * added all existing PCI addresses from the 'def' to 'addrs'. Thus this
 * function must only try to reserve addresses if info.type == NONE and
 * skip over info.type == PCI
 */
int
qemuAssignDevicePCISlots(virDomainDefPtr def,
2415
                         virQEMUCapsPtr qemuCaps,
2416
                         virDomainPCIAddressSetPtr addrs)
2417 2418
{
    size_t i, j;
2419
    virDomainPCIConnectFlags flags;
2420 2421
    virDevicePCIAddress tmp_addr;

2422 2423 2424 2425 2426
    /* PCI controllers */
    for (i = 0; i < def->ncontrollers; i++) {
        if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) {
            if (def->controllers[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
                continue;
2427 2428
            switch (def->controllers[i]->model) {
            case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
L
Laine Stump 已提交
2429 2430
            case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
                /* pci-root and pcie-root are implicit in the machine,
2431 2432 2433 2434 2435 2436
                 * and needs no address */
                continue;
            case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
                /* pci-bridge doesn't require hot-plug
                 * (although it does provide hot-plug in its slots)
                 */
2437
                flags = VIR_PCI_CONNECT_TYPE_PCI;
2438
                break;
2439 2440 2441 2442
            case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
                /* dmi-to-pci-bridge requires a non-hotplug PCIe
                 * slot
                 */
2443
                flags = VIR_PCI_CONNECT_TYPE_PCIE;
2444
                break;
2445 2446 2447 2448
            case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT:
                /* pcie-root-port can only plug into pcie-root */
                flags = VIR_PCI_CONNECT_TYPE_PCIE_ROOT;
                break;
2449 2450 2451 2452 2453 2454
            case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT:
                /* pcie-switch really does need a real PCIe
                 * port, but it doesn't need to be pcie-root
                 */
                flags = VIR_PCI_CONNECT_TYPE_PCIE_PORT;
                break;
2455 2456 2457 2458
            case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT:
                /* pcie-switch-port can only plug into pcie-switch */
                flags = VIR_PCI_CONNECT_TYPE_PCIE_SWITCH;
                break;
2459
            default:
2460
                flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI;
2461 2462
                break;
            }
2463 2464 2465
            if (virDomainPCIAddressReserveNextSlot(addrs,
                                                   &def->controllers[i]->info,
                                                   flags) < 0)
2466 2467 2468 2469
                goto error;
        }
    }

2470
    flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI;
2471

2472
    for (i = 0; i < def->nfss; i++) {
2473 2474 2475 2476 2477
        if (def->fss[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            continue;

        /* Only support VirtIO-9p-pci so far. If that changes,
         * we might need to skip devices here */
2478 2479
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->fss[i]->info,
                                               flags) < 0)
2480 2481 2482 2483
            goto error;
    }

    /* Network interfaces */
2484
    for (i = 0; i < def->nnets; i++) {
2485 2486 2487 2488 2489 2490
        /* type='hostdev' network devices might be USB, and are also
         * in hostdevs list anyway, so handle them with other hostdevs
         * instead of here.
         */
        if ((def->nets[i]->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) ||
            (def->nets[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)) {
2491
            continue;
2492
        }
2493 2494
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->nets[i]->info,
                                               flags) < 0)
2495 2496 2497 2498
            goto error;
    }

    /* Sound cards */
2499
    for (i = 0; i < def->nsounds; i++) {
2500 2501
        if (def->sounds[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            continue;
2502
        /* Skip ISA sound card, PCSPK and usb-audio */
2503
        if (def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_SB16 ||
2504 2505
            def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_PCSPK ||
            def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_USB)
2506 2507
            continue;

2508 2509
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->sounds[i]->info,
                                               flags) < 0)
2510 2511 2512
            goto error;
    }

2513
    /* Device controllers (SCSI, USB, but not IDE, FDC or CCID) */
2514
    for (i = 0; i < def->ncontrollers; i++) {
2515
        /* PCI controllers have been dealt with earlier */
2516 2517
        if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI)
            continue;
2518

2519 2520 2521 2522 2523
        /* USB controller model 'none' doesn't need a PCI address */
        if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
            def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE)
            continue;

E
Eric Blake 已提交
2524 2525 2526
        /* FDC lives behind the ISA bridge; CCID is a usb device */
        if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_FDC ||
            def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_CCID)
2527 2528 2529 2530 2531 2532 2533 2534 2535 2536
            continue;

        /* First IDE controller lives on the PIIX3 at slot=1, function=1,
           dealt with earlier on*/
        if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE &&
            def->controllers[i]->idx == 0)
            continue;

        if (def->controllers[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            continue;
2537 2538 2539

        /* USB2 needs special handling to put all companions in the same slot */
        if (IS_USB2_CONTROLLER(def->controllers[i])) {
2540
            virDevicePCIAddress addr = { 0, 0, 0, 0, false };
2541
            memset(&tmp_addr, 0, sizeof(tmp_addr));
2542
            for (j = 0; j < i; j++) {
2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555
                if (IS_USB2_CONTROLLER(def->controllers[j]) &&
                    def->controllers[j]->idx == def->controllers[i]->idx) {
                    addr = def->controllers[j]->info.addr.pci;
                    break;
                }
            }

            switch (def->controllers[i]->model) {
            case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1:
                addr.function = 7;
                break;
            case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI1:
                addr.function = 0;
J
Ján Tomko 已提交
2556
                addr.multi = VIR_TRISTATE_SWITCH_ON;
2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568
                break;
            case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI2:
                addr.function = 1;
                break;
            case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI3:
                addr.function = 2;
                break;
            }

            if (addr.slot == 0) {
                /* This is the first part of the controller, so need
                 * to find a free slot & then reserve a function */
2569
                if (virDomainPCIAddressGetNextSlot(addrs, &tmp_addr, flags) < 0)
2570 2571
                    goto error;

2572 2573
                addr.bus = tmp_addr.bus;
                addr.slot = tmp_addr.slot;
2574 2575 2576 2577

                addrs->lastaddr = addr;
                addrs->lastaddr.function = 0;
                addrs->lastaddr.multi = 0;
2578 2579
            }
            /* Finally we can reserve the slot+function */
2580 2581
            if (virDomainPCIAddressReserveAddr(addrs, &addr, flags,
                                               false, false) < 0)
2582 2583 2584 2585 2586
                goto error;

            def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
            def->controllers[i]->info.addr.pci = addr;
        } else {
2587 2588 2589
            if (virDomainPCIAddressReserveNextSlot(addrs,
                                                   &def->controllers[i]->info,
                                                   flags) < 0)
2590 2591
                goto error;
        }
2592 2593
    }

2594
    /* Disks (VirtIO only for now) */
2595
    for (i = 0; i < def->ndisks; i++) {
2596 2597 2598 2599
        /* Only VirtIO disks use PCI addrs */
        if (def->disks[i]->bus != VIR_DOMAIN_DISK_BUS_VIRTIO)
            continue;

2600 2601 2602
        /* don't touch s390 devices */
        if (def->disks[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI ||
            def->disks[i]->info.type ==
2603 2604 2605
            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 ||
            def->disks[i]->info.type ==
            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
2606 2607
            continue;

2608 2609 2610 2611 2612 2613
        /* Also ignore virtio-mmio disks if our machine allows them */
        if (def->disks[i]->info.type ==
            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO &&
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_MMIO))
            continue;

2614
        if (def->disks[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
J
Ján Tomko 已提交
2615 2616 2617
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("virtio disk cannot have an address of type '%s'"),
                           virDomainDeviceAddressTypeToString(def->disks[i]->info.type));
2618 2619 2620
            goto error;
        }

2621 2622
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->disks[i]->info,
                                               flags) < 0)
2623 2624 2625 2626
            goto error;
    }

    /* Host PCI devices */
2627
    for (i = 0; i < def->nhostdevs; i++) {
2628
        if (def->hostdevs[i]->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
2629 2630 2631 2632 2633
            continue;
        if (def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
            def->hostdevs[i]->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
            continue;

2634 2635 2636
        if (virDomainPCIAddressReserveNextSlot(addrs,
                                               def->hostdevs[i]->info,
                                               flags) < 0)
2637 2638 2639 2640 2641 2642 2643
            goto error;
    }

    /* VirtIO balloon */
    if (def->memballoon &&
        def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO &&
        def->memballoon->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
2644 2645 2646
        if (virDomainPCIAddressReserveNextSlot(addrs,
                                               &def->memballoon->info,
                                               flags) < 0)
2647 2648 2649
            goto error;
    }

2650
    /* VirtIO RNG */
2651 2652 2653 2654 2655
    for (i = 0; i < def->nrngs; i++) {
        if (def->rngs[i]->model != VIR_DOMAIN_RNG_MODEL_VIRTIO ||
            def->rngs[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            continue;

2656
        if (virDomainPCIAddressReserveNextSlot(addrs,
2657
                                               &def->rngs[i]->info, flags) < 0)
2658 2659 2660
            goto error;
    }

2661
    /* A watchdog - check if it is a PCI device */
2662
    if (def->watchdog &&
2663
        def->watchdog->model == VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB &&
2664
        def->watchdog->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
2665 2666
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->watchdog->info,
                                               flags) < 0)
2667 2668 2669
            goto error;
    }

2670 2671 2672 2673
    /* Assign a PCI slot to the primary video card if there is not an
     * assigned address. */
    if (def->nvideos > 0 &&
        def->videos[0]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
2674 2675
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->videos[0]->info,
                                               flags) < 0)
2676 2677
            goto error;
    }
2678

2679
    /* Further non-primary video cards which have to be qxl type */
2680
    for (i = 1; i < def->nvideos; i++) {
2681 2682 2683 2684 2685
        if (def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_QXL) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("non-primary video device must be type of 'qxl'"));
            goto error;
        }
2686 2687
        if (def->videos[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            continue;
2688 2689
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->videos[i]->info,
                                               flags) < 0)
2690 2691
            goto error;
    }
2692 2693 2694 2695 2696 2697 2698 2699 2700 2701

    /* Shared Memory */
    for (i = 0; i < def->nshmems; i++) {
        if (def->shmems[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            continue;

        if (virDomainPCIAddressReserveNextSlot(addrs,
                                               &def->shmems[i]->info, flags) < 0)
            goto error;
    }
2702
    for (i = 0; i < def->ninputs; i++) {
2703 2704 2705 2706 2707 2708 2709 2710
        if (def->inputs[i]->bus != VIR_DOMAIN_INPUT_BUS_VIRTIO)
            continue;
        if (def->inputs[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            continue;

        if (virDomainPCIAddressReserveNextSlot(addrs,
                                               &def->inputs[i]->info, flags) < 0)
            goto error;
2711
    }
2712
    for (i = 0; i < def->nparallels; i++) {
2713 2714
        /* Nada - none are PCI based (yet) */
    }
2715
    for (i = 0; i < def->nserials; i++) {
M
Michal Privoznik 已提交
2716 2717 2718 2719 2720 2721 2722 2723 2724 2725
        virDomainChrDefPtr chr = def->serials[i];

        if (chr->targetType != VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_PCI)
            continue;

        if (chr->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            continue;

        if (virDomainPCIAddressReserveNextSlot(addrs, &chr->info, flags) < 0)
            goto error;
2726
    }
2727
    for (i = 0; i < def->nchannels; i++) {
2728 2729
        /* Nada - none are PCI based (yet) */
    }
2730
    for (i = 0; i < def->nhubs; i++) {
M
Marc-André Lureau 已提交
2731 2732
        /* Nada - none are PCI based (yet) */
    }
2733 2734 2735

    return 0;

2736
 error:
2737 2738 2739 2740 2741
    return -1;
}

static int
qemuBuildDeviceAddressStr(virBufferPtr buf,
2742
                          virDomainDefPtr domainDef,
2743
                          virDomainDeviceInfoPtr info,
2744
                          virQEMUCapsPtr qemuCaps)
2745
{
2746 2747
    int ret = -1;
    char *devStr = NULL;
2748
    const char *contAlias = NULL;
2749

2750
    if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
2751 2752
        size_t i;

2753
        if (!(devStr = virDomainPCIAddressAsString(&info->addr.pci)))
2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780
            goto cleanup;
        for (i = 0; i < domainDef->ncontrollers; i++) {
            virDomainControllerDefPtr cont = domainDef->controllers[i];

            if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI &&
                cont->idx == info->addr.pci.bus) {
                contAlias = cont->info.alias;
                if (!contAlias) {
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("Device alias was not set for PCI "
                                     "controller with index %u required "
                                     "for device at address %s"),
                                   info->addr.pci.bus, devStr);
                    goto cleanup;
                }
                break;
            }
        }
        if (!contAlias) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Could not find PCI "
                             "controller with index %u required "
                             "for device at address %s"),
                           info->addr.pci.bus, devStr);
            goto cleanup;
        }

2781
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIFUNCTION)) {
W
Wen Congyang 已提交
2782
            if (info->addr.pci.function != 0) {
2783 2784 2785
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("Only PCI device addresses with function=0 "
                                 "are supported with this QEMU binary"));
2786
                goto cleanup;
2787
            }
J
Ján Tomko 已提交
2788
            if (info->addr.pci.multi == VIR_TRISTATE_SWITCH_ON) {
2789 2790 2791
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("'multifunction=on' is not supported with "
                                 "this QEMU binary"));
2792
                goto cleanup;
W
Wen Congyang 已提交
2793
            }
2794 2795
        }

2796 2797 2798 2799 2800 2801
        if (info->addr.pci.bus != 0 &&
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCI_BRIDGE)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Multiple PCI buses are not supported "
                             "with this QEMU binary"));
            goto cleanup;
2802
        }
2803 2804
        virBufferAsprintf(buf, ",bus=%s", contAlias);

J
Ján Tomko 已提交
2805
        if (info->addr.pci.multi == VIR_TRISTATE_SWITCH_ON)
2806
            virBufferAddLit(buf, ",multifunction=on");
J
Ján Tomko 已提交
2807
        else if (info->addr.pci.multi == VIR_TRISTATE_SWITCH_OFF)
2808 2809 2810 2811
            virBufferAddLit(buf, ",multifunction=off");
        virBufferAsprintf(buf, ",addr=0x%x", info->addr.pci.slot);
        if (info->addr.pci.function != 0)
           virBufferAsprintf(buf, ".0x%x", info->addr.pci.function);
2812
    } else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
2813 2814 2815 2816 2817
        if (!(contAlias = virDomainControllerAliasFind(domainDef,
                                                       VIR_DOMAIN_CONTROLLER_TYPE_USB,
                                                       info->addr.usb.bus)))
            goto cleanup;
        virBufferAsprintf(buf, ",bus=%s.0,port=%s", contAlias, info->addr.usb.port);
2818 2819 2820
    } else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO) {
        if (info->addr.spaprvio.has_reg)
            virBufferAsprintf(buf, ",reg=0x%llx", info->addr.spaprvio.reg);
2821 2822 2823 2824 2825 2826
    } else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
        if (info->addr.ccw.assigned)
            virBufferAsprintf(buf, ",devno=%x.%x.%04x",
                              info->addr.ccw.cssid,
                              info->addr.ccw.ssid,
                              info->addr.ccw.devno);
2827 2828 2829 2830
    } else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA) {
        virBufferAsprintf(buf, ",iobase=0x%x,irq=0x%x",
                          info->addr.isa.iobase,
                          info->addr.isa.irq);
2831
    }
2832

2833
    ret = 0;
2834
 cleanup:
2835 2836
    VIR_FREE(devStr);
    return ret;
2837 2838
}

2839 2840 2841
static int
qemuBuildRomStr(virBufferPtr buf,
                virDomainDeviceInfoPtr info,
2842
                virQEMUCapsPtr qemuCaps)
2843
{
2844
    if (info->rombar || info->romfile) {
2845
        if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
2846 2847
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("rombar and romfile are supported only for PCI devices"));
2848 2849
            return -1;
        }
2850
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_ROMBAR)) {
2851 2852
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("rombar and romfile not supported in this QEMU binary"));
2853 2854 2855 2856
            return -1;
        }

        switch (info->rombar) {
J
Ján Tomko 已提交
2857
        case VIR_TRISTATE_SWITCH_OFF:
2858 2859
            virBufferAddLit(buf, ",rombar=0");
            break;
J
Ján Tomko 已提交
2860
        case VIR_TRISTATE_SWITCH_ON:
2861 2862 2863 2864 2865
            virBufferAddLit(buf, ",rombar=1");
            break;
        default:
            break;
        }
2866 2867
        if (info->romfile)
           virBufferAsprintf(buf, ",romfile=%s", info->romfile);
2868 2869 2870 2871
    }
    return 0;
}

2872 2873
static int
qemuBuildIoEventFdStr(virBufferPtr buf,
J
Ján Tomko 已提交
2874
                      virTristateSwitch use,
2875
                      virQEMUCapsPtr qemuCaps)
2876
{
2877
    if (use && virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_IOEVENTFD))
2878
        virBufferAsprintf(buf, ",ioeventfd=%s",
J
Ján Tomko 已提交
2879
                          virTristateSwitchTypeToString(use));
2880 2881
    return 0;
}
2882 2883

#define QEMU_SERIAL_PARAM_ACCEPTED_CHARS \
2884
  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_ "
2885 2886 2887 2888

static int
qemuSafeSerialParamValue(const char *value)
{
2889
    if (strspn(value, QEMU_SERIAL_PARAM_ACCEPTED_CHARS) != strlen(value)) {
2890 2891 2892
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("driver serial '%s' contains unsafe characters"),
                       value);
2893 2894 2895 2896 2897 2898
        return -1;
    }

    return 0;
}

2899 2900 2901 2902
static char *
qemuGetSecretString(virConnectPtr conn,
                    const char *scheme,
                    bool encoded,
2903
                    virStorageAuthDefPtr authdef,
2904 2905 2906 2907 2908
                    virSecretUsageType secretUsageType)
{
    size_t secret_size;
    virSecretPtr sec = NULL;
    char *secret = NULL;
2909
    char uuidStr[VIR_UUID_STRING_BUFLEN];
2910 2911

    /* look up secret */
2912
    switch (authdef->secretType) {
2913
    case VIR_STORAGE_SECRET_TYPE_UUID:
2914 2915
        sec = virSecretLookupByUUID(conn, authdef->secret.uuid);
        virUUIDFormat(authdef->secret.uuid, uuidStr);
2916
        break;
2917
    case VIR_STORAGE_SECRET_TYPE_USAGE:
2918 2919
        sec = virSecretLookupByUsage(conn, secretUsageType,
                                     authdef->secret.usage);
2920 2921 2922 2923
        break;
    }

    if (!sec) {
2924
        if (authdef->secretType == VIR_STORAGE_SECRET_TYPE_UUID) {
2925 2926
            virReportError(VIR_ERR_NO_SECRET,
                           _("%s no secret matches uuid '%s'"),
2927
                           scheme, uuidStr);
2928 2929 2930
        } else {
            virReportError(VIR_ERR_NO_SECRET,
                           _("%s no secret matches usage value '%s'"),
2931
                           scheme, authdef->secret.usage);
2932
        }
2933 2934 2935 2936 2937 2938
        goto cleanup;
    }

    secret = (char *)conn->secretDriver->secretGetValue(sec, &secret_size, 0,
                                                        VIR_SECRET_GET_VALUE_INTERNAL_CALL);
    if (!secret) {
2939
        if (authdef->secretType == VIR_STORAGE_SECRET_TYPE_UUID) {
2940 2941 2942
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("could not get value of the secret for "
                             "username '%s' using uuid '%s'"),
2943
                           authdef->username, uuidStr);
2944 2945 2946 2947
        } else {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("could not get value of the secret for "
                             "username '%s' using usage value '%s'"),
2948
                           authdef->username, authdef->secret.usage);
2949
        }
2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964
        goto cleanup;
    }

    if (encoded) {
        char *base64 = NULL;

        base64_encode_alloc(secret, secret_size, &base64);
        VIR_FREE(secret);
        if (!base64) {
            virReportOOMError();
            goto cleanup;
        }
        secret = base64;
    }

2965
 cleanup:
2966 2967 2968
    virObjectUnref(sec);
    return secret;
}
2969

2970

2971 2972
static int
qemuParseRBDString(virDomainDiskDefPtr disk)
2973
{
2974 2975
    char *source = disk->src->path;
    int ret;
2976

2977
    disk->src->path = NULL;
2978

2979
    ret = virStorageSourceParseRBDColonString(source, disk->src);
2980

2981 2982
    VIR_FREE(source);
    return ret;
2983 2984
}

2985

2986
static int
P
Paolo Bonzini 已提交
2987 2988
qemuParseDriveURIString(virDomainDiskDefPtr def, virURIPtr uri,
                        const char *scheme)
2989 2990 2991 2992 2993
{
    int ret = -1;
    char *transp = NULL;
    char *sock = NULL;
    char *volimg = NULL;
2994
    char *secret = NULL;
2995
    virStorageAuthDefPtr authdef = NULL;
2996

2997
    if (VIR_ALLOC(def->src->hosts) < 0)
2998
        goto error;
2999

P
Paolo Bonzini 已提交
3000 3001 3002 3003
    transp = strchr(uri->scheme, '+');
    if (transp)
        *transp++ = 0;

3004
    if (STRNEQ(uri->scheme, scheme)) {
P
Paolo Bonzini 已提交
3005 3006 3007 3008 3009 3010
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Invalid transport/scheme '%s'"), uri->scheme);
        goto error;
    }

    if (!transp) {
3011
        def->src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
P
Paolo Bonzini 已提交
3012
    } else {
3013 3014
        def->src->hosts->transport = virStorageNetHostTransportTypeFromString(transp);
        if (def->src->hosts->transport < 0) {
3015
            virReportError(VIR_ERR_INTERNAL_ERROR,
P
Paolo Bonzini 已提交
3016
                           _("Invalid %s transport type '%s'"), scheme, transp);
3017 3018 3019
            goto error;
        }
    }
3020
    def->src->nhosts = 0; /* set to 1 once everything succeeds */
3021

3022 3023
    if (def->src->hosts->transport != VIR_STORAGE_NET_HOST_TRANS_UNIX) {
        if (VIR_STRDUP(def->src->hosts->name, uri->server) < 0)
3024
            goto error;
3025

3026
        if (virAsprintf(&def->src->hosts->port, "%d", uri->port) < 0)
3027
            goto error;
3028
    } else {
3029 3030
        def->src->hosts->name = NULL;
        def->src->hosts->port = 0;
3031 3032 3033
        if (uri->query) {
            if (STRPREFIX(uri->query, "socket=")) {
                sock = strchr(uri->query, '=') + 1;
3034
                if (VIR_STRDUP(def->src->hosts->socket, sock) < 0)
3035
                    goto error;
3036 3037 3038 3039 3040 3041 3042
            } else {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("Invalid query parameter '%s'"), uri->query);
                goto error;
            }
        }
    }
P
Paolo Bonzini 已提交
3043 3044
    if (uri->path) {
        volimg = uri->path + 1; /* skip the prefix slash */
3045 3046
        VIR_FREE(def->src->path);
        if (VIR_STRDUP(def->src->path, volimg) < 0)
3047
            goto error;
P
Paolo Bonzini 已提交
3048
    } else {
3049
        VIR_FREE(def->src->path);
P
Paolo Bonzini 已提交
3050
    }
3051

3052
    if (uri->user) {
3053 3054 3055 3056 3057
        const char *secrettype;
        /* formulate authdef for disk->src->auth */
        if (VIR_ALLOC(authdef) < 0)
            goto error;

3058 3059 3060 3061
        secret = strchr(uri->user, ':');
        if (secret)
            *secret = '\0';

3062
        if (VIR_STRDUP(authdef->username, uri->user) < 0)
3063
            goto error;
3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075
        if (STREQ(scheme, "iscsi")) {
            secrettype =
                virSecretUsageTypeToString(VIR_SECRET_USAGE_TYPE_ISCSI);
            if (VIR_STRDUP(authdef->secrettype, secrettype) < 0)
                goto error;
        }
        def->src->auth = authdef;
        authdef = NULL;

        /* Cannot formulate a secretType (eg, usage or uuid) given
         * what is provided.
         */
3076 3077
    }

3078
    def->src->nhosts = 1;
3079 3080
    ret = 0;

3081
 cleanup:
3082 3083 3084 3085
    virURIFree(uri);

    return ret;

3086
 error:
3087 3088
    virStorageNetHostDefClear(def->src->hosts);
    VIR_FREE(def->src->hosts);
3089
    virStorageAuthDefFree(authdef);
3090 3091 3092
    goto cleanup;
}

P
Paolo Bonzini 已提交
3093 3094 3095 3096 3097
static int
qemuParseGlusterString(virDomainDiskDefPtr def)
{
    virURIPtr uri = NULL;

3098
    if (!(uri = virURIParse(def->src->path)))
P
Paolo Bonzini 已提交
3099 3100 3101 3102 3103
        return -1;

    return qemuParseDriveURIString(def, uri, "gluster");
}

P
Paolo Bonzini 已提交
3104 3105 3106 3107 3108 3109 3110
static int
qemuParseISCSIString(virDomainDiskDefPtr def)
{
    virURIPtr uri = NULL;
    char *slash;
    unsigned lun;

3111
    if (!(uri = virURIParse(def->src->path)))
P
Paolo Bonzini 已提交
3112 3113 3114 3115 3116
        return -1;

    if (uri->path &&
        (slash = strchr(uri->path + 1, '/')) != NULL) {

3117
        if (slash[1] == '\0') {
P
Paolo Bonzini 已提交
3118
            *slash = '\0';
3119
        } else if (virStrToLong_ui(slash + 1, NULL, 10, &lun) == -1) {
P
Paolo Bonzini 已提交
3120
            virReportError(VIR_ERR_INTERNAL_ERROR,
3121
                           _("invalid name '%s' for iSCSI disk"),
3122
                           def->src->path);
3123
            virURIFree(uri);
P
Paolo Bonzini 已提交
3124 3125 3126 3127 3128 3129 3130
            return -1;
        }
    }

    return qemuParseDriveURIString(def, uri, "iscsi");
}

3131 3132 3133
static int
qemuParseNBDString(virDomainDiskDefPtr disk)
{
3134
    virStorageNetHostDefPtr h = NULL;
3135
    char *host, *port;
P
Paolo Bonzini 已提交
3136
    char *src;
3137

P
Paolo Bonzini 已提交
3138 3139
    virURIPtr uri = NULL;

3140 3141
    if (strstr(disk->src->path, "://")) {
        if (!(uri = virURIParse(disk->src->path)))
3142 3143
            return -1;
        return qemuParseDriveURIString(disk, uri, "nbd");
P
Paolo Bonzini 已提交
3144 3145
    }

3146
    if (VIR_ALLOC(h) < 0)
3147
        goto error;
3148

3149
    host = disk->src->path + strlen("nbd:");
3150 3151 3152 3153
    if (STRPREFIX(host, "unix:/")) {
        src = strchr(host + strlen("unix:"), ':');
        if (src)
            *src++ = '\0';
3154

3155
        h->transport = VIR_STORAGE_NET_HOST_TRANS_UNIX;
3156 3157
        if (VIR_STRDUP(h->socket, host + strlen("unix:")) < 0)
            goto error;
3158 3159 3160 3161
    } else {
        port = strchr(host, ':');
        if (!port) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
3162
                           _("cannot parse nbd filename '%s'"), disk->src->path);
3163 3164
            goto error;
        }
3165

3166
        *port++ = '\0';
3167 3168
        if (VIR_STRDUP(h->name, host) < 0)
            goto error;
P
Paolo Bonzini 已提交
3169

3170 3171 3172 3173
        src = strchr(port, ':');
        if (src)
            *src++ = '\0';

3174 3175
        if (VIR_STRDUP(h->port, port) < 0)
            goto error;
3176
    }
3177

P
Paolo Bonzini 已提交
3178
    if (src && STRPREFIX(src, "exportname=")) {
3179 3180
        if (VIR_STRDUP(src, strchr(src, '=') + 1) < 0)
            goto error;
P
Paolo Bonzini 已提交
3181 3182 3183 3184
    } else {
        src = NULL;
    }

3185 3186 3187 3188
    VIR_FREE(disk->src->path);
    disk->src->path = src;
    disk->src->nhosts = 1;
    disk->src->hosts = h;
3189 3190
    return 0;

3191
 error:
3192
    virStorageNetHostDefClear(h);
3193 3194 3195 3196
    VIR_FREE(h);
    return -1;
}

3197

3198 3199 3200 3201 3202 3203 3204
static int
qemuNetworkDriveGetPort(int protocol,
                        const char *port)
{
    int ret = 0;

    if (port) {
3205
        if (virStrToLong_i(port, NULL, 10, &ret) < 0 || ret < 0) {
3206 3207 3208 3209 3210 3211 3212 3213 3214
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("failed to parse port number '%s'"),
                           port);
            return -1;
        }

        return ret;
    }

3215
    switch ((virStorageNetProtocol) protocol) {
3216
        case VIR_STORAGE_NET_PROTOCOL_HTTP:
3217 3218
            return 80;

3219
        case VIR_STORAGE_NET_PROTOCOL_HTTPS:
3220 3221
            return 443;

3222
        case VIR_STORAGE_NET_PROTOCOL_FTP:
3223 3224
            return 21;

3225
        case VIR_STORAGE_NET_PROTOCOL_FTPS:
3226 3227
            return 990;

3228
        case VIR_STORAGE_NET_PROTOCOL_TFTP:
3229 3230
            return 69;

3231
        case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
3232 3233
            return 7000;

3234
        case VIR_STORAGE_NET_PROTOCOL_NBD:
3235 3236
            return 10809;

3237 3238
        case VIR_STORAGE_NET_PROTOCOL_ISCSI:
        case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
3239 3240 3241
            /* no default port specified */
            return 0;

3242 3243
        case VIR_STORAGE_NET_PROTOCOL_RBD:
        case VIR_STORAGE_NET_PROTOCOL_LAST:
3244 3245
        case VIR_STORAGE_NET_PROTOCOL_NONE:
            /* not applicable */
3246 3247 3248 3249 3250 3251
            return -1;
    }

    return -1;
}

3252
#define QEMU_DEFAULT_NBD_PORT "10809"
3253

3254
static char *
3255
qemuBuildNetworkDriveURI(virStorageSourcePtr src,
3256 3257 3258 3259
                         const char *username,
                         const char *secret)
{
    char *ret = NULL;
3260
    virBuffer buf = VIR_BUFFER_INITIALIZER;
3261
    virURIPtr uri = NULL;
3262
    size_t i;
3263

3264
    switch ((virStorageNetProtocol) src->protocol) {
3265
        case VIR_STORAGE_NET_PROTOCOL_NBD:
3266
            if (src->nhosts != 1) {
3267 3268
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("protocol '%s' accepts only one host"),
3269
                               virStorageNetProtocolTypeToString(src->protocol));
3270 3271 3272
                goto cleanup;
            }

3273 3274 3275 3276 3277 3278
            if (!((src->hosts->name && strchr(src->hosts->name, ':')) ||
                  (src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP &&
                   !src->hosts->name) ||
                  (src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_UNIX &&
                   src->hosts->socket &&
                   src->hosts->socket[0] != '/'))) {
3279 3280 3281

                virBufferAddLit(&buf, "nbd:");

3282
                switch (src->hosts->transport) {
3283
                case VIR_STORAGE_NET_HOST_TRANS_TCP:
3284
                    virBufferStrcat(&buf, src->hosts->name, NULL);
3285
                    virBufferAsprintf(&buf, ":%s",
3286
                                      src->hosts->port ? src->hosts->port :
3287 3288 3289
                                      QEMU_DEFAULT_NBD_PORT);
                    break;

3290
                case VIR_STORAGE_NET_HOST_TRANS_UNIX:
3291
                    if (!src->hosts->socket) {
3292 3293 3294 3295 3296 3297
                        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                       _("socket attribute required for "
                                         "unix transport"));
                        goto cleanup;
                    }

3298
                    virBufferAsprintf(&buf, "unix:%s", src->hosts->socket);
3299 3300 3301 3302 3303
                    break;

                default:
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("nbd does not support transport '%s'"),
3304
                                   virStorageNetHostTransportTypeToString(src->hosts->transport));
3305 3306 3307
                    goto cleanup;
                }

3308 3309
                if (src->path)
                    virBufferAsprintf(&buf, ":exportname=%s", src->path);
3310

3311
                if (virBufferCheckError(&buf) < 0)
3312 3313 3314 3315 3316 3317 3318 3319
                    goto cleanup;

                ret = virBufferContentAndReset(&buf);
                goto cleanup;
            }
            /* fallthrough */
            /* NBD code uses same formatting scheme as others in some cases */

3320 3321 3322 3323 3324 3325 3326
        case VIR_STORAGE_NET_PROTOCOL_HTTP:
        case VIR_STORAGE_NET_PROTOCOL_HTTPS:
        case VIR_STORAGE_NET_PROTOCOL_FTP:
        case VIR_STORAGE_NET_PROTOCOL_FTPS:
        case VIR_STORAGE_NET_PROTOCOL_TFTP:
        case VIR_STORAGE_NET_PROTOCOL_ISCSI:
        case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
3327
            if (src->nhosts != 1) {
3328 3329
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("protocol '%s' accepts only one host"),
3330
                               virStorageNetProtocolTypeToString(src->protocol));
3331 3332
                goto cleanup;
            }
3333

3334 3335
            if (VIR_ALLOC(uri) < 0)
                goto cleanup;
3336

3337
            if (src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP) {
3338
                if (VIR_STRDUP(uri->scheme,
3339
                               virStorageNetProtocolTypeToString(src->protocol)) < 0)
3340 3341 3342
                    goto cleanup;
            } else {
                if (virAsprintf(&uri->scheme, "%s+%s",
3343 3344
                                virStorageNetProtocolTypeToString(src->protocol),
                                virStorageNetHostTransportTypeToString(src->hosts->transport)) < 0)
3345 3346
                    goto cleanup;
            }
3347

3348
            if ((uri->port = qemuNetworkDriveGetPort(src->protocol, src->hosts->port)) < 0)
3349
                goto cleanup;
3350

3351 3352
            if (src->path) {
                if (src->volume) {
3353
                    if (virAsprintf(&uri->path, "/%s%s",
3354
                                    src->volume, src->path) < 0)
3355 3356 3357
                        goto cleanup;
                } else {
                    if (virAsprintf(&uri->path, "%s%s",
3358 3359
                                    src->path[0] == '/' ? "" : "/",
                                    src->path) < 0)
3360 3361 3362
                        goto cleanup;
                }
            }
3363

3364 3365
            if (src->hosts->socket &&
                virAsprintf(&uri->query, "socket=%s", src->hosts->socket) < 0)
3366
                goto cleanup;
3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377

            if (username) {
                if (secret) {
                    if (virAsprintf(&uri->user, "%s:%s", username, secret) < 0)
                        goto cleanup;
                } else {
                    if (VIR_STRDUP(uri->user, username) < 0)
                        goto cleanup;
                }
            }

3378
            if (VIR_STRDUP(uri->server, src->hosts->name) < 0)
3379 3380
                goto cleanup;

3381
            ret = virURIFormat(uri);
3382

3383 3384
            break;

3385
        case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
3386
            if (!src->path) {
3387 3388 3389 3390 3391
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("missing disk source for 'sheepdog' protocol"));
                goto cleanup;
            }

3392 3393
            if (src->nhosts == 0) {
                if (virAsprintf(&ret, "sheepdog:%s", src->path) < 0)
3394
                    goto cleanup;
3395
            } else if (src->nhosts == 1) {
3396
                if (virAsprintf(&ret, "sheepdog:%s:%s:%s",
3397 3398 3399
                                src->hosts->name,
                                src->hosts->port ? src->hosts->port : "7000",
                                src->path) < 0)
3400 3401 3402 3403 3404 3405 3406 3407 3408
                    goto cleanup;
            } else {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("protocol 'sheepdog' accepts up to one host"));
                goto cleanup;
            }

            break;

3409
        case VIR_STORAGE_NET_PROTOCOL_RBD:
3410
            if (strchr(src->path, ':')) {
3411 3412
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("':' not allowed in RBD source volume name '%s'"),
3413
                               src->path);
3414 3415 3416
                goto cleanup;
            }

3417
            virBufferStrcat(&buf, "rbd:", src->path, NULL);
3418

3419 3420 3421
            if (src->snapshot)
                virBufferEscape(&buf, '\\', ":", "@%s", src->snapshot);

3422 3423 3424 3425 3426 3427 3428 3429 3430
            if (username) {
                virBufferEscape(&buf, '\\', ":", ":id=%s", username);
                virBufferEscape(&buf, '\\', ":",
                                ":key=%s:auth_supported=cephx\\;none",
                                secret);
            } else {
                virBufferAddLit(&buf, ":auth_supported=none");
            }

3431
            if (src->nhosts > 0) {
3432
                virBufferAddLit(&buf, ":mon_host=");
3433
                for (i = 0; i < src->nhosts; i++) {
3434 3435 3436 3437
                    if (i)
                        virBufferAddLit(&buf, "\\;");

                    /* assume host containing : is ipv6 */
3438 3439 3440
                    if (strchr(src->hosts[i].name, ':'))
                        virBufferEscape(&buf, '\\', ":", "[%s]",
                                        src->hosts[i].name);
3441
                    else
3442
                        virBufferAsprintf(&buf, "%s", src->hosts[i].name);
3443

3444 3445
                    if (src->hosts[i].port)
                        virBufferAsprintf(&buf, "\\:%s", src->hosts[i].port);
3446 3447 3448
                }
            }

3449 3450 3451
            if (src->configFile)
                virBufferEscape(&buf, '\\', ":", ":conf=%s", src->configFile);

3452
            if (virBufferCheckError(&buf) < 0)
3453 3454 3455 3456 3457 3458
                goto cleanup;

            ret = virBufferContentAndReset(&buf);
            break;


3459
        case VIR_STORAGE_NET_PROTOCOL_LAST:
3460
        case VIR_STORAGE_NET_PROTOCOL_NONE:
3461 3462 3463
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Unexpected network protocol '%s'"),
                           virStorageNetProtocolTypeToString(src->protocol));
3464 3465
            goto cleanup;
    }
3466

3467
 cleanup:
3468
    virBufferFreeAndReset(&buf);
3469 3470 3471 3472 3473 3474
    virURIFree(uri);

    return ret;
}


3475
int
3476 3477 3478
qemuGetDriveSourceString(virStorageSourcePtr src,
                         virConnectPtr conn,
                         char **source)
3479
{
3480 3481 3482 3483 3484 3485 3486
    int actualType = virStorageSourceGetActualType(src);
    char *secret = NULL;
    char *username = NULL;
    int ret = -1;

    *source = NULL;

3487 3488 3489 3490
    /* return 1 for empty sources */
    if (virStorageSourceIsEmpty(src))
        return 1;

3491 3492
    if (conn) {
        if (actualType == VIR_STORAGE_TYPE_NETWORK &&
3493
            src->auth &&
3494 3495 3496 3497 3498
            (src->protocol == VIR_STORAGE_NET_PROTOCOL_ISCSI ||
             src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD)) {
            bool encode = false;
            int secretType = VIR_SECRET_USAGE_TYPE_ISCSI;
            const char *protocol = virStorageNetProtocolTypeToString(src->protocol);
3499
            username = src->auth->username;
3500 3501 3502 3503 3504 3505

            if (src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) {
                /* qemu requires the secret to be encoded for RBD */
                encode = true;
                secretType = VIR_SECRET_USAGE_TYPE_CEPH;
            }
3506

3507 3508 3509
            if (!(secret = qemuGetSecretString(conn,
                                               protocol,
                                               encode,
3510
                                               src->auth,
3511 3512 3513 3514 3515
                                               secretType)))
                goto cleanup;
        }
    }

3516
    switch ((virStorageType) actualType) {
E
Eric Blake 已提交
3517 3518 3519
    case VIR_STORAGE_TYPE_BLOCK:
    case VIR_STORAGE_TYPE_FILE:
    case VIR_STORAGE_TYPE_DIR:
3520 3521
        if (VIR_STRDUP(*source, src->path) < 0)
            goto cleanup;
3522 3523 3524

        break;

E
Eric Blake 已提交
3525
    case VIR_STORAGE_TYPE_NETWORK:
3526
        if (!(*source = qemuBuildNetworkDriveURI(src, username, secret)))
3527
            goto cleanup;
3528 3529
        break;

E
Eric Blake 已提交
3530
    case VIR_STORAGE_TYPE_VOLUME:
3531
    case VIR_STORAGE_TYPE_NONE:
E
Eric Blake 已提交
3532
    case VIR_STORAGE_TYPE_LAST:
3533 3534 3535
        break;
    }

3536
    ret = 0;
3537

3538
 cleanup:
J
John Ferlan 已提交
3539
    VIR_FREE(secret);
3540 3541 3542
    return ret;
}

P
Paolo Bonzini 已提交
3543

3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586
/* Perform disk definition config validity checks */
int
qemuCheckDiskConfig(virDomainDiskDefPtr disk)
{
    if (virDiskNameToIndex(disk->dst) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unsupported disk type '%s'"), disk->dst);
        goto error;
    }

    if (disk->wwn) {
        if ((disk->bus != VIR_DOMAIN_DISK_BUS_IDE) &&
            (disk->bus != VIR_DOMAIN_DISK_BUS_SCSI)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Only ide and scsi disk support wwn"));
            goto error;
        }
    }

    if ((disk->vendor || disk->product) &&
        disk->bus != VIR_DOMAIN_DISK_BUS_SCSI) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Only scsi disk supports vendor and product"));
            goto error;
    }

    if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
        /* make sure that both the bus supports type='lun' (SG_IO). */
        if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO &&
            disk->bus != VIR_DOMAIN_DISK_BUS_SCSI) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("disk device='lun' is not supported for bus='%s'"),
                           virDomainDiskQEMUBusTypeToString(disk->bus));
            goto error;
        }
        if (disk->src->type == VIR_STORAGE_TYPE_NETWORK) {
            if (disk->src->protocol != VIR_STORAGE_NET_PROTOCOL_ISCSI) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("disk device='lun' is not supported "
                                 "for protocol='%s'"),
                               virStorageNetProtocolTypeToString(disk->src->protocol));
                goto error;
            }
3587
        } else if (!virDomainDiskSourceIsBlockType(disk->src, true)) {
3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607
            goto error;
        }
        if (disk->wwn) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting wwn is not supported for lun device"));
            goto error;
        }
        if (disk->vendor || disk->product) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting vendor or product is not supported "
                             "for lun device"));
            goto error;
        }
    }
    return 0;
 error:
    return -1;
}


3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647
/* Check whether the device address is using either 'ccw' or default s390
 * address format and whether that's "legal" for the current qemu and/or
 * guest os.machine type. This is the corollary to the code which doesn't
 * find the address type set using an emulator that supports either 'ccw'
 * or s390 and sets the address type based on the capabilities.
 *
 * If the address is using 'ccw' or s390 and it's not supported, generate
 * an error and return false; otherwise, return true.
 */
bool
qemuCheckCCWS390AddressSupport(virDomainDefPtr def,
                               virDomainDeviceInfo info,
                               virQEMUCapsPtr qemuCaps,
                               const char *devicename)
{
    if (info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
        if (!qemuDomainMachineIsS390CCW(def)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("cannot use CCW address type for device "
                             "'%s' using machine type '%s'"),
                       devicename, def->os.machine);
            return false;
        } else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("CCW address type is not supported by "
                             "this QEMU"));
            return false;
        }
    } else if (info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("virtio S390 address type is not supported by "
                             "this QEMU"));
            return false;
        }
    }
    return true;
}


3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676
/* Qemu 1.2 and later have a binary flag -enable-fips that must be
 * used for VNC auth to obey FIPS settings; but the flag only
 * exists on Linux, and with no way to probe for it via QMP.  Our
 * solution: if FIPS mode is required, then unconditionally use
 * the flag, regardless of qemu version, for the following matrix:
 *
 *                          old QEMU            new QEMU
 * FIPS enabled             doesn't start       VNC auth disabled
 * FIPS disabled/missing    VNC auth enabled    VNC auth enabled
 */
bool
qemuCheckFips(void)
{
    bool ret = false;

    if (virFileExists("/proc/sys/crypto/fips_enabled")) {
        char *buf = NULL;

        if (virFileReadAll("/proc/sys/crypto/fips_enabled", 10, &buf) < 0)
            return ret;
        if (STREQ(buf, "1\n"))
            ret = true;
        VIR_FREE(buf);
    }

    return ret;
}


3677
char *
3678
qemuBuildDriveStr(virConnectPtr conn,
3679
                  virDomainDiskDefPtr disk,
3680
                  bool bootable,
3681
                  virQEMUCapsPtr qemuCaps)
3682 3683 3684
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;
    const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
3685 3686
    const char *trans =
        virDomainDiskGeometryTransTypeToString(disk->geometry.trans);
3687 3688
    int idx = virDiskNameToIndex(disk->dst);
    int busid = -1, unitid = -1;
3689
    char *source = NULL;
3690
    int actualType = virStorageSourceGetActualType(disk->src);
3691 3692

    if (idx < 0) {
3693 3694
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unsupported disk type '%s'"), disk->dst);
3695 3696 3697 3698 3699 3700
        goto error;
    }

    switch (disk->bus) {
    case VIR_DOMAIN_DISK_BUS_SCSI:
        if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
3701 3702
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("unexpected address type for scsi disk"));
3703 3704 3705 3706 3707 3708 3709
            goto error;
        }

        /* Setting bus= attr for SCSI drives, causes a controller
         * to be created. Yes this is slightly odd. It is not possible
         * to have > 1 bus on a SCSI controller (yet). */
        if (disk->info.addr.drive.bus != 0) {
3710 3711
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("SCSI controller only supports 1 bus"));
3712 3713 3714 3715 3716 3717 3718 3719
            goto error;
        }
        busid = disk->info.addr.drive.controller;
        unitid = disk->info.addr.drive.unit;
        break;

    case VIR_DOMAIN_DISK_BUS_IDE:
        if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
3720 3721
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("unexpected address type for ide disk"));
3722 3723 3724 3725
            goto error;
        }
        /* We can only have 1 IDE controller (currently) */
        if (disk->info.addr.drive.controller != 0) {
3726 3727
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Only 1 %s controller is supported"), bus);
3728 3729 3730 3731 3732 3733 3734 3735
            goto error;
        }
        busid = disk->info.addr.drive.bus;
        unitid = disk->info.addr.drive.unit;
        break;

    case VIR_DOMAIN_DISK_BUS_FDC:
        if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
3736 3737
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("unexpected address type for fdc disk"));
3738 3739 3740 3741
            goto error;
        }
        /* We can only have 1 FDC controller (currently) */
        if (disk->info.addr.drive.controller != 0) {
3742 3743
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Only 1 %s controller is supported"), bus);
3744 3745 3746 3747
            goto error;
        }
        /* We can only have 1 FDC bus (currently) */
        if (disk->info.addr.drive.bus != 0) {
3748 3749
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Only 1 %s bus is supported"), bus);
3750 3751
            goto error;
        }
3752
        if (disk->info.addr.drive.target != 0) {
3753 3754
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("target must be 0 for controller fdc"));
3755 3756
            goto error;
        }
3757 3758 3759 3760 3761 3762 3763 3764 3765
        unitid = disk->info.addr.drive.unit;

        break;

    case VIR_DOMAIN_DISK_BUS_VIRTIO:
        idx = -1;
        break;

    case VIR_DOMAIN_DISK_BUS_XEN:
3766 3767 3768
    case VIR_DOMAIN_DISK_BUS_SD:
        /* Xen and SD have no address type currently, so assign
         * based on index */
3769 3770 3771
        break;
    }

3772
    if (qemuGetDriveSourceString(disk->src, conn, &source) < 0)
3773 3774 3775
        goto error;

    if (source &&
3776 3777 3778
        !((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY ||
           disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
          disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
3779

3780 3781 3782
        virBufferAddLit(&opt, "file=");

        switch (actualType) {
E
Eric Blake 已提交
3783
        case VIR_STORAGE_TYPE_DIR:
3784
            /* QEMU only supports magic FAT format for now */
3785 3786
            if (disk->src->format > 0 &&
                disk->src->format != VIR_STORAGE_FILE_FAT) {
3787 3788
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("unsupported disk driver type for '%s'"),
3789
                               virStorageFileFormatTypeToString(disk->src->format));
3790 3791
                goto error;
            }
3792

3793
            if (!disk->src->readonly) {
3794 3795
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("cannot create virtual FAT disks in read-write mode"));
3796 3797
                goto error;
            }
3798 3799 3800

            virBufferAddLit(&opt, "fat:");

3801
            if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
3802
                virBufferAddLit(&opt, "floppy:");
3803

3804 3805
            break;

E
Eric Blake 已提交
3806
        case VIR_STORAGE_TYPE_BLOCK:
3807
            if (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN) {
3808
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
3809
                               disk->src->type == VIR_STORAGE_TYPE_VOLUME ?
3810 3811
                               _("tray status 'open' is invalid for block type volume") :
                               _("tray status 'open' is invalid for block type disk"));
3812 3813
                goto error;
            }
3814 3815 3816 3817 3818

            break;

        default:
            break;
3819
        }
3820 3821

        virBufferEscape(&opt, ',', ",", "%s,", source);
3822 3823 3824 3825 3826

        if (disk->src->format > 0 &&
            disk->src->type != VIR_STORAGE_TYPE_DIR)
            virBufferAsprintf(&opt, "format=%s,",
                              virStorageFileFormatTypeToString(disk->src->format));
3827
    }
3828
    VIR_FREE(source);
3829

3830
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
3831 3832
        virBufferAddLit(&opt, "if=none");
    else
3833
        virBufferAsprintf(&opt, "if=%s", bus);
3834

3835
    if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
3836
        if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
3837
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD))
3838
                virBufferAddLit(&opt, ",media=cdrom");
3839
        } else if (disk->bus == VIR_DOMAIN_DISK_BUS_IDE) {
3840
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_IDE_CD))
3841
                virBufferAddLit(&opt, ",media=cdrom");
3842 3843 3844 3845
        } else {
            virBufferAddLit(&opt, ",media=cdrom");
        }
    }
3846

3847
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
3848
        virBufferAsprintf(&opt, ",id=%s%s", QEMU_DRIVE_HOST_PREFIX, disk->info.alias);
3849 3850 3851
    } else {
        if (busid == -1 && unitid == -1) {
            if (idx != -1)
3852
                virBufferAsprintf(&opt, ",index=%d", idx);
3853 3854
        } else {
            if (busid != -1)
3855
                virBufferAsprintf(&opt, ",bus=%d", busid);
3856
            if (unitid != -1)
3857
                virBufferAsprintf(&opt, ",unit=%d", unitid);
3858 3859 3860
        }
    }
    if (bootable &&
3861
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_BOOT) &&
3862 3863
        (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK ||
         disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) &&
3864 3865
        disk->bus != VIR_DOMAIN_DISK_BUS_IDE)
        virBufferAddLit(&opt, ",boot=on");
3866
    if (disk->src->readonly &&
3867
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_READONLY)) {
3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878
        if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
            if (disk->bus == VIR_DOMAIN_DISK_BUS_IDE) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("readonly ide disks are not supported"));
                goto error;
            }
            if (disk->bus == VIR_DOMAIN_DISK_BUS_SATA) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("readonly sata disks are not supported"));
                goto error;
            }
3879
        }
3880
        virBufferAddLit(&opt, ",readonly=on");
3881
    }
3882
    if (disk->transient) {
3883 3884
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("transient disks not supported yet"));
3885 3886
        goto error;
    }
3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898

    /* generate geometry command string */
    if (disk->geometry.cylinders > 0 &&
        disk->geometry.heads > 0 &&
        disk->geometry.sectors > 0) {

        virBufferAsprintf(&opt, ",cyls=%u,heads=%u,secs=%u",
                          disk->geometry.cylinders,
                          disk->geometry.heads,
                          disk->geometry.sectors);

        if (disk->geometry.trans != VIR_DOMAIN_DISK_TRANS_DEFAULT)
3899
            virBufferAsprintf(&opt, ",trans=%s", trans);
3900 3901
    }

3902
    if (disk->serial &&
3903
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_SERIAL)) {
3904 3905
        if (qemuSafeSerialParamValue(disk->serial) < 0)
            goto error;
3906 3907 3908 3909 3910 3911 3912
        if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI &&
            disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("scsi-block 'lun' devices do not support the "
                             "serial property"));
            goto error;
        }
3913 3914
        virBufferAddLit(&opt, ",serial=");
        virBufferEscape(&opt, '\\', " ", "%s", disk->serial);
3915 3916 3917
    }

    if (disk->cachemode) {
3918 3919
        const char *mode = NULL;

3920
        mode = qemuDiskCacheV2TypeToString(disk->cachemode);
3921

3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933
        if (disk->cachemode == VIR_DOMAIN_DISK_CACHE_DIRECTSYNC &&
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("disk cache mode 'directsync' is not "
                             "supported by this QEMU"));
            goto error;
        } else if (disk->cachemode == VIR_DOMAIN_DISK_CACHE_UNSAFE &&
                   !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_UNSAFE)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("disk cache mode 'unsafe' is not "
                             "supported by this QEMU"));
            goto error;
3934
        }
3935

3936 3937 3938 3939 3940 3941 3942 3943 3944 3945
        if (disk->iomode == VIR_DOMAIN_DISK_IO_NATIVE &&
            disk->cachemode != VIR_DOMAIN_DISK_CACHE_DIRECTSYNC &&
            disk->cachemode != VIR_DOMAIN_DISK_CACHE_DISABLE) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("native I/O needs either no disk cache "
                             "or directsync cache mode, QEMU will fallback "
                             "to aio=threads"));
            goto error;
        }

3946
        virBufferAsprintf(&opt, ",cache=%s", mode);
3947
    } else if (disk->src->shared && !disk->src->readonly) {
3948
        virBufferAddLit(&opt, ",cache=none");
3949 3950
    }

O
Osier Yang 已提交
3951
    if (disk->copy_on_read) {
3952
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_COPY_ON_READ)) {
O
Osier Yang 已提交
3953
            virBufferAsprintf(&opt, ",copy-on-read=%s",
J
Ján Tomko 已提交
3954
                              virTristateSwitchTypeToString(disk->copy_on_read));
O
Osier Yang 已提交
3955
        } else {
3956 3957
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("copy_on_read is not supported by this QEMU binary"));
O
Osier Yang 已提交
3958 3959 3960 3961
            goto error;
        }
    }

O
Osier Yang 已提交
3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972
    if (disk->discard) {
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_DISCARD)) {
            virBufferAsprintf(&opt, ",discard=%s",
                              virDomainDiskDiscardTypeToString(disk->discard));
        } else {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("discard is not supported by this QEMU binary"));
            goto error;
        }
    }

3973
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MONITOR_JSON)) {
3974 3975 3976 3977
        const char *wpolicy = NULL, *rpolicy = NULL;

        if (disk->error_policy)
            wpolicy = virDomainDiskErrorPolicyTypeToString(disk->error_policy);
3978 3979
        if (disk->rerror_policy)
            rpolicy = virDomainDiskErrorPolicyTypeToString(disk->rerror_policy);
3980 3981

        if (disk->error_policy == VIR_DOMAIN_DISK_ERROR_POLICY_ENOSPACE) {
3982 3983 3984
            /* in the case of enospace, the option is spelled
             * differently in qemu, and it's only valid for werror,
             * not for rerror, so leave leave rerror NULL.
3985
             */
3986 3987 3988 3989
            wpolicy = "enospc";
        } else if (!rpolicy) {
            /* for other policies, rpolicy can match wpolicy */
            rpolicy = wpolicy;
3990
        }
3991 3992 3993 3994 3995

        if (wpolicy)
            virBufferAsprintf(&opt, ",werror=%s", wpolicy);
        if (rpolicy)
            virBufferAsprintf(&opt, ",rerror=%s", rpolicy);
3996 3997
    }

E
Eric Blake 已提交
3998
    if (disk->iomode) {
3999
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_AIO)) {
4000
            virBufferAsprintf(&opt, ",aio=%s",
E
Eric Blake 已提交
4001 4002
                              virDomainDiskIoTypeToString(disk->iomode));
        } else {
4003 4004 4005
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("disk aio mode not supported with this "
                             "QEMU binary"));
E
Eric Blake 已提交
4006 4007 4008 4009
            goto error;
        }
    }

4010
    /* block I/O throttling */
4011 4012 4013 4014 4015 4016
    if ((disk->blkdeviotune.total_bytes_sec ||
         disk->blkdeviotune.read_bytes_sec ||
         disk->blkdeviotune.write_bytes_sec ||
         disk->blkdeviotune.total_iops_sec ||
         disk->blkdeviotune.read_iops_sec ||
         disk->blkdeviotune.write_iops_sec) &&
4017
        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE)) {
4018 4019 4020
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("block I/O throttling not supported with this "
                         "QEMU binary"));
4021 4022 4023
        goto error;
    }

4024 4025 4026 4027 4028 4029
    /* block I/O throttling 1.7 */
    if ((disk->blkdeviotune.total_bytes_sec_max ||
         disk->blkdeviotune.read_bytes_sec_max ||
         disk->blkdeviotune.write_bytes_sec_max ||
         disk->blkdeviotune.total_iops_sec_max ||
         disk->blkdeviotune.read_iops_sec_max ||
4030 4031
         disk->blkdeviotune.write_iops_sec_max ||
         disk->blkdeviotune.size_iops_sec) &&
4032 4033
        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE_MAX)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
4034 4035
                       _("there are some block I/O throttling parameters "
                         "that are not supported with this QEMU binary"));
4036 4037 4038
        goto error;
    }

4039 4040 4041 4042 4043
    if (disk->blkdeviotune.total_bytes_sec > LLONG_MAX ||
        disk->blkdeviotune.read_bytes_sec > LLONG_MAX ||
        disk->blkdeviotune.write_bytes_sec > LLONG_MAX ||
        disk->blkdeviotune.total_iops_sec > LLONG_MAX ||
        disk->blkdeviotune.read_iops_sec > LLONG_MAX ||
4044 4045 4046 4047 4048 4049
        disk->blkdeviotune.write_iops_sec > LLONG_MAX ||
        disk->blkdeviotune.total_bytes_sec_max > LLONG_MAX ||
        disk->blkdeviotune.read_bytes_sec_max > LLONG_MAX ||
        disk->blkdeviotune.write_bytes_sec_max > LLONG_MAX ||
        disk->blkdeviotune.total_iops_sec_max > LLONG_MAX ||
        disk->blkdeviotune.read_iops_sec_max > LLONG_MAX ||
4050 4051
        disk->blkdeviotune.write_iops_sec_max > LLONG_MAX ||
        disk->blkdeviotune.size_iops_sec > LLONG_MAX) {
4052 4053 4054 4055 4056 4057
        virReportError(VIR_ERR_OVERFLOW,
                      _("block I/O throttle limit must "
                        "be less than %llu using QEMU"), LLONG_MAX);
        goto error;
    }

4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087
    if (disk->blkdeviotune.total_bytes_sec) {
        virBufferAsprintf(&opt, ",bps=%llu",
                          disk->blkdeviotune.total_bytes_sec);
    }

    if (disk->blkdeviotune.read_bytes_sec) {
        virBufferAsprintf(&opt, ",bps_rd=%llu",
                          disk->blkdeviotune.read_bytes_sec);
    }

    if (disk->blkdeviotune.write_bytes_sec) {
        virBufferAsprintf(&opt, ",bps_wr=%llu",
                          disk->blkdeviotune.write_bytes_sec);
    }

    if (disk->blkdeviotune.total_iops_sec) {
        virBufferAsprintf(&opt, ",iops=%llu",
                          disk->blkdeviotune.total_iops_sec);
    }

    if (disk->blkdeviotune.read_iops_sec) {
        virBufferAsprintf(&opt, ",iops_rd=%llu",
                          disk->blkdeviotune.read_iops_sec);
    }

    if (disk->blkdeviotune.write_iops_sec) {
        virBufferAsprintf(&opt, ",iops_wr=%llu",
                          disk->blkdeviotune.write_iops_sec);
    }

4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117
    if (disk->blkdeviotune.total_bytes_sec_max) {
        virBufferAsprintf(&opt, ",bps_max=%llu",
                          disk->blkdeviotune.total_bytes_sec_max);
    }

    if (disk->blkdeviotune.read_bytes_sec_max) {
        virBufferAsprintf(&opt, ",bps_rd_max=%llu",
                          disk->blkdeviotune.read_bytes_sec_max);
    }

    if (disk->blkdeviotune.write_bytes_sec_max) {
        virBufferAsprintf(&opt, ",bps_wr_max=%llu",
                          disk->blkdeviotune.write_bytes_sec_max);
    }

    if (disk->blkdeviotune.total_iops_sec_max) {
        virBufferAsprintf(&opt, ",iops_max=%llu",
                          disk->blkdeviotune.total_iops_sec_max);
    }

    if (disk->blkdeviotune.read_iops_sec_max) {
        virBufferAsprintf(&opt, ",iops_rd_max=%llu",
                          disk->blkdeviotune.read_iops_sec_max);
    }

    if (disk->blkdeviotune.write_iops_sec_max) {
        virBufferAsprintf(&opt, ",iops_wr_max=%llu",
                          disk->blkdeviotune.write_iops_sec_max);
    }

4118
    if (disk->blkdeviotune.size_iops_sec) {
4119 4120 4121 4122
        virBufferAsprintf(&opt, ",iops_size=%llu",
                          disk->blkdeviotune.size_iops_sec);
    }

4123
    if (virBufferCheckError(&opt) < 0)
4124 4125 4126 4127
        goto error;

    return virBufferContentAndReset(&opt);

4128
 error:
4129
    VIR_FREE(source);
4130 4131 4132 4133
    virBufferFreeAndReset(&opt);
    return NULL;
}

4134 4135

static bool
4136
qemuCheckIOThreads(virDomainDefPtr def,
4137 4138 4139
                   virDomainDiskDefPtr disk)
{
    /* Right "type" of disk" */
4140
    if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO ||
4141 4142
        (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
         disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)) {
4143
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
4144 4145
                       _("IOThreads only available for virtio pci and "
                         "virtio ccw disk"));
4146 4147 4148
        return false;
    }

4149 4150
    /* Can we find the disk iothread in the iothreadid list? */
    if (!virDomainIOThreadIDFind(def, disk->iothread)) {
4151
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
4152 4153
                       _("Disk iothread '%u' not defined in iothreadid"),
                       disk->iothread);
4154 4155 4156 4157 4158 4159 4160
        return false;
    }

    return true;
}


4161
char *
4162 4163
qemuBuildDriveDevStr(virDomainDefPtr def,
                     virDomainDiskDefPtr disk,
4164
                     int bootindex,
4165
                     virQEMUCapsPtr qemuCaps)
4166 4167 4168
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;
    const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
4169
    const char *contAlias;
4170
    int controllerModel;
4171

4172 4173 4174
    if (virDomainDiskDefDstDuplicates(def))
        goto error;

4175
    if (qemuCheckDiskConfig(disk) < 0)
4176
        goto error;
4177

4178
    /* Live only checks */
4179
    if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
4180
        /* make sure that the qemu binary supports type='lun' (SG_IO). */
4181
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SG_IO)) {
4182
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
4183 4184
                           _("disk device='lun' is not supported by "
                             "this QEMU"));
4185 4186
            goto error;
        }
4187 4188
    }

4189 4190 4191
    if (!qemuCheckCCWS390AddressSupport(def, disk->info, qemuCaps, disk->dst))
        goto error;

4192
    if (disk->iothread && !qemuCheckIOThreads(def, disk))
4193 4194
        goto error;

4195 4196
    switch (disk->bus) {
    case VIR_DOMAIN_DISK_BUS_IDE:
4197
        if (disk->info.addr.drive.target != 0) {
4198 4199
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("target must be 0 for ide controller"));
4200 4201
            goto error;
        }
4202

4203
        if (disk->wwn &&
4204
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_IDE_DRIVE_WWN)) {
4205 4206 4207 4208 4209 4210
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting wwn for ide disk is not supported "
                             "by this QEMU"));
            goto error;
        }

4211
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_IDE_CD)) {
4212 4213 4214 4215 4216 4217 4218 4219
            if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
                virBufferAddLit(&opt, "ide-cd");
            else
                virBufferAddLit(&opt, "ide-hd");
        } else {
            virBufferAddLit(&opt, "ide-drive");
        }

4220 4221 4222 4223 4224
        if (!(contAlias = virDomainControllerAliasFind(def, VIR_DOMAIN_CONTROLLER_TYPE_IDE,
                                                       disk->info.addr.drive.controller)))
           goto error;
        virBufferAsprintf(&opt, ",bus=%s.%d,unit=%d",
                          contAlias,
4225 4226 4227
                          disk->info.addr.drive.bus,
                          disk->info.addr.drive.unit);
        break;
4228

4229
    case VIR_DOMAIN_DISK_BUS_SCSI:
4230
        if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
4231
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_BLOCK)) {
4232 4233 4234
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("This QEMU doesn't support scsi-block for "
                                 "lun passthrough"));
4235 4236 4237 4238
                goto error;
            }
        }

4239
        if (disk->wwn &&
4240
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_WWN)) {
4241 4242 4243 4244 4245 4246
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting wwn for scsi disk is not supported "
                             "by this QEMU"));
            goto error;
        }

4247 4248 4249 4250
        /* Properties wwn, vendor and product were introduced in the
         * same QEMU release (1.2.0).
         */
        if ((disk->vendor || disk->product) &&
4251
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_WWN)) {
4252 4253 4254 4255 4256 4257
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting vendor or product for scsi disk is not "
                             "supported by this QEMU"));
            goto error;
        }

4258
        controllerModel =
H
Han Cheng 已提交
4259 4260
            virDomainDeviceFindControllerModel(def, &disk->info,
                                               VIR_DOMAIN_CONTROLLER_TYPE_SCSI);
4261
        if ((qemuSetSCSIControllerModel(def, qemuCaps, &controllerModel)) < 0)
4262
            goto error;
4263

4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276
        if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
            virBufferAddLit(&opt, "scsi-block");
        } else {
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) {
                if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
                    virBufferAddLit(&opt, "scsi-cd");
                else
                    virBufferAddLit(&opt, "scsi-hd");
            } else {
                virBufferAddLit(&opt, "scsi-disk");
            }
        }

4277 4278 4279 4280
        if (!(contAlias = virDomainControllerAliasFind(def, VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
                                                       disk->info.addr.drive.controller)))
           goto error;

4281 4282
        if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) {
            if (disk->info.addr.drive.target != 0) {
4283 4284 4285
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("target must be 0 for controller "
                                 "model 'lsilogic'"));
4286 4287 4288
                goto error;
            }

4289 4290
            virBufferAsprintf(&opt, ",bus=%s.%d,scsi-id=%d",
                              contAlias,
4291 4292 4293
                              disk->info.addr.drive.bus,
                              disk->info.addr.drive.unit);
        } else {
4294
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_CHANNEL)) {
4295
                if (disk->info.addr.drive.target > 7) {
4296 4297 4298
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("This QEMU doesn't support target "
                                     "greater than 7"));
4299 4300 4301
                    goto error;
                }

4302 4303
                if (disk->info.addr.drive.bus != 0 &&
                    disk->info.addr.drive.unit != 0) {
4304 4305 4306
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("This QEMU only supports both bus and "
                                     "unit equal to 0"));
4307 4308 4309 4310
                    goto error;
                }
            }

4311 4312
            virBufferAsprintf(&opt, ",bus=%s.0,channel=%d,scsi-id=%d,lun=%d",
                              contAlias,
4313 4314 4315 4316
                              disk->info.addr.drive.bus,
                              disk->info.addr.drive.target,
                              disk->info.addr.drive.unit);
        }
4317
        break;
4318

J
Jim Fehlig 已提交
4319
    case VIR_DOMAIN_DISK_BUS_SATA:
4320
        if (disk->info.addr.drive.bus != 0) {
4321 4322
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("bus must be 0 for ide controller"));
4323 4324 4325
            goto error;
        }
        if (disk->info.addr.drive.target != 0) {
4326 4327
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("target must be 0 for ide controller"));
4328 4329
            goto error;
        }
4330

4331
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_IDE_CD)) {
4332 4333 4334 4335 4336 4337 4338 4339
            if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
                virBufferAddLit(&opt, "ide-cd");
            else
                virBufferAddLit(&opt, "ide-hd");
        } else {
            virBufferAddLit(&opt, "ide-drive");
        }

4340 4341 4342 4343 4344 4345
        if (!(contAlias = virDomainControllerAliasFind(def, VIR_DOMAIN_CONTROLLER_TYPE_SATA,
                                                      disk->info.addr.drive.controller)))
           goto error;
        virBufferAsprintf(&opt, ",bus=%s.%d",
                          contAlias,
                          disk->info.addr.drive.unit);
J
Jim Fehlig 已提交
4346
        break;
4347

4348
    case VIR_DOMAIN_DISK_BUS_VIRTIO:
4349 4350
        if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
            virBufferAddLit(&opt, "virtio-blk-ccw");
4351 4352
            if (disk->iothread)
                virBufferAsprintf(&opt, ",iothread=iothread%u", disk->iothread);
4353 4354
        } else if (disk->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
4355
            virBufferAddLit(&opt, "virtio-blk-s390");
4356 4357 4358
        } else if (disk->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) {
            virBufferAddLit(&opt, "virtio-blk-device");
4359 4360
        } else {
            virBufferAddLit(&opt, "virtio-blk-pci");
4361 4362
            if (disk->iothread)
                virBufferAsprintf(&opt, ",iothread=iothread%u", disk->iothread);
4363
        }
4364
        qemuBuildIoEventFdStr(&opt, disk->ioeventfd, qemuCaps);
4365
        if (disk->event_idx &&
4366
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_EVENT_IDX)) {
4367
            virBufferAsprintf(&opt, ",event_idx=%s",
J
Ján Tomko 已提交
4368
                              virTristateSwitchTypeToString(disk->event_idx));
4369
        }
4370
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SCSI)) {
4371 4372 4373 4374 4375 4376 4377
            /* if sg_io is true but the scsi option isn't supported,
             * that means it's just always on in this version of qemu.
             */
            virBufferAsprintf(&opt, ",scsi=%s",
                              (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN)
                              ? "on" : "off");
        }
4378
        if (qemuBuildDeviceAddressStr(&opt, def, &disk->info, qemuCaps) < 0)
A
Alex Jia 已提交
4379
            goto error;
4380
        break;
4381

4382
    case VIR_DOMAIN_DISK_BUS_USB:
4383 4384 4385 4386 4387 4388
        if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
            disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("unexpected address type for usb disk"));
            goto error;
        }
4389 4390 4391 4392 4393 4394 4395
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_STORAGE)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("This QEMU doesn't support '-device "
                             "usb-storage'"));
            goto error;

        }
4396
        virBufferAddLit(&opt, "usb-storage");
4397

4398
        if (qemuBuildDeviceAddressStr(&opt, def, &disk->info, qemuCaps) < 0)
4399
            goto error;
4400
        break;
4401

4402
    default:
4403 4404
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unsupported disk bus '%s' with device setup"), bus);
4405 4406
        goto error;
    }
4407

4408 4409
    virBufferAsprintf(&opt, ",drive=%s%s", QEMU_DRIVE_HOST_PREFIX, disk->info.alias);
    virBufferAsprintf(&opt, ",id=%s", disk->info.alias);
4410
    if (bootindex && virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX))
4411
        virBufferAsprintf(&opt, ",bootindex=%d", bootindex);
4412
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKIO)) {
V
Viktor Mihajlovski 已提交
4413
        if (disk->blockio.logical_block_size > 0)
4414
            virBufferAsprintf(&opt, ",logical_block_size=%u",
V
Viktor Mihajlovski 已提交
4415 4416
                              disk->blockio.logical_block_size);
        if (disk->blockio.physical_block_size > 0)
4417
            virBufferAsprintf(&opt, ",physical_block_size=%u",
V
Viktor Mihajlovski 已提交
4418
                              disk->blockio.physical_block_size);
4419
    }
4420

4421 4422 4423 4424 4425 4426
    if (disk->wwn) {
        if (STRPREFIX(disk->wwn, "0x"))
            virBufferAsprintf(&opt, ",wwn=%s", disk->wwn);
        else
            virBufferAsprintf(&opt, ",wwn=0x%s", disk->wwn);
    }
4427

4428 4429 4430 4431 4432 4433
    if (disk->vendor)
        virBufferAsprintf(&opt, ",vendor=%s", disk->vendor);

    if (disk->product)
        virBufferAsprintf(&opt, ",product=%s", disk->product);

4434 4435
    if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_STORAGE_REMOVABLE)) {
J
Ján Tomko 已提交
4436
            if (disk->removable == VIR_TRISTATE_SWITCH_ON)
4437 4438 4439 4440
                virBufferAddLit(&opt, ",removable=on");
            else
                virBufferAddLit(&opt, ",removable=off");
        } else {
J
Ján Tomko 已提交
4441
            if (disk->removable != VIR_TRISTATE_SWITCH_ABSENT) {
4442 4443 4444 4445 4446 4447 4448 4449
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("This QEMU doesn't support setting the "
                                 "removable flag of USB storage devices"));
                goto error;
            }
        }
    }

4450
    if (virBufferCheckError(&opt) < 0)
4451 4452 4453 4454
        goto error;

    return virBufferContentAndReset(&opt);

4455
 error:
4456 4457 4458 4459 4460 4461
    virBufferFreeAndReset(&opt);
    return NULL;
}


char *qemuBuildFSStr(virDomainFSDefPtr fs,
4462
                     virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED)
4463 4464
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;
4465
    const char *driver = qemuDomainFSDriverTypeToString(fs->fsdriver);
4466
    const char *wrpolicy = virDomainFSWrpolicyTypeToString(fs->wrpolicy);
4467 4468

    if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
4469 4470
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("only supports mount filesystem type"));
4471 4472 4473
        goto error;
    }

4474
    if (!driver) {
4475 4476
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Filesystem driver type not supported"));
4477 4478 4479 4480
        goto error;
    }
    virBufferAdd(&opt, driver, -1);

4481 4482 4483 4484
    if (fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_PATH ||
        fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_DEFAULT) {
        if (fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_MAPPED) {
            virBufferAddLit(&opt, ",security_model=mapped");
4485
        } else if (fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH) {
4486
            virBufferAddLit(&opt, ",security_model=passthrough");
4487
        } else if (fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_SQUASH) {
4488 4489 4490 4491 4492 4493
            virBufferAddLit(&opt, ",security_model=none");
        }
    } else {
        /* For other fs drivers, default(passthru) should always
         * be supported */
        if (fs->accessmode != VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH) {
4494 4495
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("only supports passthrough accessmode"));
4496 4497
            goto error;
        }
4498
    }
4499 4500

    if (fs->wrpolicy) {
4501 4502 4503 4504 4505 4506 4507
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_FSDEV_WRITEOUT)) {
            virBufferAsprintf(&opt, ",writeout=%s", wrpolicy);
        } else {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("filesystem writeout not supported"));
            goto error;
        }
4508 4509
    }

4510 4511
    virBufferAsprintf(&opt, ",id=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
    virBufferAsprintf(&opt, ",path=%s", fs->src);
4512

4513
    if (fs->readonly) {
4514
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_FSDEV_READONLY)) {
4515 4516
            virBufferAddLit(&opt, ",readonly");
        } else {
4517 4518 4519
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("readonly filesystem is not supported by this "
                             "QEMU binary"));
4520 4521 4522 4523
            goto error;
        }
    }

4524
    if (virBufferCheckError(&opt) < 0)
4525 4526 4527 4528
        goto error;

    return virBufferContentAndReset(&opt);

4529
 error:
4530 4531 4532 4533 4534 4535
    virBufferFreeAndReset(&opt);
    return NULL;
}


char *
4536 4537
qemuBuildFSDevStr(virDomainDefPtr def,
                  virDomainFSDefPtr fs,
4538
                  virQEMUCapsPtr qemuCaps)
4539 4540 4541 4542
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;

    if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
4543 4544
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("can only passthrough directories"));
4545 4546 4547
        goto error;
    }

4548 4549 4550 4551 4552
    if (fs->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
        virBufferAddLit(&opt, "virtio-9p-ccw");
    else
        virBufferAddLit(&opt, "virtio-9p-pci");

4553 4554 4555
    virBufferAsprintf(&opt, ",id=%s", fs->info.alias);
    virBufferAsprintf(&opt, ",fsdev=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
    virBufferAsprintf(&opt, ",mount_tag=%s", fs->dst);
A
Alex Jia 已提交
4556

4557
    if (qemuBuildDeviceAddressStr(&opt, def, &fs->info, qemuCaps) < 0)
A
Alex Jia 已提交
4558
        goto error;
4559

4560
    if (virBufferCheckError(&opt) < 0)
4561 4562 4563 4564
        goto error;

    return virBufferContentAndReset(&opt);

4565
 error:
4566 4567 4568 4569 4570
    virBufferFreeAndReset(&opt);
    return NULL;
}


4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589
static int
qemuControllerModelUSBToCaps(int model)
{
    switch (model) {
    case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI:
        return QEMU_CAPS_PIIX3_USB_UHCI;
    case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX4_UHCI:
        return QEMU_CAPS_PIIX4_USB_UHCI;
    case VIR_DOMAIN_CONTROLLER_MODEL_USB_EHCI:
        return QEMU_CAPS_USB_EHCI;
    case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1:
    case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI1:
    case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI2:
    case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI3:
        return QEMU_CAPS_ICH9_USB_EHCI1;
    case VIR_DOMAIN_CONTROLLER_MODEL_USB_VT82C686B_UHCI:
        return QEMU_CAPS_VT82C686B_USB_UHCI;
    case VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI:
        return QEMU_CAPS_PCI_OHCI;
G
Gerd Hoffmann 已提交
4590 4591
    case VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI:
        return QEMU_CAPS_NEC_USB_XHCI;
4592 4593 4594 4595 4596 4597 4598
    default:
        return -1;
    }
}


static int
4599 4600
qemuBuildUSBControllerDevStr(virDomainDefPtr domainDef,
                             virDomainControllerDefPtr def,
4601
                             virQEMUCapsPtr qemuCaps,
4602 4603 4604
                             virBuffer *buf)
{
    const char *smodel;
4605
    int model, flags;
4606 4607

    model = def->model;
4608

4609
    if (model == -1) {
4610
        if ARCH_IS_PPC64(domainDef->os.arch)
4611 4612 4613 4614
            model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI;
        else
            model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI;
    }
4615 4616

    smodel = qemuControllerModelUSBTypeToString(model);
4617
    flags = qemuControllerModelUSBToCaps(model);
4618

4619
    if (flags == -1 || !virQEMUCapsGet(qemuCaps, flags)) {
4620 4621
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("%s not supported in this QEMU binary"), smodel);
4622 4623 4624
        return -1;
    }

4625 4626
    virBufferAsprintf(buf, "%s", smodel);

4627 4628 4629 4630 4631
    if (def->info.mastertype == VIR_DOMAIN_CONTROLLER_MASTER_USB)
        virBufferAsprintf(buf, ",masterbus=%s.0,firstport=%d",
                          def->info.alias, def->info.master.usb.startport);
    else
        virBufferAsprintf(buf, ",id=%s", def->info.alias);
4632

4633 4634 4635
    return 0;
}

4636
char *
4637 4638
qemuBuildControllerDevStr(virDomainDefPtr domainDef,
                          virDomainControllerDefPtr def,
4639
                          virQEMUCapsPtr qemuCaps,
4640
                          int *nusbcontroller)
4641 4642
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4643
    int model = def->model;
4644
    const char *modelName = NULL;
4645

4646 4647 4648 4649
    if (!qemuCheckCCWS390AddressSupport(domainDef, def->info, qemuCaps,
                                        "controller"))
        return NULL;

4650 4651 4652 4653
    if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
        if ((qemuSetSCSIControllerModel(domainDef, qemuCaps, &model)) < 0)
            return NULL;
    }
4654

4655
    if (!(def->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI &&
4656
          model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI)) {
4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671
        if (def->queues) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("'queues' is only supported by virtio-scsi controller"));
            return NULL;
        }
        if (def->cmd_per_lun) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("'cmd_per_lun' is only supported by virtio-scsi controller"));
            return NULL;
        }
        if (def->max_sectors) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("'max_sectors' is only supported by virtio-scsi controller"));
            return NULL;
        }
4672 4673 4674 4675 4676
        if (def->ioeventfd) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("'ioeventfd' is only supported by virtio-scsi controller"));
            return NULL;
        }
4677 4678
    }

4679 4680
    switch (def->type) {
    case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
4681
        switch (model) {
4682
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI:
4683 4684 4685 4686 4687
            if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
                virBufferAddLit(&buf, "virtio-scsi-ccw");
            else if (def->info.type ==
                     VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
                virBufferAddLit(&buf, "virtio-scsi-s390");
4688 4689 4690
            else if (def->info.type ==
                     VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
                virBufferAddLit(&buf, "virtio-scsi-device");
4691 4692
            else
                virBufferAddLit(&buf, "virtio-scsi-pci");
4693
            break;
4694
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC:
4695
            virBufferAddLit(&buf, "lsi");
4696 4697 4698 4699
            break;
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI:
            virBufferAddLit(&buf, "spapr-vscsi");
            break;
4700 4701 4702
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1078:
            virBufferAddLit(&buf, "megasas");
            break;
4703
        default:
4704 4705 4706
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("Unsupported controller model: %s"),
                           virDomainControllerModelSCSITypeToString(def->model));
4707
        }
4708
        virBufferAsprintf(&buf, ",id=%s", def->info.alias);
4709 4710 4711 4712 4713
        break;

    case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
        if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
            virBufferAddLit(&buf, "virtio-serial-pci");
4714 4715 4716
        } else if (def->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
            virBufferAddLit(&buf, "virtio-serial-ccw");
4717 4718 4719
        } else if (def->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
            virBufferAddLit(&buf, "virtio-serial-s390");
4720 4721 4722
        } else if (def->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) {
            virBufferAddLit(&buf, "virtio-serial-device");
4723 4724 4725
        } else {
            virBufferAddLit(&buf, "virtio-serial");
        }
4726
        virBufferAsprintf(&buf, ",id=%s", def->info.alias);
4727
        if (def->opts.vioserial.ports != -1) {
4728
            virBufferAsprintf(&buf, ",max_ports=%d",
4729 4730 4731
                              def->opts.vioserial.ports);
        }
        if (def->opts.vioserial.vectors != -1) {
4732
            virBufferAsprintf(&buf, ",vectors=%d",
4733 4734 4735 4736
                              def->opts.vioserial.vectors);
        }
        break;

E
Eric Blake 已提交
4737
    case VIR_DOMAIN_CONTROLLER_TYPE_CCID:
4738
        virBufferAsprintf(&buf, "usb-ccid,id=%s", def->info.alias);
E
Eric Blake 已提交
4739 4740
        break;

J
Jim Fehlig 已提交
4741
    case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
4742 4743 4744 4745 4746 4747
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_AHCI)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("SATA is not supported with this "
                             "QEMU binary"));
            goto error;
        }
4748
        virBufferAsprintf(&buf, "ahci,id=%s", def->info.alias);
J
Jim Fehlig 已提交
4749 4750
        break;

4751
    case VIR_DOMAIN_CONTROLLER_TYPE_USB:
4752
        if (qemuBuildUSBControllerDevStr(domainDef, def, qemuCaps, &buf) == -1)
4753 4754 4755 4756 4757 4758 4759
            goto error;

        if (nusbcontroller)
            *nusbcontroller += 1;

        break;

4760
    case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772
        if (def->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT ||
            def->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("wrong function called for pci-root/pcie-root"));
            return NULL;
        }
        if (def->idx == 0) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("index for pci controllers of model '%s' must be > 0"),
                           virDomainControllerModelPCITypeToString(def->model));
            goto error;
        }
4773 4774
        switch (def->model) {
        case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
4775
            if (def->opts.pciopts.modelName
4776 4777
                == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE ||
                def->opts.pciopts.chassisNr == -1) {
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
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("autogenerated pci-bridge options not set"));
                goto error;
            }

            modelName = virDomainControllerPCIModelNameTypeToString(def->opts.pciopts.modelName);
            if (!modelName) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("unknown pci-bridge model name value %d"),
                               def->opts.pciopts.modelName);
                goto error;
            }
            if (def->opts.pciopts.modelName
                != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCI_BRIDGE) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("PCI controller model name '%s' "
                                 "is not valid for a pci-bridge"),
                               modelName);
                goto error;
            }
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCI_BRIDGE)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("the pci-bridge controller "
                                 "is not supported in this QEMU binary"));
                goto error;
            }
            virBufferAsprintf(&buf, "%s,chassis_nr=%d,id=%s",
4805 4806
                              modelName, def->opts.pciopts.chassisNr,
                              def->info.alias);
4807
            break;
4808
        case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830
            if (def->opts.pciopts.modelName
                == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("autogenerated dmi-to-pci-bridge options not set"));
                goto error;
            }

            modelName = virDomainControllerPCIModelNameTypeToString(def->opts.pciopts.modelName);
            if (!modelName) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("unknown dmi-to-pci-bridge model name value %d"),
                               def->opts.pciopts.modelName);
                goto error;
            }
            if (def->opts.pciopts.modelName
                != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_I82801B11_BRIDGE) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("PCI controller model name '%s' "
                                 "is not valid for a dmi-to-pci-bridge"),
                               modelName);
                goto error;
            }
4831 4832
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
4833
                               _("the dmi-to-pci-bridge (i82801b11-bridge) "
4834 4835 4836
                                 "controller is not supported in this QEMU binary"));
                goto error;
            }
4837
            virBufferAsprintf(&buf, "%s,id=%s", modelName, def->info.alias);
4838
            break;
4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871
        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT:
            if (def->opts.pciopts.modelName
                == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("autogenerated pcie-root-port options not set"));
                goto error;
            }
            modelName = virDomainControllerPCIModelNameTypeToString(def->opts.pciopts.modelName);
            if (!modelName) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("unknown pcie-root-port model name value %d"),
                               def->opts.pciopts.modelName);
                goto error;
            }
            if (def->opts.pciopts.modelName
                != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_IOH3420) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("PCI controller model name '%s' "
                                 "is not valid for a pcie-root-port"),
                               modelName);
                goto error;
            }
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_IOH3420)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("the pcie-root-port (ioh3420) "
                                 "controller is not supported in this QEMU binary"));
                goto error;
            }

            virBufferAsprintf(&buf, "%s,port=0x%x,chassis=%d,id=%s",
                              modelName, def->opts.pciopts.port,
                              def->opts.pciopts.chassis, def->info.alias);
            break;
4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902
        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT:
            if (def->opts.pciopts.modelName
                == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("autogenerated pcie-switch-upstream-port options not set"));
                goto error;
            }
            modelName = virDomainControllerPCIModelNameTypeToString(def->opts.pciopts.modelName);
            if (!modelName) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("unknown pcie-switch-upstream-port model name value %d"),
                               def->opts.pciopts.modelName);
                goto error;
            }
            if (def->opts.pciopts.modelName
                != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_X3130_UPSTREAM) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("PCI controller model name '%s' "
                                 "is not valid for a pcie-switch-upstream-port"),
                               modelName);
                goto error;
            }
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_X3130_UPSTREAM)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("the pcie-switch-upstream-port (x3130-upstream) "
                                 "controller is not supported in this QEMU binary"));
                goto error;
            }

            virBufferAsprintf(&buf, "%s,id=%s", modelName, def->info.alias);
            break;
4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939
        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT:
            if (def->opts.pciopts.modelName
                == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE ||
                def->opts.pciopts.chassis == -1 ||
                def->opts.pciopts.port == -1) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("autogenerated pcie-switch-downstream-port "
                                 "options not set"));
                goto error;
            }

            modelName = virDomainControllerPCIModelNameTypeToString(def->opts.pciopts.modelName);
            if (!modelName) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("unknown pcie-switch-downstream-port model name value %d"),
                               def->opts.pciopts.modelName);
                goto error;
            }
            if (def->opts.pciopts.modelName
                != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_XIO3130_DOWNSTREAM) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("PCI controller model name '%s' "
                                 "is not valid for a pcie-switch-downstream-port"),
                               modelName);
                goto error;
            }
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("The pcie-switch-downstream-port "
                                 "(xio3130-downstream) controller "
                                 "is not supported in this QEMU binary"));
                goto error;
            }
            virBufferAsprintf(&buf, "%s,port=0x%x,chassis=%d,id=%s",
                              modelName, def->opts.pciopts.port,
                              def->opts.pciopts.chassis, def->info.alias);
            break;
4940 4941 4942
        }
        break;

4943
    case VIR_DOMAIN_CONTROLLER_TYPE_IDE:
4944 4945 4946 4947 4948
        /* Since we currently only support the integrated IDE
         * controller on various boards, if we ever get to here, it's
         * because some other machinetype had an IDE controller
         * specified, or one with a single IDE contraller had multiple
         * ide controllers specified.
4949
         */
4950
        if (qemuDomainMachineHasBuiltinIDE(domainDef))
4951
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
4952
                           _("Only a single IDE controller is supported "
4953 4954 4955 4956 4957 4958 4959
                             "for this machine type"));
        else
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("IDE controllers are unsupported for "
                             "this QEMU binary or machine type"));
        goto error;

4960
    default:
4961
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
4962
                       _("Unsupported controller type: %s"),
4963
                       virDomainControllerTypeToString(def->type));
4964 4965 4966
        goto error;
    }

4967 4968
    if (def->queues)
        virBufferAsprintf(&buf, ",num_queues=%u", def->queues);
4969

4970 4971 4972 4973 4974 4975
    if (def->cmd_per_lun)
        virBufferAsprintf(&buf, ",cmd_per_lun=%u", def->cmd_per_lun);

    if (def->max_sectors)
        virBufferAsprintf(&buf, ",max_sectors=%u", def->max_sectors);

4976 4977
    qemuBuildIoEventFdStr(&buf, def->ioeventfd, qemuCaps);

4978
    if (qemuBuildDeviceAddressStr(&buf, domainDef, &def->info, qemuCaps) < 0)
4979 4980
        goto error;

4981
    if (virBufferCheckError(&buf) < 0)
4982 4983 4984 4985
        goto error;

    return virBufferContentAndReset(&buf);

4986
 error:
4987 4988 4989 4990 4991
    virBufferFreeAndReset(&buf);
    return NULL;
}


4992 4993 4994 4995
/**
 * qemuBuildMemoryBackendStr:
 * @size: size of the memory device in kibibytes
 * @pagesize: size of the requested memory page in KiB, 0 for default
4996 4997
 * @guestNode: NUMA node in the guest that the memory object will be attached
 *             to, or -1 if NUMA is not used in the guest
4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014
 * @hostNodes: map of host nodes to alloc the memory in, NULL for default
 * @autoNodeset: fallback nodeset in case of automatic numa placement
 * @def: domain definition object
 * @qemuCaps: qemu capabilities object
 * @cfg: qemu driver config object
 * @aliasPrefix: prefix string of the alias (to allow for multiple frontents)
 * @id: index of the device (to construct the alias)
 * @backendStr: returns the object string
 *
 * Formats the configuration string for the memory device backend according
 * to the configuration. @pagesize and @hostNodes can be used to override the
 * default source configuration, both are optional.
 *
 * Returns 0 on success, 1 if only the implicit memory-device-ram with no
 * other configuration was used (to detect legacy configurations). Returns
 * -1 in case of an error.
 */
5015
int
5016 5017 5018 5019 5020 5021 5022 5023
qemuBuildMemoryBackendStr(unsigned long long size,
                          unsigned long long pagesize,
                          int guestNode,
                          virBitmapPtr userNodeset,
                          virBitmapPtr autoNodeset,
                          virDomainDefPtr def,
                          virQEMUCapsPtr qemuCaps,
                          virQEMUDriverConfigPtr cfg,
5024 5025
                          const char **backendType,
                          virJSONValuePtr *backendProps,
5026 5027 5028 5029 5030
                          bool force)
{
    virDomainHugePagePtr master_hugepage = NULL;
    virDomainHugePagePtr hugepage = NULL;
    virDomainNumatuneMemMode mode;
5031
    const long system_page_size = virGetSystemPageSizeKB();
5032
    virNumaMemAccess memAccess = VIR_NUMA_MEM_ACCESS_DEFAULT;
5033 5034
    size_t i;
    char *mem_path = NULL;
5035
    virBitmapPtr nodemask = NULL;
5036
    int ret = -1;
5037
    virJSONValuePtr props = NULL;
5038
    bool nodeSpecified = virDomainNumatuneNodeSpecified(def->numa, guestNode);
5039

5040 5041 5042
    *backendProps = NULL;
    *backendType = NULL;

5043 5044 5045 5046 5047 5048 5049 5050 5051
    if (guestNode >= 0) {
        /* memory devices could provide a invalid guest node */
        if (guestNode >= virDomainNumaGetNodeCount(def->numa)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("can't add memory backend for guest node '%d' as "
                             "the guest has only '%zu' NUMA nodes configured"),
                           guestNode, virDomainNumaGetNodeCount(def->numa));
            return -1;
        }
5052

5053 5054
        memAccess = virDomainNumaGetNodeMemoryAccessMode(def->numa, guestNode);
    }
5055

5056 5057 5058
    if (virDomainNumatuneGetMode(def->numa, guestNode, &mode) < 0 &&
        virDomainNumatuneGetMode(def->numa, -1, &mode) < 0)
        mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
5059

5060
    if (pagesize == 0) {
5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071
        /* Find the huge page size we want to use */
        for (i = 0; i < def->mem.nhugepages; i++) {
            bool thisHugepage = false;

            hugepage = &def->mem.hugepages[i];

            if (!hugepage->nodemask) {
                master_hugepage = hugepage;
                continue;
            }

5072 5073 5074 5075
            /* just find the master hugepage in case we don't use NUMA */
            if (guestNode < 0)
                continue;

5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098
            if (virBitmapGetBit(hugepage->nodemask, guestNode,
                                &thisHugepage) < 0) {
                /* Ignore this error. It's not an error after all. Well,
                 * the nodemask for this <page/> can contain lower NUMA
                 * nodes than we are querying in here. */
                continue;
            }

            if (thisHugepage) {
                /* Hooray, we've found the page size */
                break;
            }
        }

        if (i == def->mem.nhugepages) {
            /* We have not found specific huge page to be used with this
             * NUMA node. Use the generic setting then (<page/> without any
             * @nodemask) if possible. */
            hugepage = master_hugepage;
        }

        if (hugepage)
            pagesize = hugepage->size;
5099
    }
5100

5101 5102 5103 5104 5105 5106
    if (pagesize == system_page_size) {
        /* However, if user specified to use "huge" page
         * of regular system page size, it's as if they
         * hasn't specified any huge pages at all. */
        pagesize = 0;
        hugepage = NULL;
5107 5108
    }

5109 5110 5111
    if (!(props = virJSONValueNewObject()))
        return -1;

5112 5113
    if (pagesize || hugepage) {
        if (pagesize) {
5114 5115 5116
            /* Now lets see, if the huge page we want to use is even mounted
             * and ready to use */
            for (i = 0; i < cfg->nhugetlbfs; i++) {
5117
                if (cfg->hugetlbfs[i].size == pagesize)
5118 5119
                    break;
            }
5120

5121 5122 5123
            if (i == cfg->nhugetlbfs) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("Unable to find any usable hugetlbfs mount for %llu KiB"),
5124
                               pagesize);
5125 5126
                goto cleanup;
            }
5127

5128 5129 5130 5131 5132 5133 5134
            if (!(mem_path = qemuGetHugepagePath(&cfg->hugetlbfs[i])))
                goto cleanup;
        } else {
            if (!(mem_path = qemuGetDefaultHugepath(cfg->hugetlbfs,
                                                    cfg->nhugetlbfs)))
                goto cleanup;
        }
5135

5136 5137 5138 5139 5140 5141 5142
        *backendType = "memory-backend-file";

        if (virJSONValueObjectAdd(props,
                                  "b:prealloc", true,
                                  "s:mem-path", mem_path,
                                  NULL) < 0)
            goto cleanup;
5143 5144

        switch (memAccess) {
5145
        case VIR_NUMA_MEM_ACCESS_SHARED:
5146 5147
            if (virJSONValueObjectAdd(props, "b:share", true, NULL) < 0)
                goto cleanup;
5148 5149
            break;

5150
        case VIR_NUMA_MEM_ACCESS_PRIVATE:
5151 5152
            if (virJSONValueObjectAdd(props, "b:share", false, NULL) < 0)
                goto cleanup;
5153 5154
            break;

5155 5156
        case VIR_NUMA_MEM_ACCESS_DEFAULT:
        case VIR_NUMA_MEM_ACCESS_LAST:
5157 5158 5159 5160 5161 5162 5163 5164 5165 5166
            break;
        }
    } else {
        if (memAccess) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Shared memory mapping is supported "
                             "only with hugepages"));
            goto cleanup;
        }

5167
        *backendType = "memory-backend-ram";
5168 5169
    }

5170 5171
    if (virJSONValueObjectAdd(props, "U:size", size * 1024, NULL) < 0)
        goto cleanup;
5172 5173

    if (userNodeset) {
5174
        nodemask = userNodeset;
5175
    } else {
5176
        if (virDomainNumatuneMaybeGetNodeset(def->numa, autoNodeset,
5177
                                             &nodemask, guestNode) < 0)
5178 5179 5180 5181
            goto cleanup;
    }

    if (nodemask) {
5182 5183
        if (!virNumaNodesetIsAvailable(nodemask))
            goto cleanup;
5184 5185 5186 5187
        if (virJSONValueObjectAdd(props,
                                  "m:host-nodes", nodemask,
                                  "S:policy", qemuNumaPolicyTypeToString(mode),
                                  NULL) < 0)
5188 5189 5190
            goto cleanup;
    }

5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205
    /* If none of the following is requested... */
    if (!pagesize && !userNodeset && !memAccess && !nodeSpecified && !force) {
        /* report back that using the new backend is not necessary
         * to achieve the desired configuration */
        ret = 1;
    } else {
        /* otherwise check the required capability */
        if (STREQ(*backendType, "memory-backend-file") &&
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("this qemu doesn't support the "
                             "memory-backend-file object"));
            goto cleanup;
        } else if (STREQ(*backendType, "memory-backend-ram") &&
                   !virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM)) {
5206 5207 5208
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("this qemu doesn't support the "
                             "memory-backend-ram object"));
5209
            goto cleanup;
5210 5211
        }

5212
        ret = 0;
5213 5214
    }

5215 5216
    *backendProps = props;
    props = NULL;
5217 5218

 cleanup:
5219
    virJSONValueFree(props);
5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233
    VIR_FREE(mem_path);

    return ret;
}


static int
qemuBuildMemoryCellBackendStr(virDomainDefPtr def,
                              virQEMUCapsPtr qemuCaps,
                              virQEMUDriverConfigPtr cfg,
                              size_t cell,
                              virBitmapPtr auto_nodeset,
                              char **backendStr)
{
5234 5235 5236 5237 5238
    virJSONValuePtr props = NULL;
    char *alias = NULL;
    const char *backendType;
    int ret = -1;
    int rc;
5239 5240
    unsigned long long memsize = virDomainNumaGetNodeMemorySize(def->numa,
                                                                cell);
5241

5242
    *backendStr = NULL;
5243

5244 5245 5246
    if (virAsprintf(&alias, "ram-node%zu", cell) < 0)
        goto cleanup;

5247 5248 5249
    if ((rc = qemuBuildMemoryBackendStr(memsize, 0, cell, NULL, auto_nodeset,
                                        def, qemuCaps, cfg, &backendType,
                                        &props, false)) < 0)
5250 5251 5252 5253 5254 5255 5256
        goto cleanup;

    if (!(*backendStr = qemuBuildObjectCommandlineFromJSON(backendType,
                                                           alias,
                                                           props)))
        goto cleanup;

5257
    ret = rc;
5258 5259 5260 5261 5262

 cleanup:
    VIR_FREE(alias);
    virJSONValueFree(props);

5263 5264 5265 5266
    return ret;
}


5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302
static char *
qemuBuildMemoryDimmBackendStr(virDomainMemoryDefPtr mem,
                              virDomainDefPtr def,
                              virQEMUCapsPtr qemuCaps,
                              virQEMUDriverConfigPtr cfg)
{
    virJSONValuePtr props = NULL;
    char *alias = NULL;
    const char *backendType;
    char *ret = NULL;

    if (!mem->info.alias) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("memory device alias is not assigned"));
        return NULL;
    }

    if (virAsprintf(&alias, "mem%s", mem->info.alias) < 0)
        goto cleanup;

    if (qemuBuildMemoryBackendStr(mem->size, mem->pagesize,
                                  mem->targetNode, mem->sourceNodes, NULL,
                                  def, qemuCaps, cfg,
                                  &backendType, &props, true) < 0)
        goto cleanup;

    ret = qemuBuildObjectCommandlineFromJSON(backendType, alias, props);

 cleanup:
    VIR_FREE(alias);
    virJSONValueFree(props);

    return ret;
}


5303
char *
5304
qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem)
5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if (!mem->info.alias) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("missing alias for memory device"));
        return NULL;
    }

    switch ((virDomainMemoryModel) mem->model) {
    case VIR_DOMAIN_MEMORY_MODEL_DIMM:
5316 5317 5318 5319 5320 5321 5322
        virBufferAddLit(&buf, "pc-dimm,");

        if (mem->targetNode >= 0)
            virBufferAsprintf(&buf, "node=%d,", mem->targetNode);

        virBufferAsprintf(&buf, "memdev=mem%s,id=%s",
                          mem->info.alias, mem->info.alias);
5323 5324 5325

        if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM) {
            virBufferAsprintf(&buf, ",slot=%d", mem->info.addr.dimm.slot);
5326
            virBufferAsprintf(&buf, ",addr=%llu", mem->info.addr.dimm.base);
5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345
        }

        break;

    case VIR_DOMAIN_MEMORY_MODEL_NONE:
    case VIR_DOMAIN_MEMORY_MODEL_LAST:
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("invalid memory device type"));
        break;

    }

    if (virBufferCheckError(&buf) < 0)
        return NULL;

    return virBufferContentAndReset(&buf);
}


5346 5347 5348 5349 5350 5351
char *
qemuBuildNicStr(virDomainNetDefPtr net,
                const char *prefix,
                int vlan)
{
    char *str;
5352 5353
    char macaddr[VIR_MAC_STRING_BUFLEN];

5354 5355 5356 5357 5358 5359 5360 5361 5362
    ignore_value(virAsprintf(&str,
                             "%smacaddr=%s,vlan=%d%s%s%s%s",
                             prefix ? prefix : "",
                             virMacAddrFormat(&net->mac, macaddr),
                             vlan,
                             (net->model ? ",model=" : ""),
                             (net->model ? net->model : ""),
                             (net->info.alias ? ",name=" : ""),
                             (net->info.alias ? net->info.alias : "")));
5363 5364 5365 5366 5367
    return str;
}


char *
5368 5369
qemuBuildNicDevStr(virDomainDefPtr def,
                   virDomainNetDefPtr net,
5370
                   int vlan,
5371
                   int bootindex,
5372
                   size_t vhostfdSize,
5373
                   virQEMUCapsPtr qemuCaps)
5374 5375
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
5376
    const char *nic = net->model;
5377
    bool usingVirtio = false;
5378
    char macaddr[VIR_MAC_STRING_BUFLEN];
5379

5380 5381
    if (STREQ(net->model, "virtio")) {
        if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
5382
            nic = "virtio-net-ccw";
5383
        else if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
5384
            nic = "virtio-net-s390";
5385 5386
        else if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
            nic = "virtio-net-device";
5387
        else
5388
            nic = "virtio-net-pci";
5389

5390
        usingVirtio = true;
5391 5392
    }

5393
    virBufferAdd(&buf, nic, -1);
5394
    if (usingVirtio && net->driver.virtio.txmode) {
5395
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_TX_ALG)) {
5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408
            virBufferAddLit(&buf, ",tx=");
            switch (net->driver.virtio.txmode) {
                case VIR_DOMAIN_NET_VIRTIO_TX_MODE_IOTHREAD:
                    virBufferAddLit(&buf, "bh");
                    break;

                case VIR_DOMAIN_NET_VIRTIO_TX_MODE_TIMER:
                    virBufferAddLit(&buf, "timer");
                    break;
                default:
                    /* this should never happen, if it does, we need
                     * to add another case to this switch.
                     */
5409 5410
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("unrecognized virtio-net-pci 'tx' option"));
5411 5412 5413
                    goto error;
            }
        } else {
5414 5415
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("virtio-net-pci 'tx' option not supported in this QEMU binary"));
5416 5417 5418
            goto error;
        }
    }
5419
    if (usingVirtio) {
5420
        qemuBuildIoEventFdStr(&buf, net->driver.virtio.ioeventfd, qemuCaps);
5421
        if (net->driver.virtio.event_idx &&
5422
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_EVENT_IDX)) {
5423
            virBufferAsprintf(&buf, ",event_idx=%s",
J
Ján Tomko 已提交
5424
                              virTristateSwitchTypeToString(net->driver.virtio.event_idx));
5425
        }
5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449
        if (net->driver.virtio.host.csum) {
            virBufferAsprintf(&buf, ",csum=%s",
                              virTristateSwitchTypeToString(net->driver.virtio.host.csum));
        }
        if (net->driver.virtio.host.gso) {
            virBufferAsprintf(&buf, ",gso=%s",
                              virTristateSwitchTypeToString(net->driver.virtio.host.gso));
        }
        if (net->driver.virtio.host.tso4) {
            virBufferAsprintf(&buf, ",host_tso4=%s",
                              virTristateSwitchTypeToString(net->driver.virtio.host.tso4));
        }
        if (net->driver.virtio.host.tso6) {
            virBufferAsprintf(&buf, ",host_tso6=%s",
                              virTristateSwitchTypeToString(net->driver.virtio.host.tso6));
        }
        if (net->driver.virtio.host.ecn) {
            virBufferAsprintf(&buf, ",host_ecn=%s",
                              virTristateSwitchTypeToString(net->driver.virtio.host.ecn));
        }
        if (net->driver.virtio.host.ufo) {
            virBufferAsprintf(&buf, ",host_ufo=%s",
                              virTristateSwitchTypeToString(net->driver.virtio.host.ufo));
        }
J
Ján Tomko 已提交
5450 5451 5452 5453
        if (net->driver.virtio.host.mrg_rxbuf) {
            virBufferAsprintf(&buf, ",mrg_rxbuf=%s",
                              virTristateSwitchTypeToString(net->driver.virtio.host.mrg_rxbuf));
        }
5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473
        if (net->driver.virtio.guest.csum) {
            virBufferAsprintf(&buf, ",guest_csum=%s",
                              virTristateSwitchTypeToString(net->driver.virtio.guest.csum));
        }
        if (net->driver.virtio.guest.tso4) {
            virBufferAsprintf(&buf, ",guest_tso4=%s",
                              virTristateSwitchTypeToString(net->driver.virtio.guest.tso4));
        }
        if (net->driver.virtio.guest.tso6) {
            virBufferAsprintf(&buf, ",guest_tso6=%s",
                              virTristateSwitchTypeToString(net->driver.virtio.guest.tso6));
        }
        if (net->driver.virtio.guest.ecn) {
            virBufferAsprintf(&buf, ",guest_ecn=%s",
                              virTristateSwitchTypeToString(net->driver.virtio.guest.ecn));
        }
        if (net->driver.virtio.guest.ufo) {
            virBufferAsprintf(&buf, ",guest_ufo=%s",
                              virTristateSwitchTypeToString(net->driver.virtio.guest.ufo));
        }
5474
    }
5475
    if (usingVirtio && vhostfdSize > 1) {
5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486
        if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
            /* ccw provides a one to one relation of fds to queues and
             * does not support the vectors option
             */
            virBufferAddLit(&buf, ",mq=on");
        } else {
            /* As advised at http://www.linux-kvm.org/page/Multiqueue
             * we should add vectors=2*N+2 where N is the vhostfdSize
             */
            virBufferAsprintf(&buf, ",mq=on,vectors=%zu", 2 * vhostfdSize + 2);
        }
5487
    }
5488
    if (vlan == -1)
5489
        virBufferAsprintf(&buf, ",netdev=host%s", net->info.alias);
5490
    else
5491 5492
        virBufferAsprintf(&buf, ",vlan=%d", vlan);
    virBufferAsprintf(&buf, ",id=%s", net->info.alias);
5493 5494
    virBufferAsprintf(&buf, ",mac=%s",
                      virMacAddrFormat(&net->mac, macaddr));
5495
    if (qemuBuildDeviceAddressStr(&buf, def, &net->info, qemuCaps) < 0)
5496
        goto error;
5497
    if (qemuBuildRomStr(&buf, &net->info, qemuCaps) < 0)
5498
        goto error;
5499
    if (bootindex && virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX))
5500
        virBufferAsprintf(&buf, ",bootindex=%d", bootindex);
5501

5502
    if (virBufferCheckError(&buf) < 0)
5503 5504 5505 5506
        goto error;

    return virBufferContentAndReset(&buf);

5507
 error:
5508 5509 5510 5511 5512 5513 5514
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
qemuBuildHostNetStr(virDomainNetDefPtr net,
5515
                    virQEMUDriverPtr driver,
5516 5517
                    char type_sep,
                    int vlan,
5518
                    char **tapfd,
5519
                    size_t tapfdSize,
5520
                    char **vhostfd,
5521
                    size_t vhostfdSize)
5522
{
5523
    bool is_tap = false;
5524
    virBuffer buf = VIR_BUFFER_INITIALIZER;
5525
    virDomainNetType netType = virDomainNetGetActualType(net);
5526
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
5527
    size_t i;
5528

5529
    if (net->script && netType != VIR_DOMAIN_NET_TYPE_ETHERNET) {
5530 5531 5532
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("scripts are not supported on interfaces of type %s"),
                       virDomainNetTypeToString(netType));
5533
        virObjectUnref(cfg);
5534 5535 5536 5537
        return NULL;
    }

    switch (netType) {
R
Richa Marwaha 已提交
5538 5539 5540 5541 5542
    /*
     * If type='bridge', and we're running as privileged user
     * or -netdev bridge is not supported then it will fall
     * through, -net tap,fd
     */
5543
    case VIR_DOMAIN_NET_TYPE_BRIDGE:
R
Richa Marwaha 已提交
5544
    case VIR_DOMAIN_NET_TYPE_NETWORK:
5545
    case VIR_DOMAIN_NET_TYPE_DIRECT:
5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558
        virBufferAsprintf(&buf, "tap%c", type_sep);
        /* for one tapfd 'fd=' shall be used,
         * for more than one 'fds=' is the right choice */
        if (tapfdSize == 1) {
            virBufferAsprintf(&buf, "fd=%s", tapfd[0]);
        } else {
            virBufferAddLit(&buf, "fds=");
            for (i = 0; i < tapfdSize; i++) {
                if (i)
                    virBufferAddChar(&buf, ':');
                virBufferAdd(&buf, tapfd[i], -1);
            }
        }
5559
        type_sep = ',';
5560
        is_tap = true;
5561 5562 5563 5564 5565
        break;

    case VIR_DOMAIN_NET_TYPE_ETHERNET:
        virBufferAddLit(&buf, "tap");
        if (net->ifname) {
5566
            virBufferAsprintf(&buf, "%cifname=%s", type_sep, net->ifname);
5567 5568
            type_sep = ',';
        }
5569
        if (net->script) {
5570
            virBufferAsprintf(&buf, "%cscript=%s", type_sep,
5571
                              net->script);
5572 5573
            type_sep = ',';
        }
5574
        is_tap = true;
5575 5576 5577
        break;

    case VIR_DOMAIN_NET_TYPE_CLIENT:
5578 5579 5580 5581 5582 5583 5584
       virBufferAsprintf(&buf, "socket%cconnect=%s:%d",
                         type_sep,
                         net->data.socket.address,
                         net->data.socket.port);
       type_sep = ',';
       break;

5585
    case VIR_DOMAIN_NET_TYPE_SERVER:
5586 5587
       virBufferAsprintf(&buf, "socket%clisten=%s:%d",
                         type_sep,
5588 5589
                         net->data.socket.address ? net->data.socket.address
                                                  : "",
5590 5591 5592 5593
                         net->data.socket.port);
       type_sep = ',';
       break;

5594
    case VIR_DOMAIN_NET_TYPE_MCAST:
5595 5596 5597 5598 5599 5600
       virBufferAsprintf(&buf, "socket%cmcast=%s:%d",
                         type_sep,
                         net->data.socket.address,
                         net->data.socket.port);
       type_sep = ',';
       break;
5601

5602 5603 5604 5605 5606 5607 5608 5609 5610 5611
    case VIR_DOMAIN_NET_TYPE_UDP:
       virBufferAsprintf(&buf, "socket%cudp=%s:%d,localaddr=%s:%d",
                         type_sep,
                         net->data.socket.address,
                         net->data.socket.port,
                         net->data.socket.localaddr,
                         net->data.socket.localport);
       type_sep = ',';
       break;

5612 5613 5614 5615 5616 5617 5618
    case VIR_DOMAIN_NET_TYPE_USER:
    default:
        virBufferAddLit(&buf, "user");
        break;
    }

    if (vlan >= 0) {
5619
        virBufferAsprintf(&buf, "%cvlan=%d", type_sep, vlan);
5620
        if (net->info.alias)
5621
            virBufferAsprintf(&buf, ",name=host%s",
5622 5623
                              net->info.alias);
    } else {
5624
        virBufferAsprintf(&buf, "%cid=host%s",
5625 5626 5627
                          type_sep, net->info.alias);
    }

5628
    if (is_tap) {
5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641
        if (vhostfdSize) {
            virBufferAddLit(&buf, ",vhost=on,");
            if (vhostfdSize == 1) {
                virBufferAsprintf(&buf, "vhostfd=%s", vhostfd[0]);
            } else {
                virBufferAddLit(&buf, "vhostfds=");
                for (i = 0; i < vhostfdSize; i++) {
                    if (i)
                        virBufferAddChar(&buf, ':');
                    virBufferAdd(&buf, vhostfd[i], -1);
                }
            }
        }
5642
        if (net->tune.sndbuf_specified)
5643
            virBufferAsprintf(&buf, ",sndbuf=%lu", net->tune.sndbuf);
5644 5645
    }

5646 5647
    virObjectUnref(cfg);

5648
    if (virBufferCheckError(&buf) < 0)
5649 5650 5651 5652 5653 5654 5655
        return NULL;

    return virBufferContentAndReset(&buf);
}


char *
5656 5657
qemuBuildWatchdogDevStr(virDomainDefPtr def,
                        virDomainWatchdogDefPtr dev,
5658
                        virQEMUCapsPtr qemuCaps)
5659 5660 5661 5662 5663
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    const char *model = virDomainWatchdogModelTypeToString(dev->model);
    if (!model) {
5664 5665
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("missing watchdog model"));
5666 5667 5668
        goto error;
    }

5669
    virBufferAsprintf(&buf, "%s,id=%s", model, dev->info.alias);
5670
    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
5671 5672
        goto error;

5673
    if (virBufferCheckError(&buf) < 0)
5674 5675 5676 5677
        goto error;

    return virBufferContentAndReset(&buf);

5678
 error:
5679 5680 5681 5682 5683 5684
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
5685 5686
qemuBuildMemballoonDevStr(virDomainDefPtr def,
                          virDomainMemballoonDefPtr dev,
5687
                          virQEMUCapsPtr qemuCaps)
5688 5689 5690
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

5691 5692 5693 5694 5695 5696 5697
    switch (dev->info.type) {
        case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI:
            virBufferAddLit(&buf, "virtio-balloon-pci");
            break;
        case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW:
            virBufferAddLit(&buf, "virtio-balloon-ccw");
            break;
5698 5699 5700
        case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
            virBufferAddLit(&buf, "virtio-balloon-device");
            break;
5701
        default:
5702 5703 5704
            virReportError(VIR_ERR_XML_ERROR,
                           _("memballoon unsupported with address type '%s'"),
                           virDomainDeviceAddressTypeToString(dev->info.type));
5705 5706 5707
            goto error;
    }

5708
    virBufferAsprintf(&buf, ",id=%s", dev->info.alias);
5709
    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
5710 5711
        goto error;

5712
    if (virBufferCheckError(&buf) < 0)
5713 5714 5715 5716
        goto error;

    return virBufferContentAndReset(&buf);

5717
 error:
5718 5719 5720 5721
    virBufferFreeAndReset(&buf);
    return NULL;
}

5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736
static char *
qemuBuildNVRAMDevStr(virDomainNVRAMDefPtr dev)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO &&
        dev->info.addr.spaprvio.has_reg) {
        virBufferAsprintf(&buf, "spapr-nvram.reg=0x%llx",
                          dev->info.addr.spaprvio.reg);
    } else {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("nvram address type must be spaprvio"));
        goto error;
    }

5737
    if (virBufferCheckError(&buf) < 0)
5738 5739 5740 5741
        goto error;

    return virBufferContentAndReset(&buf);

5742
 error:
5743 5744 5745
    virBufferFreeAndReset(&buf);
    return NULL;
}
5746

5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790
static char *
qemuBuildVirtioInputDevStr(virDomainDefPtr def,
                           virDomainInputDefPtr dev,
                           virQEMUCapsPtr qemuCaps)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    const char *suffix;

    if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
        suffix = "-pci";
    } else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) {
        suffix = "-device";
    } else {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unsupported address type %s for virtio input device"),
                       virDomainDeviceAddressTypeToString(dev->info.type));
        goto error;
    }

    switch ((virDomainInputType) dev->type) {
    case VIR_DOMAIN_INPUT_TYPE_MOUSE:
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_MOUSE)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("virtio-mouse is not supported by this QEMU binary"));
            goto error;
        }
        virBufferAsprintf(&buf, "virtio-mouse%s,id=%s", suffix, dev->info.alias);
        break;
    case VIR_DOMAIN_INPUT_TYPE_TABLET:
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_TABLET)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("virtio-tablet is not supported by this QEMU binary"));
            goto error;
        }
        virBufferAsprintf(&buf, "virtio-tablet%s,id=%s", suffix, dev->info.alias);
        break;
    case VIR_DOMAIN_INPUT_TYPE_KBD:
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_KEYBOARD)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("virtio-keyboard is not supported by this QEMU binary"));
            goto error;
        }
        virBufferAsprintf(&buf, "virtio-keyboard%s,id=%s", suffix, dev->info.alias);
        break;
5791
    case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH:
5792 5793 5794 5795 5796 5797 5798 5799
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_INPUT_HOST)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("virtio-input-host is not supported by this QEMU binary"));
            goto error;
        }
        virBufferAsprintf(&buf, "virtio-input-host%s,id=%s,evdev=", suffix, dev->info.alias);
        virBufferEscape(&buf, ',', ",", "%s", dev->source.evdev);
        break;
5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816
    case VIR_DOMAIN_INPUT_TYPE_LAST:
        break;
    }

    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
        goto error;

    if (virBufferCheckError(&buf) < 0)
        goto error;

    return virBufferContentAndReset(&buf);

 error:
    virBufferFreeAndReset(&buf);
    return NULL;
}

5817
char *
5818 5819
qemuBuildUSBInputDevStr(virDomainDefPtr def,
                        virDomainInputDefPtr dev,
5820
                        virQEMUCapsPtr qemuCaps)
5821 5822 5823
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836
    switch (dev->type) {
    case VIR_DOMAIN_INPUT_TYPE_MOUSE:
        virBufferAsprintf(&buf, "usb-mouse,id=%s", dev->info.alias);
        break;
    case VIR_DOMAIN_INPUT_TYPE_TABLET:
        virBufferAsprintf(&buf, "usb-tablet,id=%s", dev->info.alias);
        break;
    case VIR_DOMAIN_INPUT_TYPE_KBD:
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_KBD))
            goto error;
        virBufferAsprintf(&buf, "usb-kbd,id=%s", dev->info.alias);
        break;
    }
5837

5838
    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
5839 5840
        goto error;

5841
    if (virBufferCheckError(&buf) < 0)
5842 5843 5844 5845
        goto error;

    return virBufferContentAndReset(&buf);

5846
 error:
5847 5848 5849 5850 5851 5852
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
5853 5854
qemuBuildSoundDevStr(virDomainDefPtr def,
                     virDomainSoundDefPtr sound,
5855
                     virQEMUCapsPtr qemuCaps)
5856 5857
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
5858
    const char *model = NULL;
5859

5860
    /* Hack for devices with different names in QEMU and libvirt */
5861
    switch ((virDomainSoundModel) sound->model) {
5862
    case VIR_DOMAIN_SOUND_MODEL_ES1370:
5863
        model = "ES1370";
5864 5865
        break;
    case VIR_DOMAIN_SOUND_MODEL_AC97:
5866
        model = "AC97";
5867 5868
        break;
    case VIR_DOMAIN_SOUND_MODEL_ICH6:
5869
        model = "intel-hda";
5870
        break;
5871 5872 5873 5874 5875 5876 5877 5878 5879
    case VIR_DOMAIN_SOUND_MODEL_USB:
        model = "usb-audio";
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_USB_AUDIO)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("usb-audio controller is not supported "
                             "by this QEMU binary"));
            goto error;
        }
        break;
5880 5881 5882 5883 5884 5885 5886 5887 5888
    case VIR_DOMAIN_SOUND_MODEL_ICH9:
        model = "ich9-intel-hda";
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_ICH9_INTEL_HDA)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("The ich9-intel-hda audio controller "
                             "is not supported in this QEMU binary"));
            goto error;
        }
        break;
5889 5890 5891 5892 5893 5894 5895 5896 5897
    case VIR_DOMAIN_SOUND_MODEL_SB16:
        model = "sb16";
        break;
    case VIR_DOMAIN_SOUND_MODEL_PCSPK: /* pc-speaker is handled separately */
    case VIR_DOMAIN_SOUND_MODEL_LAST:
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("sound card model '%s' is not supported by qemu"),
                       virDomainSoundModelTypeToString(sound->model));
        goto error;
5898
    }
5899

5900
    virBufferAsprintf(&buf, "%s,id=%s", model, sound->info.alias);
5901
    if (qemuBuildDeviceAddressStr(&buf, def, &sound->info, qemuCaps) < 0)
5902 5903
        goto error;

5904
    if (virBufferCheckError(&buf) < 0)
5905 5906 5907 5908
        goto error;

    return virBufferContentAndReset(&buf);

5909
 error:
5910 5911 5912 5913
    virBufferFreeAndReset(&buf);
    return NULL;
}

5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928

static int
qemuSoundCodecTypeToCaps(int type)
{
    switch (type) {
    case VIR_DOMAIN_SOUND_CODEC_TYPE_DUPLEX:
        return QEMU_CAPS_HDA_DUPLEX;
    case VIR_DOMAIN_SOUND_CODEC_TYPE_MICRO:
        return QEMU_CAPS_HDA_MICRO;
    default:
        return -1;
    }
}


5929 5930
static char *
qemuBuildSoundCodecStr(virDomainSoundDefPtr sound,
5931
                       virDomainSoundCodecDefPtr codec,
5932
                       virQEMUCapsPtr qemuCaps)
5933 5934
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
5935
    const char *stype;
5936
    int type, flags;
5937

5938 5939
    type = codec->type;
    stype = qemuSoundCodecTypeToString(type);
5940
    flags = qemuSoundCodecTypeToCaps(type);
5941

5942
    if (flags == -1 || !virQEMUCapsGet(qemuCaps, flags)) {
5943 5944
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("%s not supported in this QEMU binary"), stype);
5945 5946 5947
        goto error;
    }

5948 5949 5950
    virBufferAsprintf(&buf, "%s,id=%s-codec%d,bus=%s.0,cad=%d",
                      stype, sound->info.alias, codec->cad, sound->info.alias, codec->cad);

5951 5952
    return virBufferContentAndReset(&buf);

5953
 error:
5954 5955 5956
    virBufferFreeAndReset(&buf);
    return NULL;
}
5957 5958

static char *
5959 5960
qemuBuildDeviceVideoStr(virDomainDefPtr def,
                        virDomainVideoDefPtr video,
5961
                        virQEMUCapsPtr qemuCaps,
5962
                        bool primary)
5963 5964
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
5965
    const char *model;
5966

5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981
    if (primary) {
        model = qemuDeviceVideoTypeToString(video->type);
        if (!model || STREQ(model, "")) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("video type %s is not supported with QEMU"),
                           virDomainVideoTypeToString(video->type));
            goto error;
        }
    } else {
        if (video->type != VIR_DOMAIN_VIDEO_TYPE_QXL) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("non-primary video device must be type of 'qxl'"));
            goto error;
        }

5982
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL)) {
5983 5984 5985 5986 5987 5988
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("only one video card is currently supported"));
            goto error;
        }

        model = "qxl";
5989 5990
    }

5991
    virBufferAsprintf(&buf, "%s,id=%s", model, video->info.alias);
5992

5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004
    if (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO) {
        if (video->accel && video->accel->accel3d) {
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU_VIRGL)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("virtio-gpu 3d acceleration is not supported"));
                goto error;
            }

            virBufferAsprintf(&buf, ",virgl=%s",
                              virTristateSwitchTypeToString(video->accel->accel3d));
        }
    } else if (video->type == VIR_DOMAIN_VIDEO_TYPE_QXL) {
6005
        if (video->vram > (UINT_MAX / 1024)) {
6006
            virReportError(VIR_ERR_OVERFLOW,
6007 6008
                           _("value for 'vram' must be less than '%u'"),
                           UINT_MAX / 1024);
6009 6010
            goto error;
        }
6011 6012 6013 6014 6015 6016 6017
        if (video->ram > (UINT_MAX / 1024)) {
            virReportError(VIR_ERR_OVERFLOW,
                           _("value for 'ram' must be less than '%u'"),
                           UINT_MAX / 1024);
            goto error;
        }

6018 6019 6020 6021
        if (video->ram) {
            /* QEMU accepts bytes for ram_size. */
            virBufferAsprintf(&buf, ",ram_size=%u", video->ram * 1024);
        }
6022

6023 6024 6025 6026
        if (video->vram) {
            /* QEMU accepts bytes for vram_size. */
            virBufferAsprintf(&buf, ",vram_size=%u", video->vram * 1024);
        }
6027 6028 6029 6030 6031 6032

        if ((primary && virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_VGA_VGAMEM)) ||
            (!primary && virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_VGAMEM))) {
            /* QEMU accepts mebibytes for vgamem_mb. */
            virBufferAsprintf(&buf, ",vgamem_mb=%u", video->vgamem / 1024);
        }
6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046
    } else if (video->vram &&
        ((video->type == VIR_DOMAIN_VIDEO_TYPE_VGA &&
          virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA_VGAMEM)) ||
         (video->type == VIR_DOMAIN_VIDEO_TYPE_VMVGA &&
          virQEMUCapsGet(qemuCaps, QEMU_CAPS_VMWARE_SVGA_VGAMEM)))) {

        if (video->vram < 1024) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("value for 'vram' must be at least 1 MiB "
                                   "(1024 KiB)"));
            goto error;
        }

        virBufferAsprintf(&buf, ",vgamem_mb=%u", video->vram / 1024);
6047 6048
    }

6049
    if (qemuBuildDeviceAddressStr(&buf, def, &video->info, qemuCaps) < 0)
6050 6051
        goto error;

6052
    if (virBufferCheckError(&buf) < 0)
6053 6054 6055 6056
        goto error;

    return virBufferContentAndReset(&buf);

6057
 error:
6058 6059 6060 6061 6062 6063 6064 6065
    virBufferFreeAndReset(&buf);
    return NULL;
}


int
qemuOpenPCIConfig(virDomainHostdevDefPtr dev)
{
6066
    virDomainHostdevSubsysPCIPtr pcisrc = &dev->source.subsys.u.pci;
6067 6068 6069 6070
    char *path = NULL;
    int configfd = -1;

    if (virAsprintf(&path, "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/config",
6071 6072
                    pcisrc->addr.domain, pcisrc->addr.bus,
                    pcisrc->addr.slot, pcisrc->addr.function) < 0)
6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085
        return -1;

    configfd = open(path, O_RDWR, 0);

    if (configfd < 0)
        virReportSystemError(errno, _("Failed opening %s"), path);

    VIR_FREE(path);

    return configfd;
}

char *
6086 6087
qemuBuildPCIHostdevDevStr(virDomainDefPtr def,
                          virDomainHostdevDefPtr dev,
6088
                          int bootIndex, /* used iff dev->info->bootIndex == 0 */
6089
                          const char *configfd,
6090
                          virQEMUCapsPtr qemuCaps)
6091 6092
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
6093 6094
    virDomainHostdevSubsysPCIPtr pcisrc = &dev->source.subsys.u.pci;
    int backend = pcisrc->backend;
6095

6096
    /* caller has to assign proper passthrough backend type */
6097
    switch ((virDomainHostdevSubsysPCIBackendType) backend) {
6098
    case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
6099 6100 6101
        virBufferAddLit(&buf, "pci-assign");
        if (configfd && *configfd)
            virBufferAsprintf(&buf, ",configfd=%s", configfd);
6102 6103 6104 6105 6106 6107
        break;

    case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO:
        virBufferAddLit(&buf, "vfio-pci");
        break;

6108
    default:
6109 6110
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("invalid PCI passthrough type '%s'"),
6111
                       virDomainHostdevSubsysPCIBackendTypeToString(backend));
6112
        goto error;
6113
    }
6114

6115
    virBufferAddLit(&buf, ",host=");
6116
    if (pcisrc->addr.domain) {
6117 6118 6119 6120
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_HOST_PCI_MULTIDOMAIN)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("non-zero domain='%.4x' in host device PCI address "
                             "not supported in this QEMU binary"),
6121
                           pcisrc->addr.domain);
6122 6123
            goto error;
        }
6124
        virBufferAsprintf(&buf, "%.4x:", pcisrc->addr.domain);
6125 6126
    }
    virBufferAsprintf(&buf, "%.2x:%.2x.%.1x",
6127 6128
                      pcisrc->addr.bus, pcisrc->addr.slot,
                      pcisrc->addr.function);
6129 6130
    virBufferAsprintf(&buf, ",id=%s", dev->info->alias);
    if (dev->info->bootIndex)
6131 6132 6133
        bootIndex = dev->info->bootIndex;
    if (bootIndex)
        virBufferAsprintf(&buf, ",bootindex=%d", bootIndex);
6134
    if (qemuBuildDeviceAddressStr(&buf, def, dev->info, qemuCaps) < 0)
6135
        goto error;
6136
    if (qemuBuildRomStr(&buf, dev->info, qemuCaps) < 0)
6137
        goto error;
6138

6139
    if (virBufferCheckError(&buf) < 0)
6140 6141 6142 6143
        goto error;

    return virBufferContentAndReset(&buf);

6144
 error:
6145 6146 6147 6148 6149 6150
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
6151 6152
qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev,
                             virQEMUCapsPtr qemuCaps)
6153 6154
{
    char *ret = NULL;
6155
    virDomainHostdevSubsysPCIPtr pcisrc = &dev->source.subsys.u.pci;
6156

6157
    if (pcisrc->addr.domain) {
6158 6159 6160 6161
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_HOST_PCI_MULTIDOMAIN)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("non-zero domain='%.4x' in host device PCI address "
                             "not supported in this QEMU binary"),
6162
                           pcisrc->addr.domain);
6163 6164 6165
            goto cleanup;
        }
        ignore_value(virAsprintf(&ret, "host=%.4x:%.2x:%.2x.%.1x",
6166 6167
                                 pcisrc->addr.domain, pcisrc->addr.bus,
                                 pcisrc->addr.slot, pcisrc->addr.function));
6168 6169
    } else {
        ignore_value(virAsprintf(&ret, "host=%.2x:%.2x.%.1x",
6170 6171
                                 pcisrc->addr.bus, pcisrc->addr.slot,
                                 pcisrc->addr.function));
6172 6173
    }
 cleanup:
6174 6175 6176 6177
    return ret;
}


6178
char *
6179 6180
qemuBuildRedirdevDevStr(virDomainDefPtr def,
                        virDomainRedirdevDefPtr dev,
6181
                        virQEMUCapsPtr qemuCaps)
6182
{
6183
    size_t i;
6184
    virBuffer buf = VIR_BUFFER_INITIALIZER;
6185
    virDomainRedirFilterDefPtr redirfilter = def->redirfilter;
6186 6187

    if (dev->bus != VIR_DOMAIN_REDIRDEV_BUS_USB) {
6188 6189 6190
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Redirection bus %s is not supported by QEMU"),
                       virDomainRedirdevBusTypeToString(dev->bus));
6191 6192 6193
        goto error;
    }

6194
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_REDIR)) {
6195 6196 6197
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("USB redirection is not supported "
                         "by this version of QEMU"));
6198 6199 6200 6201
        goto error;
    }

    virBufferAsprintf(&buf, "usb-redir,chardev=char%s,id=%s",
6202
                      dev->info.alias, dev->info.alias);
6203

6204
    if (redirfilter && redirfilter->nusbdevs) {
6205
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_REDIR_FILTER)) {
6206 6207 6208 6209 6210 6211
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("USB redirection filter is not "
                             "supported by this version of QEMU"));
            goto error;
        }

6212
        virBufferAddLit(&buf, ",filter=");
6213 6214

        for (i = 0; i < redirfilter->nusbdevs; i++) {
6215
            virDomainRedirFilterUSBDevDefPtr usbdev = redirfilter->usbdevs[i];
6216 6217 6218
            if (usbdev->usbClass >= 0)
                virBufferAsprintf(&buf, "0x%02X:", usbdev->usbClass);
            else
6219
                virBufferAddLit(&buf, "-1:");
6220 6221 6222 6223

            if (usbdev->vendor >= 0)
                virBufferAsprintf(&buf, "0x%04X:", usbdev->vendor);
            else
6224
                virBufferAddLit(&buf, "-1:");
6225 6226 6227 6228

            if (usbdev->product >= 0)
                virBufferAsprintf(&buf, "0x%04X:", usbdev->product);
            else
6229
                virBufferAddLit(&buf, "-1:");
6230 6231 6232 6233

            if (usbdev->version >= 0)
                virBufferAsprintf(&buf, "0x%04X:", usbdev->version);
            else
6234
                virBufferAddLit(&buf, "-1:");
6235 6236 6237

            virBufferAsprintf(&buf, "%u", usbdev->allow);
            if (i < redirfilter->nusbdevs -1)
6238
                virBufferAddLit(&buf, "|");
6239 6240 6241
        }
    }

6242
    if (dev->info.bootIndex) {
6243
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_REDIR_BOOTINDEX)) {
6244 6245 6246 6247 6248 6249 6250 6251
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("USB redirection booting is not "
                             "supported by this version of QEMU"));
            goto error;
        }
        virBufferAsprintf(&buf, ",bootindex=%d", dev->info.bootIndex);
    }

6252
    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
6253 6254
        goto error;

6255
    if (virBufferCheckError(&buf) < 0)
6256 6257 6258 6259
        goto error;

    return virBufferContentAndReset(&buf);

6260
 error:
6261 6262 6263 6264
    virBufferFreeAndReset(&buf);
    return NULL;
}

6265
char *
6266 6267
qemuBuildUSBHostdevDevStr(virDomainDefPtr def,
                          virDomainHostdevDefPtr dev,
6268
                          virQEMUCapsPtr qemuCaps)
6269
{
6270
    virBuffer buf = VIR_BUFFER_INITIALIZER;
6271
    virDomainHostdevSubsysUSBPtr usbsrc = &dev->source.subsys.u.usb;
6272

6273
    if (!dev->missing && !usbsrc->bus && !usbsrc->device) {
6274 6275
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("USB host device is missing bus/device information"));
6276 6277 6278
        return NULL;
    }

6279 6280 6281
    virBufferAddLit(&buf, "usb-host");
    if (!dev->missing) {
        virBufferAsprintf(&buf, ",hostbus=%d,hostaddr=%d",
6282
                          usbsrc->bus, usbsrc->device);
6283 6284
    }
    virBufferAsprintf(&buf, ",id=%s", dev->info->alias);
6285 6286
    if (dev->info->bootIndex)
        virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);
6287

6288
    if (qemuBuildDeviceAddressStr(&buf, def, dev->info, qemuCaps) < 0)
6289 6290
        goto error;

6291
    if (virBufferCheckError(&buf) < 0)
6292
        goto error;
6293

6294 6295
    return virBufferContentAndReset(&buf);

6296
 error:
6297 6298
    virBufferFreeAndReset(&buf);
    return NULL;
6299 6300 6301
}


M
Marc-André Lureau 已提交
6302
char *
6303 6304
qemuBuildHubDevStr(virDomainDefPtr def,
                   virDomainHubDefPtr dev,
6305
                   virQEMUCapsPtr qemuCaps)
M
Marc-André Lureau 已提交
6306 6307 6308 6309
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if (dev->type != VIR_DOMAIN_HUB_TYPE_USB) {
6310 6311 6312
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("hub type %s not supported"),
                       virDomainHubTypeToString(dev->type));
M
Marc-André Lureau 已提交
6313 6314 6315
        goto error;
    }

6316
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_HUB)) {
6317
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6318
                       _("usb-hub not supported by QEMU binary"));
M
Marc-André Lureau 已提交
6319 6320 6321 6322 6323
        goto error;
    }

    virBufferAddLit(&buf, "usb-hub");
    virBufferAsprintf(&buf, ",id=%s", dev->info.alias);
6324
    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
M
Marc-André Lureau 已提交
6325 6326
        goto error;

6327
    if (virBufferCheckError(&buf) < 0)
M
Marc-André Lureau 已提交
6328 6329 6330 6331
        goto error;

    return virBufferContentAndReset(&buf);

6332
 error:
M
Marc-André Lureau 已提交
6333 6334 6335 6336 6337
    virBufferFreeAndReset(&buf);
    return NULL;
}


6338
char *
6339
qemuBuildUSBHostdevUSBDevStr(virDomainHostdevDefPtr dev)
6340 6341
{
    char *ret = NULL;
6342
    virDomainHostdevSubsysUSBPtr usbsrc = &dev->source.subsys.u.usb;
6343

6344 6345 6346 6347 6348 6349
    if (dev->missing) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("This QEMU doesn't not support missing USB devices"));
        return NULL;
    }

6350
    if (!usbsrc->bus && !usbsrc->device) {
6351 6352
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("USB host device is missing bus/device information"));
6353 6354 6355
        return NULL;
    }

6356
    ignore_value(virAsprintf(&ret, "host:%d.%d", usbsrc->bus, usbsrc->device));
6357 6358 6359
    return ret;
}

6360 6361 6362 6363
static char *
qemuBuildSCSIHostHostdevDrvStr(virDomainHostdevDefPtr dev,
                               virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED,
                               qemuBuildCommandLineCallbacksPtr callbacks)
6364
{
6365
    virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
6366
    virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
6367 6368
    char *sg = NULL;

6369
    sg = (callbacks->qemuGetSCSIDeviceSgName)(NULL,
6370 6371 6372 6373
                                              scsihostsrc->adapter,
                                              scsihostsrc->bus,
                                              scsihostsrc->target,
                                              scsihostsrc->unit);
6374 6375 6376 6377 6378 6379 6380 6381 6382 6383
    return sg;
}

static char *
qemuBuildSCSIiSCSIHostdevDrvStr(virConnectPtr conn,
                                virDomainHostdevDefPtr dev)
{
    char *source = NULL;
    char *secret = NULL;
    char *username = NULL;
6384 6385 6386 6387
    virStorageSource src;

    memset(&src, 0, sizeof(src));

6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402
    virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
    virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;

    if (conn && iscsisrc->auth) {
        const char *protocol =
            virStorageNetProtocolTypeToString(VIR_STORAGE_NET_PROTOCOL_ISCSI);
        bool encode = false;
        int secretType = VIR_SECRET_USAGE_TYPE_ISCSI;

        username = iscsisrc->auth->username;
        if (!(secret = qemuGetSecretString(conn, protocol, encode,
                                           iscsisrc->auth, secretType)))
            goto cleanup;
    }

6403 6404 6405 6406 6407
    src.protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
    src.path = iscsisrc->path;
    src.hosts = iscsisrc->hosts;
    src.nhosts = iscsisrc->nhosts;

6408
    /* Rather than pull what we think we want - use the network disk code */
6409
    source = qemuBuildNetworkDriveURI(&src, username, secret);
6410

6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435
 cleanup:
    VIR_FREE(secret);
    return source;
}

char *
qemuBuildSCSIHostdevDrvStr(virConnectPtr conn,
                           virDomainHostdevDefPtr dev,
                           virQEMUCapsPtr qemuCaps,
                           qemuBuildCommandLineCallbacksPtr callbacks)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    char *source = NULL;
    virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;

    if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
        if (!(source = qemuBuildSCSIiSCSIHostdevDrvStr(conn, dev)))
            goto error;
        virBufferAsprintf(&buf, "file=%s,if=none,format=raw", source);
    } else {
        if (!(source = qemuBuildSCSIHostHostdevDrvStr(dev, qemuCaps,
                                                      callbacks)))
            goto error;
        virBufferAsprintf(&buf, "file=/dev/%s,if=none", source);
    }
6436 6437 6438 6439
    virBufferAsprintf(&buf, ",id=%s-%s",
                      virDomainDeviceAddressTypeToString(dev->info->type),
                      dev->info->alias);

O
Osier Yang 已提交
6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450
    if (dev->readonly) {
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_READONLY)) {
            virBufferAddLit(&buf, ",readonly=on");
        } else {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("this qemu doesn't support 'readonly' "
                             "for -drive"));
            goto error;
        }
    }

6451
    if (virBufferCheckError(&buf) < 0)
6452 6453
        goto error;

6454
    VIR_FREE(source);
6455
    return virBufferContentAndReset(&buf);
6456
 error:
6457
    VIR_FREE(source);
6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468
    virBufferFreeAndReset(&buf);
    return NULL;
}

char *
qemuBuildSCSIHostdevDevStr(virDomainDefPtr def,
                           virDomainHostdevDefPtr dev,
                           virQEMUCapsPtr qemuCaps)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    int model = -1;
6469
    const char *contAlias;
6470 6471 6472 6473

    model = virDomainDeviceFindControllerModel(def, dev->info,
                                               VIR_DOMAIN_CONTROLLER_TYPE_SCSI);

6474
    if (qemuSetSCSIControllerModel(def, qemuCaps, &model) < 0)
6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494
        goto error;

    if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) {
        if (dev->info->addr.drive.target != 0) {
           virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("target must be 0 for scsi host device "
                             "if its controller model is 'lsilogic'"));
            goto error;
        }

        if (dev->info->addr.drive.unit > 7) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("unit must be not more than 7 for scsi host "
                             "device if its controller model is 'lsilogic'"));
            goto error;
        }
    }

    virBufferAddLit(&buf, "scsi-generic");

6495 6496 6497 6498
    if (!(contAlias = virDomainControllerAliasFind(def, VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
                                                   dev->info->addr.drive.controller)))
        goto error;

6499
    if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) {
6500 6501
        virBufferAsprintf(&buf, ",bus=%s.%d,scsi-id=%d",
                          contAlias,
6502 6503 6504
                          dev->info->addr.drive.bus,
                          dev->info->addr.drive.unit);
    } else {
6505 6506
        virBufferAsprintf(&buf, ",bus=%s.0,channel=%d,scsi-id=%d,lun=%d",
                          contAlias,
6507 6508 6509 6510
                          dev->info->addr.drive.bus,
                          dev->info->addr.drive.target,
                          dev->info->addr.drive.unit);
    }
6511

6512 6513 6514 6515
    virBufferAsprintf(&buf, ",drive=%s-%s,id=%s",
                      virDomainDeviceAddressTypeToString(dev->info->type),
                      dev->info->alias, dev->info->alias);

6516 6517 6518
    if (dev->info->bootIndex)
        virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);

6519
    if (virBufferCheckError(&buf) < 0)
6520 6521 6522
        goto error;

    return virBufferContentAndReset(&buf);
6523
 error:
6524 6525 6526
    virBufferFreeAndReset(&buf);
    return NULL;
}
6527 6528 6529

/* This function outputs a -chardev command line option which describes only the
 * host side of the character device */
6530
static char *
6531
qemuBuildChrChardevStr(virDomainChrSourceDefPtr dev, const char *alias,
6532
                       virQEMUCapsPtr qemuCaps)
6533 6534 6535 6536
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    bool telnet;

6537
    switch (dev->type) {
6538
    case VIR_DOMAIN_CHR_TYPE_NULL:
6539
        virBufferAsprintf(&buf, "null,id=char%s", alias);
6540 6541 6542
        break;

    case VIR_DOMAIN_CHR_TYPE_VC:
6543
        virBufferAsprintf(&buf, "vc,id=char%s", alias);
6544 6545 6546
        break;

    case VIR_DOMAIN_CHR_TYPE_PTY:
6547
        virBufferAsprintf(&buf, "pty,id=char%s", alias);
6548 6549 6550
        break;

    case VIR_DOMAIN_CHR_TYPE_DEV:
6551 6552 6553
        virBufferAsprintf(&buf, "%s,id=char%s,path=%s",
                          STRPREFIX(alias, "parallel") ? "parport" : "tty",
                          alias, dev->data.file.path);
6554 6555 6556
        break;

    case VIR_DOMAIN_CHR_TYPE_FILE:
6557
        virBufferAsprintf(&buf, "file,id=char%s,path=%s", alias,
6558
                          dev->data.file.path);
6559
        if (dev->data.file.append != VIR_TRISTATE_SWITCH_ABSENT) {
6560 6561 6562 6563 6564 6565 6566 6567 6568
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_FILE_APPEND)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("append not supported in this QEMU binary"));
                goto error;
            }

            virBufferAsprintf(&buf, ",append=%s",
                              virTristateSwitchTypeToString(dev->data.file.append));
        }
6569 6570 6571
        break;

    case VIR_DOMAIN_CHR_TYPE_PIPE:
6572
        virBufferAsprintf(&buf, "pipe,id=char%s,path=%s", alias,
6573
                          dev->data.file.path);
6574 6575 6576
        break;

    case VIR_DOMAIN_CHR_TYPE_STDIO:
6577
        virBufferAsprintf(&buf, "stdio,id=char%s", alias);
6578 6579
        break;

6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591
    case VIR_DOMAIN_CHR_TYPE_UDP: {
        const char *connectHost = dev->data.udp.connectHost;
        const char *bindHost = dev->data.udp.bindHost;
        const char *bindService = dev->data.udp.bindService;

        if (connectHost == NULL)
            connectHost = "";
        if (bindHost == NULL)
            bindHost = "";
        if (bindService == NULL)
            bindService = "0";

6592
        virBufferAsprintf(&buf,
6593 6594
                          "udp,id=char%s,host=%s,port=%s,localaddr=%s,"
                          "localport=%s",
6595
                          alias,
6596
                          connectHost,
6597
                          dev->data.udp.connectService,
6598
                          bindHost, bindService);
6599
        break;
6600
    }
6601 6602
    case VIR_DOMAIN_CHR_TYPE_TCP:
        telnet = dev->data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET;
6603
        virBufferAsprintf(&buf,
6604
                          "socket,id=char%s,host=%s,port=%s%s%s",
6605
                          alias,
6606 6607 6608 6609 6610 6611 6612
                          dev->data.tcp.host,
                          dev->data.tcp.service,
                          telnet ? ",telnet" : "",
                          dev->data.tcp.listen ? ",server,nowait" : "");
        break;

    case VIR_DOMAIN_CHR_TYPE_UNIX:
6613
        virBufferAsprintf(&buf,
6614
                          "socket,id=char%s,path=%s%s",
6615
                          alias,
6616 6617 6618
                          dev->data.nix.path,
                          dev->data.nix.listen ? ",server,nowait" : "");
        break;
6619 6620

    case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
6621
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEVMC)) {
6622
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6623
                           _("spicevmc not supported in this QEMU binary"));
6624 6625
            goto error;
        }
6626
        virBufferAsprintf(&buf, "spicevmc,id=char%s,name=%s", alias,
E
Eric Blake 已提交
6627
                          virDomainChrSpicevmcTypeToString(dev->data.spicevmc));
6628 6629
        break;

6630 6631 6632 6633 6634 6635 6636 6637 6638 6639
    case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEPORT)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("spiceport not supported in this QEMU binary"));
            goto error;
        }
        virBufferAsprintf(&buf, "spiceport,id=char%s,name=%s", alias,
                          dev->data.spiceport.channel);
        break;

6640
    default:
6641 6642 6643
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unsupported chardev '%s'"),
                       virDomainChrTypeToString(dev->type));
6644
        goto error;
6645 6646
    }

6647
    if (virBufferCheckError(&buf) < 0)
6648 6649 6650 6651
        goto error;

    return virBufferContentAndReset(&buf);

6652
 error:
6653 6654 6655 6656 6657
    virBufferFreeAndReset(&buf);
    return NULL;
}


6658 6659
static char *
qemuBuildChrArgStr(virDomainChrSourceDefPtr dev, const char *prefix)
6660 6661 6662 6663 6664 6665
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if (prefix)
        virBufferAdd(&buf, prefix, strlen(prefix));

6666
    switch ((virDomainChrType)dev->type) {
6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683
    case VIR_DOMAIN_CHR_TYPE_NULL:
        virBufferAddLit(&buf, "null");
        break;

    case VIR_DOMAIN_CHR_TYPE_VC:
        virBufferAddLit(&buf, "vc");
        break;

    case VIR_DOMAIN_CHR_TYPE_PTY:
        virBufferAddLit(&buf, "pty");
        break;

    case VIR_DOMAIN_CHR_TYPE_DEV:
        virBufferStrcat(&buf, dev->data.file.path, NULL);
        break;

    case VIR_DOMAIN_CHR_TYPE_FILE:
6684
        virBufferAsprintf(&buf, "file:%s", dev->data.file.path);
6685 6686 6687
        break;

    case VIR_DOMAIN_CHR_TYPE_PIPE:
6688
        virBufferAsprintf(&buf, "pipe:%s", dev->data.file.path);
6689 6690 6691 6692 6693 6694
        break;

    case VIR_DOMAIN_CHR_TYPE_STDIO:
        virBufferAddLit(&buf, "stdio");
        break;

6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706
    case VIR_DOMAIN_CHR_TYPE_UDP: {
        const char *connectHost = dev->data.udp.connectHost;
        const char *bindHost = dev->data.udp.bindHost;
        const char *bindService  = dev->data.udp.bindService;

        if (connectHost == NULL)
            connectHost = "";
        if (bindHost == NULL)
            bindHost = "";
        if (bindService == NULL)
            bindService = "0";

6707
        virBufferAsprintf(&buf, "udp:%s:%s@%s:%s",
6708
                          connectHost,
6709
                          dev->data.udp.connectService,
6710 6711
                          bindHost,
                          bindService);
6712
        break;
6713
    }
6714 6715
    case VIR_DOMAIN_CHR_TYPE_TCP:
        if (dev->data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET) {
6716
            virBufferAsprintf(&buf, "telnet:%s:%s%s",
6717 6718 6719 6720
                              dev->data.tcp.host,
                              dev->data.tcp.service,
                              dev->data.tcp.listen ? ",server,nowait" : "");
        } else {
6721
            virBufferAsprintf(&buf, "tcp:%s:%s%s",
6722 6723 6724 6725 6726 6727 6728
                              dev->data.tcp.host,
                              dev->data.tcp.service,
                              dev->data.tcp.listen ? ",server,nowait" : "");
        }
        break;

    case VIR_DOMAIN_CHR_TYPE_UNIX:
6729
        virBufferAsprintf(&buf, "unix:%s%s",
6730 6731 6732
                          dev->data.nix.path,
                          dev->data.nix.listen ? ",server,nowait" : "");
        break;
6733

6734
    case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
6735
    case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
6736
    case VIR_DOMAIN_CHR_TYPE_NMDM:
6737
    case VIR_DOMAIN_CHR_TYPE_LAST:
6738
        break;
6739 6740
    }

6741
    if (virBufferCheckError(&buf) < 0)
6742 6743 6744 6745
        goto error;

    return virBufferContentAndReset(&buf);

6746
 error:
6747 6748 6749 6750 6751
    virBufferFreeAndReset(&buf);
    return NULL;
}


6752
static char *
6753 6754
qemuBuildVirtioSerialPortDevStr(virDomainDefPtr def,
                                virDomainChrDefPtr dev,
6755
                                virQEMUCapsPtr qemuCaps)
6756 6757
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
6758 6759
    const char *contAlias;

6760 6761
    switch (dev->deviceType) {
    case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE:
6762
        virBufferAddLit(&buf, "virtconsole");
6763 6764 6765 6766
        break;
    case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL:
        /* Legacy syntax  '-device spicevmc' */
        if (dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC &&
6767
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC)) {
6768 6769 6770 6771 6772 6773
            virBufferAddLit(&buf, "spicevmc");
        } else {
            virBufferAddLit(&buf, "virtserialport");
        }
        break;
    default:
6774 6775
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Cannot use virtio serial for parallel/serial devices"));
6776 6777
        return NULL;
    }
6778

6779
    if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
6780
        dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW &&
6781
        dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
6782 6783 6784 6785
        /* Check it's a virtio-serial address */
        if (dev->info.type !=
            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL)
        {
6786 6787
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("virtio serial device has invalid address type"));
6788 6789 6790
            goto error;
        }

6791 6792 6793 6794 6795 6796 6797
        contAlias = virDomainControllerAliasFind(def, VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL,
                                                 dev->info.addr.vioserial.controller);
        if (!contAlias)
            goto error;

        virBufferAsprintf(&buf, ",bus=%s.%d,nr=%d", contAlias,
                          dev->info.addr.vioserial.bus,
6798 6799 6800
                          dev->info.addr.vioserial.port);
    }

6801 6802
    if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
        dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC &&
6803 6804
        dev->target.name &&
        STRNEQ(dev->target.name, "com.redhat.spice.0")) {
6805 6806 6807
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Unsupported spicevmc target name '%s'"),
                       dev->target.name);
6808 6809
        goto error;
    }
6810 6811 6812

    if (!(dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
          dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC &&
6813
          virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC))) {
6814
        virBufferAsprintf(&buf, ",chardev=char%s,id=%s",
6815
                          dev->info.alias, dev->info.alias);
6816 6817 6818
        if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
            (dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC ||
             dev->target.name)) {
6819 6820
            virBufferAsprintf(&buf, ",name=%s", dev->target.name
                              ? dev->target.name : "com.redhat.spice.0");
6821
        }
6822 6823
    } else {
        virBufferAsprintf(&buf, ",id=%s", dev->info.alias);
6824
    }
6825
    if (virBufferCheckError(&buf) < 0)
6826 6827 6828 6829
        goto error;

    return virBufferContentAndReset(&buf);

6830
 error:
6831 6832 6833 6834
    virBufferFreeAndReset(&buf);
    return NULL;
}

6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854
static char *
qemuBuildSclpDevStr(virDomainChrDefPtr dev)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE) {
        switch (dev->targetType) {
        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLP:
            virBufferAddLit(&buf, "sclpconsole");
            break;
        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLPLM:
            virBufferAddLit(&buf, "sclplmconsole");
            break;
        }
    } else {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Cannot use slcp with devices other than console"));
        goto error;
    }
    virBufferAsprintf(&buf, ",chardev=char%s,id=%s",
                      dev->info.alias, dev->info.alias);
6855
    if (virBufferCheckError(&buf) < 0)
6856 6857 6858 6859
        goto error;

    return virBufferContentAndReset(&buf);

6860
 error:
6861 6862 6863 6864
    virBufferFreeAndReset(&buf);
    return NULL;
}

6865 6866

static int
6867 6868 6869
qemuBuildRNGBackendChrdevStr(virDomainRNGDefPtr rng,
                             virQEMUCapsPtr qemuCaps,
                             char **chr)
6870
{
6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888
    *chr = NULL;

    switch ((virDomainRNGBackend) rng->backend) {
    case VIR_DOMAIN_RNG_BACKEND_RANDOM:
    case VIR_DOMAIN_RNG_BACKEND_LAST:
        /* no chardev backend is needed */
        return 0;

    case VIR_DOMAIN_RNG_BACKEND_EGD:
        if (!(*chr = qemuBuildChrChardevStr(rng->source.chardev,
                                            rng->info.alias, qemuCaps)))
            return -1;
    }

    return 0;
}


6889
int
6890 6891 6892 6893 6894 6895
qemuBuildRNGBackendProps(virDomainRNGDefPtr rng,
                         virQEMUCapsPtr qemuCaps,
                         const char **type,
                         virJSONValuePtr *props)
{
    char *charBackendAlias = NULL;
6896 6897
    int ret = -1;

6898
    switch ((virDomainRNGBackend) rng->backend) {
6899 6900 6901 6902
    case VIR_DOMAIN_RNG_BACKEND_RANDOM:
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_RNG_RANDOM)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("this qemu doesn't support the rng-random "
6903
                             "backend"));
6904 6905 6906
            goto cleanup;
        }

6907
        *type = "rng-random";
6908

6909 6910 6911
        if (virJSONValueObjectCreate(props, "s:filename", rng->source.file,
                                     NULL) < 0)
            goto cleanup;
6912 6913 6914
        break;

    case VIR_DOMAIN_RNG_BACKEND_EGD:
6915 6916 6917 6918 6919 6920 6921
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_RNG_EGD)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("this qemu doesn't support the rng-egd "
                             "backend"));
            goto cleanup;
        }

6922 6923 6924
        *type = "rng-egd";

        if (virAsprintf(&charBackendAlias, "char%s", rng->info.alias) < 0)
6925 6926
            goto cleanup;

6927 6928 6929
        if (virJSONValueObjectCreate(props, "s:chardev", charBackendAlias,
                                     NULL) < 0)
            goto cleanup;
6930

6931 6932 6933
        break;

    case VIR_DOMAIN_RNG_BACKEND_LAST:
6934 6935 6936
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("unknown rng-random backend"));
        goto cleanup;
6937 6938 6939 6940
    }

    ret = 0;

6941
 cleanup:
6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966
    VIR_FREE(charBackendAlias);
    return ret;
}


static char *
qemuBuildRNGBackendStr(virDomainRNGDefPtr rng,
                       virQEMUCapsPtr qemuCaps)
{
    const char *type = NULL;
    char *alias = NULL;
    virJSONValuePtr props = NULL;
    char *ret = NULL;

    if (virAsprintf(&alias, "obj%s", rng->info.alias) < 0)
        goto cleanup;

    if (qemuBuildRNGBackendProps(rng, qemuCaps, &type, &props) < 0)
        goto cleanup;

    ret = qemuBuildObjectCommandlineFromJSON(type, alias, props);

 cleanup:
    VIR_FREE(alias);
    virJSONValueFree(props);
6967 6968 6969 6970
    return ret;
}


6971 6972 6973 6974
char *
qemuBuildRNGDevStr(virDomainDefPtr def,
                   virDomainRNGDefPtr dev,
                   virQEMUCapsPtr qemuCaps)
6975 6976 6977 6978 6979 6980 6981 6982
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if (dev->model != VIR_DOMAIN_RNG_MODEL_VIRTIO ||
        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_RNG)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("this qemu doesn't support RNG device type '%s'"),
                       virDomainRNGModelTypeToString(dev->model));
6983
        goto error;
6984 6985
    }

6986 6987 6988 6989
    if (!qemuCheckCCWS390AddressSupport(def, dev->info, qemuCaps,
                                        dev->source.file))
        goto error;

6990
    if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
6991 6992
        virBufferAsprintf(&buf, "virtio-rng-ccw,rng=obj%s,id=%s",
                          dev->info.alias, dev->info.alias);
6993
    else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
6994 6995
        virBufferAsprintf(&buf, "virtio-rng-s390,rng=obj%s,id=%s",
                          dev->info.alias, dev->info.alias);
6996
    else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
6997 6998
        virBufferAsprintf(&buf, "virtio-rng-device,rng=obj%s,id=%s",
                          dev->info.alias, dev->info.alias);
6999
    else
7000 7001
        virBufferAsprintf(&buf, "virtio-rng-pci,rng=obj%s,id=%s",
                          dev->info.alias, dev->info.alias);
7002

7003 7004 7005 7006 7007 7008 7009 7010
    if (dev->rate > 0) {
        virBufferAsprintf(&buf, ",max-bytes=%u", dev->rate);
        if (dev->period)
            virBufferAsprintf(&buf, ",period=%u", dev->period);
        else
            virBufferAddLit(&buf, ",period=1000");
    }

7011
    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
7012 7013 7014
        goto error;
    if (virBufferCheckError(&buf) < 0)
        goto error;
7015

7016
    return virBufferContentAndReset(&buf);
7017

7018
 error:
7019
    virBufferFreeAndReset(&buf);
7020
    return NULL;
7021 7022 7023
}


E
Eric Blake 已提交
7024
static char *qemuBuildTPMBackendStr(const virDomainDef *def,
7025
                                    virCommandPtr cmd,
7026
                                    virQEMUCapsPtr qemuCaps,
7027 7028
                                    const char *emulator,
                                    int *tpmfd, int *cancelfd)
7029
{
E
Eric Blake 已提交
7030
    const virDomainTPMDef *tpm = def->tpm;
7031 7032
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    const char *type = virDomainTPMBackendTypeToString(tpm->type);
7033
    char *cancel_path = NULL, *devset = NULL;
7034
    const char *tpmdev;
7035

7036 7037 7038
    *tpmfd = -1;
    *cancelfd = -1;

7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049
    virBufferAsprintf(&buf, "%s,id=tpm-%s", type, tpm->info.alias);

    switch (tpm->type) {
    case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_TPM_PASSTHROUGH))
            goto no_support;

        tpmdev = tpm->data.passthrough.source.data.file.path;
        if (!(cancel_path = virTPMCreateCancelPath(tpmdev)))
            goto error;

7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ADD_FD)) {
            *tpmfd = open(tpmdev, O_RDWR);
            if (*tpmfd < 0) {
                virReportSystemError(errno, _("Could not open TPM device %s"),
                                     tpmdev);
                goto error;
            }

            virCommandPassFD(cmd, *tpmfd,
                             VIR_COMMAND_PASS_FD_CLOSE_PARENT);
            devset = qemuVirCommandGetDevSet(cmd, *tpmfd);
            if (devset == NULL)
                goto error;

            *cancelfd = open(cancel_path, O_WRONLY);
            if (*cancelfd < 0) {
                virReportSystemError(errno,
                                     _("Could not open TPM device's cancel "
                                       "path %s"), cancel_path);
                goto error;
            }
            VIR_FREE(cancel_path);

            virCommandPassFD(cmd, *cancelfd,
                             VIR_COMMAND_PASS_FD_CLOSE_PARENT);
            cancel_path = qemuVirCommandGetDevSet(cmd, *cancelfd);
            if (cancel_path == NULL)
                goto error;
        }
7079
        virBufferAddLit(&buf, ",path=");
7080
        virBufferEscape(&buf, ',', ",", "%s", devset ? devset : tpmdev);
7081 7082 7083

        virBufferAddLit(&buf, ",cancel-path=");
        virBufferEscape(&buf, ',', ",", "%s", cancel_path);
7084 7085

        VIR_FREE(devset);
7086 7087 7088 7089 7090 7091 7092
        VIR_FREE(cancel_path);

        break;
    case VIR_DOMAIN_TPM_TYPE_LAST:
        goto error;
    }

7093
    if (virBufferCheckError(&buf) < 0)
7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104
        goto error;

    return virBufferContentAndReset(&buf);

 no_support:
    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                   _("The QEMU executable %s does not support TPM "
                     "backend type %s"),
                   emulator, type);

 error:
7105 7106 7107
    VIR_FREE(devset);
    VIR_FREE(cancel_path);

7108 7109 7110 7111 7112
    virBufferFreeAndReset(&buf);
    return NULL;
}


E
Eric Blake 已提交
7113
static char *qemuBuildTPMDevStr(const virDomainDef *def,
7114 7115 7116 7117
                                virQEMUCapsPtr qemuCaps,
                                const char *emulator)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
E
Eric Blake 已提交
7118
    const virDomainTPMDef *tpm = def->tpm;
7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131
    const char *model = virDomainTPMModelTypeToString(tpm->model);

    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_TPM_TIS)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("The QEMU executable %s does not support TPM "
                       "model %s"),
                       emulator, model);
        goto error;
    }

    virBufferAsprintf(&buf, "%s,tpmdev=tpm-%s,id=%s",
                      model, tpm->info.alias, tpm->info.alias);

7132
    if (virBufferCheckError(&buf) < 0)
7133 7134 7135 7136 7137 7138 7139 7140 7141 7142
        goto error;

    return virBufferContentAndReset(&buf);

 error:
    virBufferFreeAndReset(&buf);
    return NULL;
}


7143
static char *qemuBuildSmbiosBiosStr(virSysinfoBIOSDefPtr def)
7144 7145 7146
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

7147
    if (!def)
7148
        return NULL;
7149 7150 7151 7152

    virBufferAddLit(&buf, "type=0");

    /* 0:Vendor */
7153 7154
    if (def->vendor)
        virBufferAsprintf(&buf, ",vendor=%s", def->vendor);
7155
    /* 0:BIOS Version */
7156 7157
    if (def->version)
        virBufferAsprintf(&buf, ",version=%s", def->version);
7158
    /* 0:BIOS Release Date */
7159 7160
    if (def->date)
        virBufferAsprintf(&buf, ",date=%s", def->date);
7161
    /* 0:System BIOS Major Release and 0:System BIOS Minor Release */
7162 7163
    if (def->release)
        virBufferAsprintf(&buf, ",release=%s", def->release);
7164

7165
    if (virBufferCheckError(&buf) < 0)
7166 7167 7168 7169
        goto error;

    return virBufferContentAndReset(&buf);

7170
 error:
7171
    virBufferFreeAndReset(&buf);
7172
    return NULL;
7173 7174
}

7175 7176
static char *qemuBuildSmbiosSystemStr(virSysinfoSystemDefPtr def,
                                      bool skip_uuid)
7177 7178 7179
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

7180 7181 7182 7183
    if (!def ||
        (!def->manufacturer && !def->product && !def->version &&
         !def->serial && (!def->uuid || skip_uuid) &&
         def->sku && !def->family))
7184 7185 7186 7187 7188
        return NULL;

    virBufferAddLit(&buf, "type=1");

    /* 1:Manufacturer */
7189
    if (def->manufacturer)
7190
        virBufferAsprintf(&buf, ",manufacturer=%s",
7191
                          def->manufacturer);
7192
     /* 1:Product Name */
7193 7194
    if (def->product)
        virBufferAsprintf(&buf, ",product=%s", def->product);
7195
    /* 1:Version */
7196 7197
    if (def->version)
        virBufferAsprintf(&buf, ",version=%s", def->version);
7198
    /* 1:Serial Number */
7199 7200
    if (def->serial)
        virBufferAsprintf(&buf, ",serial=%s", def->serial);
7201
    /* 1:UUID */
7202 7203
    if (def->uuid && !skip_uuid)
        virBufferAsprintf(&buf, ",uuid=%s", def->uuid);
7204
    /* 1:SKU Number */
7205 7206
    if (def->sku)
        virBufferAsprintf(&buf, ",sku=%s", def->sku);
7207
    /* 1:Family */
7208 7209
    if (def->family)
        virBufferAsprintf(&buf, ",family=%s", def->family);
7210

7211
    if (virBufferCheckError(&buf) < 0)
7212 7213 7214 7215
        goto error;

    return virBufferContentAndReset(&buf);

7216
 error:
7217
    virBufferFreeAndReset(&buf);
7218
    return NULL;
7219 7220
}

7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259
static char *qemuBuildSmbiosBaseBoardStr(virSysinfoBaseBoardDefPtr def)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if (!def)
        return NULL;

    virBufferAddLit(&buf, "type=2");

    /* 2:Manufacturer */
    if (def->manufacturer)
        virBufferAsprintf(&buf, ",manufacturer=%s",
                          def->manufacturer);
    /* 2:Product Name */
    if (def->product)
        virBufferAsprintf(&buf, ",product=%s", def->product);
    /* 2:Version */
    if (def->version)
        virBufferAsprintf(&buf, ",version=%s", def->version);
    /* 2:Serial Number */
    if (def->serial)
        virBufferAsprintf(&buf, ",serial=%s", def->serial);
    /* 2:Asset Tag */
    if (def->asset)
        virBufferAsprintf(&buf, ",asset=%s", def->asset);
    /* 2:Location */
    if (def->location)
        virBufferAsprintf(&buf, ",location=%s", def->location);

    if (virBufferCheckError(&buf) < 0)
        goto error;

    return virBufferContentAndReset(&buf);

 error:
    virBufferFreeAndReset(&buf);
    return NULL;
}

7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278
static char *
qemuBuildClockArgStr(virDomainClockDefPtr def)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    switch (def->offset) {
    case VIR_DOMAIN_CLOCK_OFFSET_UTC:
        virBufferAddLit(&buf, "base=utc");
        break;

    case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME:
    case VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE:
        virBufferAddLit(&buf, "base=localtime");
        break;

    case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: {
        time_t now = time(NULL);
        struct tm nowbits;

7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297
        if (def->data.variable.basis == VIR_DOMAIN_CLOCK_BASIS_LOCALTIME) {
            long localOffset;

            /* in the case of basis='localtime', rather than trying to
             * keep that basis (and associated offset from UTC) in the
             * status and deal with adding in the difference each time
             * there is an RTC_CHANGE event, it is simpler and less
             * error prone to just convert the adjustment an offset
             * from UTC right now (and change the status to
             * "basis='utc' to reflect this). This eliminates
             * potential errors in both RTC_CHANGE events and in
             * migration (in the case that the status of DST, or the
             * timezone of the destination host, changed relative to
             * startup).
             */
            if (virTimeLocalOffsetFromUTC(&localOffset) < 0)
               goto error;
            def->data.variable.adjustment += localOffset;
            def->data.variable.basis = VIR_DOMAIN_CLOCK_BASIS_UTC;
7298
        }
7299

7300 7301 7302
        now += def->data.variable.adjustment;
        gmtime_r(&now, &nowbits);

7303 7304 7305 7306 7307 7308 7309 7310
        /* when an RTC_CHANGE event is received from qemu, we need to
         * have the adjustment used at domain start time available to
         * compute the new offset from UTC. As this new value is
         * itself stored in def->data.variable.adjustment, we need to
         * save a copy of it now.
        */
        def->data.variable.adjustment0 = def->data.variable.adjustment;

7311
        virBufferAsprintf(&buf, "base=%d-%02d-%02dT%02d:%02d:%02d",
7312 7313 7314 7315 7316 7317 7318 7319 7320
                          nowbits.tm_year + 1900,
                          nowbits.tm_mon + 1,
                          nowbits.tm_mday,
                          nowbits.tm_hour,
                          nowbits.tm_min,
                          nowbits.tm_sec);
    }   break;

    default:
7321 7322 7323
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unsupported clock offset '%s'"),
                       virDomainClockOffsetTypeToString(def->offset));
7324 7325 7326 7327
        goto error;
    }

    /* Look for an 'rtc' timer element, and add in appropriate clock= and driftfix= */
7328
    size_t i;
7329 7330 7331 7332 7333 7334
    for (i = 0; i < def->ntimers; i++) {
        if (def->timers[i]->name == VIR_DOMAIN_TIMER_NAME_RTC) {
            switch (def->timers[i]->track) {
            case -1: /* unspecified - use hypervisor default */
                break;
            case VIR_DOMAIN_TIMER_TRACK_BOOT:
7335 7336 7337
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("unsupported rtc timer track '%s'"),
                               virDomainTimerTrackTypeToString(def->timers[i]->track));
7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358
                goto error;
            case VIR_DOMAIN_TIMER_TRACK_GUEST:
                virBufferAddLit(&buf, ",clock=vm");
                break;
            case VIR_DOMAIN_TIMER_TRACK_WALL:
                virBufferAddLit(&buf, ",clock=host");
                break;
            }

            switch (def->timers[i]->tickpolicy) {
            case -1:
            case VIR_DOMAIN_TIMER_TICKPOLICY_DELAY:
                /* This is the default - missed ticks delivered when
                   next scheduled, at normal rate */
                break;
            case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP:
                /* deliver ticks at a faster rate until caught up */
                virBufferAddLit(&buf, ",driftfix=slew");
                break;
            case VIR_DOMAIN_TIMER_TICKPOLICY_MERGE:
            case VIR_DOMAIN_TIMER_TICKPOLICY_DISCARD:
7359 7360 7361
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("unsupported rtc timer tickpolicy '%s'"),
                               virDomainTimerTickpolicyTypeToString(def->timers[i]->tickpolicy));
7362 7363 7364 7365 7366 7367
                goto error;
            }
            break; /* no need to check other timers - there is only one rtc */
        }
    }

7368
    if (virBufferCheckError(&buf) < 0)
7369 7370 7371 7372
        goto error;

    return virBufferContentAndReset(&buf);

7373
 error:
7374 7375 7376 7377 7378
    virBufferFreeAndReset(&buf);
    return NULL;
}

static int
7379 7380 7381 7382 7383 7384
qemuBuildCpuModelArgStr(virQEMUDriverPtr driver,
                        const virDomainDef *def,
                        virBufferPtr buf,
                        virQEMUCapsPtr qemuCaps,
                        bool *hasHwVirt,
                        bool migrating)
7385
{
7386 7387
    int ret = -1;
    size_t i;
7388
    virCPUDefPtr host = NULL;
7389
    virCPUDefPtr guest = NULL;
7390
    virCPUDefPtr cpu = NULL;
7391
    virCPUDefPtr featCpu = NULL;
7392
    size_t ncpus = 0;
7393
    char **cpus = NULL;
7394
    virCPUDataPtr data = NULL;
7395
    virCPUDataPtr hostData = NULL;
7396
    char *compare_msg = NULL;
7397 7398
    virCPUCompareResult cmp;
    const char *preferred;
7399
    virCapsPtr caps = NULL;
7400 7401 7402
    bool compareAgainstHost = ((def->virtType == VIR_DOMAIN_VIRT_KVM ||
                                def->cpu->mode != VIR_CPU_MODE_CUSTOM) &&
                               def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH);
7403

7404 7405 7406 7407 7408
    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
        goto cleanup;

    host = caps->host.cpu;

7409 7410 7411 7412 7413 7414 7415
    if (!host ||
        !host->model ||
        (ncpus = virQEMUCapsGetCPUDefinitions(qemuCaps, &cpus)) == 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("CPU specification not supported by hypervisor"));
        goto cleanup;
    }
7416

7417 7418 7419
    if (!(cpu = virCPUDefCopy(def->cpu)))
        goto cleanup;

7420
    if (cpu->mode == VIR_CPU_MODE_HOST_MODEL &&
7421 7422 7423
        !migrating &&
        cpuUpdate(cpu, host) < 0)
        goto cleanup;
7424

7425 7426
    /* For non-KVM, CPU features are emulated, so host compat doesn't matter */
    if (compareAgainstHost) {
7427 7428
        bool noTSX = false;

7429 7430 7431
        cmp = cpuGuestData(host, cpu, &data, &compare_msg);
        switch (cmp) {
        case VIR_CPU_COMPARE_INCOMPATIBLE:
7432 7433 7434 7435 7436 7437 7438 7439
            if (cpuEncode(host->arch, host, NULL, &hostData,
                          NULL, NULL, NULL, NULL) == 0 &&
                (!cpuHasFeature(hostData, "hle") ||
                 !cpuHasFeature(hostData, "rtm")) &&
                (STREQ_NULLABLE(cpu->model, "Haswell") ||
                 STREQ_NULLABLE(cpu->model, "Broadwell")))
                noTSX = true;

7440
            if (compare_msg) {
7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451
                if (noTSX) {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("guest and host CPU are not compatible: "
                                     "%s; try using '%s-noTSX' CPU model"),
                                   compare_msg, cpu->model);
                } else {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("guest and host CPU are not compatible: "
                                     "%s"),
                                   compare_msg);
                }
7452
            } else {
7453 7454 7455 7456 7457 7458 7459 7460 7461 7462
                if (noTSX) {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("guest CPU is not compatible with host "
                                     "CPU; try using '%s-noTSX' CPU model"),
                                   cpu->model);
                } else {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("guest CPU is not compatible with host "
                                     "CPU"));
                }
7463 7464 7465 7466
            }
            /* fall through */
        case VIR_CPU_COMPARE_ERROR:
            goto cleanup;
7467

7468 7469 7470
        default:
            break;
        }
7471 7472 7473 7474 7475
    }

    /* Only 'svm' requires --enable-nesting. The nested
     * 'vmx' patches now simply hook off the CPU features
     */
7476 7477
    if ((def->os.arch == VIR_ARCH_X86_64 || def->os.arch == VIR_ARCH_I686) &&
         compareAgainstHost) {
7478 7479
        int hasSVM = cpuHasFeature(data, "svm");
        if (hasSVM < 0)
7480
            goto cleanup;
7481 7482
        *hasHwVirt = hasSVM > 0 ? true : false;
    }
7483

7484 7485 7486
    if ((cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) ||
        ((cpu->mode == VIR_CPU_MODE_HOST_MODEL) &&
          ARCH_IS_PPC64(def->os.arch))) {
7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500
        const char *mode = virCPUModeTypeToString(cpu->mode);
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_HOST)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("CPU mode '%s' is not supported by QEMU"
                             " binary"), mode);
            goto cleanup;
        }
        if (def->virtType != VIR_DOMAIN_VIRT_KVM) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("CPU mode '%s' is only supported with kvm"),
                           mode);
            goto cleanup;
        }
        virBufferAddLit(buf, "host");
7501

7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514
        if (def->os.arch == VIR_ARCH_ARMV7L &&
            host->arch == VIR_ARCH_AARCH64) {
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_AARCH64_OFF)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("QEMU binary does not support CPU "
                                 "host-passthrough for armv7l on "
                                 "aarch64 host"));
                goto cleanup;
            }

            virBufferAddLit(buf, ",aarch64=off");
        }

7515
        if (ARCH_IS_PPC64(def->os.arch) &&
7516 7517
            cpu->mode == VIR_CPU_MODE_HOST_MODEL &&
            def->cpu->model != NULL) {
7518
            virBufferAsprintf(buf, ",compat=%s", def->cpu->model);
7519 7520
        } else {
            featCpu = cpu;
7521 7522
        }

7523 7524 7525 7526
    } else {
        if (VIR_ALLOC(guest) < 0)
            goto cleanup;
        if (VIR_STRDUP(guest->vendor_id, cpu->vendor_id) < 0)
7527 7528
            goto cleanup;

7529 7530 7531 7532 7533 7534
        if (compareAgainstHost) {
            guest->arch = host->arch;
            if (cpu->match == VIR_CPU_MATCH_MINIMUM)
                preferred = host->model;
            else
                preferred = cpu->model;
7535

7536 7537 7538 7539 7540 7541 7542 7543 7544 7545
            guest->type = VIR_CPU_TYPE_GUEST;
            guest->fallback = cpu->fallback;
            if (cpuDecode(guest, data,
                          (const char **)cpus, ncpus, preferred) < 0)
                goto cleanup;
        } else {
            guest->arch = def->os.arch;
            if (VIR_STRDUP(guest->model, cpu->model) < 0)
                goto cleanup;
        }
7546 7547 7548
        virBufferAdd(buf, guest->model, -1);
        if (guest->vendor_id)
            virBufferAsprintf(buf, ",vendor=%s", guest->vendor_id);
7549 7550 7551 7552 7553
        featCpu = guest;
    }

    if (featCpu) {
        for (i = 0; i < featCpu->nfeatures; i++) {
7554
            char sign;
7555
            if (featCpu->features[i].policy == VIR_CPU_FEATURE_DISABLE)
7556 7557 7558
                sign = '-';
            else
                sign = '+';
7559

7560
            virBufferAsprintf(buf, ",%c%s", sign, featCpu->features[i].name);
7561
        }
7562
    }
7563

7564
    ret = 0;
7565
 cleanup:
7566 7567 7568
    virObjectUnref(caps);
    VIR_FREE(compare_msg);
    cpuDataFree(data);
7569
    cpuDataFree(hostData);
7570 7571 7572 7573
    virCPUDefFree(guest);
    virCPUDefFree(cpu);
    return ret;
}
7574

7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589
static int
qemuBuildCpuArgStr(virQEMUDriverPtr driver,
                   const virDomainDef *def,
                   const char *emulator,
                   virQEMUCapsPtr qemuCaps,
                   virArch hostarch,
                   char **opt,
                   bool *hasHwVirt,
                   bool migrating)
{
    const char *default_model;
    bool have_cpu = false;
    int ret = -1;
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    size_t i;
7590

7591
    *hasHwVirt = false;
7592

7593 7594 7595 7596 7597 7598 7599 7600 7601 7602
    if (def->os.arch == VIR_ARCH_I686)
        default_model = "qemu32";
    else
        default_model = "qemu64";

    if (def->cpu &&
        (def->cpu->mode != VIR_CPU_MODE_CUSTOM || def->cpu->model)) {
        if (qemuBuildCpuModelArgStr(driver, def, &buf, qemuCaps,
                                    hasHwVirt, migrating) < 0)
            goto cleanup;
7603
        have_cpu = true;
7604
    } else {
7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616
        /*
         * Need to force a 32-bit guest CPU type if
         *
         *  1. guest OS is i686
         *  2. host OS is x86_64
         *  3. emulator is qemu-kvm or kvm
         *
         * Or
         *
         *  1. guest OS is i686
         *  2. emulator is qemu-system-x86_64
         */
7617
        if (def->os.arch == VIR_ARCH_I686 &&
7618
            ((hostarch == VIR_ARCH_X86_64 &&
7619
              strstr(emulator, "kvm")) ||
7620 7621 7622 7623 7624 7625
             strstr(emulator, "x86_64"))) {
            virBufferAdd(&buf, default_model, -1);
            have_cpu = true;
        }
    }

7626
    /* Handle paravirtual timers  */
7627
    for (i = 0; i < def->clock.ntimers; i++) {
7628 7629 7630 7631 7632 7633
        virDomainTimerDefPtr timer = def->clock.timers[i];

        if (timer->present == -1)
            continue;

        if (timer->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK) {
7634 7635
            virBufferAsprintf(&buf, "%s,%ckvmclock",
                              have_cpu ? "" : default_model,
7636 7637 7638 7639 7640 7641
                              timer->present ? '+' : '-');
            have_cpu = true;
        } else if (timer->name == VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK &&
                   timer->present) {
            virBufferAsprintf(&buf, "%s,hv_time",
                              have_cpu ? "" : default_model);
M
Martin Kletzander 已提交
7642
            have_cpu = true;
7643
        }
7644 7645
    }

7646 7647
    if (def->apic_eoi) {
        char sign;
J
Ján Tomko 已提交
7648
        if (def->apic_eoi == VIR_TRISTATE_SWITCH_ON)
7649 7650 7651 7652 7653 7654 7655
            sign = '+';
        else
            sign = '-';

        virBufferAsprintf(&buf, "%s,%ckvm_pv_eoi",
                          have_cpu ? "" : default_model,
                          sign);
M
Martin Kletzander 已提交
7656
        have_cpu = true;
7657 7658
    }

7659 7660
    if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK]) {
        char sign;
J
Ján Tomko 已提交
7661
        if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK] == VIR_TRISTATE_SWITCH_ON)
7662 7663 7664 7665 7666 7667 7668 7669 7670 7671
            sign = '+';
        else
            sign = '-';

        virBufferAsprintf(&buf, "%s,%ckvm_pv_unhalt",
                          have_cpu ? "" : default_model,
                          sign);
        have_cpu = true;
    }

J
Ján Tomko 已提交
7672
    if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_TRISTATE_SWITCH_ON) {
7673 7674 7675 7676 7677 7678
        if (!have_cpu) {
            virBufferAdd(&buf, default_model, -1);
            have_cpu = true;
        }

        for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
7679
            switch ((virDomainHyperv) i) {
7680
            case VIR_DOMAIN_HYPERV_RELAXED:
7681
            case VIR_DOMAIN_HYPERV_VAPIC:
J
Ján Tomko 已提交
7682
                if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
7683 7684 7685 7686
                    virBufferAsprintf(&buf, ",hv_%s",
                                      virDomainHypervTypeToString(i));
                break;

7687
            case VIR_DOMAIN_HYPERV_SPINLOCKS:
J
Ján Tomko 已提交
7688
                if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
7689 7690
                    virBufferAsprintf(&buf, ",hv_spinlocks=0x%x",
                                      def->hyperv_spinlocks);
7691 7692
                break;

7693
            /* coverity[dead_error_begin] */
7694 7695 7696 7697 7698 7699
            case VIR_DOMAIN_HYPERV_LAST:
                break;
            }
        }
    }

D
Dmitry Andreev 已提交
7700 7701 7702 7703 7704 7705
    for (i = 0; i < def->npanics; i++) {
        if (def->panics[i]->model == VIR_DOMAIN_PANIC_MODEL_HYPERV) {
            if (!have_cpu) {
                virBufferAdd(&buf, default_model, -1);
                have_cpu = true;
            }
7706

D
Dmitry Andreev 已提交
7707 7708 7709
            virBufferAddLit(&buf, ",hv_crash");
            break;
        }
7710 7711
    }

7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724
    if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
        if (!have_cpu) {
            virBufferAdd(&buf, default_model, -1);
            have_cpu = true;
        }

        for (i = 0; i < VIR_DOMAIN_KVM_LAST; i++) {
            switch ((virDomainKVM) i) {
            case VIR_DOMAIN_KVM_HIDDEN:
                if (def->kvm_features[i] == VIR_TRISTATE_SWITCH_ON)
                    virBufferAddLit(&buf, ",kvm=off");
                break;

J
John Ferlan 已提交
7725
            /* coverity[dead_error_begin] */
7726 7727 7728 7729 7730 7731
            case VIR_DOMAIN_KVM_LAST:
                break;
            }
        }
    }

7732 7733 7734 7735 7736 7737 7738 7739 7740 7741
    if (def->features[VIR_DOMAIN_FEATURE_PMU]) {
        virTristateSwitch pmu = def->features[VIR_DOMAIN_FEATURE_PMU];
        if (!have_cpu)
            virBufferAdd(&buf, default_model, -1);

        virBufferAsprintf(&buf, ",pmu=%s",
                          virTristateSwitchTypeToString(pmu));
        have_cpu = true;
    }

7742
    if (virBufferCheckError(&buf) < 0)
7743
        goto cleanup;
7744 7745 7746 7747 7748

    *opt = virBufferContentAndReset(&buf);

    ret = 0;

7749
 cleanup:
7750 7751 7752
    return ret;
}

7753 7754
static int
qemuBuildObsoleteAccelArg(virCommandPtr cmd,
E
Eric Blake 已提交
7755
                          const virDomainDef *def,
7756 7757
                          virQEMUCapsPtr qemuCaps)
{
7758 7759
    bool disableKVM = false;
    bool enableKVM = false;
7760 7761 7762 7763

    switch (def->virtType) {
    case VIR_DOMAIN_VIRT_QEMU:
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
7764
            disableKVM = true;
7765 7766 7767
        break;

    case VIR_DOMAIN_VIRT_KQEMU:
7768 7769
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("the QEMU binary does not support kqemu"));
7770 7771 7772 7773
        break;

    case VIR_DOMAIN_VIRT_KVM:
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KVM)) {
7774
            enableKVM = true;
7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800
        } else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("the QEMU binary does not support kvm"));
            return -1;
        }
        break;

    case VIR_DOMAIN_VIRT_XEN:
        /* XXX better check for xenner */
        break;

    default:
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("the QEMU binary does not support %s"),
                       virDomainVirtTypeToString(def->virtType));
        return -1;
    }

    if (disableKVM)
        virCommandAddArg(cmd, "-no-kvm");
    if (enableKVM)
        virCommandAddArg(cmd, "-enable-kvm");

    return 0;
}

7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820 7821 7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833
static bool
qemuAppendKeyWrapMachineParm(virBuffer *buf, virQEMUCapsPtr qemuCaps,
                             int flag, const char *pname, int pstate)
{
    if (pstate != VIR_TRISTATE_SWITCH_ABSENT) {
        if (!virQEMUCapsGet(qemuCaps, flag)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("%s is not available with this QEMU binary"), pname);
            return false;
        }

        virBufferAsprintf(buf, ",%s=%s", pname,
                          virTristateSwitchTypeToString(pstate));
    }

    return true;
}

static bool
qemuAppendKeyWrapMachineParms(virBuffer *buf, virQEMUCapsPtr qemuCaps,
                              const virDomainKeyWrapDef *keywrap)
{
    if (!qemuAppendKeyWrapMachineParm(buf, qemuCaps, QEMU_CAPS_AES_KEY_WRAP,
                                      "aes-key-wrap", keywrap->aes))
        return false;

    if (!qemuAppendKeyWrapMachineParm(buf, qemuCaps, QEMU_CAPS_DEA_KEY_WRAP,
                                      "dea-key-wrap", keywrap->dea))
        return false;

    return true;
}

7834 7835
static int
qemuBuildMachineArgStr(virCommandPtr cmd,
E
Eric Blake 已提交
7836
                       const virDomainDef *def,
7837
                       virQEMUCapsPtr qemuCaps)
7838
{
7839 7840
    bool obsoleteAccel = false;

7841 7842 7843 7844 7845 7846 7847
    /* This should *never* be NULL, since we always provide
     * a machine in the capabilities data for QEMU. So this
     * check is just here as a safety in case the unexpected
     * happens */
    if (!def->os.machine)
        return 0;

7848
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_OPT)) {
7849 7850 7851 7852
        /* if no parameter to the machine type is needed, we still use
         * '-M' to keep the most of the compatibility with older versions.
         */
        virCommandAddArgList(cmd, "-M", def->os.machine, NULL);
7853 7854 7855 7856
        if (def->mem.dump_core) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("dump-guest-core is not available "
                             "with this QEMU binary"));
7857 7858
            return -1;
        }
7859 7860 7861 7862 7863 7864 7865 7866

        if (def->mem.nosharepages) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("disable shared memory is not available "
                             "with this QEMU binary"));
             return -1;
        }

7867
        obsoleteAccel = true;
7868 7869 7870 7871 7872 7873 7874

        if (def->keywrap) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("key wrap support is not available "
                             "with this QEMU binary"));
            return -1;
        }
7875 7876
    } else {
        virBuffer buf = VIR_BUFFER_INITIALIZER;
7877
        virTristateSwitch vmport = def->features[VIR_DOMAIN_FEATURE_VMPORT];
7878 7879

        virCommandAddArg(cmd, "-machine");
7880 7881
        virBufferAdd(&buf, def->os.machine, -1);

7882 7883 7884 7885 7886 7887 7888
        if (def->virtType == VIR_DOMAIN_VIRT_QEMU)
            virBufferAddLit(&buf, ",accel=tcg");
        else if (def->virtType == VIR_DOMAIN_VIRT_KVM)
            virBufferAddLit(&buf, ",accel=kvm");
        else
            obsoleteAccel = true;

L
Li Zhang 已提交
7889 7890 7891 7892
        /* To avoid the collision of creating USB controllers when calling
         * machine->init in QEMU, it needs to set usb=off
         */
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_USB_OPT))
7893
            virBufferAddLit(&buf, ",usb=off");
L
Li Zhang 已提交
7894

7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907
        if (vmport) {
            if (!virQEMUCapsSupportsVmport(qemuCaps, def)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("vmport is not available "
                                 "with this QEMU binary"));
                virBufferFreeAndReset(&buf);
                return -1;
            }

            virBufferAsprintf(&buf, ",vmport=%s",
                              virTristateSwitchTypeToString(vmport));
        }

7908 7909 7910 7911 7912
        if (def->mem.dump_core) {
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DUMP_GUEST_CORE)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("dump-guest-core is not available "
                                 "with this QEMU binary"));
7913
                virBufferFreeAndReset(&buf);
7914 7915 7916 7917
                return -1;
            }

            virBufferAsprintf(&buf, ",dump-guest-core=%s",
J
Ján Tomko 已提交
7918
                              virTristateSwitchTypeToString(def->mem.dump_core));
7919 7920
        }

7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932
        if (def->mem.nosharepages) {
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MEM_MERGE)) {
                virBufferAddLit(&buf, ",mem-merge=off");
            } else {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("disable shared memory is not available "
                                 "with this QEMU binary"));
                virBufferFreeAndReset(&buf);
                return -1;
            }
        }

7933 7934 7935 7936 7937
        if (def->keywrap &&
            !qemuAppendKeyWrapMachineParms(&buf, qemuCaps, def->keywrap)) {
            virBufferFreeAndReset(&buf);
            return -1;
        }
7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968

        if (def->features[VIR_DOMAIN_FEATURE_GIC] == VIR_TRISTATE_SWITCH_ON) {
            if (def->gic_version) {
                if ((def->os.arch != VIR_ARCH_ARMV7L &&
                     def->os.arch != VIR_ARCH_AARCH64) ||
                    (STRNEQ(def->os.machine, "virt") &&
                     !STRPREFIX(def->os.machine, "virt-"))) {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("gic-version option is available "
                                     "only for ARM virt machine"));
                    virBufferFreeAndReset(&buf);
                    return -1;
                }

                /* 2 is the default, so we don't put it as option for
                 * backwards compatibility
                 */
                if (def->gic_version != 2) {
                    if (!virQEMUCapsGet(qemuCaps,
                                        QEMU_CAPS_MACH_VIRT_GIC_VERSION)) {
                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                       _("gic-version option is not available "
                                         "with this QEMU binary"));
                        virBufferFreeAndReset(&buf);
                        return -1;
                    }

                    virBufferAsprintf(&buf, ",gic-version=%d", def->gic_version);
                }
            }
        }
7969

7970
        virCommandAddArgBuffer(cmd, &buf);
7971 7972
    }

7973 7974 7975 7976
    if (obsoleteAccel &&
        qemuBuildObsoleteAccelArg(cmd, def, qemuCaps) < 0)
        return -1;

7977 7978 7979
    return 0;
}

7980
static char *
E
Eric Blake 已提交
7981
qemuBuildSmpArgStr(const virDomainDef *def,
7982
                   virQEMUCapsPtr qemuCaps)
7983 7984 7985
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

7986
    virBufferAsprintf(&buf, "%u", virDomainDefGetVcpus(def));
7987

7988
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SMP_TOPOLOGY)) {
7989
        if (virDomainDefHasVcpusOffline(def))
7990
            virBufferAsprintf(&buf, ",maxcpus=%u", virDomainDefGetVcpusMax(def));
7991 7992 7993
        /* sockets, cores, and threads are either all zero
         * or all non-zero, thus checking one of them is enough */
        if (def->cpu && def->cpu->sockets) {
7994 7995 7996
            virBufferAsprintf(&buf, ",sockets=%u", def->cpu->sockets);
            virBufferAsprintf(&buf, ",cores=%u", def->cpu->cores);
            virBufferAsprintf(&buf, ",threads=%u", def->cpu->threads);
7997
        } else {
7998
            virBufferAsprintf(&buf, ",sockets=%u", virDomainDefGetVcpusMax(def));
7999 8000
            virBufferAsprintf(&buf, ",cores=%u", 1);
            virBufferAsprintf(&buf, ",threads=%u", 1);
8001
        }
8002
    } else if (virDomainDefHasVcpusOffline(def)) {
8003 8004
        virBufferFreeAndReset(&buf);
        /* FIXME - consider hot-unplugging cpus after boot for older qemu */
8005 8006 8007
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("setting current vcpu count less than maximum is "
                         "not supported with this QEMU binary"));
8008 8009 8010
        return NULL;
    }

8011
    if (virBufferCheckError(&buf) < 0)
8012 8013 8014 8015 8016
        return NULL;

    return virBufferContentAndReset(&buf);
}

8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081
static int
qemuBuildMemPathStr(virQEMUDriverConfigPtr cfg,
                    virDomainDefPtr def,
                    virQEMUCapsPtr qemuCaps,
                    virCommandPtr cmd)
{
    const long system_page_size = virGetSystemPageSizeKB();
    char *mem_path = NULL;
    size_t i = 0;

    /*
     *  No-op if hugepages were not requested.
     */
    if (!def->mem.nhugepages)
        return 0;

    /* There is one special case: if user specified "huge"
     * pages of regular system pages size.
     * And there is nothing to do in this case.
     */
    if (def->mem.hugepages[0].size == system_page_size)
        return 0;

    if (!cfg->nhugetlbfs) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("hugetlbfs filesystem is not mounted "
                               "or disabled by administrator config"));
        return -1;
    }

    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MEM_PATH)) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("hugepage backing not supported by '%s'"),
                       def->emulator);
        return -1;
    }

    if (!def->mem.hugepages[0].size) {
        if (!(mem_path = qemuGetDefaultHugepath(cfg->hugetlbfs,
                                                cfg->nhugetlbfs)))
            return -1;
    } else {
        for (i = 0; i < cfg->nhugetlbfs; i++) {
            if (cfg->hugetlbfs[i].size == def->mem.hugepages[0].size)
                break;
        }

        if (i == cfg->nhugetlbfs) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Unable to find any usable hugetlbfs "
                             "mount for %llu KiB"),
                           def->mem.hugepages[0].size);
            return -1;
        }

        if (!(mem_path = qemuGetHugepagePath(&cfg->hugetlbfs[i])))
            return -1;
    }

    virCommandAddArgList(cmd, "-mem-prealloc", "-mem-path", mem_path, NULL);
    VIR_FREE(mem_path);

    return 0;
}

B
Bharata B Rao 已提交
8082
static int
8083
qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
8084
                    virDomainDefPtr def,
8085
                    virCommandPtr cmd,
8086
                    virQEMUCapsPtr qemuCaps,
8087
                    virBitmapPtr auto_nodeset)
B
Bharata B Rao 已提交
8088
{
8089
    size_t i;
B
Bharata B Rao 已提交
8090
    virBuffer buf = VIR_BUFFER_INITIALIZER;
8091
    char *cpumask = NULL, *tmpmask = NULL, *next = NULL;
8092 8093 8094
    char **nodeBackends = NULL;
    bool needBackend = false;
    int rc;
8095
    int ret = -1;
8096
    size_t ncells = virDomainNumaGetNodeCount(def->numa);
8097
    const long system_page_size = virGetSystemPageSizeKB();
B
Bharata B Rao 已提交
8098

8099
    if (virDomainNumatuneHasPerNodeBinding(def->numa) &&
8100 8101
        !(virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) ||
          virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE))) {
8102 8103 8104 8105 8106 8107
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Per-node memory binding is not supported "
                         "with this QEMU"));
        goto cleanup;
    }

8108 8109
    if (def->mem.nhugepages &&
        def->mem.hugepages[0].size != system_page_size &&
8110 8111 8112 8113 8114 8115 8116
        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("huge pages per NUMA node are not "
                         "supported with this QEMU"));
        goto cleanup;
    }

8117
    if (!virDomainNumatuneNodesetIsAvailable(def->numa, auto_nodeset))
8118 8119
        goto cleanup;

8120 8121 8122 8123 8124 8125 8126 8127 8128
    for (i = 0; i < def->mem.nhugepages; i++) {
        ssize_t next_bit, pos = 0;

        if (!def->mem.hugepages[i].nodemask) {
            /* This is the master hugepage to use. Skip it as it has no
             * nodemask anyway. */
            continue;
        }

8129
        if (ncells) {
8130 8131
            /* Fortunately, we allow only guest NUMA nodes to be continuous
             * starting from zero. */
8132
            pos = ncells - 1;
8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143
        }

        next_bit = virBitmapNextSetBit(def->mem.hugepages[i].nodemask, pos);
        if (next_bit >= 0) {
            virReportError(VIR_ERR_XML_DETAIL,
                           _("hugepages: node %zd not found"),
                           next_bit);
            goto cleanup;
        }
    }

8144
    if (VIR_ALLOC_N(nodeBackends, ncells) < 0)
8145 8146 8147 8148
        goto cleanup;

    /* using of -numa memdev= cannot be combined with -numa mem=, thus we
     * need to check which approach to use */
8149
    for (i = 0; i < ncells; i++) {
8150 8151
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) ||
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) {
8152 8153 8154
            if ((rc = qemuBuildMemoryCellBackendStr(def, qemuCaps, cfg, i,
                                                    auto_nodeset,
                                                    &nodeBackends[i])) < 0)
8155 8156
                goto cleanup;

8157 8158
            if (rc == 0)
                needBackend = true;
8159
        } else {
8160
            if (virDomainNumaGetNodeMemoryAccessMode(def->numa, i)) {
8161 8162 8163 8164 8165
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("Shared memory mapping is not supported "
                                 "with this QEMU"));
                goto cleanup;
            }
8166
        }
8167 8168
    }

8169 8170 8171 8172
    if (!needBackend &&
        qemuBuildMemPathStr(cfg, def, qemuCaps, cmd) < 0)
        goto cleanup;

8173
    for (i = 0; i < ncells; i++) {
8174
        VIR_FREE(cpumask);
8175
        if (!(cpumask = virBitmapFormat(virDomainNumaGetNodeCpumask(def->numa, i))))
8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187
            goto cleanup;

        if (strchr(cpumask, ',') &&
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("disjoint NUMA cpu ranges are not supported "
                             "with this QEMU"));
            goto cleanup;
        }

        if (needBackend)
            virCommandAddArgList(cmd, "-object", nodeBackends[i], NULL);
8188

B
Bharata B Rao 已提交
8189
        virCommandAddArg(cmd, "-numa");
8190
        virBufferAsprintf(&buf, "node,nodeid=%zu", i);
8191

8192 8193 8194 8195 8196 8197 8198
        for (tmpmask = cpumask; tmpmask; tmpmask = next) {
            if ((next = strchr(tmpmask, ',')))
                *(next++) = '\0';
            virBufferAddLit(&buf, ",cpus=");
            virBufferAdd(&buf, tmpmask, -1);
        }

8199
        if (needBackend)
8200
            virBufferAsprintf(&buf, ",memdev=ram-node%zu", i);
8201
        else
8202
            virBufferAsprintf(&buf, ",mem=%llu",
8203
                              virDomainNumaGetNodeMemorySize(def->numa, i) / 1024);
B
Bharata B Rao 已提交
8204 8205 8206

        virCommandAddArgBuffer(cmd, &buf);
    }
8207
    ret = 0;
B
Bharata B Rao 已提交
8208

8209
 cleanup:
8210
    VIR_FREE(cpumask);
8211 8212

    if (nodeBackends) {
8213
        for (i = 0; i < ncells; i++)
8214 8215 8216 8217 8218
            VIR_FREE(nodeBackends[i]);

        VIR_FREE(nodeBackends);
    }

B
Bharata B Rao 已提交
8219
    virBufferFreeAndReset(&buf);
8220
    return ret;
B
Bharata B Rao 已提交
8221
}
8222

8223

8224 8225 8226 8227 8228 8229 8230 8231 8232 8233 8234 8235 8236 8237 8238 8239 8240 8241 8242 8243 8244 8245 8246
static int
qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg,
                                virCommandPtr cmd,
                                virDomainDefPtr def,
                                virQEMUCapsPtr qemuCaps,
                                virDomainGraphicsDefPtr graphics)
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;
    const char *listenNetwork;
    const char *listenAddr = NULL;
    char *netAddr = NULL;
    bool escapeAddr;
    int ret;

    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VNC)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("vnc graphics are not supported with this QEMU"));
        goto error;
    }

    if (graphics->data.vnc.socket || cfg->vncAutoUnixSocket) {
        if (!graphics->data.vnc.socket &&
            virAsprintf(&graphics->data.vnc.socket,
8247
                        "%s/domain-%s/vnc.sock", cfg->libDir, def->name) == -1)
8248
            goto error;
8249 8250 8251

        virBufferAsprintf(&opt, "unix:%s", graphics->data.vnc.socket);

8252 8253 8254 8255 8256 8257 8258 8259
    } else {
        if (!graphics->data.vnc.autoport &&
            (graphics->data.vnc.port < 5900 ||
             graphics->data.vnc.port > 65535)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("vnc port must be in range [5900,65535]"));
            goto error;
        }
8260

8261 8262 8263 8264
        switch (virDomainGraphicsListenGetType(graphics, 0)) {
        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
            listenAddr = virDomainGraphicsListenGetAddress(graphics, 0);
            break;
8265

8266 8267 8268
        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK:
            listenNetwork = virDomainGraphicsListenGetNetwork(graphics, 0);
            if (!listenNetwork)
8269
                break;
8270 8271 8272 8273 8274 8275
            ret = networkGetNetworkAddress(listenNetwork, &netAddr);
            if (ret <= -2) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("network-based listen not possible, "
                                       "network driver not present"));
                goto error;
8276
            }
8277 8278
            if (ret < 0)
                goto error;
8279

8280 8281 8282 8283 8284 8285 8286 8287
            listenAddr = netAddr;
            /* store the address we found in the <graphics> element so it
             * will show up in status. */
            if (virDomainGraphicsListenSetAddress(graphics, 0,
                                                  listenAddr, -1, false) < 0)
                goto error;
            break;
        }
8288

8289 8290
        if (!listenAddr)
            listenAddr = cfg->vncListen;
8291

8292 8293 8294 8295 8296 8297 8298 8299 8300
        escapeAddr = strchr(listenAddr, ':') != NULL;
        if (escapeAddr)
            virBufferAsprintf(&opt, "[%s]", listenAddr);
        else
            virBufferAdd(&opt, listenAddr, -1);
        virBufferAsprintf(&opt, ":%d",
                          graphics->data.vnc.port - 5900);

        VIR_FREE(netAddr);
8301 8302
    }

8303 8304 8305 8306 8307 8308 8309 8310 8311 8312
    if (!graphics->data.vnc.socket &&
        graphics->data.vnc.websocket) {
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VNC_WEBSOCKET)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("VNC WebSockets are not supported "
                             "with this QEMU binary"));
            goto error;
        }
        virBufferAsprintf(&opt, ",websocket=%d", graphics->data.vnc.websocket);
    }
8313

8314 8315 8316 8317 8318 8319 8320
    if (graphics->data.vnc.sharePolicy) {
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VNC_SHARE_POLICY)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("vnc display sharing policy is not "
                             "supported with this QEMU"));
            goto error;
        }
8321

8322 8323
        virBufferAsprintf(&opt, ",share=%s",
                          virDomainGraphicsVNCSharePolicyTypeToString(
8324
                              graphics->data.vnc.sharePolicy));
8325
    }
8326

8327 8328
    if (graphics->data.vnc.auth.passwd || cfg->vncPassword)
        virBufferAddLit(&opt, ",password");
8329

8330 8331 8332 8333 8334 8335 8336
    if (cfg->vncTLS) {
        virBufferAddLit(&opt, ",tls");
        if (cfg->vncTLSx509verify)
            virBufferAsprintf(&opt, ",x509verify=%s", cfg->vncTLSx509certdir);
        else
            virBufferAsprintf(&opt, ",x509=%s", cfg->vncTLSx509certdir);
    }
8337

8338 8339
    if (cfg->vncSASL) {
        virBufferAddLit(&opt, ",sasl");
8340

8341 8342
        if (cfg->vncSASLdir)
            virCommandAddEnvPair(cmd, "SASL_CONF_PATH", cfg->vncSASLdir);
8343

8344
        /* TODO: Support ACLs later */
8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 8355 8356
    }

    virCommandAddArg(cmd, "-vnc");
    virCommandAddArgBuffer(cmd, &opt);
    if (graphics->data.vnc.keymap)
        virCommandAddArgList(cmd, "-k", graphics->data.vnc.keymap, NULL);

    /* Unless user requested it, set the audio backend to none, to
     * prevent it opening the host OS audio devices, since that causes
     * security issues and might not work when using VNC.
     */
    if (cfg->vncAllowHostAudio)
8357
        virCommandAddEnvPassBlockSUID(cmd, "QEMU_AUDIO_DRV", NULL);
8358 8359 8360 8361 8362
    else
        virCommandAddEnvString(cmd, "QEMU_AUDIO_DRV=none");

    return 0;

8363
 error:
8364 8365 8366 8367 8368 8369
    VIR_FREE(netAddr);
    virBufferFreeAndReset(&opt);
    return -1;
}


8370 8371 8372 8373 8374 8375 8376 8377 8378 8379 8380 8381 8382 8383
static int
qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg,
                                  virCommandPtr cmd,
                                  virQEMUCapsPtr qemuCaps,
                                  virDomainGraphicsDefPtr graphics)
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;
    const char *listenNetwork;
    const char *listenAddr = NULL;
    char *netAddr = NULL;
    int ret;
    int defaultMode = graphics->data.spice.defaultMode;
    int port = graphics->data.spice.port;
    int tlsPort = graphics->data.spice.tlsPort;
8384
    size_t i;
8385 8386 8387 8388 8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400 8401 8402 8403 8404 8405 8406

    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("spice graphics are not supported with this QEMU"));
        goto error;
    }

    if (port > 0 || tlsPort <= 0)
        virBufferAsprintf(&opt, "port=%u", port);

    if (tlsPort > 0) {
        if (!cfg->spiceTLS) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("spice TLS port set in XML configuration,"
                             " but TLS is disabled in qemu.conf"));
            goto error;
        }
        if (port > 0)
            virBufferAddChar(&opt, ',');
        virBufferAsprintf(&opt, "tls-port=%u", tlsPort);
    }

8407 8408 8409 8410 8411 8412 8413 8414 8415 8416
    if (cfg->spiceSASL) {
        virBufferAddLit(&opt, ",sasl");

        if (cfg->spiceSASLdir)
            virCommandAddEnvPair(cmd, "SASL_CONF_PATH",
                                 cfg->spiceSASLdir);

        /* TODO: Support ACLs later */
    }

8417 8418 8419 8420 8421 8422 8423 8424 8425 8426 8427 8428 8429 8430 8431 8432
    switch (virDomainGraphicsListenGetType(graphics, 0)) {
    case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
        listenAddr = virDomainGraphicsListenGetAddress(graphics, 0);
        break;

    case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK:
        listenNetwork = virDomainGraphicsListenGetNetwork(graphics, 0);
        if (!listenNetwork)
            break;
        ret = networkGetNetworkAddress(listenNetwork, &netAddr);
        if (ret <= -2) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("network-based listen not possible, "
                                   "network driver not present"));
            goto error;
        }
8433
        if (ret < 0)
8434
            goto error;
8435

8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453 8454
        listenAddr = netAddr;
        /* store the address we found in the <graphics> element so it will
         * show up in status. */
        if (virDomainGraphicsListenSetAddress(graphics, 0,
                                              listenAddr, -1, false) < 0)
           goto error;
        break;
    }

    if (!listenAddr)
        listenAddr = cfg->spiceListen;
    if (listenAddr)
        virBufferAsprintf(&opt, ",addr=%s", listenAddr);

    VIR_FREE(netAddr);

    if (graphics->data.spice.mousemode) {
        switch (graphics->data.spice.mousemode) {
        case VIR_DOMAIN_GRAPHICS_SPICE_MOUSE_MODE_SERVER:
8455
            virBufferAddLit(&opt, ",agent-mouse=off");
8456 8457
            break;
        case VIR_DOMAIN_GRAPHICS_SPICE_MOUSE_MODE_CLIENT:
8458
            virBufferAddLit(&opt, ",agent-mouse=on");
8459 8460 8461 8462 8463 8464 8465 8466 8467 8468 8469 8470 8471
            break;
        default:
            break;
        }
    }

    /* In the password case we set it via monitor command, to avoid
     * making it visible on CLI, so there's no use of password=XXX
     * in this bit of the code */
    if (!graphics->data.spice.auth.passwd &&
        !cfg->spicePassword)
        virBufferAddLit(&opt, ",disable-ticketing");

8472 8473
    if (tlsPort > 0)
        virBufferAsprintf(&opt, ",x509-dir=%s", cfg->spiceTLSx509certdir);
8474 8475 8476

    switch (defaultMode) {
    case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE:
8477
        virBufferAddLit(&opt, ",tls-channel=default");
8478 8479
        break;
    case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_INSECURE:
8480
        virBufferAddLit(&opt, ",plaintext-channel=default");
8481 8482 8483 8484 8485 8486
        break;
    case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_ANY:
        /* nothing */
        break;
    }

8487
    for (i = 0; i < VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST; i++) {
8488
        switch (graphics->data.spice.channels[i]) {
8489
        case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE:
8490
            if (tlsPort <= 0) {
8491 8492
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("spice secure channels set in XML configuration, "
8493
                                 "but TLS port is not provided"));
8494 8495 8496 8497 8498
                goto error;
            }
            virBufferAsprintf(&opt, ",tls-channel=%s",
                              virDomainGraphicsSpiceChannelNameTypeToString(i));
            break;
8499

8500
        case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_INSECURE:
8501 8502 8503 8504 8505 8506
            if (port <= 0) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("spice insecure channels set in XML "
                                 "configuration, but plain port is not provided"));
                goto error;
            }
8507 8508 8509
            virBufferAsprintf(&opt, ",plaintext-channel=%s",
                              virDomainGraphicsSpiceChannelNameTypeToString(i));
            break;
8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 8532 8533 8534

        case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_ANY:
            switch (defaultMode) {
            case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE:
                if (tlsPort <= 0) {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("spice defaultMode secure requested in XML "
                                     "configuration but TLS port not provided"));
                    goto error;
                }
                break;

            case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_INSECURE:
                if (port <= 0) {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("spice defaultMode insecure requested in XML "
                                     "configuration but plain port not provided"));
                    goto error;
                }
                break;

            case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_ANY:
                /* don't care */
            break;
            }
8535 8536
        }
    }
8537

8538 8539 8540 8541 8542 8543 8544 8545 8546 8547 8548
    if (graphics->data.spice.image)
        virBufferAsprintf(&opt, ",image-compression=%s",
                          virDomainGraphicsSpiceImageCompressionTypeToString(graphics->data.spice.image));
    if (graphics->data.spice.jpeg)
        virBufferAsprintf(&opt, ",jpeg-wan-compression=%s",
                          virDomainGraphicsSpiceJpegCompressionTypeToString(graphics->data.spice.jpeg));
    if (graphics->data.spice.zlib)
        virBufferAsprintf(&opt, ",zlib-glz-wan-compression=%s",
                          virDomainGraphicsSpiceZlibCompressionTypeToString(graphics->data.spice.zlib));
    if (graphics->data.spice.playback)
        virBufferAsprintf(&opt, ",playback-compression=%s",
J
Ján Tomko 已提交
8549
                          virTristateSwitchTypeToString(graphics->data.spice.playback));
8550 8551 8552
    if (graphics->data.spice.streaming)
        virBufferAsprintf(&opt, ",streaming-video=%s",
                          virDomainGraphicsSpiceStreamingModeTypeToString(graphics->data.spice.streaming));
J
Ján Tomko 已提交
8553
    if (graphics->data.spice.copypaste == VIR_TRISTATE_BOOL_NO)
8554
        virBufferAddLit(&opt, ",disable-copy-paste");
J
Ján Tomko 已提交
8555
    if (graphics->data.spice.filetransfer == VIR_TRISTATE_BOOL_NO) {
8556 8557 8558 8559 8560 8561 8562 8563
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_FILE_XFER_DISABLE)) {
           virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                          _("This QEMU can't disable file transfers through spice"));
            goto error;
        } else {
            virBufferAddLit(&opt, ",disable-agent-file-xfer");
        }
    }
8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 8575 8576 8577 8578 8579 8580 8581 8582 8583 8584

    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEAMLESS_MIGRATION)) {
        /* If qemu supports seamless migration turn it
         * unconditionally on. If migration destination
         * doesn't support it, it fallbacks to previous
         * migration algorithm silently. */
        virBufferAddLit(&opt, ",seamless-migration=on");
    }

    virCommandAddArg(cmd, "-spice");
    virCommandAddArgBuffer(cmd, &opt);
    if (graphics->data.spice.keymap)
        virCommandAddArgList(cmd, "-k",
                             graphics->data.spice.keymap, NULL);
    /* SPICE includes native support for tunnelling audio, so we
     * set the audio backend to point at SPICE's own driver
     */
    virCommandAddEnvString(cmd, "QEMU_AUDIO_DRV=spice");

    return 0;

8585
 error:
8586 8587 8588 8589 8590
    VIR_FREE(netAddr);
    virBufferFreeAndReset(&opt);
    return -1;
}

8591
static int
8592
qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg,
8593 8594
                             virCommandPtr cmd,
                             virDomainDefPtr def,
8595
                             virQEMUCapsPtr qemuCaps,
8596
                             virDomainGraphicsDefPtr graphics)
8597
{
8598
    switch ((virDomainGraphicsType) graphics->type) {
8599
    case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
8600
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SDL)) {
8601
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
8602 8603
                           _("sdl not supported by '%s'"), def->emulator);
            return -1;
8604 8605
        }

8606
        if (graphics->data.sdl.xauth)
8607
            virCommandAddEnvPair(cmd, "XAUTHORITY", graphics->data.sdl.xauth);
8608
        if (graphics->data.sdl.display)
8609
            virCommandAddEnvPair(cmd, "DISPLAY", graphics->data.sdl.display);
8610 8611
        if (graphics->data.sdl.fullscreen)
            virCommandAddArg(cmd, "-full-screen");
8612

8613 8614 8615 8616
        /* If using SDL for video, then we should just let it
         * use QEMU's host audio drivers, possibly SDL too
         * User can set these two before starting libvirtd
         */
8617 8618
        virCommandAddEnvPassBlockSUID(cmd, "QEMU_AUDIO_DRV", NULL);
        virCommandAddEnvPassBlockSUID(cmd, "SDL_AUDIODRIVER", NULL);
B
Bharata B Rao 已提交
8619

8620 8621 8622
        /* New QEMU has this flag to let us explicitly ask for
         * SDL graphics. This is better than relying on the
         * default, since the default changes :-( */
8623
        virCommandAddArg(cmd, "-sdl");
8624

8625 8626 8627 8628 8629 8630 8631 8632 8633 8634 8635
        break;

    case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
        return qemuBuildGraphicsVNCCommandLine(cfg, cmd, def, qemuCaps, graphics);

    case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
        return qemuBuildGraphicsSPICECommandLine(cfg, cmd, qemuCaps, graphics);

    case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
    case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
    case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
8636 8637 8638
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unsupported graphics type '%s'"),
                       virDomainGraphicsTypeToString(graphics->type));
8639
        return -1;
8640
    }
8641

8642 8643
    return 0;
}
8644

M
Michele Paolino 已提交
8645 8646 8647 8648
static int
qemuBuildVhostuserCommandLine(virCommandPtr cmd,
                              virDomainDefPtr def,
                              virDomainNetDefPtr net,
8649 8650
                              virQEMUCapsPtr qemuCaps,
                              int bootindex)
M
Michele Paolino 已提交
8651 8652 8653
{
    virBuffer chardev_buf = VIR_BUFFER_INITIALIZER;
    virBuffer netdev_buf = VIR_BUFFER_INITIALIZER;
8654
    unsigned int queues = net->driver.virtio.queues;
M
Michele Paolino 已提交
8655 8656 8657 8658 8659 8660 8661 8662 8663 8664 8665 8666 8667 8668 8669 8670 8671 8672 8673 8674 8675 8676 8677 8678 8679 8680 8681 8682 8683 8684 8685 8686 8687 8688 8689 8690 8691
    char *nic = NULL;

    if (!qemuDomainSupportsNetdev(def, qemuCaps, net)) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("Netdev support unavailable"));
        goto error;
    }

    switch ((virDomainChrType) net->data.vhostuser->type) {
    case VIR_DOMAIN_CHR_TYPE_UNIX:
        virBufferAsprintf(&chardev_buf, "socket,id=char%s,path=%s%s",
                          net->info.alias, net->data.vhostuser->data.nix.path,
                          net->data.vhostuser->data.nix.listen ? ",server" : "");
        break;

    case VIR_DOMAIN_CHR_TYPE_NULL:
    case VIR_DOMAIN_CHR_TYPE_VC:
    case VIR_DOMAIN_CHR_TYPE_PTY:
    case VIR_DOMAIN_CHR_TYPE_DEV:
    case VIR_DOMAIN_CHR_TYPE_FILE:
    case VIR_DOMAIN_CHR_TYPE_PIPE:
    case VIR_DOMAIN_CHR_TYPE_STDIO:
    case VIR_DOMAIN_CHR_TYPE_UDP:
    case VIR_DOMAIN_CHR_TYPE_TCP:
    case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
    case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
    case VIR_DOMAIN_CHR_TYPE_NMDM:
    case VIR_DOMAIN_CHR_TYPE_LAST:
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("vhost-user type '%s' not supported"),
                        virDomainChrTypeToString(net->data.vhostuser->type));
        goto error;
    }

    virBufferAsprintf(&netdev_buf, "type=vhost-user,id=host%s,chardev=char%s",
                      net->info.alias, net->info.alias);

8692
    if (queues > 1) {
J
Ján Tomko 已提交
8693
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VHOSTUSER_MULTIQUEUE)) {
8694 8695 8696 8697 8698 8699 8700 8701
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("multi-queue is not supported for vhost-user "
                             "with this QEMU binary"));
            goto error;
        }
        virBufferAsprintf(&netdev_buf, ",queues=%u", queues);
    }

M
Michele Paolino 已提交
8702 8703 8704 8705 8706 8707
    virCommandAddArg(cmd, "-chardev");
    virCommandAddArgBuffer(cmd, &chardev_buf);

    virCommandAddArg(cmd, "-netdev");
    virCommandAddArgBuffer(cmd, &netdev_buf);

8708 8709
    if (!(nic = qemuBuildNicDevStr(def, net, -1, bootindex,
                                   queues, qemuCaps))) {
M
Michele Paolino 已提交
8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("Error generating NIC -device string"));
        goto error;
    }

    virCommandAddArgList(cmd, "-device", nic, NULL);
    VIR_FREE(nic);

    return 0;

 error:
    virBufferFreeAndReset(&chardev_buf);
    virBufferFreeAndReset(&netdev_buf);
    VIR_FREE(nic);

    return -1;
}

8728 8729 8730 8731 8732 8733 8734 8735
static int
qemuBuildInterfaceCommandLine(virCommandPtr cmd,
                              virQEMUDriverPtr driver,
                              virDomainDefPtr def,
                              virDomainNetDefPtr net,
                              virQEMUCapsPtr qemuCaps,
                              int vlan,
                              int bootindex,
8736
                              virNetDevVPortProfileOp vmop,
8737
                              bool standalone,
8738 8739
                              size_t *nnicindexes,
                              int **nicindexes)
8740 8741 8742
{
    int ret = -1;
    char *nic = NULL, *host = NULL;
8743
    int *tapfd = NULL;
8744
    size_t tapfdSize = 0;
8745
    int *vhostfd = NULL;
8746
    size_t vhostfdSize = 0;
8747 8748
    char **tapfdName = NULL;
    char **vhostfdName = NULL;
8749
    int actualType = virDomainNetGetActualType(net);
8750
    virQEMUDriverConfigPtr cfg = NULL;
8751
    virNetDevBandwidthPtr actualBandwidth;
8752
    size_t i;
8753

8754 8755 8756 8757

    if (!bootindex)
        bootindex = net->info.bootIndex;

M
Michele Paolino 已提交
8758
    if (actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER)
8759
        return qemuBuildVhostuserCommandLine(cmd, def, net, qemuCaps, bootindex);
M
Michele Paolino 已提交
8760

8761 8762 8763 8764 8765 8766 8767
    if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
        /* NET_TYPE_HOSTDEV devices are really hostdev devices, so
         * their commandlines are constructed with other hostdevs.
         */
        return 0;
    }

8768 8769 8770
    /* Currently nothing besides TAP devices supports multiqueue. */
    if (net->driver.virtio.queues > 0 &&
        !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
8771 8772
          actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
          actualType == VIR_DOMAIN_NET_TYPE_DIRECT)) {
8773 8774 8775 8776 8777 8778
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Multiqueue network is not supported for: %s"),
                       virDomainNetTypeToString(actualType));
        return -1;
    }

8779 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789
    /* and only TAP devices support nwfilter rules */
    if (net->filter &&
        !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
          actualType == VIR_DOMAIN_NET_TYPE_BRIDGE)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("filterref is not supported for "
                         "network interfaces of type %s"),
                       virDomainNetTypeToString(actualType));
        return -1;
    }

8790 8791 8792 8793 8794 8795 8796 8797 8798
    if (net->backend.tap &&
        !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
          actualType == VIR_DOMAIN_NET_TYPE_BRIDGE)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Custom tap device path is not supported for: %s"),
                       virDomainNetTypeToString(actualType));
        return -1;
    }

8799 8800
    cfg = virQEMUDriverGetConfig(driver);

8801 8802
    if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
        actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
8803 8804 8805 8806 8807
        tapfdSize = net->driver.virtio.queues;
        if (!tapfdSize)
            tapfdSize = 1;

        if (VIR_ALLOC_N(tapfd, tapfdSize) < 0 ||
8808
            VIR_ALLOC_N(tapfdName, tapfdSize) < 0)
8809 8810
            goto cleanup;

8811 8812
        memset(tapfd, -1, tapfdSize * sizeof(tapfd[0]));

8813
        if (qemuNetworkIfaceConnect(def, driver, net,
8814
                                    tapfd, &tapfdSize) < 0)
8815 8816
            goto cleanup;
    } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
8817 8818 8819 8820 8821 8822
        tapfdSize = net->driver.virtio.queues;
        if (!tapfdSize)
            tapfdSize = 1;

        if (VIR_ALLOC_N(tapfd, tapfdSize) < 0 ||
            VIR_ALLOC_N(tapfdName, tapfdSize) < 0)
8823
            goto cleanup;
8824 8825 8826 8827

        memset(tapfd, -1, tapfdSize * sizeof(tapfd[0]));

        if (qemuPhysIfaceConnect(def, driver, net, tapfd, tapfdSize, vmop) < 0)
8828 8829 8830
            goto cleanup;
    }

8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844
    /* For types whose implementations use a netdev on the host, add
     * an entry to nicindexes for passing on to systemd.
    */
    switch ((virDomainNetType)actualType) {
    case VIR_DOMAIN_NET_TYPE_ETHERNET:
    case VIR_DOMAIN_NET_TYPE_NETWORK:
    case VIR_DOMAIN_NET_TYPE_BRIDGE:
    case VIR_DOMAIN_NET_TYPE_DIRECT:
    {
        int nicindex;

        /* network and bridge use a tap device, and direct uses a
         * macvtap device
         */
8845 8846
        if (virQEMUDriverIsPrivileged(driver) && nicindexes && nnicindexes &&
            net->ifname) {
8847 8848 8849 8850 8851 8852 8853 8854 8855 8856 8857 8858
            if (virNetDevGetIndex(net->ifname, &nicindex) < 0 ||
                VIR_APPEND_ELEMENT(*nicindexes, *nnicindexes, nicindex) < 0)
                goto cleanup;
        }
        break;
    }

    case VIR_DOMAIN_NET_TYPE_USER:
    case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
    case VIR_DOMAIN_NET_TYPE_SERVER:
    case VIR_DOMAIN_NET_TYPE_CLIENT:
    case VIR_DOMAIN_NET_TYPE_MCAST:
8859
    case VIR_DOMAIN_NET_TYPE_UDP:
8860 8861 8862 8863 8864 8865 8866 8867 8868 8869 8870 8871 8872 8873 8874 8875
    case VIR_DOMAIN_NET_TYPE_INTERNAL:
    case VIR_DOMAIN_NET_TYPE_HOSTDEV:
    case VIR_DOMAIN_NET_TYPE_LAST:
       /* These types don't use a network device on the host, but
        * instead use some other type of connection to the emulated
        * device in the qemu process.
        *
        * (Note that hostdev can't be considered as "using a network
        * device", because by the time it is being used, it has been
        * detached from the hostside network driver so it doesn't show
        * up in the list of interfaces on the host - it's just some
        * PCI device.)
        */
       break;
    }

8876 8877 8878 8879 8880 8881 8882 8883 8884 8885 8886 8887
    /* Set bandwidth or warn if requested and not supported. */
    actualBandwidth = virDomainNetGetActualBandwidth(net);
    if (actualBandwidth) {
        if (virNetDevSupportBandwidth(actualType)) {
            if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false) < 0)
                goto cleanup;
        } else {
            VIR_WARN("setting bandwidth on interfaces of "
                     "type '%s' is not implemented yet",
                     virDomainNetTypeToString(actualType));
        }
    }
8888

8889 8890 8891 8892 8893
    if ((actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
         actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
         actualType == VIR_DOMAIN_NET_TYPE_ETHERNET ||
         actualType == VIR_DOMAIN_NET_TYPE_DIRECT) &&
        !standalone) {
8894 8895
        /* Attempt to use vhost-net mode for these types of
           network device */
8896 8897 8898 8899 8900
        vhostfdSize = net->driver.virtio.queues;
        if (!vhostfdSize)
            vhostfdSize = 1;

        if (VIR_ALLOC_N(vhostfd, vhostfdSize) < 0 ||
8901
            VIR_ALLOC_N(vhostfdName, vhostfdSize))
8902 8903
            goto cleanup;

8904 8905
        memset(vhostfd, -1, vhostfdSize * sizeof(vhostfd[0]));

8906
        if (qemuOpenVhostNet(def, net, qemuCaps, vhostfd, &vhostfdSize) < 0)
8907 8908 8909
            goto cleanup;
    }

8910
    for (i = 0; i < tapfdSize; i++) {
M
Michal Privoznik 已提交
8911 8912 8913
        if (virSecurityManagerSetTapFDLabel(driver->securityManager,
                                            def, tapfd[i]) < 0)
            goto cleanup;
8914 8915
        virCommandPassFD(cmd, tapfd[i],
                         VIR_COMMAND_PASS_FD_CLOSE_PARENT);
8916
        if (virAsprintf(&tapfdName[i], "%d", tapfd[i]) < 0)
8917 8918 8919
            goto cleanup;
    }

8920
    for (i = 0; i < vhostfdSize; i++) {
8921 8922
        virCommandPassFD(cmd, vhostfd[i],
                         VIR_COMMAND_PASS_FD_CLOSE_PARENT);
8923
        if (virAsprintf(&vhostfdName[i], "%d", vhostfd[i]) < 0)
8924
            goto cleanup;
8925 8926 8927 8928 8929 8930 8931 8932 8933 8934
    }

    /* Possible combinations:
     *
     *  1. Old way:   -net nic,model=e1000,vlan=1 -net tap,vlan=1
     *  2. Semi-new:  -device e1000,vlan=1        -net tap,vlan=1
     *  3. Best way:  -netdev type=tap,id=netdev1 -device e1000,id=netdev1
     *
     * NB, no support for -netdev without use of -device
     */
8935
    if (qemuDomainSupportsNetdev(def, qemuCaps, net)) {
8936
        if (!(host = qemuBuildHostNetStr(net, driver,
8937 8938 8939
                                         ',', vlan,
                                         tapfdName, tapfdSize,
                                         vhostfdName, vhostfdSize)))
8940 8941 8942
            goto cleanup;
        virCommandAddArgList(cmd, "-netdev", host, NULL);
    }
8943
    if (qemuDomainSupportsNicdev(def, qemuCaps, net)) {
8944
        if (!(nic = qemuBuildNicDevStr(def, net, vlan, bootindex,
8945
                                       vhostfdSize, qemuCaps)))
8946 8947 8948 8949 8950 8951 8952
            goto cleanup;
        virCommandAddArgList(cmd, "-device", nic, NULL);
    } else {
        if (!(nic = qemuBuildNicStr(net, "nic,", vlan)))
            goto cleanup;
        virCommandAddArgList(cmd, "-net", nic, NULL);
    }
8953
    if (!qemuDomainSupportsNetdev(def, qemuCaps, net)) {
8954
        if (!(host = qemuBuildHostNetStr(net, driver,
8955 8956 8957
                                         ',', vlan,
                                         tapfdName, tapfdSize,
                                         vhostfdName, vhostfdSize)))
8958 8959 8960 8961 8962
            goto cleanup;
        virCommandAddArgList(cmd, "-net", host, NULL);
    }

    ret = 0;
8963
 cleanup:
8964 8965
    if (ret < 0) {
        virErrorPtr saved_err = virSaveLastError();
8966
        virDomainConfNWFilterTeardown(net);
8967 8968 8969
        virSetError(saved_err);
        virFreeError(saved_err);
    }
8970
    for (i = 0; tapfd && i < tapfdSize && tapfd[i] >= 0; i++) {
8971 8972
        if (ret < 0)
            VIR_FORCE_CLOSE(tapfd[i]);
8973 8974
        if (tapfdName)
            VIR_FREE(tapfdName[i]);
8975
    }
8976
    for (i = 0; vhostfd && i < vhostfdSize && vhostfd[i] >= 0; i++) {
8977 8978
        if (ret < 0)
            VIR_FORCE_CLOSE(vhostfd[i]);
8979 8980
        if (vhostfdName)
            VIR_FREE(vhostfdName[i]);
8981 8982 8983
    }
    VIR_FREE(tapfd);
    VIR_FREE(vhostfd);
8984 8985 8986 8987
    VIR_FREE(nic);
    VIR_FREE(host);
    VIR_FREE(tapfdName);
    VIR_FREE(vhostfdName);
8988
    virObjectUnref(cfg);
8989 8990 8991
    return ret;
}

8992 8993
char *
qemuBuildShmemDevStr(virDomainDefPtr def,
8994 8995 8996 8997 8998 8999 9000 9001 9002 9003 9004 9005 9006 9007 9008 9009 9010
                     virDomainShmemDefPtr shmem,
                     virQEMUCapsPtr qemuCaps)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_IVSHMEM)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("ivshmem device is not supported "
                         "with this QEMU binary"));
        goto error;
    }

    virBufferAddLit(&buf, "ivshmem");
    if (shmem->size) {
        /*
         * Thanks to our parsing code, we have a guarantee that the
         * size is power of two and is at least a mebibyte in size.
M
Martin Kletzander 已提交
9011
         * But because it may change in the future, the checks are
9012 9013 9014 9015 9016 9017 9018 9019 9020
         * doubled in here.
         */
        if (shmem->size & (shmem->size - 1)) {
            virReportError(VIR_ERR_XML_ERROR, "%s",
                           _("shmem size must be a power of two"));
            goto error;
        }
        if (shmem->size < 1024 * 1024) {
            virReportError(VIR_ERR_XML_ERROR, "%s",
9021
                           _("shmem size must be at least 1 MiB (1024 KiB)"));
9022 9023
            goto error;
        }
M
Martin Kletzander 已提交
9024
        virBufferAsprintf(&buf, ",size=%llum", shmem->size >> 20);
9025 9026 9027
    }

    if (!shmem->server.enabled) {
9028
        virBufferAsprintf(&buf, ",shm=%s,id=%s", shmem->name, shmem->info.alias);
9029
    } else {
9030
        virBufferAsprintf(&buf, ",chardev=char%s,id=%s", shmem->info.alias, shmem->info.alias);
9031 9032 9033 9034 9035 9036 9037 9038 9039 9040
        if (shmem->msi.enabled) {
            virBufferAddLit(&buf, ",msi=on");
            if (shmem->msi.vectors)
                virBufferAsprintf(&buf, ",vectors=%u", shmem->msi.vectors);
            if (shmem->msi.ioeventfd)
                virBufferAsprintf(&buf, ",ioeventfd=%s",
                                  virTristateSwitchTypeToString(shmem->msi.ioeventfd));
        }
    }

9041 9042 9043 9044 9045 9046 9047
    if (shmem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("only 'pci' addresses are supported for the "
                         "shared memory device"));
        goto error;
    }

9048 9049 9050 9051 9052 9053
    if (qemuBuildDeviceAddressStr(&buf, def, &shmem->info, qemuCaps) < 0)
        goto error;

    if (virBufferCheckError(&buf) < 0)
        goto error;

9054
    return virBufferContentAndReset(&buf);
9055 9056 9057

 error:
    virBufferFreeAndReset(&buf);
9058 9059 9060 9061 9062 9063 9064 9065 9066
    return NULL;
}

char *
qemuBuildShmemBackendStr(virDomainShmemDefPtr shmem,
                         virQEMUCapsPtr qemuCaps)
{
    char *devstr = NULL;

9067 9068
    if (!shmem->server.chr.data.nix.path &&
        virAsprintf(&shmem->server.chr.data.nix.path,
9069 9070 9071 9072
                    "/var/lib/libvirt/shmem-%s-sock",
                    shmem->name) < 0)
        return NULL;

9073
    devstr = qemuBuildChrChardevStr(&shmem->server.chr, shmem->info.alias, qemuCaps);
9074 9075

    return devstr;
9076 9077 9078 9079 9080 9081 9082 9083
}

static int
qemuBuildShmemCommandLine(virCommandPtr cmd,
                          virDomainDefPtr def,
                          virDomainShmemDefPtr shmem,
                          virQEMUCapsPtr qemuCaps)
{
9084 9085 9086
    char *devstr = NULL;

    if (!(devstr = qemuBuildShmemDevStr(def, shmem, qemuCaps)))
9087
        return -1;
9088 9089
    virCommandAddArgList(cmd, "-device", devstr, NULL);
    VIR_FREE(devstr);
9090 9091

    if (shmem->server.enabled) {
9092
        if (!(devstr = qemuBuildShmemBackendStr(shmem, qemuCaps)))
9093 9094
            return -1;

9095
        virCommandAddArgList(cmd, "-chardev", devstr, NULL);
9096 9097 9098 9099 9100 9101
        VIR_FREE(devstr);
    }

    return 0;
}

9102 9103 9104 9105 9106 9107 9108 9109 9110 9111 9112 9113
static int
qemuBuildChrDeviceCommandLine(virCommandPtr cmd,
                              virDomainDefPtr def,
                              virDomainChrDefPtr chr,
                              virQEMUCapsPtr qemuCaps)
{
    char *devstr = NULL;

    if (qemuBuildChrDeviceStr(&devstr, def, chr, qemuCaps) < 0)
        return -1;

    virCommandAddArgList(cmd, "-device", devstr, NULL);
9114
    VIR_FREE(devstr);
9115 9116 9117
    return 0;
}

9118 9119 9120 9121 9122 9123 9124 9125 9126 9127 9128 9129 9130 9131 9132 9133 9134 9135 9136 9137 9138 9139 9140 9141 9142 9143 9144 9145 9146 9147 9148 9149 9150 9151 9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 9162 9163 9164 9165 9166 9167 9168 9169 9170 9171 9172 9173 9174 9175 9176 9177 9178 9179 9180 9181 9182 9183 9184 9185 9186
static int
qemuBuildDomainLoaderCommandLine(virCommandPtr cmd,
                                 virDomainDefPtr def,
                                 virQEMUCapsPtr qemuCaps)
{
    int ret = -1;
    virDomainLoaderDefPtr loader = def->os.loader;
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    int unit = 0;

    if (!loader)
        return 0;

    switch ((virDomainLoader) loader->type) {
    case VIR_DOMAIN_LOADER_TYPE_ROM:
        virCommandAddArg(cmd, "-bios");
        virCommandAddArg(cmd, loader->path);
        break;

    case VIR_DOMAIN_LOADER_TYPE_PFLASH:
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_ACPI) &&
            def->features[VIR_DOMAIN_FEATURE_ACPI] != VIR_TRISTATE_SWITCH_ON) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("ACPI must be enabled in order to use UEFI"));
            goto cleanup;
        }

        virBufferAsprintf(&buf,
                          "file=%s,if=pflash,format=raw,unit=%d",
                          loader->path, unit);
        unit++;

        if (loader->readonly) {
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_READONLY)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("this qemu doesn't support passing "
                                 "readonly attribute"));
                goto cleanup;
            }

            virBufferAsprintf(&buf, ",readonly=%s",
                              virTristateSwitchTypeToString(loader->readonly));
        }

        virCommandAddArg(cmd, "-drive");
        virCommandAddArgBuffer(cmd, &buf);

        if (loader->nvram) {
            virBufferFreeAndReset(&buf);
            virBufferAsprintf(&buf,
                              "file=%s,if=pflash,format=raw,unit=%d",
                              loader->nvram, unit);

            virCommandAddArg(cmd, "-drive");
            virCommandAddArgBuffer(cmd, &buf);
        }
        break;

    case VIR_DOMAIN_LOADER_TYPE_LAST:
        /* nada */
        break;
    }

    ret = 0;
 cleanup:
    virBufferFreeAndReset(&buf);
    return ret;
}

9187 9188 9189 9190 9191 9192 9193
static int
qemuBuildTPMCommandLine(virDomainDefPtr def,
                        virCommandPtr cmd,
                        virQEMUCapsPtr qemuCaps,
                        const char *emulator)
{
    char *optstr;
9194 9195 9196
    int tpmfd = -1;
    int cancelfd = -1;
    char *fdset;
9197

9198 9199
    if (!(optstr = qemuBuildTPMBackendStr(def, cmd, qemuCaps, emulator,
                                          &tpmfd, &cancelfd)))
9200 9201 9202 9203 9204
        return -1;

    virCommandAddArgList(cmd, "-tpmdev", optstr, NULL);
    VIR_FREE(optstr);

9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221 9222
    if (tpmfd >= 0) {
        fdset = qemuVirCommandGetFDSet(cmd, tpmfd);
        if (!fdset)
            return -1;

        virCommandAddArgList(cmd, "-add-fd", fdset, NULL);
        VIR_FREE(fdset);
    }

    if (cancelfd >= 0) {
        fdset = qemuVirCommandGetFDSet(cmd, cancelfd);
        if (!fdset)
            return -1;

        virCommandAddArgList(cmd, "-add-fd", fdset, NULL);
        VIR_FREE(fdset);
    }

9223 9224 9225 9226 9227 9228 9229 9230 9231 9232
    if (!(optstr = qemuBuildTPMDevStr(def, qemuCaps, emulator)))
        return -1;

    virCommandAddArgList(cmd, "-device", optstr, NULL);
    VIR_FREE(optstr);

    return 0;
}


9233 9234 9235 9236
qemuBuildCommandLineCallbacks buildCommandLineCallbacks = {
    .qemuGetSCSIDeviceSgName = virSCSIDeviceGetSgName,
};

9237 9238 9239 9240 9241 9242 9243 9244 9245
/*
 * Constructs a argv suitable for launching qemu with config defined
 * for a given virtual machine.
 *
 * XXX 'conn' is only required to resolve network -> bridge name
 * figure out how to remove this requirement some day
 */
virCommandPtr
qemuBuildCommandLine(virConnectPtr conn,
9246
                     virQEMUDriverPtr driver,
9247 9248 9249
                     virDomainDefPtr def,
                     virDomainChrSourceDefPtr monitor_chr,
                     bool monitor_json,
9250
                     virQEMUCapsPtr qemuCaps,
9251
                     const char *migrateURI,
9252
                     virDomainSnapshotObjPtr snapshot,
9253
                     virNetDevVPortProfileOp vmop,
C
Cole Robinson 已提交
9254
                     qemuBuildCommandLineCallbacksPtr callbacks,
9255
                     bool standalone,
9256
                     bool enableFips,
9257 9258 9259
                     virBitmapPtr nodeset,
                     size_t *nnicindexes,
                     int **nicindexes)
9260
{
9261
    virErrorPtr originalError = NULL;
9262
    size_t i, j;
9263 9264 9265 9266 9267 9268 9269
    const char *emulator;
    char uuid[VIR_UUID_STRING_BUFLEN];
    char *cpu;
    char *smp;
    int last_good_net = -1;
    bool hasHwVirt = false;
    virCommandPtr cmd = NULL;
9270
    bool allowReboot = true;
9271
    bool emitBootindex = false;
9272 9273 9274
    int sdl = 0;
    int vnc = 0;
    int spice = 0;
9275
    int usbcontroller = 0;
M
Martin Kletzander 已提交
9276
    int actualSerials = 0;
9277 9278
    bool usblegacy = false;
    int contOrder[] = {
9279 9280 9281 9282
        /*
         * List of controller types that we add commandline args for,
         * *in the order we want to add them*.
         *
9283 9284 9285
         * The floppy controller is implicit on PIIX4 and older Q35
         * machines. For newer Q35 machines it is added out of the
         * controllers loop, after the floppy drives.
9286
         *
9287 9288 9289
         * We don't add PCI/PCIe root controller either, because it's
         * implicit, but we do add PCI bridges and other PCI
         * controllers, so we leave that in to check each
9290 9291 9292
         * one. Likewise, we don't do anything for the primary IDE
         * controller on an i440fx machine or primary SATA on q35, but
         * we do add those beyond these two exceptions.
9293
         */
9294
        VIR_DOMAIN_CONTROLLER_TYPE_PCI,
9295 9296
        VIR_DOMAIN_CONTROLLER_TYPE_USB,
        VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
9297
        VIR_DOMAIN_CONTROLLER_TYPE_IDE,
9298 9299 9300 9301
        VIR_DOMAIN_CONTROLLER_TYPE_SATA,
        VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL,
        VIR_DOMAIN_CONTROLLER_TYPE_CCID,
    };
9302
    virArch hostarch = virArchFromHost();
9303
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
J
Ján Tomko 已提交
9304
    virBuffer boot_buf = VIR_BUFFER_INITIALIZER;
9305
    char *boot_order_str = NULL, *boot_opts_str = NULL;
9306 9307
    virBuffer fdc_opts = VIR_BUFFER_INITIALIZER;
    char *fdc_opts_str = NULL;
9308 9309
    int bootCD = 0, bootFloppy = 0, bootDisk = 0, bootHostdevNet = 0;

9310

9311
    VIR_DEBUG("conn=%p driver=%p def=%p mon=%p json=%d "
9312
              "qemuCaps=%p migrateURI=%s snapshot=%p vmop=%d",
9313
              conn, driver, def, monitor_chr, monitor_json,
9314
              qemuCaps, migrateURI, snapshot, vmop);
9315

9316 9317 9318 9319
    virUUIDFormat(def->uuid, uuid);

    emulator = def->emulator;

9320
    if (!virQEMUDriverIsPrivileged(driver)) {
9321
        /* If we have no cgroups then we can have no tunings that
9322 9323
         * require them */

9324 9325 9326 9327
        if (virMemoryLimitIsSet(def->mem.hard_limit) ||
            virMemoryLimitIsSet(def->mem.soft_limit) ||
            def->mem.min_guarantee ||
            virMemoryLimitIsSet(def->mem.swap_hard_limit)) {
9328 9329 9330 9331 9332
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Memory tuning is not available in session mode"));
            goto error;
        }

9333
        if (def->blkio.weight) {
9334 9335 9336 9337 9338
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Block I/O tuning is not available in session mode"));
            goto error;
        }

9339
        if (def->cputune.sharesSpecified || def->cputune.period ||
9340 9341 9342 9343 9344 9345 9346 9347
            def->cputune.quota || def->cputune.emulator_period ||
            def->cputune.emulator_quota) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("CPU tuning is not available in session mode"));
            goto error;
        }
    }

9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 9358 9359 9360 9361
    for (i = 0; i < def->ngraphics; ++i) {
        switch (def->graphics[i]->type) {
        case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
            ++sdl;
            break;
        case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
            ++vnc;
            break;
        case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
            ++spice;
            break;
        }
    }

9362 9363 9364 9365
    /*
     * do not use boot=on for drives when not using KVM since this
     * is not supported at all in upstream QEmu.
     */
9366
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) &&
9367
        (def->virtType == VIR_DOMAIN_VIRT_QEMU))
9368
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_DRIVE_BOOT);
9369 9370

    cmd = virCommandNew(emulator);
9371

9372
    virCommandAddEnvPassCommon(cmd);
9373

9374 9375 9376 9377 9378 9379 9380
    virCommandAddArg(cmd, "-name");
    if (cfg->setProcessName &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_NAME_PROCESS)) {
        virCommandAddArgFormat(cmd, "%s,process=qemu:%s",
                               def->name, def->name);
    } else {
        virCommandAddArg(cmd, def->name);
9381
    }
C
Cole Robinson 已提交
9382 9383 9384 9385

    if (!standalone)
        virCommandAddArg(cmd, "-S"); /* freeze CPU */

9386
    if (enableFips)
9387
        virCommandAddArg(cmd, "-enable-fips");
9388

9389
    if (qemuBuildMachineArgStr(cmd, def, qemuCaps) < 0)
9390
        goto error;
9391

9392
    if (qemuBuildCpuArgStr(driver, def, emulator, qemuCaps,
9393
                           hostarch, &cpu, &hasHwVirt, !!migrateURI) < 0)
9394
        goto error;
9395

9396 9397 9398 9399
    if (cpu) {
        virCommandAddArgList(cmd, "-cpu", cpu, NULL);
        VIR_FREE(cpu);

9400
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NESTING) &&
9401 9402
            hasHwVirt)
            virCommandAddArg(cmd, "-enable-nesting");
9403
    }
9404

9405 9406
    if (qemuBuildDomainLoaderCommandLine(cmd, def, qemuCaps) < 0)
        goto error;
9407

9408
    if (!migrateURI && !snapshot &&
9409
        qemuDomainAlignMemorySizes(def) < 0)
9410 9411
        goto error;

9412 9413 9414
    if (qemuDomainDefValidateMemoryHotplug(def, qemuCaps, NULL) < 0)
        goto error;

9415
    virCommandAddArg(cmd, "-m");
9416

9417
    if (virDomainDefHasMemoryHotplug(def)) {
9418 9419 9420 9421 9422 9423 9424 9425 9426
        /* Use the 'k' suffix to let qemu handle the units */
        virCommandAddArgFormat(cmd, "size=%lluk,slots=%u,maxmem=%lluk",
                               virDomainDefGetMemoryInitial(def),
                               def->mem.memory_slots,
                               def->mem.max_memory);

    } else {
       virCommandAddArgFormat(cmd, "%llu", virDomainDefGetMemoryInitial(def) / 1024);
    }
9427

9428 9429 9430 9431 9432 9433 9434
    /*
     * Add '-mem-path' (and '-mem-prealloc') parameter here only if
     * there is no numa node specified.
     */
    if (!virDomainNumaGetNodeCount(def->numa) &&
        qemuBuildMemPathStr(cfg, def, qemuCaps, cmd) < 0)
        goto error;
9435

9436 9437 9438 9439 9440 9441 9442 9443 9444 9445 9446
    if (def->mem.locked && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_MLOCK)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("memory locking not supported by QEMU binary"));
        goto error;
    }
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MLOCK)) {
        virCommandAddArg(cmd, "-realtime");
        virCommandAddArgFormat(cmd, "mlock=%s",
                               def->mem.locked ? "on" : "off");
    }

9447
    virCommandAddArg(cmd, "-smp");
9448
    if (!(smp = qemuBuildSmpArgStr(def, qemuCaps)))
9449 9450 9451 9452
        goto error;
    virCommandAddArg(cmd, smp);
    VIR_FREE(smp);

9453 9454 9455 9456 9457 9458 9459
    if (def->niothreadids) {
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_IOTHREAD)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("IOThreads not supported for this QEMU"));
            goto error;
        }

9460 9461
        /* Create iothread objects using the defined iothreadids list
         * and the defined id and name from the list. These may be used
J
John Ferlan 已提交
9462
         * by a disk definition which will associate to an iothread by
9463
         * supplying a value of an id from the list
J
John Ferlan 已提交
9464
         */
9465
        for (i = 0; i < def->niothreadids; i++) {
J
John Ferlan 已提交
9466
            virCommandAddArg(cmd, "-object");
9467 9468
            virCommandAddArgFormat(cmd, "iothread,id=iothread%u",
                                   def->iothreadids[i]->iothread_id);
J
John Ferlan 已提交
9469 9470 9471
        }
    }

9472 9473
    if (virDomainNumaGetNodeCount(def->numa) &&
        qemuBuildNumaArgStr(cfg, def, cmd, qemuCaps, nodeset) < 0)
9474 9475
            goto error;

9476 9477
    /* memory hotplug requires NUMA to be enabled - we already checked
     * that memory devices are present only when NUMA is */
9478

9479

9480 9481 9482
    for (i = 0; i < def->nmems; i++) {
        char *backStr;
        char *dimmStr;
9483

9484 9485 9486
        if (!(backStr = qemuBuildMemoryDimmBackendStr(def->mems[i], def,
                                                      qemuCaps, cfg)))
            goto error;
9487

9488
        if (!(dimmStr = qemuBuildMemoryDeviceStr(def->mems[i]))) {
9489
            VIR_FREE(backStr);
9490
            goto error;
9491
        }
9492 9493 9494 9495 9496

        virCommandAddArgList(cmd, "-object", backStr, "-device", dimmStr, NULL);

        VIR_FREE(backStr);
        VIR_FREE(dimmStr);
9497 9498
    }

9499
    virCommandAddArgList(cmd, "-uuid", uuid, NULL);
9500
    if (def->virtType == VIR_DOMAIN_VIRT_XEN ||
9501 9502
        def->os.type == VIR_DOMAIN_OSTYPE_XEN ||
        def->os.type == VIR_DOMAIN_OSTYPE_LINUX) {
9503 9504 9505 9506
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("qemu emulator '%s' does not support xen"),
                       def->emulator);
        goto error;
9507 9508
    }

9509 9510 9511 9512 9513
    if ((def->os.smbios_mode != VIR_DOMAIN_SMBIOS_NONE) &&
        (def->os.smbios_mode != VIR_DOMAIN_SMBIOS_EMULATE)) {
        virSysinfoDefPtr source = NULL;
        bool skip_uuid = false;

9514
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SMBIOS_TYPE)) {
9515 9516 9517
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("the QEMU binary %s does not support smbios settings"),
                           emulator);
9518 9519 9520
            goto error;
        }

9521 9522 9523
        /* should we really error out or just warn in those cases ? */
        if (def->os.smbios_mode == VIR_DOMAIN_SMBIOS_HOST) {
            if (driver->hostsysinfo == NULL) {
9524
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
9525
                               _("Host SMBIOS information is not available"));
9526
                goto error;
9527
            }
9528 9529 9530 9531 9532 9533 9534 9535 9536
            source = driver->hostsysinfo;
            /* Host and guest uuid must differ, by definition of UUID. */
            skip_uuid = true;
        } else if (def->os.smbios_mode == VIR_DOMAIN_SMBIOS_SYSINFO) {
            if (def->sysinfo == NULL) {
                virReportError(VIR_ERR_XML_ERROR,
                               _("Domain '%s' sysinfo are not available"),
                               def->name);
                goto error;
9537
            }
9538 9539
            source = def->sysinfo;
            /* domain_conf guaranteed that system_uuid matches guest uuid. */
9540
        }
9541 9542
        if (source != NULL) {
            char *smbioscmd;
9543

9544
            smbioscmd = qemuBuildSmbiosBiosStr(source->bios);
9545 9546 9547
            if (smbioscmd != NULL) {
                virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
                VIR_FREE(smbioscmd);
9548
            }
9549
            smbioscmd = qemuBuildSmbiosSystemStr(source->system, skip_uuid);
9550 9551 9552
            if (smbioscmd != NULL) {
                virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
                VIR_FREE(smbioscmd);
9553
            }
9554 9555 9556 9557 9558 9559 9560 9561 9562 9563 9564 9565 9566 9567 9568

            if (source->nbaseBoard > 1) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("qemu does not support more than "
                                 "one entry to Type 2 in SMBIOS table"));
                goto error;
            }

            for (i = 0; i < source->nbaseBoard; i++) {
                if (!(smbioscmd = qemuBuildSmbiosBaseBoardStr(source->baseBoard + i)))
                    goto error;

                virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
                VIR_FREE(smbioscmd);
            }
9569
        }
9570
    }
9571

9572 9573 9574 9575 9576 9577 9578
    /*
     * NB, -nographic *MUST* come before any serial, or monitor
     * or parallel port flags due to QEMU craziness, where it
     * decides to change the serial port & monitor to be on stdout
     * if you ask for nographic. So we have to make sure we override
     * these defaults ourselves...
     */
9579
    if (!def->graphics) {
9580
        virCommandAddArg(cmd, "-nographic");
9581

9582
        if (cfg->nogfxAllowHostAudio)
9583
            virCommandAddEnvPassBlockSUID(cmd, "QEMU_AUDIO_DRV", NULL);
9584 9585 9586 9587
        else
            virCommandAddEnvString(cmd, "QEMU_AUDIO_DRV=none");
    }

9588
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
9589
        /* Disable global config files and default devices */
9590
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_USER_CONFIG))
9591
            virCommandAddArg(cmd, "-no-user-config");
9592
        else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NODEFCONFIG))
9593 9594
            virCommandAddArg(cmd, "-nodefconfig");
        virCommandAddArg(cmd, "-nodefaults");
9595 9596
    }

9597
    /* Serial graphics adapter */
J
Ján Tomko 已提交
9598
    if (def->os.bios.useserial == VIR_TRISTATE_BOOL_YES) {
9599
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
9600 9601 9602 9603
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("qemu does not support -device"));
            goto error;
        }
9604
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGA)) {
9605 9606 9607 9608 9609 9610 9611
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("qemu does not support SGA"));
            goto error;
        }
        if (!def->nserials) {
            virReportError(VIR_ERR_XML_ERROR, "%s",
                           _("need at least one serial port to use SGA"));
9612 9613
            goto error;
        }
9614
        virCommandAddArgList(cmd, "-device", "sga", NULL);
9615 9616
    }

9617 9618 9619
    if (monitor_chr) {
        char *chrdev;
        /* Use -chardev if it's available */
9620
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV)) {
J
Jim Fehlig 已提交
9621

9622 9623
            virCommandAddArg(cmd, "-chardev");
            if (!(chrdev = qemuBuildChrChardevStr(monitor_chr, "monitor",
9624
                                                  qemuCaps)))
9625 9626 9627
                goto error;
            virCommandAddArg(cmd, chrdev);
            VIR_FREE(chrdev);
9628

9629 9630 9631 9632 9633 9634 9635 9636
            virCommandAddArg(cmd, "-mon");
            virCommandAddArgFormat(cmd,
                                   "chardev=charmonitor,id=monitor,mode=%s",
                                   monitor_json ? "control" : "readline");
        } else {
            const char *prefix = NULL;
            if (monitor_json)
                prefix = "control,";
9637

9638 9639 9640 9641 9642
            virCommandAddArg(cmd, "-monitor");
            if (!(chrdev = qemuBuildChrArgStr(monitor_chr, prefix)))
                goto error;
            virCommandAddArg(cmd, chrdev);
            VIR_FREE(chrdev);
9643 9644 9645
        }
    }

9646
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_RTC)) {
9647
        char *rtcopt;
9648 9649 9650 9651 9652 9653 9654 9655 9656 9657 9658
        virCommandAddArg(cmd, "-rtc");
        if (!(rtcopt = qemuBuildClockArgStr(&def->clock)))
            goto error;
        virCommandAddArg(cmd, rtcopt);
        VIR_FREE(rtcopt);
    } else {
        switch (def->clock.offset) {
        case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME:
        case VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE:
            virCommandAddArg(cmd, "-localtime");
            break;
9659

9660 9661 9662
        case VIR_DOMAIN_CLOCK_OFFSET_UTC:
            /* Nothing, its the default */
            break;
9663

9664 9665 9666 9667
        default:
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("unsupported clock offset '%s'"),
                           virDomainClockOffsetTypeToString(def->clock.offset));
9668
            goto error;
9669 9670 9671 9672 9673
        }
    }
    if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE &&
        def->clock.data.timezone) {
        virCommandAddEnvPair(cmd, "TZ", def->clock.data.timezone);
9674 9675
    }

9676
    for (i = 0; i < def->clock.ntimers; i++) {
9677
        switch ((virDomainTimerNameType) def->clock.timers[i]->name) {
9678 9679 9680 9681 9682 9683
        case VIR_DOMAIN_TIMER_NAME_PLATFORM:
        case VIR_DOMAIN_TIMER_NAME_TSC:
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("unsupported timer type (name) '%s'"),
                           virDomainTimerNameTypeToString(def->clock.timers[i]->name));
            goto error;
9684

9685
        case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
9686 9687 9688
        case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK:
            /* Timers above are handled when building -cpu.  */
        case VIR_DOMAIN_TIMER_NAME_LAST:
9689 9690 9691 9692 9693 9694
            break;

        case VIR_DOMAIN_TIMER_NAME_RTC:
            /* This has already been taken care of (in qemuBuildClockArgStr)
               if QEMU_CAPS_RTC is set (mutually exclusive with
               QEMUD_FLAG_RTC_TD_HACK) */
9695
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_RTC_TD_HACK)) {
9696 9697 9698 9699
                switch (def->clock.timers[i]->tickpolicy) {
                case -1:
                case VIR_DOMAIN_TIMER_TICKPOLICY_DELAY:
                    /* the default - do nothing */
9700
                    break;
9701 9702
                case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP:
                    virCommandAddArg(cmd, "-rtc-td-hack");
9703
                    break;
9704 9705 9706 9707 9708
                case VIR_DOMAIN_TIMER_TICKPOLICY_MERGE:
                case VIR_DOMAIN_TIMER_TICKPOLICY_DISCARD:
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("unsupported rtc tickpolicy '%s'"),
                                   virDomainTimerTickpolicyTypeToString(def->clock.timers[i]->tickpolicy));
J
Ján Tomko 已提交
9709
                    goto error;
9710
                }
9711 9712 9713 9714
            } else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_RTC) &&
                       (def->clock.timers[i]->tickpolicy
                        != VIR_DOMAIN_TIMER_TICKPOLICY_DELAY) &&
                       (def->clock.timers[i]->tickpolicy != -1)) {
9715 9716 9717 9718 9719 9720
                /* a non-default rtc policy was given, but there is no
                   way to implement it in this version of qemu */
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("unsupported rtc tickpolicy '%s'"),
                               virDomainTimerTickpolicyTypeToString(def->clock.timers[i]->tickpolicy));
                goto error;
9721
            }
9722
            break;
9723

9724 9725 9726 9727 9728 9729
        case VIR_DOMAIN_TIMER_NAME_PIT:
            switch (def->clock.timers[i]->tickpolicy) {
            case -1:
            case VIR_DOMAIN_TIMER_TICKPOLICY_DELAY:
                /* delay is the default if we don't have kernel
                   (-no-kvm-pit), otherwise, the default is catchup. */
9730 9731 9732 9733
                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM_PIT_TICK_POLICY))
                    virCommandAddArgList(cmd, "-global",
                                         "kvm-pit.lost_tick_policy=discard", NULL);
                else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_KVM_PIT))
9734 9735 9736
                    virCommandAddArg(cmd, "-no-kvm-pit-reinjection");
                break;
            case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP:
9737 9738
                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_KVM_PIT) ||
                    virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM_PIT_TICK_POLICY)) {
9739
                    /* do nothing - this is default for kvm-pit */
9740
                } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_TDF)) {
9741 9742
                    /* -tdf switches to 'catchup' with userspace pit. */
                    virCommandAddArg(cmd, "-tdf");
9743
                } else {
9744 9745 9746 9747
                    /* can't catchup if we have neither pit mode */
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("unsupported pit tickpolicy '%s'"),
                                   virDomainTimerTickpolicyTypeToString(def->clock.timers[i]->tickpolicy));
9748 9749 9750
                    goto error;
                }
                break;
9751 9752 9753 9754 9755 9756 9757
            case VIR_DOMAIN_TIMER_TICKPOLICY_MERGE:
            case VIR_DOMAIN_TIMER_TICKPOLICY_DISCARD:
                /* no way to support these modes for pit in qemu */
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("unsupported pit tickpolicy '%s'"),
                               virDomainTimerTickpolicyTypeToString(def->clock.timers[i]->tickpolicy));
                goto error;
9758
            }
9759
            break;
9760

9761 9762 9763 9764 9765 9766 9767
        case VIR_DOMAIN_TIMER_NAME_HPET:
            /* the only meaningful attribute for hpet is "present". If
             * present is -1, that means it wasn't specified, and
             * should be left at the default for the
             * hypervisor. "default" when -no-hpet exists is "yes",
             * and when -no-hpet doesn't exist is "no". "confusing"?
             * "yes"! */
9768

9769
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_HPET)) {
9770 9771 9772 9773 9774 9775 9776
                if (def->clock.timers[i]->present == 0)
                    virCommandAddArg(cmd, "-no-hpet");
            } else {
                /* no hpet timer available. The only possible action
                   is to raise an error if present="yes" */
                if (def->clock.timers[i]->present == 1) {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
9777 9778
                                   "%s", _("hpet timer is not supported"));
                    goto error;
9779 9780
                }
            }
9781 9782 9783
            break;
        }
    }
9784

9785 9786 9787 9788 9789 9790 9791
    /* Only add -no-reboot option if each event destroys domain */
    if (def->onReboot == VIR_DOMAIN_LIFECYCLE_DESTROY &&
        def->onPoweroff == VIR_DOMAIN_LIFECYCLE_DESTROY &&
        (def->onCrash == VIR_DOMAIN_LIFECYCLE_CRASH_DESTROY ||
         def->onCrash == VIR_DOMAIN_LIFECYCLE_CRASH_COREDUMP_DESTROY)) {
        allowReboot = false;
        virCommandAddArg(cmd, "-no-reboot");
9792
    }
9793

9794 9795 9796 9797
    /* If JSON monitor is enabled, we can receive an event
     * when QEMU stops. If we use no-shutdown, then we can
     * watch for this event and do a soft/warm reboot.
     */
9798 9799
    if (monitor_json && allowReboot &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) {
9800
        virCommandAddArg(cmd, "-no-shutdown");
9801
    }
9802

9803
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_ACPI)) {
J
Ján Tomko 已提交
9804
        if (def->features[VIR_DOMAIN_FEATURE_ACPI] != VIR_TRISTATE_SWITCH_ON)
9805 9806
            virCommandAddArg(cmd, "-no-acpi");
    }
9807

9808
    if (def->pm.s3) {
9809
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DISABLE_S3)) {
9810 9811 9812
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("setting ACPI S3 not supported"));
            goto error;
9813
        }
9814 9815
        virCommandAddArg(cmd, "-global");
        virCommandAddArgFormat(cmd, "PIIX4_PM.disable_s3=%d",
J
Ján Tomko 已提交
9816
                               def->pm.s3 == VIR_TRISTATE_BOOL_NO);
9817 9818 9819
    }

    if (def->pm.s4) {
9820
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DISABLE_S4)) {
9821
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
9822 9823 9824 9825 9826
                           "%s", _("setting ACPI S4 not supported"));
            goto error;
        }
        virCommandAddArg(cmd, "-global");
        virCommandAddArgFormat(cmd, "PIIX4_PM.disable_s4=%d",
J
Ján Tomko 已提交
9827
                               def->pm.s4 == VIR_TRISTATE_BOOL_NO);
9828
    }
9829

J
Ján Tomko 已提交
9830 9831 9832 9833 9834 9835 9836 9837
    /*
     * We prefer using explicit bootindex=N parameters for predictable
     * results even though domain XML doesn't use per device boot elements.
     * However, we can't use bootindex if boot menu was requested.
     */
    if (!def->os.nBootDevs) {
        /* def->os.nBootDevs is guaranteed to be > 0 unless per-device boot
         * configuration is used
9838
         */
J
Ján Tomko 已提交
9839 9840 9841 9842
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("hypervisor lacks deviceboot feature"));
            goto error;
9843
        }
J
Ján Tomko 已提交
9844 9845 9846 9847 9848 9849
        emitBootindex = true;
    } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX) &&
               (def->os.bootmenu != VIR_TRISTATE_BOOL_YES ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_MENU))) {
        emitBootindex = true;
    }
9850

J
Ján Tomko 已提交
9851 9852
    if (!emitBootindex) {
        char boot[VIR_DOMAIN_BOOT_LAST+1];
9853

J
Ján Tomko 已提交
9854 9855 9856 9857 9858 9859 9860 9861 9862 9863 9864 9865 9866 9867 9868 9869 9870
        for (i = 0; i < def->os.nBootDevs; i++) {
            switch (def->os.bootDevs[i]) {
            case VIR_DOMAIN_BOOT_CDROM:
                boot[i] = 'd';
                break;
            case VIR_DOMAIN_BOOT_FLOPPY:
                boot[i] = 'a';
                break;
            case VIR_DOMAIN_BOOT_DISK:
                boot[i] = 'c';
                break;
            case VIR_DOMAIN_BOOT_NET:
                boot[i] = 'n';
                break;
            default:
                boot[i] = 'c';
                break;
9871 9872
            }
        }
J
Ján Tomko 已提交
9873
        boot[def->os.nBootDevs] = '\0';
9874

J
Ján Tomko 已提交
9875
        virBufferAsprintf(&boot_buf, "%s", boot);
9876 9877 9878
        if (virBufferCheckError(&boot_buf) < 0)
            goto error;
        boot_order_str = virBufferContentAndReset(&boot_buf);
J
Ján Tomko 已提交
9879
    }
9880

J
Ján Tomko 已提交
9881 9882 9883
    if (def->os.bootmenu) {
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_MENU)) {
            if (def->os.bootmenu == VIR_TRISTATE_BOOL_YES)
9884
                virBufferAddLit(&boot_buf, "menu=on,");
J
Ján Tomko 已提交
9885
            else
9886
                virBufferAddLit(&boot_buf, "menu=off,");
J
Ján Tomko 已提交
9887 9888 9889 9890 9891
        } else {
            /* We cannot emit an error when bootmenu is enabled but
             * unsupported because of backward compatibility */
            VIR_WARN("bootmenu is enabled but not "
                     "supported by this QEMU binary");
9892
        }
J
Ján Tomko 已提交
9893
    }
9894

J
Ján Tomko 已提交
9895 9896 9897 9898 9899 9900 9901
    if (def->os.bios.rt_set) {
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_REBOOT_TIMEOUT)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("reboot timeout is not supported "
                             "by this QEMU binary"));
            goto error;
        }
9902

J
Ján Tomko 已提交
9903
        virBufferAsprintf(&boot_buf,
9904
                          "reboot-timeout=%d,",
J
Ján Tomko 已提交
9905 9906
                          def->os.bios.rt_delay);
    }
9907

J
Ján Tomko 已提交
9908 9909 9910 9911 9912 9913
    if (def->os.bm_timeout_set) {
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPLASH_TIMEOUT)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("splash timeout is not supported "
                             "by this QEMU binary"));
            goto error;
9914 9915
        }

9916
        virBufferAsprintf(&boot_buf, "splash-time=%u,", def->os.bm_timeout);
J
Ján Tomko 已提交
9917
    }
9918

9919 9920 9921 9922
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_STRICT))
        virBufferAddLit(&boot_buf, "strict=on,");

    virBufferTrim(&boot_buf, ",", -1);
J
Ján Tomko 已提交
9923

9924 9925
    if (virBufferCheckError(&boot_buf) < 0)
        goto error;
J
Ján Tomko 已提交
9926

9927 9928 9929
    boot_opts_str = virBufferContentAndReset(&boot_buf);
    if (boot_order_str || boot_opts_str) {
        virCommandAddArg(cmd, "-boot");
J
Ján Tomko 已提交
9930

9931 9932 9933 9934 9935 9936 9937
        if (boot_order_str && boot_opts_str) {
            virCommandAddArgFormat(cmd, "order=%s,%s",
                                   boot_order_str, boot_opts_str);
        } else if (boot_order_str) {
            virCommandAddArg(cmd, boot_order_str);
        } else if (boot_opts_str) {
            virCommandAddArg(cmd, boot_opts_str);
9938
        }
J
Ján Tomko 已提交
9939
    }
9940
    VIR_FREE(boot_opts_str);
9941
    VIR_FREE(boot_order_str);
9942

J
Ján Tomko 已提交
9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9954 9955
    if (def->os.kernel)
        virCommandAddArgList(cmd, "-kernel", def->os.kernel, NULL);
    if (def->os.initrd)
        virCommandAddArgList(cmd, "-initrd", def->os.initrd, NULL);
    if (def->os.cmdline)
        virCommandAddArgList(cmd, "-append", def->os.cmdline, NULL);
    if (def->os.dtb) {
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DTB)) {
            virCommandAddArgList(cmd, "-dtb", def->os.dtb, NULL);
        } else {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("dtb is not supported with this QEMU binary"));
            goto error;
O
Olivia Yin 已提交
9956
        }
9957
    }
9958

9959 9960 9961 9962 9963 9964 9965 9966 9967 9968 9969 9970 9971 9972 9973 9974 9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990 9991 9992 9993 9994 9995 9996 9997 9998 9999 10000 10001 10002 10003 10004 10005
    for (i = 0; i < def->ncontrollers; i++) {
        virDomainControllerDefPtr cont = def->controllers[i];
        if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI &&
            cont->opts.pciopts.pcihole64) {
            const char *hoststr = NULL;
            bool cap = false;
            bool machine = false;

            switch (cont->model) {
            case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
                hoststr = "i440FX-pcihost";
                cap = virQEMUCapsGet(qemuCaps, QEMU_CAPS_I440FX_PCI_HOLE64_SIZE);
                machine = qemuDomainMachineIsI440FX(def);
                break;

            case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
                hoststr = "q35-pcihost";
                cap = virQEMUCapsGet(qemuCaps, QEMU_CAPS_Q35_PCI_HOLE64_SIZE);
                machine = qemuDomainMachineIsQ35(def);
                break;

            default:
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("64-bit PCI hole setting is only for root"
                                 " PCI controllers"));
                goto error;
            }

            if (!machine) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                             _("Setting the 64-bit PCI hole size is not "
                             "supported for machine '%s'"), def->os.machine);
                goto error;
            }
            if (!cap) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("64-bit PCI hole size setting is not supported "
                                 "with this QEMU binary"));
                goto error;
            }

            virCommandAddArg(cmd, "-global");
            virCommandAddArgFormat(cmd, "%s.pci-hole64-size=%luK", hoststr,
                                   cont->opts.pciopts.pcihole64size);
        }
    }

10006
    for (i = 0; i < def->ndisks; i++) {
10007
        virDomainDiskDefPtr disk = def->disks[i];
10008

10009
        if (disk->src->driverName != NULL &&
10010
            STRNEQ(disk->src->driverName, "qemu")) {
10011 10012
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("unsupported driver name '%s' for disk '%s'"),
10013
                           disk->src->driverName, disk->src->path);
10014 10015 10016 10017
            goto error;
        }
    }

10018
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10019 10020 10021
        for (j = 0; j < ARRAY_CARDINALITY(contOrder); j++) {
            for (i = 0; i < def->ncontrollers; i++) {
                virDomainControllerDefPtr cont = def->controllers[i];
10022
                char *devstr;
10023

10024 10025
                if (cont->type != contOrder[j])
                    continue;
10026

10027
                /* skip USB controllers with type none.*/
10028 10029 10030 10031 10032 10033
                if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
                    cont->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE) {
                    usbcontroller = -1; /* mark we don't want a controller */
                    continue;
                }

10034
                /* skip pci-root/pcie-root */
10035
                if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI &&
L
Laine Stump 已提交
10036
                    (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT ||
10037
                     cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT))
10038 10039
                    continue;

10040 10041 10042
                /* first SATA controller on Q35 machines is implicit */
                if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_SATA &&
                    cont->idx == 0 && qemuDomainMachineIsQ35(def))
10043
                        continue;
10044

10045
                /* first IDE controller is implicit on various machines */
10046
                if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE &&
10047
                    cont->idx == 0 && qemuDomainMachineHasBuiltinIDE(def))
10048 10049
                        continue;

10050 10051 10052 10053 10054 10055
                if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
                    cont->model == -1 &&
                    !qemuDomainMachineIsQ35(def) &&
                    (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI) ||
                     (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_OHCI) &&
                      ARCH_IS_PPC64(def->os.arch)))) {
10056 10057 10058 10059
                    if (usblegacy) {
                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                       _("Multiple legacy USB controllers are "
                                         "not supported"));
10060 10061
                        goto error;
                    }
10062
                    usblegacy = true;
10063
                    continue;
10064
                }
10065 10066 10067 10068 10069 10070 10071

                virCommandAddArg(cmd, "-device");
                if (!(devstr = qemuBuildControllerDevStr(def, cont, qemuCaps,
                                                         &usbcontroller)))
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
10072
            }
10073 10074
        }
    }
10075

10076 10077 10078
    if (usbcontroller == 0 &&
        !qemuDomainMachineIsQ35(def) &&
        !ARCH_IS_S390(def->os.arch))
10079
        virCommandAddArg(cmd, "-usb");
10080

10081
    for (i = 0; i < def->nhubs; i++) {
10082 10083
        virDomainHubDefPtr hub = def->hubs[i];
        char *optstr;
10084

10085
        virCommandAddArg(cmd, "-device");
10086
        if (!(optstr = qemuBuildHubDevStr(def, hub, qemuCaps)))
10087 10088 10089 10090
            goto error;
        virCommandAddArg(cmd, optstr);
        VIR_FREE(optstr);
    }
10091

10092 10093 10094 10095 10096 10097 10098 10099 10100 10101 10102 10103 10104 10105
    if ((virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_BOOT) || emitBootindex)) {
        /* bootDevs will get translated into either bootindex=N or boot=on
         * depending on what qemu supports */
        for (i = 0; i < def->os.nBootDevs; i++) {
            switch (def->os.bootDevs[i]) {
            case VIR_DOMAIN_BOOT_CDROM:
                bootCD = i + 1;
                break;
            case VIR_DOMAIN_BOOT_FLOPPY:
                bootFloppy = i + 1;
                break;
            case VIR_DOMAIN_BOOT_DISK:
                bootDisk = i + 1;
                break;
10106
            }
10107
        }
10108
    }
10109

10110 10111 10112 10113 10114 10115 10116 10117 10118 10119 10120 10121 10122 10123 10124 10125 10126 10127
    for (i = 0; i < def->ndisks; i++) {
        char *optstr;
        int bootindex = 0;
        virDomainDiskDefPtr disk = def->disks[i];
        bool withDeviceArg = false;
        bool deviceFlagMasked = false;

        /* Unless we have -device, then USB disks need special
           handling */
        if ((disk->bus == VIR_DOMAIN_DISK_BUS_USB) &&
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
            if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
                virCommandAddArg(cmd, "-usbdevice");
                virCommandAddArgFormat(cmd, "disk:%s", disk->src->path);
            } else {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("unsupported usb disk type for '%s'"),
                               disk->src->path);
10128 10129
                goto error;
            }
10130 10131
            continue;
        }
10132

10133 10134 10135 10136 10137 10138 10139 10140 10141 10142 10143 10144 10145 10146 10147 10148 10149 10150 10151 10152 10153 10154 10155 10156 10157 10158 10159 10160 10161 10162 10163 10164 10165 10166 10167 10168 10169 10170
        /* PowerPC pseries based VMs do not support floppy device */
        if ((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) &&
            ARCH_IS_PPC64(def->os.arch) && STRPREFIX(def->os.machine, "pseries")) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("PowerPC pseries machines do not support floppy device"));
            goto error;
        }

        switch (disk->device) {
        case VIR_DOMAIN_DISK_DEVICE_CDROM:
            bootindex = bootCD;
            bootCD = 0;
            break;
        case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
            bootindex = bootFloppy;
            bootFloppy = 0;
            break;
        case VIR_DOMAIN_DISK_DEVICE_DISK:
        case VIR_DOMAIN_DISK_DEVICE_LUN:
            bootindex = bootDisk;
            bootDisk = 0;
            break;
        }

        virCommandAddArg(cmd, "-drive");

        /* Unfortunately it is not possible to use
           -device for floppies, xen PV, or SD
           devices. Fortunately, those don't need
           static PCI addresses, so we don't really
           care that we can't use -device */
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
            if (disk->bus != VIR_DOMAIN_DISK_BUS_XEN &&
                disk->bus != VIR_DOMAIN_DISK_BUS_SD) {
                withDeviceArg = true;
            } else {
                virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE);
                deviceFlagMasked = true;
10171
            }
10172 10173 10174 10175 10176 10177 10178 10179 10180 10181
        }
        optstr = qemuBuildDriveStr(conn, disk,
                                   emitBootindex ? false : !!bootindex,
                                   qemuCaps);
        if (deviceFlagMasked)
            virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE);
        if (!optstr)
            goto error;
        virCommandAddArg(cmd, optstr);
        VIR_FREE(optstr);
10182

10183 10184 10185 10186
        if (!emitBootindex)
            bootindex = 0;
        else if (disk->info.bootIndex)
            bootindex = disk->info.bootIndex;
10187

10188 10189 10190 10191 10192 10193 10194 10195 10196 10197
        if (withDeviceArg) {
            if (disk->bus == VIR_DOMAIN_DISK_BUS_FDC) {
                if (virAsprintf(&optstr, "drive%c=drive-%s",
                                disk->info.addr.drive.unit ? 'B' : 'A',
                                disk->info.alias) < 0)
                    goto error;

                if (!qemuDomainMachineNeedsFDC(def)) {
                    virCommandAddArg(cmd, "-global");
                    virCommandAddArgFormat(cmd, "isa-fdc.%s", optstr);
10198
                } else {
10199
                    virBufferAsprintf(&fdc_opts, "%s,", optstr);
10200
                }
10201
                VIR_FREE(optstr);
10202

10203 10204 10205 10206 10207
                if (bootindex) {
                    if (virAsprintf(&optstr, "bootindex%c=%d",
                                    disk->info.addr.drive.unit
                                    ? 'B' : 'A',
                                    bootindex) < 0)
J
Ján Tomko 已提交
10208 10209
                        goto error;

10210 10211 10212 10213 10214 10215
                    if (!qemuDomainMachineNeedsFDC(def)) {
                        virCommandAddArg(cmd, "-global");
                        virCommandAddArgFormat(cmd, "isa-fdc.%s", optstr);
                    } else {
                        virBufferAsprintf(&fdc_opts, "%s,", optstr);
                    }
J
Ján Tomko 已提交
10216
                    VIR_FREE(optstr);
E
Eric Blake 已提交
10217 10218
                }
            } else {
10219
                virCommandAddArg(cmd, "-device");
E
Eric Blake 已提交
10220

10221 10222
                if (!(optstr = qemuBuildDriveDevStr(def, disk, bootindex,
                                                    qemuCaps)))
10223
                    goto error;
10224 10225
                virCommandAddArg(cmd, optstr);
                VIR_FREE(optstr);
E
Eric Blake 已提交
10226 10227 10228
            }
        }
    }
10229 10230 10231 10232 10233 10234 10235
    /* Newer Q35 machine types require an explicit FDC controller */
    virBufferTrim(&fdc_opts, ",", -1);
    if ((fdc_opts_str = virBufferContentAndReset(&fdc_opts))) {
        virCommandAddArg(cmd, "-device");
        virCommandAddArgFormat(cmd, "isa-fdc,%s", fdc_opts_str);
        VIR_FREE(fdc_opts_str);
    }
E
Eric Blake 已提交
10236

10237
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_FSDEV)) {
10238
        for (i = 0; i < def->nfss; i++) {
10239 10240
            char *optstr;
            virDomainFSDefPtr fs = def->fss[i];
10241

10242
            virCommandAddArg(cmd, "-fsdev");
10243
            if (!(optstr = qemuBuildFSStr(fs, qemuCaps)))
10244 10245 10246
                goto error;
            virCommandAddArg(cmd, optstr);
            VIR_FREE(optstr);
10247

10248
            virCommandAddArg(cmd, "-device");
10249
            if (!(optstr = qemuBuildFSDevStr(def, fs, qemuCaps)))
10250 10251 10252 10253 10254 10255 10256 10257 10258
                goto error;
            virCommandAddArg(cmd, optstr);
            VIR_FREE(optstr);
        }
    } else {
        if (def->nfss) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("filesystem passthrough not supported by this QEMU"));
            goto error;
10259 10260 10261
        }
    }

10262
    if (!def->nnets) {
10263
        /* If we have -device, then we set -nodefault already */
10264
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
10265
            virCommandAddArgList(cmd, "-net", "none", NULL);
10266
    } else {
10267
        int bootNet = 0;
10268

10269 10270 10271 10272
        if (emitBootindex) {
            /* convert <boot dev='network'/> to bootindex since we didn't emit
             * -boot n
             */
10273
            for (i = 0; i < def->os.nBootDevs; i++) {
10274 10275 10276 10277
                if (def->os.bootDevs[i] == VIR_DOMAIN_BOOT_NET) {
                    bootNet = i + 1;
                    break;
                }
10278 10279 10280
            }
        }

10281
        for (i = 0; i < def->nnets; i++) {
10282
            virDomainNetDefPtr net = def->nets[i];
10283
            int vlan;
10284

10285
            /* VLANs are not used with -netdev, so don't record them */
10286
            if (qemuDomainSupportsNetdev(def, qemuCaps, net))
10287
                vlan = -1;
10288 10289
            else
                vlan = i;
10290

10291
            if (qemuBuildInterfaceCommandLine(cmd, driver, def, net,
10292
                                              qemuCaps, vlan, bootNet, vmop,
10293
                                              standalone, nnicindexes, nicindexes) < 0)
10294
                goto error;
10295

10296
            last_good_net = i;
10297 10298 10299 10300 10301 10302 10303 10304 10305 10306
            /* if this interface is a type='hostdev' interface and we
             * haven't yet added a "bootindex" parameter to an
             * emulated network device, save the bootindex - hostdev
             * interface commandlines will be built later on when we
             * cycle through all the hostdevs, and we'll use it then.
             */
            if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_HOSTDEV &&
                bootHostdevNet == 0) {
                bootHostdevNet = bootNet;
            }
10307
            bootNet = 0;
10308 10309 10310
        }
    }

10311 10312 10313 10314 10315
    if (def->nsmartcards) {
        /* -device usb-ccid was already emitted along with other
         * controllers.  For now, qemu handles only one smartcard.  */
        virDomainSmartcardDefPtr smartcard = def->smartcards[0];
        char *devstr;
10316
        virBuffer opt = VIR_BUFFER_INITIALIZER;
10317
        const char *database;
10318

10319 10320 10321 10322
        if (def->nsmartcards > 1 ||
            smartcard->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID ||
            smartcard->info.addr.ccid.controller != 0 ||
            smartcard->info.addr.ccid.slot != 0) {
10323
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
10324 10325 10326
                           _("this QEMU binary lacks multiple smartcard "
                             "support"));
            virBufferFreeAndReset(&opt);
10327 10328 10329
            goto error;
        }

10330 10331
        switch (smartcard->type) {
        case VIR_DOMAIN_SMARTCARD_TYPE_HOST:
10332 10333
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) {
10334 10335 10336 10337
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("this QEMU binary lacks smartcard host "
                                 "mode support"));
                goto error;
10338 10339
            }

10340 10341
            virBufferAddLit(&opt, "ccid-card-emulated,backend=nss-emulated");
            break;
10342

10343
        case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES:
10344 10345
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) {
10346 10347 10348 10349 10350
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("this QEMU binary lacks smartcard host "
                                 "mode support"));
                goto error;
            }
10351

10352 10353 10354 10355
            virBufferAddLit(&opt, "ccid-card-emulated,backend=certificates");
            for (j = 0; j < VIR_DOMAIN_SMARTCARD_NUM_CERTIFICATES; j++) {
                if (strchr(smartcard->data.cert.file[j], ',')) {
                    virBufferFreeAndReset(&opt);
10356
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
10357 10358
                                   _("invalid certificate name: %s"),
                                   smartcard->data.cert.file[j]);
10359 10360
                    goto error;
                }
10361
                virBufferAsprintf(&opt, ",cert%zu=%s", j + 1,
10362 10363 10364 10365 10366 10367 10368 10369
                                  smartcard->data.cert.file[j]);
            }
            if (smartcard->data.cert.database) {
                if (strchr(smartcard->data.cert.database, ',')) {
                    virBufferFreeAndReset(&opt);
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("invalid database name: %s"),
                                   smartcard->data.cert.database);
10370 10371
                    goto error;
                }
10372 10373 10374
                database = smartcard->data.cert.database;
            } else {
                database = VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE;
10375
            }
10376
            virBufferAsprintf(&opt, ",db=%s", database);
10377
            break;
10378

10379
        case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
10380 10381
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_PASSTHRU)) {
10382 10383 10384 10385
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("this QEMU binary lacks smartcard "
                                 "passthrough mode support"));
                goto error;
10386 10387
            }

10388 10389 10390
            virCommandAddArg(cmd, "-chardev");
            if (!(devstr = qemuBuildChrChardevStr(&smartcard->data.passthru,
                                                  smartcard->info.alias,
10391
                                                  qemuCaps))) {
10392 10393
                virBufferFreeAndReset(&opt);
                goto error;
10394
            }
10395 10396
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);
10397

10398 10399 10400
            virBufferAsprintf(&opt, "ccid-card-passthru,chardev=char%s",
                              smartcard->info.alias);
            break;
10401

10402 10403 10404 10405 10406
        default:
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("unexpected smartcard type %d"),
                           smartcard->type);
            virBufferFreeAndReset(&opt);
10407 10408
            goto error;
        }
10409 10410 10411 10412
        virCommandAddArg(cmd, "-device");
        virBufferAsprintf(&opt, ",id=%s,bus=ccid0.0", smartcard->info.alias);
        virCommandAddArgBuffer(cmd, &opt);
    }
10413

10414 10415 10416
    for (i = 0; i < def->nserials; i++) {
        virDomainChrDefPtr serial = def->serials[i];
        char *devstr;
10417

10418 10419 10420
        if (serial->source.type == VIR_DOMAIN_CHR_TYPE_SPICEPORT && !spice)
            continue;

10421 10422 10423 10424 10425 10426 10427 10428 10429 10430 10431 10432 10433 10434 10435 10436 10437 10438
        /* Use -chardev with -device if they are available */
        if (virQEMUCapsSupportsChardev(def, qemuCaps, serial)) {
            virCommandAddArg(cmd, "-chardev");
            if (!(devstr = qemuBuildChrChardevStr(&serial->source,
                                                  serial->info.alias,
                                                  qemuCaps)))
                goto error;
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);

            if (qemuBuildChrDeviceCommandLine(cmd, def, serial, qemuCaps) < 0)
                goto error;
        } else {
            virCommandAddArg(cmd, "-serial");
            if (!(devstr = qemuBuildChrArgStr(&serial->source, NULL)))
                goto error;
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);
10439
        }
10440
        actualSerials++;
10441
    }
10442

M
Martin Kletzander 已提交
10443 10444 10445 10446
    /* If we have -device, then we set -nodefault already */
    if (!actualSerials && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
            virCommandAddArgList(cmd, "-serial", "none", NULL);

10447 10448
    if (!def->nparallels) {
        /* If we have -device, then we set -nodefault already */
10449
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
10450 10451
            virCommandAddArgList(cmd, "-parallel", "none", NULL);
    } else {
10452
        for (i = 0; i < def->nparallels; i++) {
10453 10454
            virDomainChrDefPtr parallel = def->parallels[i];
            char *devstr;
10455

10456
            /* Use -chardev with -device if they are available */
10457 10458
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) &&
                virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10459 10460 10461
                virCommandAddArg(cmd, "-chardev");
                if (!(devstr = qemuBuildChrChardevStr(&parallel->source,
                                                      parallel->info.alias,
10462
                                                      qemuCaps)))
10463 10464 10465
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
10466

10467 10468
                if (qemuBuildChrDeviceCommandLine(cmd, def, parallel, qemuCaps) < 0)
                    goto error;
10469 10470 10471
            } else {
                virCommandAddArg(cmd, "-parallel");
                if (!(devstr = qemuBuildChrArgStr(&parallel->source, NULL)))
10472
                    goto error;
10473 10474 10475
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
            }
10476
        }
10477
    }
10478

10479
    for (i = 0; i < def->nchannels; i++) {
10480 10481
        virDomainChrDefPtr channel = def->channels[i];
        char *devstr;
10482

10483 10484
        switch (channel->targetType) {
        case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD:
10485 10486
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10487 10488
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("guestfwd requires QEMU to support -chardev & -device"));
10489 10490
                goto error;
            }
10491

10492 10493 10494
            virCommandAddArg(cmd, "-chardev");
            if (!(devstr = qemuBuildChrChardevStr(&channel->source,
                                                  channel->info.alias,
10495
                                                  qemuCaps)))
10496 10497 10498 10499
                goto error;
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);

10500
            if (qemuBuildChrDeviceStr(&devstr, def, channel, qemuCaps) < 0)
10501
                goto error;
10502 10503
            virCommandAddArgList(cmd, "-netdev", devstr, NULL);
            VIR_FREE(devstr);
10504 10505
            break;

10506
        case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO:
10507
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10508 10509
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("virtio channel requires QEMU to support -device"));
10510 10511
                goto error;
            }
10512

10513 10514 10515 10516 10517 10518 10519 10520 10521 10522 10523 10524 10525 10526 10527 10528 10529
            /*
             * TODO: Refactor so that we generate this (and onther
             * things) somewhere else then where we are building the
             * command line.
             */
            if (channel->source.type == VIR_DOMAIN_CHR_TYPE_UNIX &&
                !channel->source.data.nix.path) {
                if (virAsprintf(&channel->source.data.nix.path,
                                "%s/domain-%s/%s",
                                cfg->channelTargetDir, def->name,
                                channel->target.name ? channel->target.name
                                : "unknown.sock") < 0)
                    goto error;

                channel->source.data.nix.listen = true;
            }

10530
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC) &&
10531 10532 10533 10534 10535 10536 10537 10538 10539
                channel->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC) {
                /* spicevmc was originally introduced via a -device
                 * with a backend internal to qemu; although we prefer
                 * the newer -chardev interface.  */
                ;
            } else {
                virCommandAddArg(cmd, "-chardev");
                if (!(devstr = qemuBuildChrChardevStr(&channel->source,
                                                      channel->info.alias,
10540
                                                      qemuCaps)))
10541 10542 10543
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
10544
            }
10545

10546
            if (qemuBuildChrDeviceCommandLine(cmd, def, channel, qemuCaps) < 0)
10547
                goto error;
10548 10549
            break;
        }
10550
    }
10551

10552
    /* Explicit console devices */
10553
    for (i = 0; i < def->nconsoles; i++) {
10554 10555
        virDomainChrDefPtr console = def->consoles[i];
        char *devstr;
10556

10557
        switch (console->targetType) {
10558 10559
        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLP:
        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLPLM:
10560
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10561 10562 10563 10564
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("sclp console requires QEMU to support -device"));
                goto error;
            }
10565
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCLP_S390)) {
10566 10567 10568 10569 10570 10571 10572 10573
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("sclp console requires QEMU to support s390-sclp"));
                goto error;
            }

            virCommandAddArg(cmd, "-chardev");
            if (!(devstr = qemuBuildChrChardevStr(&console->source,
                                                  console->info.alias,
10574
                                                  qemuCaps)))
10575 10576 10577 10578
                goto error;
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);

10579
            if (qemuBuildChrDeviceCommandLine(cmd, def, console, qemuCaps) < 0)
10580 10581 10582
                goto error;
            break;

10583
        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO:
10584
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10585 10586 10587
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("virtio channel requires QEMU to support -device"));
                goto error;
P
Peng Zhou 已提交
10588 10589
            }

10590 10591 10592
            virCommandAddArg(cmd, "-chardev");
            if (!(devstr = qemuBuildChrChardevStr(&console->source,
                                                  console->info.alias,
10593
                                                  qemuCaps)))
10594 10595 10596
                goto error;
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);
10597

10598
            if (qemuBuildChrDeviceCommandLine(cmd, def, console, qemuCaps) < 0)
10599
                goto error;
10600
            break;
10601 10602

        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL:
10603
            break;
10604 10605 10606 10607 10608 10609

        default:
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("unsupported console target type %s"),
                           NULLSTR(virDomainChrConsoleTargetTypeToString(console->targetType)));
            goto error;
10610
        }
10611
    }
10612

10613
    if (def->tpm) {
10614
        if (qemuBuildTPMCommandLine(def, cmd, qemuCaps, emulator) < 0)
10615 10616 10617
            goto error;
    }

10618
    for (i = 0; i < def->ninputs; i++) {
10619 10620 10621
        virDomainInputDefPtr input = def->inputs[i];

        if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) {
10622
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10623 10624
                char *optstr;
                virCommandAddArg(cmd, "-device");
10625
                if (!(optstr = qemuBuildUSBInputDevStr(def, input, qemuCaps)))
10626
                    goto error;
10627 10628 10629
                virCommandAddArg(cmd, optstr);
                VIR_FREE(optstr);
            } else {
10630 10631 10632 10633 10634 10635 10636 10637 10638 10639 10640
                switch (input->type) {
                    case VIR_DOMAIN_INPUT_TYPE_MOUSE:
                        virCommandAddArgList(cmd, "-usbdevice", "mouse", NULL);
                        break;
                    case VIR_DOMAIN_INPUT_TYPE_TABLET:
                        virCommandAddArgList(cmd, "-usbdevice", "tablet", NULL);
                        break;
                    case VIR_DOMAIN_INPUT_TYPE_KBD:
                        virCommandAddArgList(cmd, "-usbdevice", "keyboard", NULL);
                        break;
                }
10641
            }
10642 10643 10644 10645 10646 10647 10648
        } else if (input->bus == VIR_DOMAIN_INPUT_BUS_VIRTIO) {
            char *optstr;
            virCommandAddArg(cmd, "-device");
            if (!(optstr = qemuBuildVirtioInputDevStr(def, input, qemuCaps)))
                goto error;
            virCommandAddArg(cmd, optstr);
            VIR_FREE(optstr);
10649
        }
10650
    }
10651

10652 10653 10654 10655
    if (sdl > 1 || vnc > 1 || spice > 1) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("only 1 graphics device of each type "
                         "(sdl, vnc, spice) is supported"));
10656 10657 10658
        goto error;
    }

10659
    for (i = 0; i < def->ngraphics; ++i) {
10660
        if (qemuBuildGraphicsCommandLine(cfg, cmd, def, qemuCaps,
10661 10662 10663
                                         def->graphics[i]) < 0)
            goto error;
    }
10664

10665
    if (def->nvideos > 0) {
10666
        int primaryVideoType = def->videos[0]->type;
10667
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY) &&
10668
             ((primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_VGA &&
10669
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VGA)) ||
10670
             (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_CIRRUS &&
10671
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_CIRRUS_VGA)) ||
10672
             (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_VMVGA &&
10673
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMWARE_SVGA)) ||
10674
             (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_QXL &&
M
Marc-André Lureau 已提交
10675 10676 10677 10678
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL_VGA)) ||
             (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_VIRTIO &&
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU)))
            ) {
10679
            for (i = 0; i < def->nvideos; i++) {
10680 10681
                char *str;
                virCommandAddArg(cmd, "-device");
10682
                if (!(str = qemuBuildDeviceVideoStr(def, def->videos[i], qemuCaps, !i)))
10683 10684 10685 10686 10687
                    goto error;

                virCommandAddArg(cmd, str);
                VIR_FREE(str);
            }
10688
        } else {
10689
            if (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_XEN) {
10690 10691
                /* nothing - vga has no effect on Xen pvfb */
            } else {
10692
                if ((primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_QXL) &&
10693
                    !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA_QXL)) {
10694 10695
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("This QEMU does not support QXL graphics adapters"));
10696 10697 10698
                    goto error;
                }

10699
                const char *vgastr = qemuVideoTypeToString(primaryVideoType);
10700
                if (!vgastr || STREQ(vgastr, "")) {
10701 10702
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("video type %s is not supported with QEMU"),
10703
                                   virDomainVideoTypeToString(primaryVideoType));
10704 10705 10706 10707
                    goto error;
                }

                virCommandAddArgList(cmd, "-vga", vgastr, NULL);
10708

10709 10710 10711 10712 10713 10714 10715 10716 10717 10718 10719 10720 10721
                /* If we cannot use --device option to specify the video device
                 * in QEMU we will fallback to the old --vga option. To get the
                 * correct device name for the --vga option the 'qemuVideo' is
                 * used, but to set some device attributes we need to use the
                 * --global option and for that we need to specify the device
                 * name the same as for --device option and for that we need to
                 * use 'qemuDeviceVideo'.
                 *
                 * See 'Graphics Devices' section in docs/qdev-device-use.txt in
                 * QEMU repository.
                 */
                const char *dev = qemuDeviceVideoTypeToString(primaryVideoType);

10722 10723
                if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_QXL &&
                    (def->videos[0]->vram || def->videos[0]->ram) &&
10724
                    virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10725 10726
                    unsigned int ram = def->videos[0]->ram;
                    unsigned int vram = def->videos[0]->vram;
10727
                    unsigned int vgamem = def->videos[0]->vgamem;
10728 10729 10730 10731 10732 10733 10734 10735 10736 10737 10738 10739 10740

                    if (vram > (UINT_MAX / 1024)) {
                        virReportError(VIR_ERR_OVERFLOW,
                               _("value for 'vram' must be less than '%u'"),
                                       UINT_MAX / 1024);
                        goto error;
                    }
                    if (ram > (UINT_MAX / 1024)) {
                        virReportError(VIR_ERR_OVERFLOW,
                           _("value for 'ram' must be less than '%u'"),
                                       UINT_MAX / 1024);
                        goto error;
                    }
10741

10742
                    if (ram) {
E
Eric Blake 已提交
10743
                        virCommandAddArg(cmd, "-global");
10744 10745 10746 10747 10748 10749 10750
                        virCommandAddArgFormat(cmd, "%s.ram_size=%u",
                                               dev, ram * 1024);
                    }
                    if (vram) {
                        virCommandAddArg(cmd, "-global");
                        virCommandAddArgFormat(cmd, "%s.vram_size=%u",
                                               dev, vram * 1024);
10751
                    }
10752 10753 10754 10755 10756 10757
                    if (vgamem &&
                        virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_VGA_VGAMEM)) {
                        virCommandAddArg(cmd, "-global");
                        virCommandAddArgFormat(cmd, "%s.vgamem_mb=%u",
                                               dev, vgamem / 1024);
                    }
10758
                }
10759 10760 10761 10762 10763 10764 10765 10766 10767 10768 10769 10770 10771 10772 10773 10774 10775 10776 10777 10778

                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) &&
                    def->videos[0]->vram &&
                    ((primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_VGA &&
                      virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA_VGAMEM)) ||
                     (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_VMVGA &&
                      virQEMUCapsGet(qemuCaps, QEMU_CAPS_VMWARE_SVGA_VGAMEM)))) {
                    unsigned int vram = def->videos[0]->vram;

                    if (vram < 1024) {
                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                       "%s", _("value for 'vgamem' must be at "
                                               "least 1 MiB (1024 KiB)"));
                        goto error;
                    }

                    virCommandAddArg(cmd, "-global");
                    virCommandAddArgFormat(cmd, "%s.vgamem_mb=%u",
                                           dev, vram / 1024);
                }
10779
            }
10780 10781

            if (def->nvideos > 1) {
10782
                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10783
                    for (i = 1; i < def->nvideos; i++) {
10784 10785 10786 10787 10788 10789 10790 10791 10792 10793
                        char *str;
                        if (def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_QXL) {
                            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                           _("video type %s is only valid as primary video card"),
                                           virDomainVideoTypeToString(def->videos[0]->type));
                            goto error;
                        }

                        virCommandAddArg(cmd, "-device");

10794
                        if (!(str = qemuBuildDeviceVideoStr(def, def->videos[i], qemuCaps, false)))
10795 10796 10797 10798 10799 10800 10801 10802 10803 10804 10805
                            goto error;

                        virCommandAddArg(cmd, str);
                        VIR_FREE(str);
                    }
                } else {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   "%s", _("only one video card is currently supported"));
                    goto error;
                }
            }
10806 10807 10808 10809
        }

    } else {
        /* If we have -device, then we set -nodefault already */
10810 10811
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) &&
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA_NONE))
10812 10813 10814 10815 10816
            virCommandAddArgList(cmd, "-vga", "none", NULL);
    }

    /* Add sound hardware */
    if (def->nsounds) {
10817
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10818
            for (i = 0; i < def->nsounds; i++) {
10819 10820 10821 10822 10823 10824 10825 10826 10827 10828
                virDomainSoundDefPtr sound = def->sounds[i];
                char *str = NULL;

                /* Sadly pcspk device doesn't use -device syntax. Fortunately
                 * we don't need to set any PCI address on it, so we don't
                 * mind too much */
                if (sound->model == VIR_DOMAIN_SOUND_MODEL_PCSPK) {
                    virCommandAddArgList(cmd, "-soundhw", "pcspk", NULL);
                } else {
                    virCommandAddArg(cmd, "-device");
10829
                    if (!(str = qemuBuildSoundDevStr(def, sound, qemuCaps)))
10830 10831 10832
                        goto error;

                    virCommandAddArg(cmd, str);
10833
                    VIR_FREE(str);
10834 10835
                    if (sound->model == VIR_DOMAIN_SOUND_MODEL_ICH6 ||
                        sound->model == VIR_DOMAIN_SOUND_MODEL_ICH9) {
10836 10837
                        char *codecstr = NULL;

10838
                        for (j = 0; j < sound->ncodecs; j++) {
10839
                            virCommandAddArg(cmd, "-device");
10840
                            if (!(codecstr = qemuBuildSoundCodecStr(sound, sound->codecs[j], qemuCaps))) {
10841
                                goto error;
10842

10843 10844 10845 10846
                            }
                            virCommandAddArg(cmd, codecstr);
                            VIR_FREE(codecstr);
                        }
10847
                        if (j == 0) {
10848 10849 10850 10851 10852
                            virDomainSoundCodecDef codec = {
                                VIR_DOMAIN_SOUND_CODEC_TYPE_DUPLEX,
                                0
                            };
                            virCommandAddArg(cmd, "-device");
10853
                            if (!(codecstr = qemuBuildSoundCodecStr(sound, &codec, qemuCaps))) {
10854 10855 10856 10857 10858 10859
                                goto error;

                            }
                            virCommandAddArg(cmd, codecstr);
                            VIR_FREE(codecstr);
                        }
10860
                    }
10861 10862 10863 10864 10865
                }
            }
        } else {
            int size = 100;
            char *modstr;
10866
            if (VIR_ALLOC_N(modstr, size+1) < 0)
10867
                goto error;
10868

10869
            for (i = 0; i < def->nsounds && size > 0; i++) {
10870 10871 10872 10873
                virDomainSoundDefPtr sound = def->sounds[i];
                const char *model = virDomainSoundModelTypeToString(sound->model);
                if (!model) {
                    VIR_FREE(modstr);
10874 10875
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   "%s", _("invalid sound model"));
10876 10877
                    goto error;
                }
10878

10879 10880
                if (sound->model == VIR_DOMAIN_SOUND_MODEL_ICH6 ||
                    sound->model == VIR_DOMAIN_SOUND_MODEL_ICH9) {
A
Alex Jia 已提交
10881
                    VIR_FREE(modstr);
10882 10883
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("this QEMU binary lacks hda support"));
10884 10885 10886
                    goto error;
                }

10887 10888 10889 10890 10891 10892 10893 10894 10895 10896 10897 10898 10899 10900 10901
                strncat(modstr, model, size);
                size -= strlen(model);
                if (i < (def->nsounds - 1))
                    strncat(modstr, ",", size--);
            }
            virCommandAddArgList(cmd, "-soundhw", modstr, NULL);
            VIR_FREE(modstr);
        }
    }

    /* Add watchdog hardware */
    if (def->watchdog) {
        virDomainWatchdogDefPtr watchdog = def->watchdog;
        char *optstr;

10902
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10903 10904
            virCommandAddArg(cmd, "-device");

10905
            optstr = qemuBuildWatchdogDevStr(def, watchdog, qemuCaps);
10906 10907 10908 10909 10910 10911 10912
            if (!optstr)
                goto error;
        } else {
            virCommandAddArg(cmd, "-watchdog");

            const char *model = virDomainWatchdogModelTypeToString(watchdog->model);
            if (!model) {
10913 10914
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               "%s", _("missing watchdog model"));
10915 10916 10917
                goto error;
            }

10918 10919
            if (VIR_STRDUP(optstr, model) < 0)
                goto error;
10920 10921 10922 10923 10924 10925 10926 10927 10928
        }
        virCommandAddArg(cmd, optstr);
        VIR_FREE(optstr);

        int act = watchdog->action;
        if (act == VIR_DOMAIN_WATCHDOG_ACTION_DUMP)
            act = VIR_DOMAIN_WATCHDOG_ACTION_PAUSE;
        const char *action = virDomainWatchdogActionTypeToString(act);
        if (!action) {
10929 10930
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("invalid watchdog action"));
10931 10932 10933 10934 10935
            goto error;
        }
        virCommandAddArgList(cmd, "-watchdog-action", action, NULL);
    }

10936
    /* Add redirected devices */
10937
    for (i = 0; i < def->nredirdevs; i++) {
10938 10939 10940 10941 10942 10943
        virDomainRedirdevDefPtr redirdev = def->redirdevs[i];
        char *devstr;

        virCommandAddArg(cmd, "-chardev");
        if (!(devstr = qemuBuildChrChardevStr(&redirdev->source.chr,
                                              redirdev->info.alias,
10944
                                              qemuCaps))) {
10945 10946 10947 10948 10949 10950
            goto error;
        }

        virCommandAddArg(cmd, devstr);
        VIR_FREE(devstr);

10951 10952 10953
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("redirected devices are not supported by this QEMU"));
10954
            goto error;
10955 10956
        }

10957 10958

        virCommandAddArg(cmd, "-device");
10959
        if (!(devstr = qemuBuildRedirdevDevStr(def, redirdev, qemuCaps)))
10960 10961 10962 10963 10964
            goto error;
        virCommandAddArg(cmd, devstr);
        VIR_FREE(devstr);
    }

10965
    /* Add host passthrough hardware */
10966
    for (i = 0; i < def->nhostdevs; i++) {
10967 10968 10969
        virDomainHostdevDefPtr hostdev = def->hostdevs[i];
        char *devstr;

10970
        if (hostdev->info->bootIndex) {
10971
            if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
10972
                (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
10973 10974
                 hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
                 hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)) {
10975
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
10976
                               _("booting from assigned devices is only "
10977
                                 "supported for PCI, USB and SCSI devices"));
10978
                goto error;
10979
            } else {
10980 10981
                if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
                    if (hostdev->source.subsys.u.pci.backend
10982
                        == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
10983 10984 10985 10986 10987 10988 10989 10990 10991 10992 10993 10994 10995 10996
                        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VFIO_PCI_BOOTINDEX)) {
                            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                           _("booting from PCI devices assigned with VFIO "
                                             "is not supported with this version of qemu"));
                            goto error;
                        }
                    } else {
                        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_BOOTINDEX)) {
                            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                           _("booting from assigned PCI devices is not "
                                             "supported with this version of qemu"));
                            goto error;
                        }
                    }
10997 10998
                }
                if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
10999
                    !virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_HOST_BOOTINDEX)) {
11000
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
11001 11002
                                   _("booting from assigned USB devices is not "
                                     "supported with this version of qemu"));
11003 11004
                    goto error;
                }
11005 11006 11007 11008 11009 11010 11011
                if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI &&
                    !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SCSI_GENERIC_BOOTINDEX)) {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("booting from assigned SCSI devices is not"
                                     " supported with this version of qemu"));
                    goto error;
                }
11012 11013 11014
            }
        }

11015 11016 11017 11018
        /* USB */
        if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
            hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {

11019
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
11020
                virCommandAddArg(cmd, "-device");
11021
                if (!(devstr = qemuBuildUSBHostdevDevStr(def, hostdev, qemuCaps)))
11022 11023 11024 11025 11026
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
            } else {
                virCommandAddArg(cmd, "-usbdevice");
11027
                if (!(devstr = qemuBuildUSBHostdevUSBDevStr(hostdev)))
11028 11029 11030 11031 11032 11033 11034 11035 11036
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
            }
        }

        /* PCI */
        if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
            hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
11037
            int backend = hostdev->source.subsys.u.pci.backend;
11038

11039
            if (backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
11040 11041 11042 11043 11044 11045
                if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("VFIO PCI device assignment is not "
                                     "supported by this version of qemu"));
                    goto error;
                }
11046 11047
            }

11048
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
11049
                char *configfd_name = NULL;
11050 11051 11052 11053 11054 11055 11056 11057 11058 11059
                int bootIndex = hostdev->info->bootIndex;

                /* bootNet will be non-0 if boot order was set and no other
                 * net devices were encountered
                 */
                if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET &&
                    bootIndex == 0) {
                    bootIndex = bootHostdevNet;
                    bootHostdevNet = 0;
                }
11060
                if ((backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) &&
11061
                    virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
11062 11063 11064 11065 11066
                    int configfd = qemuOpenPCIConfig(hostdev);

                    if (configfd >= 0) {
                        if (virAsprintf(&configfd_name, "%d", configfd) < 0) {
                            VIR_FORCE_CLOSE(configfd);
11067
                            goto error;
11068 11069
                        }

11070 11071
                        virCommandPassFD(cmd, configfd,
                                         VIR_COMMAND_PASS_FD_CLOSE_PARENT);
11072 11073 11074
                    }
                }
                virCommandAddArg(cmd, "-device");
11075 11076
                devstr = qemuBuildPCIHostdevDevStr(def, hostdev, bootIndex,
                                                   configfd_name, qemuCaps);
11077 11078 11079 11080 11081
                VIR_FREE(configfd_name);
                if (!devstr)
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
11082
            } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCIDEVICE)) {
11083
                virCommandAddArg(cmd, "-pcidevice");
11084
                if (!(devstr = qemuBuildPCIHostdevPCIDevStr(hostdev, qemuCaps)))
11085 11086 11087 11088
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
            } else {
11089 11090
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("PCI device assignment is not supported by this version of qemu"));
11091 11092 11093
                goto error;
            }
        }
11094 11095 11096 11097

        /* SCSI */
        if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
            hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {
11098
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) &&
11099 11100 11101 11102
                virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SCSI_GENERIC)) {
                char *drvstr;

                virCommandAddArg(cmd, "-drive");
11103
                if (!(drvstr = qemuBuildSCSIHostdevDrvStr(conn, hostdev, qemuCaps, callbacks)))
11104 11105 11106 11107 11108 11109 11110 11111 11112 11113 11114 11115 11116 11117 11118
                    goto error;
                virCommandAddArg(cmd, drvstr);
                VIR_FREE(drvstr);

                virCommandAddArg(cmd, "-device");
                if (!(devstr = qemuBuildSCSIHostdevDevStr(def, hostdev, qemuCaps)))
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
            } else {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("SCSI passthrough is not supported by this version of qemu"));
                goto error;
            }
        }
11119 11120
    }

11121
    if (migrateURI)
11122
        virCommandAddArgList(cmd, "-incoming", migrateURI, NULL);
11123 11124 11125 11126 11127 11128 11129

    /* QEMU changed its default behavior to not include the virtio balloon
     * device.  Explicitly request it to ensure it will be present.
     *
     * NB: Earlier we declared that VirtIO balloon will always be in
     * slot 0x3 on bus 0x0
     */
11130 11131
    if (STREQLEN(def->os.machine, "s390-virtio", 10) &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390) && def->memballoon)
11132 11133 11134 11135
        def->memballoon->model = VIR_DOMAIN_MEMBALLOON_MODEL_NONE;

    if (def->memballoon &&
        def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_NONE) {
11136
        if (def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO) {
11137 11138 11139
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("Memory balloon device type '%s' is not supported by this version of qemu"),
                           virDomainMemballoonModelTypeToString(def->memballoon->model));
11140 11141
            goto error;
        }
11142
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
11143 11144 11145
            char *optstr;
            virCommandAddArg(cmd, "-device");

11146
            optstr = qemuBuildMemballoonDevStr(def, def->memballoon, qemuCaps);
11147 11148 11149 11150
            if (!optstr)
                goto error;
            virCommandAddArg(cmd, optstr);
            VIR_FREE(optstr);
11151
        } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BALLOON)) {
11152 11153 11154 11155
            virCommandAddArgList(cmd, "-balloon", "virtio", NULL);
        }
    }

11156
    for (i = 0; i < def->nrngs; i++) {
11157 11158 11159 11160 11161 11162 11163 11164 11165 11166 11167 11168 11169 11170 11171 11172 11173 11174
        virDomainRNGDefPtr rng = def->rngs[i];
        char *tmp;

        if (!rng->info.alias) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("RNG device is missing alias"));
            goto error;
        }

        /* possibly add character device for backend */
        if (qemuBuildRNGBackendChrdevStr(rng, qemuCaps, &tmp) < 0)
            goto error;

        if (tmp) {
            virCommandAddArgList(cmd, "-chardev", tmp, NULL);
            VIR_FREE(tmp);
        }

11175
        /* add the RNG source backend */
11176
        if (!(tmp = qemuBuildRNGBackendStr(rng, qemuCaps)))
11177 11178
            goto error;

11179 11180 11181
        virCommandAddArgList(cmd, "-object", tmp, NULL);
        VIR_FREE(tmp);

11182
        /* add the device */
11183
        if (!(tmp = qemuBuildRNGDevStr(def, rng, qemuCaps)))
11184
            goto error;
11185 11186
        virCommandAddArgList(cmd, "-device", tmp, NULL);
        VIR_FREE(tmp);
11187 11188
    }

11189
    if (def->nvram) {
11190
        if (ARCH_IS_PPC64(def->os.arch) &&
11191
            STRPREFIX(def->os.machine, "pseries")) {
11192 11193 11194 11195 11196 11197 11198 11199 11200 11201 11202 11203 11204 11205 11206 11207 11208 11209 11210 11211 11212
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVRAM)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("nvram device is not supported by "
                                 "this QEMU binary"));
                goto error;
            }

            char *optstr;
            virCommandAddArg(cmd, "-global");
            optstr = qemuBuildNVRAMDevStr(def->nvram);
            if (!optstr)
                goto error;
            if (optstr)
                virCommandAddArg(cmd, optstr);
            VIR_FREE(optstr);
        } else {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                          _("nvram device is only supported for PPC64"));
            goto error;
        }
    }
11213 11214
    if (snapshot)
        virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL);
11215 11216 11217 11218 11219 11220 11221 11222 11223 11224 11225 11226 11227

    if (def->namespaceData) {
        qemuDomainCmdlineDefPtr qemucmd;

        qemucmd = def->namespaceData;
        for (i = 0; i < qemucmd->num_args; i++)
            virCommandAddArg(cmd, qemucmd->args[i]);
        for (i = 0; i < qemucmd->num_env; i++)
            virCommandAddEnvPair(cmd, qemucmd->env_name[i],
                                 qemucmd->env_value[i]
                                 ? qemucmd->env_value[i] : "");
    }

11228
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SECCOMP_SANDBOX)) {
11229
        if (cfg->seccompSandbox == 0)
11230
            virCommandAddArgList(cmd, "-sandbox", "off", NULL);
11231
        else if (cfg->seccompSandbox > 0)
11232
            virCommandAddArgList(cmd, "-sandbox", "on", NULL);
11233
    } else if (cfg->seccompSandbox > 0) {
11234 11235 11236 11237 11238
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("QEMU does not support seccomp sandboxes"));
        goto error;
    }

D
Dmitry Andreev 已提交
11239 11240
    for (i = 0; i < def->npanics; i++) {
        switch ((virDomainPanicModel) def->panics[i]->model) {
11241 11242 11243 11244 11245 11246 11247 11248 11249 11250
        case VIR_DOMAIN_PANIC_MODEL_HYPERV:
            /* Panic with model 'hyperv' is not a device, it should
             * be configured in cpu commandline. The address
             * cannot be configured by the user */
            if (!ARCH_IS_X86(def->os.arch)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("only i686 and x86_64 guests support "
                                 "panic device of model 'hyperv'"));
                goto error;
            }
D
Dmitry Andreev 已提交
11251
            if (def->panics[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
11252 11253 11254 11255 11256 11257 11258 11259
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("setting the panic device address is not "
                                 "supported for model 'hyperv'"));
                goto error;
            }
            break;

        case VIR_DOMAIN_PANIC_MODEL_PSERIES:
11260 11261 11262
            /* For pSeries guests, the firmware provides the same
             * functionality as the pvpanic device. The address
             * cannot be configured by the user */
11263 11264 11265 11266 11267 11268 11269
            if (!ARCH_IS_PPC64(def->os.arch) ||
                !STRPREFIX(def->os.machine, "pseries")) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("only pSeries guests support panic device "
                                 "of model 'pseries'"));
                goto error;
            }
D
Dmitry Andreev 已提交
11270
            if (def->panics[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
11271 11272
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("setting the panic device address is not "
11273
                                 "supported for model 'pseries'"));
11274 11275
                goto error;
            }
11276 11277 11278
            break;

        case VIR_DOMAIN_PANIC_MODEL_ISA:
11279 11280 11281 11282 11283 11284 11285
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PANIC)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("the QEMU binary does not support the "
                                 "panic device"));
                goto error;
            }

D
Dmitry Andreev 已提交
11286
            switch (def->panics[i]->info.type) {
11287
            case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA:
H
Hu Tao 已提交
11288 11289
                virCommandAddArg(cmd, "-device");
                virCommandAddArgFormat(cmd, "pvpanic,ioport=%d",
D
Dmitry Andreev 已提交
11290
                                       def->panics[i]->info.addr.isa.iobase);
11291 11292 11293
                break;

            case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE:
H
Hu Tao 已提交
11294
                virCommandAddArgList(cmd, "-device", "pvpanic", NULL);
11295 11296 11297
                break;

            default:
11298 11299 11300 11301
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("panic is supported only "
                                 "with ISA address type"));
                goto error;
H
Hu Tao 已提交
11302
            }
11303 11304 11305 11306 11307

        /* default model value was changed before in post parse */
        case VIR_DOMAIN_PANIC_MODEL_DEFAULT:
        case VIR_DOMAIN_PANIC_MODEL_LAST:
            break;
H
Hu Tao 已提交
11308 11309 11310
        }
    }

11311 11312 11313 11314 11315
    for (i = 0; i < def->nshmems; i++) {
        if (qemuBuildShmemCommandLine(cmd, def, def->shmems[i], qemuCaps))
            goto error;
    }

11316 11317
    /* In some situations, eg. VFIO passthrough, QEMU might need to lock a
     * significant amount of memory, so we need to set the limit accordingly */
11318 11319
    if (qemuDomainRequiresMemLock(def))
        virCommandSetMaxMemLock(cmd, qemuDomainGetMemLockLimitBytes(def));
11320

11321 11322 11323 11324
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSG_TIMESTAMP) &&
        cfg->logTimestamp)
        virCommandAddArgList(cmd, "-msg", "timestamp=on", NULL);

11325
    virObjectUnref(cfg);
11326 11327
    return cmd;

11328
 error:
11329
    VIR_FREE(boot_order_str);
11330
    VIR_FREE(boot_opts_str);
J
Ján Tomko 已提交
11331
    virBufferFreeAndReset(&boot_buf);
11332
    virObjectUnref(cfg);
11333 11334 11335
    /* free up any resources in the network driver
     * but don't overwrite the original error */
    originalError = virSaveLastError();
11336
    for (i = 0; last_good_net != -1 && i <= last_good_net; i++)
11337
        virDomainConfNWFilterTeardown(def->nets[i]);
11338
    virSetError(originalError);
J
John Ferlan 已提交
11339
    virFreeError(originalError);
11340 11341 11342 11343
    virCommandFree(cmd);
    return NULL;
}

11344 11345 11346
/* This function generates the correct '-device' string for character
 * devices of each architecture.
 */
11347 11348
static int
qemuBuildSerialChrDeviceStr(char **deviceStr,
11349
                            virDomainDefPtr def,
11350 11351 11352 11353
                            virDomainChrDefPtr serial,
                            virQEMUCapsPtr qemuCaps,
                            virArch arch,
                            char *machine)
11354 11355 11356
{
    virBuffer cmd = VIR_BUFFER_INITIALIZER;

11357
    if (ARCH_IS_PPC64(arch) && STRPREFIX(machine, "pseries")) {
11358 11359 11360 11361
        if (serial->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
            serial->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO) {
            virBufferAsprintf(&cmd, "spapr-vty,chardev=char%s",
                              serial->info.alias);
11362
            if (qemuBuildDeviceAddressStr(&cmd, def, &serial->info, qemuCaps) < 0)
11363 11364
                goto error;
        }
G
Guannan Ren 已提交
11365 11366 11367
    } else {
        virBufferAsprintf(&cmd, "%s,chardev=char%s,id=%s",
                          virDomainChrSerialTargetTypeToString(serial->targetType),
11368 11369
                          serial->info.alias, serial->info.alias);

11370 11371
        switch (serial->targetType) {
        case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB:
11372
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_SERIAL)) {
G
Guannan Ren 已提交
11373 11374 11375 11376 11377 11378 11379 11380 11381 11382 11383 11384
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("usb-serial is not supported in this QEMU binary"));
                goto error;
            }

            if (serial->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
                serial->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("usb-serial requires address of usb type"));
                goto error;
            }

11385
            if (qemuBuildDeviceAddressStr(&cmd, def, &serial->info, qemuCaps) < 0)
11386
                goto error;
11387 11388 11389
            break;

        case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_ISA:
11390 11391
            if (serial->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
                serial->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA) {
11392
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
11393
                               _("isa-serial requires address of isa type"));
11394 11395
                goto error;
            }
11396 11397 11398

            if (qemuBuildDeviceAddressStr(&cmd, def, &serial->info, qemuCaps) < 0)
                goto error;
11399
            break;
M
Michal Privoznik 已提交
11400 11401 11402 11403 11404 11405 11406 11407 11408 11409 11410 11411 11412 11413 11414 11415 11416 11417

        case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_PCI:
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCI_SERIAL)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("pci-serial is not supported with this QEMU binary"));
                goto error;
            }

            if (serial->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
                serial->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("pci-serial requires address of pci type"));
                goto error;
            }

            if (qemuBuildDeviceAddressStr(&cmd, def, &serial->info, qemuCaps) < 0)
                goto error;
            break;
G
Guannan Ren 已提交
11418 11419 11420
        }
    }

11421
    if (virBufferCheckError(&cmd) < 0)
11422 11423
        goto error;

11424 11425
    *deviceStr = virBufferContentAndReset(&cmd);
    return 0;
11426

11427
 error:
11428
    virBufferFreeAndReset(&cmd);
11429 11430 11431 11432 11433 11434 11435 11436
    return -1;
}

static int
qemuBuildParallelChrDeviceStr(char **deviceStr,
                              virDomainChrDefPtr chr)
{
    if (virAsprintf(deviceStr, "isa-parallel,chardev=char%s,id=%s",
J
Ján Tomko 已提交
11437
                    chr->info.alias, chr->info.alias) < 0)
11438 11439
        return -1;
    return 0;
11440
}
11441

11442 11443
static int
qemuBuildChannelChrDeviceStr(char **deviceStr,
11444
                             virDomainDefPtr def,
11445 11446 11447 11448 11449 11450 11451
                             virDomainChrDefPtr chr,
                             virQEMUCapsPtr qemuCaps)
{
    int ret = -1;
    char *addr = NULL;
    int port;

11452
    switch ((virDomainChrChannelTargetType) chr->targetType) {
11453 11454 11455 11456 11457 11458 11459 11460
    case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD:

        addr = virSocketAddrFormat(chr->target.addr);
        if (!addr)
            return ret;
        port = virSocketAddrGetPort(chr->target.addr);

        if (virAsprintf(deviceStr,
11461
                        "user,guestfwd=tcp:%s:%i-chardev:char%s,id=user-%s",
J
Ján Tomko 已提交
11462
                        addr, port, chr->info.alias, chr->info.alias) < 0)
11463 11464 11465 11466
            goto cleanup;
        break;

    case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO:
11467
        if (!(*deviceStr = qemuBuildVirtioSerialPortDevStr(def, chr, qemuCaps)))
11468
            goto cleanup;
11469 11470 11471 11472 11473 11474 11475 11476
        break;

    case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_NONE:
    case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST:
        return ret;
    }

    ret = 0;
11477
 cleanup:
11478 11479 11480 11481 11482 11483
    VIR_FREE(addr);
    return ret;
}

static int
qemuBuildConsoleChrDeviceStr(char **deviceStr,
11484
                             virDomainDefPtr def,
11485 11486 11487 11488 11489
                             virDomainChrDefPtr chr,
                             virQEMUCapsPtr qemuCaps)
{
    int ret = -1;

11490
    switch ((virDomainChrConsoleTargetType) chr->targetType) {
11491 11492 11493 11494 11495 11496 11497
    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLP:
    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLPLM:
        if (!(*deviceStr = qemuBuildSclpDevStr(chr)))
            goto cleanup;
        break;

    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO:
11498
        if (!(*deviceStr = qemuBuildVirtioSerialPortDevStr(def, chr, qemuCaps)))
11499 11500 11501 11502
            goto cleanup;
        break;

    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL:
11503 11504
        break;

11505 11506 11507 11508 11509 11510
    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_NONE:
    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_XEN:
    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_UML:
    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LXC:
    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_OPENVZ:
    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LAST:
11511 11512 11513 11514
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unsupported console target type %s"),
                       NULLSTR(virDomainChrConsoleTargetTypeToString(chr->targetType)));
        goto cleanup;
11515 11516 11517
    }

    ret = 0;
11518
 cleanup:
11519 11520 11521 11522 11523 11524 11525 11526 11527 11528 11529
    return ret;
}

int
qemuBuildChrDeviceStr(char **deviceStr,
                      virDomainDefPtr vmdef,
                      virDomainChrDefPtr chr,
                      virQEMUCapsPtr qemuCaps)
{
    int ret = -1;

11530
    switch ((virDomainChrDeviceType) chr->deviceType) {
11531
    case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL:
11532
        ret = qemuBuildSerialChrDeviceStr(deviceStr, vmdef, chr, qemuCaps,
11533 11534 11535 11536 11537 11538 11539 11540 11541
                                          vmdef->os.arch,
                                          vmdef->os.machine);
        break;

    case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL:
        ret = qemuBuildParallelChrDeviceStr(deviceStr, chr);
        break;

    case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL:
11542
        ret = qemuBuildChannelChrDeviceStr(deviceStr, vmdef, chr, qemuCaps);
11543 11544 11545
        break;

    case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE:
11546
        ret = qemuBuildConsoleChrDeviceStr(deviceStr, vmdef, chr, qemuCaps);
11547 11548 11549 11550 11551 11552 11553 11554 11555 11556
        break;

    case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST:
        return ret;
    }

    return ret;
}


11557 11558 11559 11560 11561 11562 11563
/*
 * This method takes a string representing a QEMU command line ARGV set
 * optionally prefixed by a list of environment variables. It then tries
 * to split it up into a NULL terminated list of env & argv, splitting
 * on space
 */
static int qemuStringToArgvEnv(const char *args,
E
Eric Blake 已提交
11564 11565
                               char ***retenv,
                               char ***retargv)
11566 11567
{
    char **arglist = NULL;
11568 11569 11570
    size_t argcount = 0;
    size_t argalloc = 0;
    size_t envend;
11571
    size_t i;
11572 11573
    const char *curr = args;
    const char *start;
E
Eric Blake 已提交
11574 11575
    char **progenv = NULL;
    char **progargv = NULL;
11576 11577 11578 11579 11580 11581 11582 11583

    /* Iterate over string, splitting on sequences of ' ' */
    while (curr && *curr != '\0') {
        char *arg;
        const char *next;

        start = curr;
        /* accept a space in CEPH_ARGS */
11584
        if (STRPREFIX(curr, "CEPH_ARGS=-m "))
11585 11586 11587 11588 11589 11590 11591 11592 11593 11594 11595 11596 11597 11598 11599
            start += strlen("CEPH_ARGS=-m ");
        if (*start == '\'') {
            if (start == curr)
                curr++;
            next = strchr(start + 1, '\'');
        } else if (*start == '"') {
            if (start == curr)
                curr++;
            next = strchr(start + 1, '"');
        } else {
            next = strchr(start, ' ');
        }
        if (!next)
            next = strchr(curr, '\n');

11600
        if (VIR_STRNDUP(arg, curr, next ? next - curr : -1) < 0)
11601
            goto error;
11602

11603 11604
        if (next && (*next == '\'' || *next == '"'))
            next++;
11605

11606 11607 11608
        if (VIR_RESIZE_N(arglist, argalloc, argcount, 2) < 0) {
            VIR_FREE(arg);
            goto error;
11609 11610 11611
        }

        arglist[argcount++] = arg;
11612
        arglist[argcount] = NULL;
11613 11614 11615 11616 11617 11618 11619 11620 11621

        while (next && c_isspace(*next))
            next++;

        curr = next;
    }

    /* Iterate over list of args, finding first arg not containing
     * the '=' character (eg, skip over env vars FOO=bar) */
11622
    for (envend = 0; ((envend < argcount) &&
11623 11624 11625 11626 11627 11628 11629
                       (strchr(arglist[envend], '=') != NULL));
         envend++)
        ; /* nada */

    /* Copy the list of env vars */
    if (envend > 0) {
        if (VIR_REALLOC_N(progenv, envend+1) < 0)
11630
            goto error;
11631
        for (i = 0; i < envend; i++)
11632 11633 11634 11635 11636 11637
            progenv[i] = arglist[i];
        progenv[i] = NULL;
    }

    /* Copy the list of argv */
    if (VIR_REALLOC_N(progargv, argcount-envend + 1) < 0)
11638
        goto error;
11639
    for (i = envend; i < argcount; i++)
11640 11641 11642 11643 11644 11645 11646 11647 11648 11649
        progargv[i-envend] = arglist[i];
    progargv[i-envend] = NULL;

    VIR_FREE(arglist);

    *retenv = progenv;
    *retargv = progargv;

    return 0;

11650
 error:
11651 11652
    VIR_FREE(progenv);
    VIR_FREE(progargv);
E
Eric Blake 已提交
11653
    virStringFreeList(arglist);
11654 11655 11656 11657 11658 11659 11660
    return -1;
}


/*
 * Search for a named env variable, and return the value part
 */
E
Eric Blake 已提交
11661
static const char *qemuFindEnv(char **progenv,
11662 11663
                               const char *name)
{
11664
    size_t i;
11665 11666
    int len = strlen(name);

11667
    for (i = 0; progenv && progenv[i]; i++) {
11668 11669 11670 11671 11672 11673 11674 11675 11676 11677 11678 11679 11680 11681 11682 11683 11684 11685
        if (STREQLEN(progenv[i], name, len) &&
            progenv[i][len] == '=')
            return progenv[i] + len + 1;
    }
    return NULL;
}

/*
 * Takes a string containing a set of key=value,key=value,key...
 * parameters and splits them up, returning two arrays with
 * the individual keys and values. If allowEmptyValue is nonzero,
 * the "=value" part is optional and if a key with no value is found,
 * NULL is be placed into corresponding place in retvalues.
 */
int
qemuParseKeywords(const char *str,
                  char ***retkeywords,
                  char ***retvalues,
11686
                  int *retnkeywords,
11687 11688 11689 11690 11691 11692 11693 11694
                  int allowEmptyValue)
{
    int keywordCount = 0;
    int keywordAlloc = 0;
    char **keywords = NULL;
    char **values = NULL;
    const char *start = str;
    const char *end;
11695
    size_t i;
11696 11697 11698

    *retkeywords = NULL;
    *retvalues = NULL;
11699
    *retnkeywords = 0;
11700 11701 11702 11703 11704 11705 11706 11707
    end = start + strlen(str);

    while (start) {
        const char *separator;
        const char *endmark;
        char *keyword;
        char *value = NULL;

11708 11709 11710 11711 11712 11713 11714 11715
        endmark = start;
        do {
            /* Qemu accepts ',,' as an escape for a literal comma;
             * skip past those here while searching for the end of the
             * value, then strip them down below */
            endmark = strchr(endmark, ',');
        } while (endmark && endmark[1] == ',' && (endmark += 2));
        if (!endmark)
11716 11717 11718 11719 11720 11721
            endmark = end;
        if (!(separator = strchr(start, '=')))
            separator = end;

        if (separator >= endmark) {
            if (!allowEmptyValue) {
11722 11723
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("malformed keyword arguments in '%s'"), str);
11724 11725 11726 11727 11728
                goto error;
            }
            separator = endmark;
        }

11729 11730
        if (VIR_STRNDUP(keyword, start, separator - start) < 0)
            goto error;
11731 11732 11733

        if (separator < endmark) {
            separator++;
11734
            if (VIR_STRNDUP(value, separator, endmark - separator) < 0) {
11735
                VIR_FREE(keyword);
11736
                goto error;
11737
            }
11738 11739 11740 11741 11742 11743 11744 11745 11746 11747
            if (strchr(value, ',')) {
                char *p = strchr(value, ',') + 1;
                char *q = p + 1;
                while (*q) {
                    if (*q == ',')
                        q++;
                    *p++ = *q++;
                }
                *p = '\0';
            }
11748 11749 11750 11751 11752 11753 11754
        }

        if (keywordAlloc == keywordCount) {
            if (VIR_REALLOC_N(keywords, keywordAlloc + 10) < 0 ||
                VIR_REALLOC_N(values, keywordAlloc + 10) < 0) {
                VIR_FREE(keyword);
                VIR_FREE(value);
11755
                goto error;
11756 11757 11758 11759 11760 11761 11762 11763 11764 11765 11766 11767 11768
            }
            keywordAlloc += 10;
        }

        keywords[keywordCount] = keyword;
        values[keywordCount] = value;
        keywordCount++;

        start = endmark < end ? endmark + 1 : NULL;
    }

    *retkeywords = keywords;
    *retvalues = values;
11769 11770
    *retnkeywords = keywordCount;
    return 0;
11771

11772
 error:
11773
    for (i = 0; i < keywordCount; i++) {
11774 11775 11776 11777 11778 11779 11780 11781 11782 11783 11784 11785 11786 11787 11788 11789
        VIR_FREE(keywords[i]);
        VIR_FREE(values[i]);
    }
    VIR_FREE(keywords);
    VIR_FREE(values);
    return -1;
}

/*
 * Tries to parse new style QEMU -drive  args.
 *
 * eg -drive file=/dev/HostVG/VirtData1,if=ide,index=1
 *
 * Will fail if not using the 'index' keyword
 */
static virDomainDiskDefPtr
11790
qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt,
11791
                         const char *val,
11792
                         virDomainDefPtr dom,
11793 11794
                         int nvirtiodisk,
                         bool old_style_ceph_args)
11795 11796 11797 11798 11799
{
    virDomainDiskDefPtr def = NULL;
    char **keywords;
    char **values;
    int nkeywords;
11800
    size_t i;
11801 11802 11803 11804
    int idx = -1;
    int busid = -1;
    int unitid = -1;

11805 11806 11807 11808 11809
    if (qemuParseKeywords(val,
                          &keywords,
                          &values,
                          &nkeywords,
                          0) < 0)
11810 11811
        return NULL;

11812
    if (VIR_ALLOC(def) < 0)
11813
        goto cleanup;
11814 11815
    if (VIR_ALLOC(def->src) < 0)
        goto error;
11816

11817
    if ((ARCH_IS_PPC64(dom->os.arch) &&
11818
        dom->os.machine && STRPREFIX(dom->os.machine, "pseries")))
11819 11820 11821
        def->bus = VIR_DOMAIN_DISK_BUS_SCSI;
    else
       def->bus = VIR_DOMAIN_DISK_BUS_IDE;
11822
    def->device = VIR_DOMAIN_DISK_DEVICE_DISK;
11823
    def->src->type = VIR_STORAGE_TYPE_FILE;
11824

11825
    for (i = 0; i < nkeywords; i++) {
11826 11827
        if (STREQ(keywords[i], "file")) {
            if (values[i] && STRNEQ(values[i], "")) {
11828
                def->src->path = values[i];
11829
                values[i] = NULL;
11830 11831 11832 11833 11834 11835
                if (STRPREFIX(def->src->path, "/dev/"))
                    def->src->type = VIR_STORAGE_TYPE_BLOCK;
                else if (STRPREFIX(def->src->path, "nbd:") ||
                         STRPREFIX(def->src->path, "nbd+")) {
                    def->src->type = VIR_STORAGE_TYPE_NETWORK;
                    def->src->protocol = VIR_STORAGE_NET_PROTOCOL_NBD;
11836

11837 11838
                    if (qemuParseNBDString(def) < 0)
                        goto error;
11839 11840
                } else if (STRPREFIX(def->src->path, "rbd:")) {
                    char *p = def->src->path;
11841

11842 11843 11844
                    def->src->type = VIR_STORAGE_TYPE_NETWORK;
                    def->src->protocol = VIR_STORAGE_NET_PROTOCOL_RBD;
                    if (VIR_STRDUP(def->src->path, p + strlen("rbd:")) < 0)
11845
                        goto error;
11846
                    /* old-style CEPH_ARGS env variable is parsed later */
11847 11848 11849 11850
                    if (!old_style_ceph_args && qemuParseRBDString(def) < 0) {
                        VIR_FREE(p);
                        goto error;
                    }
11851 11852

                    VIR_FREE(p);
11853 11854 11855 11856
                } else if (STRPREFIX(def->src->path, "gluster:") ||
                           STRPREFIX(def->src->path, "gluster+")) {
                    def->src->type = VIR_STORAGE_TYPE_NETWORK;
                    def->src->protocol = VIR_STORAGE_NET_PROTOCOL_GLUSTER;
11857 11858

                    if (qemuParseGlusterString(def) < 0)
11859
                        goto error;
11860 11861 11862
                } else if (STRPREFIX(def->src->path, "iscsi:")) {
                    def->src->type = VIR_STORAGE_TYPE_NETWORK;
                    def->src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
P
Paolo Bonzini 已提交
11863 11864 11865

                    if (qemuParseISCSIString(def) < 0)
                        goto error;
11866 11867
                } else if (STRPREFIX(def->src->path, "sheepdog:")) {
                    char *p = def->src->path;
11868 11869
                    char *port, *vdi;

11870 11871 11872
                    def->src->type = VIR_STORAGE_TYPE_NETWORK;
                    def->src->protocol = VIR_STORAGE_NET_PROTOCOL_SHEEPDOG;
                    if (VIR_STRDUP(def->src->path, p + strlen("sheepdog:")) < 0)
11873
                        goto error;
11874
                    VIR_FREE(p);
11875

11876 11877
                    /* def->src->path must be [vdiname] or [host]:[port]:[vdiname] */
                    port = strchr(def->src->path, ':');
11878
                    if (port) {
11879 11880
                        *port = '\0';
                        vdi = strchr(port + 1, ':');
11881
                        if (!vdi) {
11882
                            *port = ':';
11883
                            virReportError(VIR_ERR_INTERNAL_ERROR,
11884
                                           _("cannot parse sheepdog filename '%s'"),
11885
                                           def->src->path);
11886
                            goto error;
11887
                        }
11888
                        port++;
11889
                        *vdi++ = '\0';
11890
                        if (VIR_ALLOC(def->src->hosts) < 0)
11891
                            goto error;
11892 11893 11894
                        def->src->nhosts = 1;
                        def->src->hosts->name = def->src->path;
                        if (VIR_STRDUP(def->src->hosts->port, port) < 0)
11895
                            goto error;
11896 11897 11898
                        def->src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
                        def->src->hosts->socket = NULL;
                        if (VIR_STRDUP(def->src->path, vdi) < 0)
11899
                            goto error;
11900
                    }
11901
                } else {
11902
                    def->src->type = VIR_STORAGE_TYPE_FILE;
11903
                }
11904
            } else {
11905
                def->src->type = VIR_STORAGE_TYPE_FILE;
11906 11907
            }
        } else if (STREQ(keywords[i], "if")) {
11908
            if (STREQ(values[i], "ide")) {
11909
                def->bus = VIR_DOMAIN_DISK_BUS_IDE;
11910
                if ((ARCH_IS_PPC64(dom->os.arch) &&
11911
                     dom->os.machine && STRPREFIX(dom->os.machine, "pseries"))) {
11912 11913 11914 11915
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("pseries systems do not support ide devices '%s'"), val);
                    goto error;
                }
11916
            } else if (STREQ(values[i], "scsi")) {
11917
                def->bus = VIR_DOMAIN_DISK_BUS_SCSI;
11918 11919 11920
            } else if (STREQ(values[i], "floppy")) {
                def->bus = VIR_DOMAIN_DISK_BUS_FDC;
                def->device = VIR_DOMAIN_DISK_DEVICE_FLOPPY;
11921
            } else if (STREQ(values[i], "virtio")) {
11922
                def->bus = VIR_DOMAIN_DISK_BUS_VIRTIO;
11923
            } else if (STREQ(values[i], "xen")) {
11924
                def->bus = VIR_DOMAIN_DISK_BUS_XEN;
11925
            } else if (STREQ(values[i], "sd")) {
11926
                def->bus = VIR_DOMAIN_DISK_BUS_SD;
11927
            }
11928 11929 11930
        } else if (STREQ(keywords[i], "media")) {
            if (STREQ(values[i], "cdrom")) {
                def->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
11931
                def->src->readonly = true;
11932
            } else if (STREQ(values[i], "floppy")) {
11933
                def->device = VIR_DOMAIN_DISK_DEVICE_FLOPPY;
11934
            }
11935
        } else if (STREQ(keywords[i], "format")) {
11936
            if (VIR_STRDUP(def->src->driverName, "qemu") < 0)
11937
                goto error;
11938
            def->src->format = virStorageFileFormatTypeFromString(values[i]);
11939 11940 11941 11942 11943 11944 11945 11946 11947
        } else if (STREQ(keywords[i], "cache")) {
            if (STREQ(values[i], "off") ||
                STREQ(values[i], "none"))
                def->cachemode = VIR_DOMAIN_DISK_CACHE_DISABLE;
            else if (STREQ(values[i], "writeback") ||
                     STREQ(values[i], "on"))
                def->cachemode = VIR_DOMAIN_DISK_CACHE_WRITEBACK;
            else if (STREQ(values[i], "writethrough"))
                def->cachemode = VIR_DOMAIN_DISK_CACHE_WRITETHRU;
11948 11949
            else if (STREQ(values[i], "directsync"))
                def->cachemode = VIR_DOMAIN_DISK_CACHE_DIRECTSYNC;
11950 11951
            else if (STREQ(values[i], "unsafe"))
                def->cachemode = VIR_DOMAIN_DISK_CACHE_UNSAFE;
11952
        } else if (STREQ(keywords[i], "werror")) {
11953 11954
            if (STREQ(values[i], "stop"))
                def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_STOP;
11955 11956
            else if (STREQ(values[i], "report"))
                def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_REPORT;
11957 11958
            else if (STREQ(values[i], "ignore"))
                def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_IGNORE;
11959
            else if (STREQ(values[i], "enospc"))
11960
                def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_ENOSPACE;
11961 11962 11963 11964 11965 11966 11967
        } else if (STREQ(keywords[i], "rerror")) {
            if (STREQ(values[i], "stop"))
                def->rerror_policy = VIR_DOMAIN_DISK_ERROR_POLICY_STOP;
            else if (STREQ(values[i], "report"))
                def->rerror_policy = VIR_DOMAIN_DISK_ERROR_POLICY_REPORT;
            else if (STREQ(values[i], "ignore"))
                def->rerror_policy = VIR_DOMAIN_DISK_ERROR_POLICY_IGNORE;
11968 11969
        } else if (STREQ(keywords[i], "index")) {
            if (virStrToLong_i(values[i], NULL, 10, &idx) < 0) {
11970 11971
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse drive index '%s'"), val);
11972
                goto error;
11973 11974 11975
            }
        } else if (STREQ(keywords[i], "bus")) {
            if (virStrToLong_i(values[i], NULL, 10, &busid) < 0) {
11976 11977
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse drive bus '%s'"), val);
11978
                goto error;
11979 11980 11981
            }
        } else if (STREQ(keywords[i], "unit")) {
            if (virStrToLong_i(values[i], NULL, 10, &unitid) < 0) {
11982 11983
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse drive unit '%s'"), val);
11984
                goto error;
11985 11986 11987
            }
        } else if (STREQ(keywords[i], "readonly")) {
            if ((values[i] == NULL) || STREQ(values[i], "on"))
11988
                def->src->readonly = true;
E
Eric Blake 已提交
11989 11990
        } else if (STREQ(keywords[i], "aio")) {
            if ((def->iomode = virDomainDiskIoTypeFromString(values[i])) < 0) {
11991 11992
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse io mode '%s'"), values[i]);
11993
                goto error;
E
Eric Blake 已提交
11994
            }
11995 11996 11997 11998 11999 12000 12001 12002
        } else if (STREQ(keywords[i], "cyls")) {
            if (virStrToLong_ui(values[i], NULL, 10,
                                &(def->geometry.cylinders)) < 0) {
                virDomainDiskDefFree(def);
                def = NULL;
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse cylinders value'%s'"),
                               values[i]);
12003
                goto error;
12004 12005 12006 12007 12008 12009 12010 12011 12012
            }
        } else if (STREQ(keywords[i], "heads")) {
            if (virStrToLong_ui(values[i], NULL, 10,
                                &(def->geometry.heads)) < 0) {
                virDomainDiskDefFree(def);
                def = NULL;
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse heads value'%s'"),
                               values[i]);
12013
                goto error;
12014 12015 12016 12017 12018 12019 12020 12021 12022
            }
        } else if (STREQ(keywords[i], "secs")) {
            if (virStrToLong_ui(values[i], NULL, 10,
                                &(def->geometry.sectors)) < 0) {
                virDomainDiskDefFree(def);
                def = NULL;
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse sectors value'%s'"),
                               values[i]);
12023
                goto error;
12024 12025 12026 12027
            }
        } else if (STREQ(keywords[i], "trans")) {
            def->geometry.trans =
                virDomainDiskGeometryTransTypeFromString(values[i]);
12028 12029
            if ((def->geometry.trans < VIR_DOMAIN_DISK_TRANS_DEFAULT) ||
                (def->geometry.trans >= VIR_DOMAIN_DISK_TRANS_LAST)) {
12030 12031 12032
                virDomainDiskDefFree(def);
                def = NULL;
                virReportError(VIR_ERR_INTERNAL_ERROR,
12033
                               _("cannot parse translation value '%s'"),
12034
                               values[i]);
12035
                goto error;
12036
            }
12037 12038 12039
        }
    }

12040 12041 12042
    if (def->rerror_policy == def->error_policy)
        def->rerror_policy = 0;

12043
    if (!def->src->path &&
12044
        def->device == VIR_DOMAIN_DISK_DEVICE_DISK &&
12045
        def->src->type != VIR_STORAGE_TYPE_NETWORK) {
12046 12047
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("missing file parameter in drive '%s'"), val);
12048
        goto error;
12049 12050 12051 12052 12053 12054 12055 12056
    }
    if (idx == -1 &&
        def->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
        idx = nvirtiodisk;

    if (idx == -1 &&
        unitid == -1 &&
        busid == -1) {
12057
        virReportError(VIR_ERR_INTERNAL_ERROR,
12058 12059 12060
                       _("missing index/unit/bus parameter in drive '%s'"),
                       val);
        goto error;
12061 12062 12063 12064 12065 12066 12067 12068 12069 12070 12071 12072 12073 12074 12075 12076 12077 12078 12079 12080 12081
    }

    if (idx == -1) {
        if (unitid == -1)
            unitid = 0;
        if (busid == -1)
            busid = 0;
        switch (def->bus) {
        case VIR_DOMAIN_DISK_BUS_IDE:
            idx = (busid * 2) + unitid;
            break;
        case VIR_DOMAIN_DISK_BUS_SCSI:
            idx = (busid * 7) + unitid;
            break;
        default:
            idx = unitid;
            break;
        }
    }

    if (def->bus == VIR_DOMAIN_DISK_BUS_IDE) {
12082
        ignore_value(VIR_STRDUP(def->dst, "hda"));
12083 12084
    } else if (def->bus == VIR_DOMAIN_DISK_BUS_SCSI ||
               def->bus == VIR_DOMAIN_DISK_BUS_SD) {
12085
        ignore_value(VIR_STRDUP(def->dst, "sda"));
12086
    } else if (def->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
12087
        ignore_value(VIR_STRDUP(def->dst, "vda"));
12088
    } else if (def->bus == VIR_DOMAIN_DISK_BUS_XEN) {
12089
        ignore_value(VIR_STRDUP(def->dst, "xvda"));
12090 12091
    } else if (def->bus == VIR_DOMAIN_DISK_BUS_FDC) {
        ignore_value(VIR_STRDUP(def->dst, "fda"));
12092
    } else {
12093
        ignore_value(VIR_STRDUP(def->dst, "hda"));
12094 12095
    }

12096
    if (!def->dst)
12097
        goto error;
12098 12099 12100 12101 12102
    if (STREQ(def->dst, "xvda"))
        def->dst[3] = 'a' + idx;
    else
        def->dst[2] = 'a' + idx;

12103
    if (virDomainDiskDefAssignAddress(xmlopt, def, dom) < 0) {
12104 12105
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("invalid device name '%s'"), def->dst);
12106 12107
        virDomainDiskDefFree(def);
        def = NULL;
12108
        goto cleanup;
12109 12110
    }

12111
 cleanup:
12112
    for (i = 0; i < nkeywords; i++) {
12113 12114 12115 12116 12117 12118
        VIR_FREE(keywords[i]);
        VIR_FREE(values[i]);
    }
    VIR_FREE(keywords);
    VIR_FREE(values);
    return def;
12119

12120
 error:
12121 12122 12123
    virDomainDiskDefFree(def);
    def = NULL;
    goto cleanup;
12124 12125 12126 12127 12128 12129 12130 12131 12132 12133
}

/*
 * Tries to find a NIC definition matching a vlan we want
 */
static const char *
qemuFindNICForVLAN(int nnics,
                   const char **nics,
                   int wantvlan)
{
12134
    size_t i;
12135
    for (i = 0; i < nnics; i++) {
12136 12137 12138 12139 12140 12141 12142 12143 12144
        int gotvlan;
        const char *tmp = strstr(nics[i], "vlan=");
        char *end;
        if (!tmp)
            continue;

        tmp += strlen("vlan=");

        if (virStrToLong_i(tmp, &end, 10, &gotvlan) < 0) {
12145 12146
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot parse NIC vlan in '%s'"), nics[i]);
12147 12148 12149 12150 12151 12152 12153 12154 12155 12156
            return NULL;
        }

        if (gotvlan == wantvlan)
            return nics[i];
    }

    if (wantvlan == 0 && nnics > 0)
        return nics[0];

12157 12158
    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("cannot find NIC definition for vlan %d"), wantvlan);
12159 12160 12161 12162 12163 12164 12165 12166 12167 12168
    return NULL;
}


/*
 * Tries to parse a QEMU -net backend argument. Gets given
 * a list of all known -net frontend arguments to try and
 * match up against. Horribly complicated stuff
 */
static virDomainNetDefPtr
12169
qemuParseCommandLineNet(virDomainXMLOptionPtr xmlopt,
12170 12171 12172 12173 12174 12175 12176 12177 12178 12179 12180
                        const char *val,
                        int nnics,
                        const char **nics)
{
    virDomainNetDefPtr def = NULL;
    char **keywords = NULL;
    char **values = NULL;
    int nkeywords;
    const char *nic;
    int wantvlan = 0;
    const char *tmp;
12181
    bool genmac = true;
12182
    size_t i;
12183 12184 12185 12186

    tmp = strchr(val, ',');

    if (tmp) {
12187 12188 12189 12190 12191
        if (qemuParseKeywords(tmp+1,
                              &keywords,
                              &values,
                              &nkeywords,
                              0) < 0)
12192 12193 12194 12195 12196
            return NULL;
    } else {
        nkeywords = 0;
    }

12197
    if (VIR_ALLOC(def) < 0)
12198 12199 12200 12201 12202 12203 12204 12205 12206 12207 12208 12209 12210
        goto cleanup;

    /* 'tap' could turn into libvirt type=ethernet, type=bridge or
     * type=network, but we can't tell, so use the generic config */
    if (STRPREFIX(val, "tap,"))
        def->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
    else if (STRPREFIX(val, "socket"))
        def->type = VIR_DOMAIN_NET_TYPE_CLIENT;
    else if (STRPREFIX(val, "user"))
        def->type = VIR_DOMAIN_NET_TYPE_USER;
    else
        def->type = VIR_DOMAIN_NET_TYPE_ETHERNET;

12211
    for (i = 0; i < nkeywords; i++) {
12212 12213
        if (STREQ(keywords[i], "vlan")) {
            if (virStrToLong_i(values[i], NULL, 10, &wantvlan) < 0) {
12214 12215
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse vlan in '%s'"), val);
12216 12217 12218 12219 12220 12221
                virDomainNetDefFree(def);
                def = NULL;
                goto cleanup;
            }
        } else if (def->type == VIR_DOMAIN_NET_TYPE_ETHERNET &&
                   STREQ(keywords[i], "script") && STRNEQ(values[i], "")) {
12222
            def->script = values[i];
12223 12224 12225 12226 12227 12228 12229 12230 12231 12232 12233 12234 12235 12236 12237 12238 12239 12240 12241 12242 12243
            values[i] = NULL;
        } else if (def->type == VIR_DOMAIN_NET_TYPE_ETHERNET &&
                   STREQ(keywords[i], "ifname")) {
            def->ifname = values[i];
            values[i] = NULL;
        }
    }


    /* Done parsing the nic backend. Now to try and find corresponding
     * frontend, based off vlan number. NB this assumes a 1-1 mapping
     */

    nic = qemuFindNICForVLAN(nnics, nics, wantvlan);
    if (!nic) {
        virDomainNetDefFree(def);
        def = NULL;
        goto cleanup;
    }

    if (!STRPREFIX(nic, "nic")) {
12244 12245
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot parse NIC definition '%s'"), nic);
12246 12247 12248 12249 12250
        virDomainNetDefFree(def);
        def = NULL;
        goto cleanup;
    }

12251
    for (i = 0; i < nkeywords; i++) {
12252 12253 12254 12255 12256 12257 12258
        VIR_FREE(keywords[i]);
        VIR_FREE(values[i]);
    }
    VIR_FREE(keywords);
    VIR_FREE(values);

    if (STRPREFIX(nic, "nic,")) {
12259 12260 12261 12262 12263
        if (qemuParseKeywords(nic + strlen("nic,"),
                              &keywords,
                              &values,
                              &nkeywords,
                              0) < 0) {
12264 12265 12266 12267 12268 12269 12270 12271
            virDomainNetDefFree(def);
            def = NULL;
            goto cleanup;
        }
    } else {
        nkeywords = 0;
    }

12272
    for (i = 0; i < nkeywords; i++) {
12273
        if (STREQ(keywords[i], "macaddr")) {
12274
            genmac = false;
12275
            if (virMacAddrParse(values[i], &def->mac) < 0) {
12276 12277 12278
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("unable to parse mac address '%s'"),
                               values[i]);
12279 12280 12281 12282 12283 12284 12285
                virDomainNetDefFree(def);
                def = NULL;
                goto cleanup;
            }
        } else if (STREQ(keywords[i], "model")) {
            def->model = values[i];
            values[i] = NULL;
12286 12287
        } else if (STREQ(keywords[i], "vhost")) {
            if ((values[i] == NULL) || STREQ(values[i], "on")) {
12288
                def->driver.virtio.name = VIR_DOMAIN_NET_BACKEND_TYPE_VHOST;
12289
            } else if (STREQ(keywords[i], "off")) {
12290
                def->driver.virtio.name = VIR_DOMAIN_NET_BACKEND_TYPE_QEMU;
12291
            }
12292 12293
        } else if (STREQ(keywords[i], "sndbuf") && values[i]) {
            if (virStrToLong_ul(values[i], NULL, 10, &def->tune.sndbuf) < 0) {
12294 12295
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse sndbuf size in '%s'"), val);
12296 12297 12298 12299 12300
                virDomainNetDefFree(def);
                def = NULL;
                goto cleanup;
            }
            def->tune.sndbuf_specified = true;
12301 12302 12303 12304
        }
    }

    if (genmac)
12305
        virDomainNetGenerateMAC(xmlopt, &def->mac);
12306

12307
 cleanup:
12308
    for (i = 0; i < nkeywords; i++) {
12309 12310 12311 12312 12313 12314 12315 12316 12317 12318 12319 12320 12321 12322 12323 12324 12325 12326
        VIR_FREE(keywords[i]);
        VIR_FREE(values[i]);
    }
    VIR_FREE(keywords);
    VIR_FREE(values);
    return def;
}


/*
 * Tries to parse a QEMU PCI device
 */
static virDomainHostdevDefPtr
qemuParseCommandLinePCI(const char *val)
{
    int bus = 0, slot = 0, func = 0;
    const char *start;
    char *end;
12327 12328 12329
    virDomainHostdevDefPtr def = virDomainHostdevDefAlloc();

    if (!def)
12330
        goto error;
12331 12332

    if (!STRPREFIX(val, "host=")) {
12333 12334
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown PCI device syntax '%s'"), val);
12335
        goto error;
12336 12337 12338 12339
    }

    start = val + strlen("host=");
    if (virStrToLong_i(start, &end, 16, &bus) < 0 || *end != ':') {
12340 12341
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot extract PCI device bus '%s'"), val);
12342
        goto error;
12343 12344 12345
    }
    start = end + 1;
    if (virStrToLong_i(start, &end, 16, &slot) < 0 || *end != '.') {
12346 12347
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot extract PCI device slot '%s'"), val);
12348
        goto error;
12349 12350 12351
    }
    start = end + 1;
    if (virStrToLong_i(start, NULL, 16, &func) < 0) {
12352 12353
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot extract PCI device function '%s'"), val);
12354
        goto error;
12355 12356 12357
    }

    def->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
12358
    def->managed = true;
12359
    def->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
12360 12361 12362
    def->source.subsys.u.pci.addr.bus = bus;
    def->source.subsys.u.pci.addr.slot = slot;
    def->source.subsys.u.pci.addr.function = func;
12363
    return def;
12364 12365 12366 12367

 error:
    virDomainHostdevDefFree(def);
    return NULL;
12368 12369 12370 12371 12372 12373 12374 12375 12376
}


/*
 * Tries to parse a QEMU USB device
 */
static virDomainHostdevDefPtr
qemuParseCommandLineUSB(const char *val)
{
12377
    virDomainHostdevDefPtr def = virDomainHostdevDefAlloc();
12378
    virDomainHostdevSubsysUSBPtr usbsrc;
12379 12380 12381 12382
    int first = 0, second = 0;
    const char *start;
    char *end;

12383
    if (!def)
12384
        goto error;
12385
    usbsrc = &def->source.subsys.u.usb;
12386

12387
    if (!STRPREFIX(val, "host:")) {
12388 12389
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown USB device syntax '%s'"), val);
12390
        goto error;
12391 12392 12393 12394 12395
    }

    start = val + strlen("host:");
    if (strchr(start, ':')) {
        if (virStrToLong_i(start, &end, 16, &first) < 0 || *end != ':') {
12396 12397
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot extract USB device vendor '%s'"), val);
12398
            goto error;
12399 12400 12401
        }
        start = end + 1;
        if (virStrToLong_i(start, NULL, 16, &second) < 0) {
12402 12403
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot extract USB device product '%s'"), val);
12404
            goto error;
12405 12406 12407
        }
    } else {
        if (virStrToLong_i(start, &end, 10, &first) < 0 || *end != '.') {
12408 12409
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot extract USB device bus '%s'"), val);
12410
            goto error;
12411 12412 12413
        }
        start = end + 1;
        if (virStrToLong_i(start, NULL, 10, &second) < 0) {
12414 12415
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot extract USB device address '%s'"), val);
12416
            goto error;
12417 12418 12419 12420
        }
    }

    def->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
12421
    def->managed = false;
12422 12423
    def->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB;
    if (*end == '.') {
12424 12425
        usbsrc->bus = first;
        usbsrc->device = second;
12426
    } else {
12427 12428
        usbsrc->vendor = first;
        usbsrc->product = second;
12429 12430
    }
    return def;
12431 12432 12433 12434

 error:
    virDomainHostdevDefFree(def);
    return NULL;
12435 12436 12437 12438 12439 12440
}


/*
 * Tries to parse a QEMU serial/parallel device
 */
12441 12442 12443
static int
qemuParseCommandLineChr(virDomainChrSourceDefPtr source,
                        const char *val)
12444 12445
{
    if (STREQ(val, "null")) {
12446
        source->type = VIR_DOMAIN_CHR_TYPE_NULL;
12447
    } else if (STREQ(val, "vc")) {
12448
        source->type = VIR_DOMAIN_CHR_TYPE_VC;
12449
    } else if (STREQ(val, "pty")) {
12450
        source->type = VIR_DOMAIN_CHR_TYPE_PTY;
12451
    } else if (STRPREFIX(val, "file:")) {
12452
        source->type = VIR_DOMAIN_CHR_TYPE_FILE;
12453 12454
        if (VIR_STRDUP(source->data.file.path, val + strlen("file:")) < 0)
            goto error;
12455
    } else if (STRPREFIX(val, "pipe:")) {
12456
        source->type = VIR_DOMAIN_CHR_TYPE_PIPE;
12457 12458
        if (VIR_STRDUP(source->data.file.path, val + strlen("pipe:")) < 0)
            goto error;
12459
    } else if (STREQ(val, "stdio")) {
12460
        source->type = VIR_DOMAIN_CHR_TYPE_STDIO;
12461 12462
    } else if (STRPREFIX(val, "udp:")) {
        const char *svc1, *host2, *svc2;
12463
        source->type = VIR_DOMAIN_CHR_TYPE_UDP;
12464 12465 12466 12467 12468
        val += strlen("udp:");
        svc1 = strchr(val, ':');
        host2 = svc1 ? strchr(svc1, '@') : NULL;
        svc2 = host2 ? strchr(host2, ':') : NULL;

12469 12470 12471
        if (svc1 && svc1 != val &&
            VIR_STRNDUP(source->data.udp.connectHost, val, svc1 - val) < 0)
            goto error;
12472 12473 12474

        if (svc1) {
            svc1++;
12475 12476 12477
            if (VIR_STRNDUP(source->data.udp.connectService, svc1,
                            host2 ? host2 - svc1 : strlen(svc1)) < 0)
                goto error;
12478 12479 12480 12481
        }

        if (host2) {
            host2++;
12482 12483
            if (svc2 && svc2 != host2 &&
                VIR_STRNDUP(source->data.udp.bindHost, host2, svc2 - host2) < 0)
12484
                goto error;
12485
        }
12486

12487 12488
        if (svc2) {
            svc2++;
12489
            if (STRNEQ(svc2, "0")) {
12490 12491
                if (VIR_STRDUP(source->data.udp.bindService, svc2) < 0)
                    goto error;
12492
            }
12493 12494 12495 12496
        }
    } else if (STRPREFIX(val, "tcp:") ||
               STRPREFIX(val, "telnet:")) {
        const char *opt, *svc;
12497
        source->type = VIR_DOMAIN_CHR_TYPE_TCP;
12498 12499 12500 12501
        if (STRPREFIX(val, "tcp:")) {
            val += strlen("tcp:");
        } else {
            val += strlen("telnet:");
12502
            source->data.tcp.protocol = VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET;
12503 12504 12505
        }
        svc = strchr(val, ':');
        if (!svc) {
12506 12507
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot find port number in character device %s"), val);
12508 12509 12510 12511
            goto error;
        }
        opt = strchr(svc, ',');
        if (opt && strstr(opt, "server"))
12512
            source->data.tcp.listen = true;
12513

12514 12515
        if (VIR_STRNDUP(source->data.tcp.host, val, svc - val) < 0)
            goto error;
12516
        svc++;
12517
        if (VIR_STRNDUP(source->data.tcp.service, svc, opt ? opt - svc : -1) < 0)
12518
            goto error;
12519 12520 12521 12522
    } else if (STRPREFIX(val, "unix:")) {
        const char *opt;
        val += strlen("unix:");
        opt = strchr(val, ',');
12523
        source->type = VIR_DOMAIN_CHR_TYPE_UNIX;
12524
        if (VIR_STRNDUP(source->data.nix.path, val, opt ? opt - val : -1) < 0)
12525
            goto error;
12526 12527

    } else if (STRPREFIX(val, "/dev")) {
12528
        source->type = VIR_DOMAIN_CHR_TYPE_DEV;
12529 12530
        if (VIR_STRDUP(source->data.file.path, val) < 0)
            goto error;
12531
    } else {
12532 12533
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown character device syntax %s"), val);
12534 12535 12536
        goto error;
    }

12537
    return 0;
12538

12539
 error:
12540
    return -1;
12541 12542 12543 12544 12545 12546 12547 12548 12549
}


static virCPUDefPtr
qemuInitGuestCPU(virDomainDefPtr dom)
{
    if (!dom->cpu) {
        virCPUDefPtr cpu;

12550
        if (VIR_ALLOC(cpu) < 0)
12551 12552 12553 12554 12555 12556 12557 12558 12559 12560 12561 12562 12563 12564 12565
            return NULL;

        cpu->type = VIR_CPU_TYPE_GUEST;
        cpu->match = VIR_CPU_MATCH_EXACT;
        dom->cpu = cpu;
    }

    return dom->cpu;
}


static int
qemuParseCommandLineCPU(virDomainDefPtr dom,
                        const char *val)
{
12566
    virCPUDefPtr cpu = NULL;
12567
    char **tokens;
12568
    char **hv_tokens = NULL;
12569
    char *model = NULL;
12570
    int ret = -1;
12571
    size_t i;
12572

12573 12574
    if (!(tokens = virStringSplit(val, ",", 0)))
        goto cleanup;
12575

12576 12577
    if (tokens[0] == NULL)
        goto syntax;
12578

12579 12580 12581 12582 12583 12584 12585
    for (i = 0; tokens[i] != NULL; i++) {
        if (*tokens[i] == '\0')
            goto syntax;

        if (i == 0) {
            if (VIR_STRDUP(model, tokens[i]) < 0)
                goto cleanup;
12586

12587
            if (STRNEQ(model, "qemu32") && STRNEQ(model, "qemu64")) {
12588
                if (!(cpu = qemuInitGuestCPU(dom)))
12589
                    goto cleanup;
12590 12591 12592 12593

                cpu->model = model;
                model = NULL;
            }
12594 12595
        } else if (*tokens[i] == '+' || *tokens[i] == '-') {
            const char *feature = tokens[i] + 1; /* '+' or '-' */
12596 12597
            int policy;

12598
            if (*tokens[i] == '+')
12599 12600 12601 12602
                policy = VIR_CPU_FEATURE_REQUIRE;
            else
                policy = VIR_CPU_FEATURE_DISABLE;

12603
            if (*feature == '\0')
12604 12605
                goto syntax;

12606 12607 12608 12609 12610 12611 12612 12613
            if (dom->os.arch != VIR_ARCH_X86_64 &&
                dom->os.arch != VIR_ARCH_I686) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("%s platform doesn't support CPU features'"),
                               virArchToString(dom->os.arch));
                goto cleanup;
             }

12614 12615
            if (STREQ(feature, "kvmclock")) {
                bool present = (policy == VIR_CPU_FEATURE_REQUIRE);
12616
                size_t j;
12617

12618 12619
                for (j = 0; j < dom->clock.ntimers; j++) {
                    if (dom->clock.timers[j]->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK)
12620 12621 12622
                        break;
                }

12623
                if (j == dom->clock.ntimers) {
12624 12625 12626 12627 12628
                    virDomainTimerDefPtr timer;
                    if (VIR_ALLOC(timer) < 0 ||
                        VIR_APPEND_ELEMENT_COPY(dom->clock.timers,
                                                dom->clock.ntimers, timer) < 0) {
                        VIR_FREE(timer);
12629
                        goto cleanup;
12630 12631 12632 12633 12634 12635
                    }
                    timer->name = VIR_DOMAIN_TIMER_NAME_KVMCLOCK;
                    timer->present = present;
                    timer->tickpolicy = -1;
                    timer->track = -1;
                    timer->mode = -1;
12636 12637
                } else if (dom->clock.timers[j]->present != -1 &&
                    dom->clock.timers[j]->present != present) {
12638 12639
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("conflicting occurrences of kvmclock feature"));
12640
                    goto cleanup;
12641
                }
12642 12643
            } else if (STREQ(feature, "kvm_pv_eoi")) {
                if (policy == VIR_CPU_FEATURE_REQUIRE)
J
Ján Tomko 已提交
12644
                    dom->apic_eoi = VIR_TRISTATE_SWITCH_ON;
12645
                else
J
Ján Tomko 已提交
12646
                    dom->apic_eoi = VIR_TRISTATE_SWITCH_OFF;
12647 12648 12649
            } else {
                if (!cpu) {
                    if (!(cpu = qemuInitGuestCPU(dom)))
12650
                        goto cleanup;
12651

12652 12653 12654 12655
                    cpu->model = model;
                    model = NULL;
                }

12656 12657
                if (virCPUDefAddFeature(cpu, feature, policy) < 0)
                    goto cleanup;
12658
            }
12659
        } else if (STREQ(tokens[i], "hv_crash")) {
D
Dmitry Andreev 已提交
12660 12661 12662 12663 12664 12665 12666 12667 12668 12669 12670 12671 12672 12673 12674 12675
            size_t j;
            for (j = 0; j < dom->npanics; j++) {
                 if (dom->panics[j]->model == VIR_DOMAIN_PANIC_MODEL_HYPERV)
                     break;
            }

            if (j == dom->npanics) {
                virDomainPanicDefPtr panic;
                if (VIR_ALLOC(panic) < 0 ||
                    VIR_APPEND_ELEMENT_COPY(dom->panics,
                                            dom->npanics, panic) < 0) {
                    VIR_FREE(panic);
                    goto cleanup;
                }
                panic->model = VIR_DOMAIN_PANIC_MODEL_HYPERV;
            }
12676
        } else if (STRPREFIX(tokens[i], "hv_")) {
12677 12678
            const char *token = tokens[i] + 3; /* "hv_" */
            const char *feature, *value;
12679 12680
            int f;

12681 12682 12683 12684 12685 12686 12687 12688 12689
            if (*token == '\0')
                goto syntax;

            if (!(hv_tokens = virStringSplit(token, "=", 2)))
                goto cleanup;

            feature = hv_tokens[0];
            value = hv_tokens[1];

12690
            if (*feature == '\0')
12691 12692
                goto syntax;

J
Ján Tomko 已提交
12693
            dom->features[VIR_DOMAIN_FEATURE_HYPERV] = VIR_TRISTATE_SWITCH_ON;
12694 12695 12696 12697 12698

            if ((f = virDomainHypervTypeFromString(feature)) < 0) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("unsupported HyperV Enlightenment feature "
                                 "'%s'"), feature);
12699
                goto cleanup;
12700 12701
            }

12702
            switch ((virDomainHyperv) f) {
12703
            case VIR_DOMAIN_HYPERV_RELAXED:
12704 12705 12706 12707 12708 12709 12710
            case VIR_DOMAIN_HYPERV_VAPIC:
                if (value) {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("HyperV feature '%s' should not "
                                     "have a value"), feature);
                    goto cleanup;
                }
J
Ján Tomko 已提交
12711
                dom->hyperv_features[f] = VIR_TRISTATE_SWITCH_ON;
12712 12713
                break;

12714
            case VIR_DOMAIN_HYPERV_SPINLOCKS:
J
Ján Tomko 已提交
12715
                dom->hyperv_features[f] = VIR_TRISTATE_SWITCH_ON;
12716 12717 12718 12719 12720 12721 12722 12723 12724 12725 12726 12727 12728 12729
                if (!value) {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("missing HyperV spinlock retry count"));
                    goto cleanup;
                }

                if (virStrToLong_ui(value, NULL, 0, &dom->hyperv_spinlocks) < 0) {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("cannot parse HyperV spinlock retry count"));
                    goto cleanup;
                }

                if (dom->hyperv_spinlocks < 0xFFF)
                    dom->hyperv_spinlocks = 0xFFF;
12730 12731
                break;

12732 12733 12734
            case VIR_DOMAIN_HYPERV_LAST:
                break;
            }
12735 12736
            virStringFreeList(hv_tokens);
            hv_tokens = NULL;
12737 12738 12739
        } else if (STREQ(tokens[i], "kvm=off")) {
             dom->features[VIR_DOMAIN_FEATURE_KVM] = VIR_TRISTATE_SWITCH_ON;
             dom->kvm_features[VIR_DOMAIN_KVM_HIDDEN] = VIR_TRISTATE_SWITCH_ON;
12740
        }
12741
    }
12742

12743
    if (dom->os.arch == VIR_ARCH_X86_64) {
12744
        bool is_32bit = false;
12745
        if (cpu) {
12746
            virCPUDataPtr cpuData = NULL;
12747

12748 12749 12750
            if (cpuEncode(VIR_ARCH_X86_64, cpu, NULL, &cpuData,
                          NULL, NULL, NULL, NULL) < 0)
                goto cleanup;
12751

J
Jiri Denemark 已提交
12752 12753
            is_32bit = (cpuHasFeature(cpuData, "lm") != 1);
            cpuDataFree(cpuData);
12754 12755 12756
        } else if (model) {
            is_32bit = STREQ(model, "qemu32");
        }
12757

12758
        if (is_32bit)
12759
            dom->os.arch = VIR_ARCH_I686;
12760
    }
12761 12762 12763

    ret = 0;

12764
 cleanup:
12765
    VIR_FREE(model);
12766
    virStringFreeList(tokens);
12767
    virStringFreeList(hv_tokens);
12768
    return ret;
12769

12770
 syntax:
12771 12772
    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("unknown CPU syntax '%s'"), val);
12773
    goto cleanup;
12774 12775 12776 12777 12778 12779 12780 12781 12782 12783 12784
}


static int
qemuParseCommandLineSmp(virDomainDefPtr dom,
                        const char *val)
{
    unsigned int sockets = 0;
    unsigned int cores = 0;
    unsigned int threads = 0;
    unsigned int maxcpus = 0;
12785
    unsigned int vcpus = 0;
12786
    size_t i;
12787 12788 12789 12790 12791 12792 12793
    int nkws;
    char **kws;
    char **vals;
    int n;
    char *end;
    int ret;

12794
    if (qemuParseKeywords(val, &kws, &vals, &nkws, 1) < 0)
12795 12796 12797 12798 12799
        return -1;

    for (i = 0; i < nkws; i++) {
        if (vals[i] == NULL) {
            if (i > 0 ||
12800
                virStrToLong_ui(kws[i], &end, 10, &vcpus) < 0 || *end != '\0')
12801 12802 12803 12804 12805 12806 12807 12808 12809 12810 12811 12812 12813 12814 12815 12816 12817
                goto syntax;
        } else {
            if (virStrToLong_i(vals[i], &end, 10, &n) < 0 || *end != '\0')
                goto syntax;
            if (STREQ(kws[i], "sockets"))
                sockets = n;
            else if (STREQ(kws[i], "cores"))
                cores = n;
            else if (STREQ(kws[i], "threads"))
                threads = n;
            else if (STREQ(kws[i], "maxcpus"))
                maxcpus = n;
            else
                goto syntax;
        }
    }

12818
    if (maxcpus == 0)
12819
        maxcpus = vcpus;
12820 12821 12822

    if (virDomainDefSetVcpusMax(dom, maxcpus) < 0)
        goto error;
12823

12824 12825 12826
    if (virDomainDefSetVcpus(dom, vcpus) < 0)
        goto error;

12827 12828 12829 12830 12831 12832 12833 12834
    if (sockets && cores && threads) {
        virCPUDefPtr cpu;

        if (!(cpu = qemuInitGuestCPU(dom)))
            goto error;
        cpu->sockets = sockets;
        cpu->cores = cores;
        cpu->threads = threads;
12835
    } else if (sockets || cores || threads) {
12836
        goto syntax;
12837
    }
12838 12839 12840

    ret = 0;

12841
 cleanup:
12842 12843 12844 12845 12846 12847 12848 12849 12850
    for (i = 0; i < nkws; i++) {
        VIR_FREE(kws[i]);
        VIR_FREE(vals[i]);
    }
    VIR_FREE(kws);
    VIR_FREE(vals);

    return ret;

12851
 syntax:
12852 12853
    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("cannot parse CPU topology '%s'"), val);
12854
 error:
12855 12856 12857 12858 12859
    ret = -1;
    goto cleanup;
}


12860
static void
12861 12862
qemuParseCommandLineBootDevs(virDomainDefPtr def, const char *str)
{
12863 12864
    int n, b = 0;

12865
    for (n = 0; str[n] && b < VIR_DOMAIN_BOOT_LAST; n++) {
12866 12867 12868 12869 12870 12871 12872 12873 12874 12875 12876 12877 12878 12879 12880
        if (str[n] == 'a')
            def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_FLOPPY;
        else if (str[n] == 'c')
            def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_DISK;
        else if (str[n] == 'd')
            def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_CDROM;
        else if (str[n] == 'n')
            def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_NET;
        else if (str[n] == ',')
            break;
    }
    def->os.nBootDevs = b;
}


12881 12882 12883 12884 12885
/*
 * Analyse the env and argv settings and reconstruct a
 * virDomainDefPtr representing these settings as closely
 * as is practical. This is not an exact science....
 */
E
Eric Blake 已提交
12886 12887 12888 12889 12890 12891 12892 12893
static virDomainDefPtr
qemuParseCommandLine(virCapsPtr qemuCaps,
                     virDomainXMLOptionPtr xmlopt,
                     char **progenv,
                     char **progargv,
                     char **pidfile,
                     virDomainChrSourceDefPtr *monConfig,
                     bool *monJSON)
12894 12895
{
    virDomainDefPtr def;
12896
    size_t i;
12897
    bool nographics = false;
12898
    bool fullscreen = false;
12899
    char **list = NULL;
12900
    char *path;
12901
    size_t nnics = 0;
12902 12903 12904
    const char **nics = NULL;
    int video = VIR_DOMAIN_VIDEO_TYPE_CIRRUS;
    int nvirtiodisk = 0;
W
Wen Congyang 已提交
12905
    qemuDomainCmdlineDefPtr cmd = NULL;
E
Eric Blake 已提交
12906
    virDomainDiskDefPtr disk = NULL;
12907
    const char *ceph_args = qemuFindEnv(progenv, "CEPH_ARGS");
D
Daniel P. Berrange 已提交
12908
    bool have_sdl = false;
12909

12910 12911 12912 12913 12914 12915 12916
    if (pidfile)
        *pidfile = NULL;
    if (monConfig)
        *monConfig = NULL;
    if (monJSON)
        *monJSON = false;

12917
    if (!progargv[0]) {
12918 12919
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("no emulator path found"));
12920 12921 12922
        return NULL;
    }

12923
    if (!(def = virDomainDefNew()))
12924
        goto error;
12925 12926 12927

    /* allocate the cmdlinedef up-front; if it's unused, we'll free it later */
    if (VIR_ALLOC(cmd) < 0)
12928
        goto error;
12929

E
Eric Blake 已提交
12930
    if (virUUIDGenerate(def->uuid) < 0) {
12931 12932
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to generate uuid"));
E
Eric Blake 已提交
12933 12934
        goto error;
    }
12935 12936

    def->id = -1;
12937
    def->mem.cur_balloon = 64 * 1024;
12938
    virDomainDefSetMemoryTotal(def, def->mem.cur_balloon);
12939 12940
    if (virDomainDefSetVcpusMax(def, 1) < 0)
        goto error;
12941 12942
    if (virDomainDefSetVcpus(def, 1) < 0)
        goto error;
12943
    def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC;
12944

12945
    def->onReboot = VIR_DOMAIN_LIFECYCLE_RESTART;
12946
    def->onCrash = VIR_DOMAIN_LIFECYCLE_CRASH_DESTROY;
12947 12948
    def->onPoweroff = VIR_DOMAIN_LIFECYCLE_DESTROY;
    def->virtType = VIR_DOMAIN_VIRT_QEMU;
12949 12950
    if (VIR_STRDUP(def->emulator, progargv[0]) < 0)
        goto error;
12951

12952 12953
    if (!(path = last_component(def->emulator)))
        goto error;
12954

12955 12956
    def->os.type = VIR_DOMAIN_OSTYPE_HVM;
    if (strstr(path, "kvm")) {
12957
        def->virtType = VIR_DOMAIN_VIRT_KVM;
12958
        def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_TRISTATE_SWITCH_ON;
12959 12960
    }

12961
    if (def->virtType == VIR_DOMAIN_VIRT_KVM)
12962
        def->os.arch = qemuCaps->host.arch;
12963
    else if (STRPREFIX(path, "qemu-system-"))
12964
        def->os.arch = virArchFromString(path + strlen("qemu-system-"));
12965
    else
12966
        def->os.arch = VIR_ARCH_I686;
12967

12968 12969
    if ((def->os.arch == VIR_ARCH_I686) ||
        (def->os.arch == VIR_ARCH_X86_64))
J
Ján Tomko 已提交
12970
        def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_TRISTATE_SWITCH_ON;
12971

12972 12973 12974
#define WANT_VALUE()                                                   \
    const char *val = progargv[++i];                                   \
    if (!val) {                                                        \
12975
        virReportError(VIR_ERR_INTERNAL_ERROR,                         \
12976
                       _("missing value for %s argument"), arg);       \
12977 12978 12979 12980 12981
        goto error;                                                    \
    }

    /* One initial loop to get list of NICs, so we
     * can correlate them later */
12982
    for (i = 1; progargv[i]; i++) {
12983 12984 12985 12986 12987 12988 12989 12990
        const char *arg = progargv[i];
        /* Make sure we have a single - for all options to
           simplify next logic */
        if (STRPREFIX(arg, "--"))
            arg++;

        if (STREQ(arg, "-net")) {
            WANT_VALUE();
12991 12992 12993
            if (STRPREFIX(val, "nic") &&
                VIR_APPEND_ELEMENT(nics, nnics, val) < 0)
                goto error;
12994 12995 12996 12997
        }
    }

    /* Now the real processing loop */
12998
    for (i = 1; progargv[i]; i++) {
12999
        const char *arg = progargv[i];
L
Laine Stump 已提交
13000 13001
        bool argRecognized = true;

13002 13003 13004 13005 13006 13007 13008 13009 13010 13011
        /* Make sure we have a single - for all options to
           simplify next logic */
        if (STRPREFIX(arg, "--"))
            arg++;

        if (STREQ(arg, "-vnc")) {
            virDomainGraphicsDefPtr vnc;
            char *tmp;
            WANT_VALUE();
            if (VIR_ALLOC(vnc) < 0)
13012
                goto error;
13013 13014
            vnc->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;

13015
            if (STRPREFIX(val, "unix:")) {
13016
                /* -vnc unix:/some/big/path */
13017
                if (VIR_STRDUP(vnc->data.vnc.socket, val + 5) < 0) {
13018
                    virDomainGraphicsDefFree(vnc);
13019
                    goto error;
13020 13021
                }
            } else {
13022 13023 13024 13025 13026 13027
                /*
                 * -vnc 127.0.0.1:4
                 * -vnc [2001:1:2:3:4:5:1234:1234]:4
                 * -vnc some.host.name:4
                 */
                char *opts;
13028
                char *port;
13029 13030 13031 13032 13033
                const char *sep = ":";
                if (val[0] == '[')
                    sep = "]:";
                tmp = strstr(val, sep);
                if (!tmp) {
13034
                    virDomainGraphicsDefFree(vnc);
13035 13036
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("missing VNC port number in '%s'"), val);
13037 13038
                    goto error;
                }
13039 13040
                port = tmp + strlen(sep);
                if (virStrToLong_i(port, &opts, 10,
13041
                                   &vnc->data.vnc.port) < 0) {
13042
                    virDomainGraphicsDefFree(vnc);
13043
                    virReportError(VIR_ERR_INTERNAL_ERROR,
13044
                                   _("cannot parse VNC port '%s'"), port);
13045 13046 13047
                    goto error;
                }
                if (val[0] == '[')
13048 13049
                    virDomainGraphicsListenSetAddress(vnc, 0,
                                                      val+1, tmp-(val+1), true);
13050
                else
13051 13052 13053 13054
                    virDomainGraphicsListenSetAddress(vnc, 0,
                                                      val, tmp-val, true);
                if (!virDomainGraphicsListenGetAddress(vnc, 0)) {
                    virDomainGraphicsDefFree(vnc);
13055
                    goto error;
13056
                }
13057 13058

                if (*opts == ',') {
13059 13060 13061
                    char *orig_opts;

                    if (VIR_STRDUP(orig_opts, opts + 1) < 0) {
13062
                        virDomainGraphicsDefFree(vnc);
13063
                        goto error;
13064 13065 13066 13067 13068 13069 13070 13071 13072 13073 13074 13075 13076 13077 13078 13079 13080 13081 13082 13083 13084 13085 13086 13087 13088 13089 13090 13091 13092 13093 13094 13095
                    }
                    opts = orig_opts;

                    while (opts && *opts) {
                        char *nextopt = strchr(opts, ',');
                        if (nextopt)
                            *(nextopt++) = '\0';

                        if (STRPREFIX(opts, "websocket")) {
                            char *websocket = opts + strlen("websocket");
                            if (*(websocket++) == '=' &&
                                *websocket) {
                                /* If the websocket continues with
                                 * '=<something>', we'll parse it */
                                if (virStrToLong_i(websocket,
                                                   NULL, 0,
                                                   &vnc->data.vnc.websocket) < 0) {
                                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                                   _("cannot parse VNC "
                                                     "WebSocket port '%s'"),
                                                   websocket);
                                    virDomainGraphicsDefFree(vnc);
                                    VIR_FREE(orig_opts);
                                    goto error;
                                }
                            } else {
                                /* Otherwise, we'll compute the port the same
                                 * way QEMU does, by adding a 5700 to the
                                 * display value. */
                                vnc->data.vnc.websocket =
                                    vnc->data.vnc.port + 5700;
                            }
13096 13097 13098 13099 13100 13101 13102 13103 13104 13105 13106 13107 13108 13109 13110 13111 13112 13113 13114 13115 13116 13117 13118
                        } else if (STRPREFIX(opts, "share=")) {
                            char *sharePolicy = opts + strlen("share=");
                            if (sharePolicy && *sharePolicy) {
                                int policy =
                                    virDomainGraphicsVNCSharePolicyTypeFromString(sharePolicy);

                                if (policy < 0) {
                                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                                   _("unknown vnc display sharing policy '%s'"),
                                                     sharePolicy);
                                    virDomainGraphicsDefFree(vnc);
                                    VIR_FREE(orig_opts);
                                    goto error;
                                } else {
                                    vnc->data.vnc.sharePolicy = policy;
                                }
                            } else {
                                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                               _("missing vnc sharing policy"));
                                virDomainGraphicsDefFree(vnc);
                                VIR_FREE(orig_opts);
                                goto error;
                            }
13119 13120 13121 13122 13123 13124
                        }

                        opts = nextopt;
                    }
                    VIR_FREE(orig_opts);
                }
13125
                vnc->data.vnc.port += 5900;
13126
                vnc->data.vnc.autoport = false;
13127 13128
            }

13129
            if (VIR_APPEND_ELEMENT(def->graphics, def->ngraphics, vnc) < 0) {
13130
                virDomainGraphicsDefFree(vnc);
13131
                goto error;
13132
            }
13133
        } else if (STREQ(arg, "-sdl")) {
D
Daniel P. Berrange 已提交
13134
            have_sdl = true;
13135 13136 13137 13138
        } else if (STREQ(arg, "-m")) {
            int mem;
            WANT_VALUE();
            if (virStrToLong_i(val, NULL, 10, &mem) < 0) {
13139 13140
                virReportError(VIR_ERR_INTERNAL_ERROR, \
                               _("cannot parse memory level '%s'"), val);
13141 13142
                goto error;
            }
13143
            virDomainDefSetMemoryTotal(def, mem * 1024);
13144
            def->mem.cur_balloon = mem * 1024;
13145 13146 13147 13148 13149 13150 13151
        } else if (STREQ(arg, "-smp")) {
            WANT_VALUE();
            if (qemuParseCommandLineSmp(def, val) < 0)
                goto error;
        } else if (STREQ(arg, "-uuid")) {
            WANT_VALUE();
            if (virUUIDParse(val, def->uuid) < 0) {
13152 13153
                virReportError(VIR_ERR_INTERNAL_ERROR, \
                               _("cannot parse UUID '%s'"), val);
13154 13155 13156 13157 13158 13159 13160
                goto error;
            }
        } else if (STRPREFIX(arg, "-hd") ||
                   STRPREFIX(arg, "-sd") ||
                   STRPREFIX(arg, "-fd") ||
                   STREQ(arg, "-cdrom")) {
            WANT_VALUE();
13161
            if (!(disk = virDomainDiskDefNew(xmlopt)))
13162
                goto error;
13163

13164
            if (STRPREFIX(val, "/dev/")) {
13165
                disk->src->type = VIR_STORAGE_TYPE_BLOCK;
13166
            } else if (STRPREFIX(val, "nbd:")) {
13167 13168
                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_NBD;
13169
            } else if (STRPREFIX(val, "rbd:")) {
13170 13171
                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_RBD;
13172
                val += strlen("rbd:");
13173
            } else if (STRPREFIX(val, "gluster")) {
13174 13175
                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_GLUSTER;
13176
            } else if (STRPREFIX(val, "sheepdog:")) {
13177 13178
                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_SHEEPDOG;
13179
                val += strlen("sheepdog:");
13180
            } else {
13181
                disk->src->type = VIR_STORAGE_TYPE_FILE;
13182
            }
13183 13184
            if (STREQ(arg, "-cdrom")) {
                disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
13185
                if ((ARCH_IS_PPC64(def->os.arch) &&
13186
                    def->os.machine && STRPREFIX(def->os.machine, "pseries")))
13187
                    disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
13188 13189
                if (VIR_STRDUP(disk->dst, "hdc") < 0)
                    goto error;
13190
                disk->src->readonly = true;
13191 13192 13193 13194 13195 13196 13197 13198 13199 13200
            } else {
                if (STRPREFIX(arg, "-fd")) {
                    disk->device = VIR_DOMAIN_DISK_DEVICE_FLOPPY;
                    disk->bus = VIR_DOMAIN_DISK_BUS_FDC;
                } else {
                    disk->device = VIR_DOMAIN_DISK_DEVICE_DISK;
                    if (STRPREFIX(arg, "-hd"))
                        disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
                    else
                        disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
13201
                   if ((ARCH_IS_PPC64(def->os.arch) &&
13202
                       def->os.machine && STRPREFIX(def->os.machine, "pseries")))
13203
                       disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
13204
                }
13205 13206
                if (VIR_STRDUP(disk->dst, arg + 1) < 0)
                    goto error;
13207
            }
13208
            if (VIR_STRDUP(disk->src->path, val) < 0)
13209
                goto error;
13210

13211
            if (disk->src->type == VIR_STORAGE_TYPE_NETWORK) {
13212
                char *port;
13213

13214
                switch ((virStorageNetProtocol) disk->src->protocol) {
13215
                case VIR_STORAGE_NET_PROTOCOL_NBD:
13216
                    if (qemuParseNBDString(disk) < 0)
13217 13218
                        goto error;
                    break;
13219
                case VIR_STORAGE_NET_PROTOCOL_RBD:
13220 13221 13222
                    /* old-style CEPH_ARGS env variable is parsed later */
                    if (!ceph_args && qemuParseRBDString(disk) < 0)
                        goto error;
13223
                    break;
13224
                case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
13225
                    /* disk->src must be [vdiname] or [host]:[port]:[vdiname] */
13226
                    port = strchr(disk->src->path, ':');
13227 13228 13229 13230 13231 13232
                    if (port) {
                        char *vdi;

                        *port++ = '\0';
                        vdi = strchr(port, ':');
                        if (!vdi) {
13233 13234
                            virReportError(VIR_ERR_INTERNAL_ERROR,
                                           _("cannot parse sheepdog filename '%s'"), val);
13235 13236 13237
                            goto error;
                        }
                        *vdi++ = '\0';
13238
                        if (VIR_ALLOC(disk->src->hosts) < 0)
13239
                            goto error;
13240 13241 13242
                        disk->src->nhosts = 1;
                        disk->src->hosts->name = disk->src->path;
                        if (VIR_STRDUP(disk->src->hosts->port, port) < 0)
13243
                            goto error;
13244
                        if (VIR_STRDUP(disk->src->path, vdi) < 0)
13245
                            goto error;
13246 13247
                    }
                    break;
13248
                case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
13249 13250 13251
                    if (qemuParseGlusterString(disk) < 0)
                        goto error;

P
Paolo Bonzini 已提交
13252
                    break;
13253
                case VIR_STORAGE_NET_PROTOCOL_ISCSI:
P
Paolo Bonzini 已提交
13254 13255 13256
                    if (qemuParseISCSIString(disk) < 0)
                        goto error;

13257
                    break;
13258 13259 13260 13261 13262 13263
                case VIR_STORAGE_NET_PROTOCOL_HTTP:
                case VIR_STORAGE_NET_PROTOCOL_HTTPS:
                case VIR_STORAGE_NET_PROTOCOL_FTP:
                case VIR_STORAGE_NET_PROTOCOL_FTPS:
                case VIR_STORAGE_NET_PROTOCOL_TFTP:
                case VIR_STORAGE_NET_PROTOCOL_LAST:
13264
                case VIR_STORAGE_NET_PROTOCOL_NONE:
13265 13266
                    /* ignored for now */
                    break;
13267 13268 13269
                }
            }

13270
            if (virDomainDiskDefAssignAddress(xmlopt, disk, def) < 0) {
13271 13272 13273
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("Cannot assign address for device name '%s'"),
                               disk->dst);
13274
                goto error;
13275
            }
13276

13277
            if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
13278
                goto error;
13279
        } else if (STREQ(arg, "-no-acpi")) {
J
Ján Tomko 已提交
13280
            def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_TRISTATE_SWITCH_ABSENT;
13281 13282 13283 13284
        } else if (STREQ(arg, "-no-reboot")) {
            def->onReboot = VIR_DOMAIN_LIFECYCLE_DESTROY;
        } else if (STREQ(arg, "-no-kvm")) {
            def->virtType = VIR_DOMAIN_VIRT_QEMU;
P
Paolo Bonzini 已提交
13285 13286
        } else if (STREQ(arg, "-enable-kvm")) {
            def->virtType = VIR_DOMAIN_VIRT_KVM;
13287
        } else if (STREQ(arg, "-nographic")) {
13288
            nographics = true;
13289
        } else if (STREQ(arg, "-full-screen")) {
13290
            fullscreen = true;
13291 13292 13293 13294
        } else if (STREQ(arg, "-localtime")) {
            def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME;
        } else if (STREQ(arg, "-kernel")) {
            WANT_VALUE();
13295 13296
            if (VIR_STRDUP(def->os.kernel, val) < 0)
                goto error;
13297 13298
        } else if (STREQ(arg, "-bios")) {
            WANT_VALUE();
13299 13300
            if (VIR_ALLOC(def->os.loader) < 0 ||
                VIR_STRDUP(def->os.loader->path, val) < 0)
13301
                goto error;
13302 13303
        } else if (STREQ(arg, "-initrd")) {
            WANT_VALUE();
13304 13305
            if (VIR_STRDUP(def->os.initrd, val) < 0)
                goto error;
13306 13307
        } else if (STREQ(arg, "-append")) {
            WANT_VALUE();
13308 13309
            if (VIR_STRDUP(def->os.cmdline, val) < 0)
                goto error;
O
Olivia Yin 已提交
13310 13311
        } else if (STREQ(arg, "-dtb")) {
            WANT_VALUE();
13312 13313
            if (VIR_STRDUP(def->os.dtb, val) < 0)
                goto error;
13314
        } else if (STREQ(arg, "-boot")) {
13315
            const char *token = NULL;
13316 13317
            WANT_VALUE();

13318
            if (!strchr(val, ',')) {
13319
                qemuParseCommandLineBootDevs(def, val);
13320
            } else {
13321 13322 13323 13324 13325 13326 13327
                token = val;
                while (token && *token) {
                    if (STRPREFIX(token, "order=")) {
                        token += strlen("order=");
                        qemuParseCommandLineBootDevs(def, token);
                    } else if (STRPREFIX(token, "menu=on")) {
                        def->os.bootmenu = 1;
13328 13329 13330 13331 13332 13333 13334 13335 13336 13337 13338 13339 13340 13341 13342 13343
                    } else if (STRPREFIX(token, "reboot-timeout=")) {
                        int num;
                        char *endptr;
                        if (virStrToLong_i(token + strlen("reboot-timeout="),
                                           &endptr, 10, &num) < 0 ||
                            (*endptr != '\0' && endptr != strchr(token, ','))) {
                            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                           _("cannot parse reboot-timeout value"));
                            goto error;
                        }
                        if (num > 65535)
                            num = 65535;
                        else if (num < -1)
                            num = -1;
                        def->os.bios.rt_delay = num;
                        def->os.bios.rt_set = true;
13344 13345 13346 13347 13348 13349 13350 13351
                    }
                    token = strchr(token, ',');
                    /* This incrementation has to be done here in order to make it
                     * possible to pass the token pointer properly into the loop */
                    if (token)
                        token++;
                }
            }
13352 13353 13354 13355 13356
        } else if (STREQ(arg, "-name")) {
            char *process;
            WANT_VALUE();
            process = strstr(val, ",process=");
            if (process == NULL) {
13357 13358
                if (VIR_STRDUP(def->name, val) < 0)
                    goto error;
13359
            } else {
13360 13361
                if (VIR_STRNDUP(def->name, val, process - val) < 0)
                    goto error;
13362
            }
13363 13364
            if (STREQ(def->name, ""))
                VIR_FREE(def->name);
13365 13366
        } else if (STREQ(arg, "-M") ||
                   STREQ(arg, "-machine")) {
13367 13368 13369 13370 13371 13372
            char *param;
            size_t j = 0;

            /* -machine [type=]name[,prop[=value][,...]]
             * Set os.machine only if first parameter lacks '=' or
             * contains explicit type='...' */
13373
            WANT_VALUE();
13374 13375
            if (!(list = virStringSplit(val, ",", 0)))
                goto error;
13376 13377 13378 13379 13380
            param = list[0];

            if (STRPREFIX(param, "type="))
                param += strlen("type=");
            if (!strchr(param, '=')) {
13381
                if (VIR_STRDUP(def->os.machine, param) < 0)
13382
                    goto error;
13383 13384 13385 13386 13387 13388 13389
                j++;
            }

            /* handle all remaining "-machine" parameters */
            while ((param = list[j++])) {
                if (STRPREFIX(param, "dump-guest-core=")) {
                    param += strlen("dump-guest-core=");
J
Ján Tomko 已提交
13390
                    def->mem.dump_core = virTristateSwitchTypeFromString(param);
13391
                    if (def->mem.dump_core <= 0)
J
Ján Tomko 已提交
13392
                        def->mem.dump_core = VIR_TRISTATE_SWITCH_ABSENT;
13393 13394 13395 13396
                } else if (STRPREFIX(param, "mem-merge=off")) {
                    def->mem.nosharepages = true;
                } else if (STRPREFIX(param, "accel=kvm")) {
                    def->virtType = VIR_DOMAIN_VIRT_KVM;
J
Ján Tomko 已提交
13397
                    def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_TRISTATE_SWITCH_ON;
13398 13399 13400 13401 13402 13403 13404 13405 13406 13407 13408 13409 13410 13411 13412 13413 13414 13415 13416 13417 13418 13419 13420 13421 13422 13423
                } else if (STRPREFIX(param, "aes-key-wrap=")) {
                    if (STREQ(arg, "-M")) {
                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                       _("aes-key-wrap is not supported with "
                                         "this QEMU binary"));
                        goto error;
                    }
                    param += strlen("aes-key-wrap=");
                    if (!def->keywrap && VIR_ALLOC(def->keywrap) < 0)
                        goto error;
                    def->keywrap->aes = virTristateSwitchTypeFromString(param);
                    if (def->keywrap->aes < 0)
                        def->keywrap->aes = VIR_TRISTATE_SWITCH_ABSENT;
                } else if (STRPREFIX(param, "dea-key-wrap=")) {
                    if (STREQ(arg, "-M")) {
                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                       _("dea-key-wrap is not supported with "
                                         "this QEMU binary"));
                        goto error;
                    }
                    param += strlen("dea-key-wrap=");
                    if (!def->keywrap && VIR_ALLOC(def->keywrap) < 0)
                        goto error;
                    def->keywrap->dea = virTristateSwitchTypeFromString(param);
                    if (def->keywrap->dea < 0)
                        def->keywrap->dea = VIR_TRISTATE_SWITCH_ABSENT;
13424 13425
                }
            }
13426
            virStringFreeList(list);
13427
            list = NULL;
13428 13429 13430 13431
        } else if (STREQ(arg, "-serial")) {
            WANT_VALUE();
            if (STRNEQ(val, "none")) {
                virDomainChrDefPtr chr;
13432 13433 13434 13435

                if (!(chr = virDomainChrDefNew()))
                    goto error;

E
Eric Blake 已提交
13436 13437
                if (qemuParseCommandLineChr(&chr->source, val) < 0) {
                    virDomainChrDefFree(chr);
13438
                    goto error;
E
Eric Blake 已提交
13439
                }
13440 13441 13442
                chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
                chr->target.port = def->nserials;
                if (VIR_APPEND_ELEMENT(def->serials, def->nserials, chr) < 0) {
13443
                    virDomainChrDefFree(chr);
13444
                    goto error;
13445 13446 13447 13448 13449 13450
                }
            }
        } else if (STREQ(arg, "-parallel")) {
            WANT_VALUE();
            if (STRNEQ(val, "none")) {
                virDomainChrDefPtr chr;
13451 13452 13453 13454

                if (!(chr = virDomainChrDefNew()))
                    goto error;

E
Eric Blake 已提交
13455 13456
                if (qemuParseCommandLineChr(&chr->source, val) < 0) {
                    virDomainChrDefFree(chr);
13457
                    goto error;
E
Eric Blake 已提交
13458
                }
13459 13460 13461
                chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL;
                chr->target.port = def->nparallels;
                if (VIR_APPEND_ELEMENT(def->parallels, def->nparallels, chr) < 0) {
13462
                    virDomainChrDefFree(chr);
13463
                    goto error;
13464 13465 13466 13467 13468
                }
            }
        } else if (STREQ(arg, "-usbdevice")) {
            WANT_VALUE();
            if (STREQ(val, "tablet") ||
13469 13470
                STREQ(val, "mouse") ||
                STREQ(val, "keyboard")) {
13471 13472
                virDomainInputDefPtr input;
                if (VIR_ALLOC(input) < 0)
13473
                    goto error;
13474 13475 13476
                input->bus = VIR_DOMAIN_INPUT_BUS_USB;
                if (STREQ(val, "tablet"))
                    input->type = VIR_DOMAIN_INPUT_TYPE_TABLET;
13477
                else if (STREQ(val, "mouse"))
13478
                    input->type = VIR_DOMAIN_INPUT_TYPE_MOUSE;
13479 13480 13481 13482
                else
                    input->type = VIR_DOMAIN_INPUT_TYPE_KBD;

                if (VIR_APPEND_ELEMENT(def->inputs, def->ninputs, input) < 0) {
13483
                    virDomainInputDefFree(input);
13484
                    goto error;
13485 13486
                }
            } else if (STRPREFIX(val, "disk:")) {
13487
                if (!(disk = virDomainDiskDefNew(xmlopt)))
13488
                    goto error;
13489
                if (VIR_STRDUP(disk->src->path, val + strlen("disk:")) < 0)
13490
                    goto error;
13491 13492
                if (STRPREFIX(disk->src->path, "/dev/"))
                    disk->src->type = VIR_STORAGE_TYPE_BLOCK;
13493
                else
13494
                    disk->src->type = VIR_STORAGE_TYPE_FILE;
13495 13496
                disk->device = VIR_DOMAIN_DISK_DEVICE_DISK;
                disk->bus = VIR_DOMAIN_DISK_BUS_USB;
J
Ján Tomko 已提交
13497
                disk->removable = VIR_TRISTATE_SWITCH_ABSENT;
13498 13499
                if (VIR_STRDUP(disk->dst, "sda") < 0)
                    goto error;
13500
                if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
13501
                    goto error;
13502 13503 13504 13505
            } else {
                virDomainHostdevDefPtr hostdev;
                if (!(hostdev = qemuParseCommandLineUSB(val)))
                    goto error;
13506
                if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev) < 0) {
13507
                    virDomainHostdevDefFree(hostdev);
13508
                    goto error;
13509 13510 13511 13512 13513 13514
                }
            }
        } else if (STREQ(arg, "-net")) {
            WANT_VALUE();
            if (!STRPREFIX(val, "nic") && STRNEQ(val, "none")) {
                virDomainNetDefPtr net;
13515
                if (!(net = qemuParseCommandLineNet(xmlopt, val, nnics, nics)))
13516
                    goto error;
13517
                if (VIR_APPEND_ELEMENT(def->nets, def->nnets, net) < 0) {
13518
                    virDomainNetDefFree(net);
13519
                    goto error;
13520 13521 13522 13523
                }
            }
        } else if (STREQ(arg, "-drive")) {
            WANT_VALUE();
13524
            if (!(disk = qemuParseCommandLineDisk(xmlopt, val, def,
13525
                                                  nvirtiodisk,
13526
                                                  ceph_args != NULL)))
13527 13528 13529
                goto error;
            if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
                nvirtiodisk++;
13530 13531
            if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
                goto error;
13532 13533 13534 13535 13536
        } else if (STREQ(arg, "-pcidevice")) {
            virDomainHostdevDefPtr hostdev;
            WANT_VALUE();
            if (!(hostdev = qemuParseCommandLinePCI(val)))
                goto error;
13537
            if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev) < 0) {
13538
                virDomainHostdevDefFree(hostdev);
13539
                goto error;
13540 13541 13542 13543 13544 13545 13546 13547 13548 13549 13550 13551 13552 13553 13554 13555
            }
        } else if (STREQ(arg, "-soundhw")) {
            const char *start;
            WANT_VALUE();
            start = val;
            while (start) {
                const char *tmp = strchr(start, ',');
                int type = -1;
                if (STRPREFIX(start, "pcspk")) {
                    type = VIR_DOMAIN_SOUND_MODEL_PCSPK;
                } else if (STRPREFIX(start, "sb16")) {
                    type = VIR_DOMAIN_SOUND_MODEL_SB16;
                } else if (STRPREFIX(start, "es1370")) {
                    type = VIR_DOMAIN_SOUND_MODEL_ES1370;
                } else if (STRPREFIX(start, "ac97")) {
                    type = VIR_DOMAIN_SOUND_MODEL_AC97;
13556 13557
                } else if (STRPREFIX(start, "hda")) {
                    type = VIR_DOMAIN_SOUND_MODEL_ICH6;
13558 13559 13560 13561 13562
                }

                if (type != -1) {
                    virDomainSoundDefPtr snd;
                    if (VIR_ALLOC(snd) < 0)
13563
                        goto error;
13564
                    snd->model = type;
13565
                    if (VIR_APPEND_ELEMENT(def->sounds, def->nsounds, snd) < 0) {
13566
                        VIR_FREE(snd);
13567
                        goto error;
13568 13569 13570 13571 13572 13573 13574
                    }
                }

                start = tmp ? tmp + 1 : NULL;
            }
        } else if (STREQ(arg, "-watchdog")) {
            WANT_VALUE();
13575
            int model = virDomainWatchdogModelTypeFromString(val);
13576 13577 13578 13579

            if (model != -1) {
                virDomainWatchdogDefPtr wd;
                if (VIR_ALLOC(wd) < 0)
13580
                    goto error;
13581 13582 13583 13584 13585 13586
                wd->model = model;
                wd->action = VIR_DOMAIN_WATCHDOG_ACTION_RESET;
                def->watchdog = wd;
            }
        } else if (STREQ(arg, "-watchdog-action") && def->watchdog) {
            WANT_VALUE();
13587
            int action = virDomainWatchdogActionTypeFromString(val);
13588 13589 13590 13591 13592

            if (action != -1)
                def->watchdog->action = action;
        } else if (STREQ(arg, "-bootloader")) {
            WANT_VALUE();
13593 13594
            if (VIR_STRDUP(def->os.bootloader, val) < 0)
                goto error;
13595 13596 13597 13598 13599 13600 13601 13602 13603
        } else if (STREQ(arg, "-vmwarevga")) {
            video = VIR_DOMAIN_VIDEO_TYPE_VMVGA;
        } else if (STREQ(arg, "-std-vga")) {
            video = VIR_DOMAIN_VIDEO_TYPE_VGA;
        } else if (STREQ(arg, "-vga")) {
            WANT_VALUE();
            if (STRNEQ(val, "none")) {
                video = qemuVideoTypeFromString(val);
                if (video < 0) {
13604 13605
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("unknown video adapter type '%s'"), val);
13606 13607 13608 13609 13610 13611 13612 13613 13614 13615 13616
                    goto error;
                }
            }
        } else if (STREQ(arg, "-cpu")) {
            WANT_VALUE();
            if (qemuParseCommandLineCPU(def, val) < 0)
                goto error;
        } else if (STREQ(arg, "-domid")) {
            WANT_VALUE();
            /* ignore, generted on the fly */
        } else if (STREQ(arg, "-usb")) {
13617 13618
            virDomainControllerDefPtr ctldef;
            if (VIR_ALLOC(ctldef) < 0)
13619
                goto error;
13620 13621 13622
            ctldef->type = VIR_DOMAIN_CONTROLLER_TYPE_USB;
            ctldef->idx = 0;
            ctldef->model = -1;
13623 13624
            if (virDomainControllerInsert(def, ctldef) < 0) {
                VIR_FREE(ctldef);
13625
                goto error;
13626
            }
13627 13628
        } else if (STREQ(arg, "-pidfile")) {
            WANT_VALUE();
13629
            if (pidfile)
13630 13631
                if (VIR_STRDUP(*pidfile, val) < 0)
                    goto error;
13632 13633 13634 13635 13636
        } else if (STREQ(arg, "-incoming")) {
            WANT_VALUE();
            /* ignore, used via restore/migrate APIs */
        } else if (STREQ(arg, "-monitor")) {
            WANT_VALUE();
13637 13638 13639 13640
            if (monConfig) {
                virDomainChrSourceDefPtr chr;

                if (VIR_ALLOC(chr) < 0)
13641
                    goto error;
13642

E
Eric Blake 已提交
13643 13644
                if (qemuParseCommandLineChr(chr, val) < 0) {
                    virDomainChrSourceDefFree(chr);
13645
                    goto error;
E
Eric Blake 已提交
13646
                }
13647 13648 13649

                *monConfig = chr;
            }
13650 13651 13652 13653 13654 13655 13656 13657
        } else if (STREQ(arg, "-global") &&
                   STRPREFIX(progargv[i + 1], "PIIX4_PM.disable_s3=")) {
            /* We want to parse only the known "-global" parameters,
             * so the ones that we don't know are still added to the
             * namespace */
            WANT_VALUE();

            val += strlen("PIIX4_PM.disable_s3=");
13658
            if (STREQ(val, "0")) {
J
Ján Tomko 已提交
13659
                def->pm.s3 = VIR_TRISTATE_BOOL_YES;
13660
            } else if (STREQ(val, "1")) {
J
Ján Tomko 已提交
13661
                def->pm.s3 = VIR_TRISTATE_BOOL_NO;
13662
            } else {
13663 13664 13665 13666 13667 13668 13669 13670 13671 13672 13673 13674
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("invalid value for disable_s3 parameter: "
                                 "'%s'"), val);
                goto error;
            }

        } else if (STREQ(arg, "-global") &&
                   STRPREFIX(progargv[i + 1], "PIIX4_PM.disable_s4=")) {

            WANT_VALUE();

            val += strlen("PIIX4_PM.disable_s4=");
13675
            if (STREQ(val, "0")) {
J
Ján Tomko 已提交
13676
                def->pm.s4 = VIR_TRISTATE_BOOL_YES;
13677
            } else if (STREQ(val, "1")) {
J
Ján Tomko 已提交
13678
                def->pm.s4 = VIR_TRISTATE_BOOL_NO;
13679
            } else {
13680 13681 13682 13683 13684 13685
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("invalid value for disable_s4 parameter: "
                                 "'%s'"), val);
                goto error;
            }

13686 13687 13688 13689 13690
        } else if (STREQ(arg, "-global") &&
                   STRPREFIX(progargv[i + 1], "spapr-nvram.reg=")) {
            WANT_VALUE();

            if (VIR_ALLOC(def->nvram) < 0)
13691
                goto error;
13692 13693 13694 13695 13696 13697 13698 13699 13700 13701 13702

            def->nvram->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
            def->nvram->info.addr.spaprvio.has_reg = true;

            val += strlen("spapr-nvram.reg=");
            if (virStrToLong_ull(val, NULL, 16,
                                 &def->nvram->info.addr.spaprvio.reg) < 0) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse nvram's address '%s'"), val);
                goto error;
            }
13703 13704 13705
        } else if (STREQ(arg, "-S") ||
                   STREQ(arg, "-nodefaults") ||
                   STREQ(arg, "-nodefconfig")) {
13706
            /* ignore, always added by libvirt */
L
Laine Stump 已提交
13707 13708 13709 13710 13711 13712 13713 13714 13715 13716 13717 13718 13719 13720 13721 13722 13723 13724
        } else if (STREQ(arg, "-device") && progargv[1 + 1]) {
            const char *opts = progargv[i + 1];

            /* NB: we can't do WANT_VALUE until we're sure that we
             * recognize the device, otherwise the !argRecognized
             * logic below will be messed up
             */

            if (STRPREFIX(opts, "virtio-balloon")) {
                WANT_VALUE();
                if (VIR_ALLOC(def->memballoon) < 0)
                    goto error;
                def->memballoon->model = VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO;
            } else {
                /* add in new -device's here */

                argRecognized = false;
            }
13725
        } else {
L
Laine Stump 已提交
13726 13727 13728 13729
            argRecognized = false;
        }

        if (!argRecognized) {
13730
            char *tmp = NULL;
13731 13732 13733 13734 13735
            /* something we can't yet parse.  Add it to the qemu namespace
             * cmdline/environment advanced options and hope for the best
             */
            VIR_WARN("unknown QEMU argument '%s', adding to the qemu namespace",
                     arg);
13736 13737 13738
            if (VIR_STRDUP(tmp, arg) < 0 ||
                VIR_APPEND_ELEMENT(cmd->args, cmd->num_args, tmp) < 0) {
                VIR_FREE(tmp);
13739
                goto error;
13740
            }
13741 13742 13743 13744
        }
    }

#undef WANT_VALUE
13745 13746 13747
    if (def->ndisks > 0 && ceph_args) {
        char *hosts, *port, *saveptr = NULL, *token;
        virDomainDiskDefPtr first_rbd_disk = NULL;
13748
        for (i = 0; i < def->ndisks; i++) {
13749 13750
            if (def->disks[i]->src->type == VIR_STORAGE_TYPE_NETWORK &&
                def->disks[i]->src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) {
13751 13752
                first_rbd_disk = def->disks[i];
                break;
13753
            }
13754
        }
13755

13756
        if (!first_rbd_disk) {
13757 13758
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("CEPH_ARGS was set without an rbd disk"));
13759 13760
            goto error;
        }
13761

13762 13763
        /* CEPH_ARGS should be: -m host1[:port1][,host2[:port2]]... */
        if (!STRPREFIX(ceph_args, "-m ")) {
13764 13765
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("could not parse CEPH_ARGS '%s'"), ceph_args);
13766 13767
            goto error;
        }
13768 13769
        if (VIR_STRDUP(hosts, strchr(ceph_args, ' ') + 1) < 0)
            goto error;
13770
        first_rbd_disk->src->nhosts = 0;
13771 13772
        token = strtok_r(hosts, ",", &saveptr);
        while (token != NULL) {
13773 13774
            if (VIR_REALLOC_N(first_rbd_disk->src->hosts,
                              first_rbd_disk->src->nhosts + 1) < 0) {
13775
                VIR_FREE(hosts);
13776
                goto error;
13777 13778 13779 13780
            }
            port = strchr(token, ':');
            if (port) {
                *port++ = '\0';
13781
                if (VIR_STRDUP(port, port) < 0) {
13782
                    VIR_FREE(hosts);
13783
                    goto error;
13784 13785
                }
            }
13786 13787
            first_rbd_disk->src->hosts[first_rbd_disk->src->nhosts].port = port;
            if (VIR_STRDUP(first_rbd_disk->src->hosts[first_rbd_disk->src->nhosts].name,
13788
                           token) < 0) {
13789
                VIR_FREE(hosts);
13790
                goto error;
13791
            }
13792 13793
            first_rbd_disk->src->hosts[first_rbd_disk->src->nhosts].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
            first_rbd_disk->src->hosts[first_rbd_disk->src->nhosts].socket = NULL;
13794

13795
            first_rbd_disk->src->nhosts++;
13796 13797 13798 13799
            token = strtok_r(NULL, ",", &saveptr);
        }
        VIR_FREE(hosts);

13800
        if (first_rbd_disk->src->nhosts == 0) {
13801 13802
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("found no rbd hosts in CEPH_ARGS '%s'"), ceph_args);
13803
            goto error;
13804 13805 13806
        }
    }

13807
    if (!def->os.machine) {
13808 13809 13810 13811 13812 13813 13814 13815 13816 13817 13818
        virCapsDomainDataPtr capsdata;

        if (!(capsdata = virCapabilitiesDomainDataLookup(qemuCaps, def->os.type,
                def->os.arch, def->virtType, NULL, NULL)))
            goto error;

        if (VIR_STRDUP(def->os.machine, capsdata->machinetype) < 0) {
            VIR_FREE(capsdata);
            goto error;
        }
        VIR_FREE(capsdata);
13819 13820
    }

D
Daniel P. Berrange 已提交
13821
    if (!nographics && (def->ngraphics == 0 || have_sdl)) {
13822 13823 13824 13825
        virDomainGraphicsDefPtr sdl;
        const char *display = qemuFindEnv(progenv, "DISPLAY");
        const char *xauth = qemuFindEnv(progenv, "XAUTHORITY");
        if (VIR_ALLOC(sdl) < 0)
13826
            goto error;
13827 13828
        sdl->type = VIR_DOMAIN_GRAPHICS_TYPE_SDL;
        sdl->data.sdl.fullscreen = fullscreen;
13829
        if (VIR_STRDUP(sdl->data.sdl.display, display) < 0) {
13830
            VIR_FREE(sdl);
13831
            goto error;
13832
        }
13833
        if (VIR_STRDUP(sdl->data.sdl.xauth, xauth) < 0) {
13834
            VIR_FREE(sdl);
13835
            goto error;
13836 13837
        }

13838
        if (VIR_APPEND_ELEMENT(def->graphics, def->ngraphics, sdl) < 0) {
13839
            virDomainGraphicsDefFree(sdl);
13840
            goto error;
13841 13842 13843 13844 13845 13846
        }
    }

    if (def->ngraphics) {
        virDomainVideoDefPtr vid;
        if (VIR_ALLOC(vid) < 0)
13847
            goto error;
13848 13849 13850 13851 13852
        if (def->virtType == VIR_DOMAIN_VIRT_XEN)
            vid->type = VIR_DOMAIN_VIDEO_TYPE_XEN;
        else
            vid->type = video;
        vid->vram = virDomainVideoDefaultRAM(def, vid->type);
13853 13854
        if (vid->type == VIR_DOMAIN_VIDEO_TYPE_QXL) {
            vid->ram = virDomainVideoDefaultRAM(def, vid->type);
13855
            vid->vgamem = QEMU_QXL_VGAMEM_DEFAULT;
13856 13857 13858 13859
        } else {
            vid->ram = 0;
            vid->vgamem = 0;
        }
13860 13861
        vid->heads = 1;

13862
        if (VIR_APPEND_ELEMENT(def->videos, def->nvideos, vid) < 0) {
13863
            virDomainVideoDefFree(vid);
13864
            goto error;
13865 13866 13867 13868 13869 13870 13871 13872 13873
        }
    }

    /*
     * having a balloon is the default, define one with type="none" to avoid it
     */
    if (!def->memballoon) {
        virDomainMemballoonDefPtr memballoon;
        if (VIR_ALLOC(memballoon) < 0)
13874
            goto error;
L
Laine Stump 已提交
13875
        memballoon->model = VIR_DOMAIN_MEMBALLOON_MODEL_NONE;
13876 13877 13878 13879 13880 13881 13882 13883 13884

        def->memballoon = memballoon;
    }

    VIR_FREE(nics);

    if (virDomainDefAddImplicitControllers(def) < 0)
        goto error;

13885 13886
    if (virDomainDefPostParse(def, qemuCaps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
                              xmlopt) < 0)
13887 13888
        goto error;

13889
    if (cmd->num_args || cmd->num_env) {
13890
        def->ns = *virDomainXMLOptionGetNamespace(xmlopt);
13891 13892 13893
        def->namespaceData = cmd;
    }
    else
13894
        qemuDomainCmdlineDefFree(cmd);
13895 13896 13897

    return def;

13898
 error:
E
Eric Blake 已提交
13899
    virDomainDiskDefFree(disk);
13900
    qemuDomainCmdlineDefFree(cmd);
13901
    virDomainDefFree(def);
13902
    virStringFreeList(list);
13903
    VIR_FREE(nics);
13904 13905 13906 13907 13908 13909
    if (monConfig) {
        virDomainChrSourceDefFree(*monConfig);
        *monConfig = NULL;
    }
    if (pidfile)
        VIR_FREE(*pidfile);
13910 13911 13912 13913
    return NULL;
}


13914
virDomainDefPtr qemuParseCommandLineString(virCapsPtr qemuCaps,
13915
                                           virDomainXMLOptionPtr xmlopt,
13916 13917 13918 13919
                                           const char *args,
                                           char **pidfile,
                                           virDomainChrSourceDefPtr *monConfig,
                                           bool *monJSON)
13920
{
E
Eric Blake 已提交
13921 13922
    char **progenv = NULL;
    char **progargv = NULL;
13923 13924 13925 13926 13927
    virDomainDefPtr def = NULL;

    if (qemuStringToArgvEnv(args, &progenv, &progargv) < 0)
        goto cleanup;

13928
    def = qemuParseCommandLine(qemuCaps, xmlopt, progenv, progargv,
13929
                               pidfile, monConfig, monJSON);
13930

13931
 cleanup:
E
Eric Blake 已提交
13932 13933
    virStringFreeList(progargv);
    virStringFreeList(progenv);
13934 13935 13936

    return def;
}
13937 13938


13939
static int qemuParseProcFileStrings(int pid_value,
13940
                                    const char *name,
E
Eric Blake 已提交
13941
                                    char ***list)
13942 13943 13944 13945 13946 13947 13948
{
    char *path = NULL;
    int ret = -1;
    char *data = NULL;
    ssize_t len;
    char *tmp;
    size_t nstr = 0;
13949
    char **str = NULL;
13950

13951
    if (virAsprintf(&path, "/proc/%d/%s", pid_value, name) < 0)
13952 13953 13954 13955 13956 13957 13958
        goto cleanup;

    if ((len = virFileReadAll(path, 1024*128, &data)) < 0)
        goto cleanup;

    tmp = data;
    while (tmp < (data + len)) {
13959
        if (VIR_EXPAND_N(str, nstr, 1) < 0)
13960 13961
            goto cleanup;

13962
        if (VIR_STRDUP(str[nstr-1], tmp) < 0)
13963 13964 13965 13966 13967 13968 13969
            goto cleanup;
        /* Skip arg */
        tmp += strlen(tmp);
        /* Skip \0 separator */
        tmp++;
    }

13970
    if (VIR_EXPAND_N(str, nstr, 1) < 0)
13971 13972 13973 13974 13975
        goto cleanup;

    str[nstr-1] = NULL;

    ret = nstr-1;
E
Eric Blake 已提交
13976
    *list = str;
13977

13978
 cleanup:
E
Eric Blake 已提交
13979 13980
    if (ret < 0)
        virStringFreeList(str);
13981 13982 13983 13984 13985
    VIR_FREE(data);
    VIR_FREE(path);
    return ret;
}

13986
virDomainDefPtr qemuParseCommandLinePid(virCapsPtr qemuCaps,
13987
                                        virDomainXMLOptionPtr xmlopt,
13988
                                        pid_t pid,
13989 13990 13991 13992 13993
                                        char **pidfile,
                                        virDomainChrSourceDefPtr *monConfig,
                                        bool *monJSON)
{
    virDomainDefPtr def = NULL;
E
Eric Blake 已提交
13994 13995
    char **progargv = NULL;
    char **progenv = NULL;
13996 13997 13998
    char *exepath = NULL;
    char *emulator;

13999 14000 14001 14002
    /* The parser requires /proc/pid, which only exists on platforms
     * like Linux where pid_t fits in int.  */
    if ((int) pid != pid ||
        qemuParseProcFileStrings(pid, "cmdline", &progargv) < 0 ||
14003 14004 14005
        qemuParseProcFileStrings(pid, "environ", &progenv) < 0)
        goto cleanup;

14006
    if (!(def = qemuParseCommandLine(qemuCaps, xmlopt, progenv, progargv,
14007 14008 14009
                                     pidfile, monConfig, monJSON)))
        goto cleanup;

14010
    if (virAsprintf(&exepath, "/proc/%d/exe", (int) pid) < 0)
14011 14012 14013 14014 14015
        goto cleanup;

    if (virFileResolveLink(exepath, &emulator) < 0) {
        virReportSystemError(errno,
                             _("Unable to resolve %s for pid %u"),
14016
                             exepath, (int) pid);
14017 14018 14019 14020 14021
        goto cleanup;
    }
    VIR_FREE(def->emulator);
    def->emulator = emulator;

14022
 cleanup:
14023
    VIR_FREE(exepath);
E
Eric Blake 已提交
14024 14025
    virStringFreeList(progargv);
    virStringFreeList(progenv);
14026 14027
    return def;
}