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

#include <config.h>

#include "qemu_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 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111
        case VIR_DOMAIN_CONTROLLER_TYPE_USB:
            if ((def->controllers[i]->model
                 == VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI1) &&
                (def->controllers[i]->info.type
                 == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)) {
                /* Try to assign the first found USB2 controller to
                 * 00:1D.0 and 2nd to 00:1A.0 (because that is their
                 * standard location on real Q35 hardware) unless they
                 * are already taken, but don't insist on it.
                 *
                 * (NB: all other controllers at the same index will
                 * get assigned to the same slot as the UHCI1 when
                 * addresses are later assigned to all devices.)
                 */
                bool assign = false;

                memset(&tmp_addr, 0, sizeof(tmp_addr));
                tmp_addr.slot = 0x1D;
                if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
                    assign = true;
                } else {
                    tmp_addr.slot = 0x1A;
                    if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr))
                        assign = true;
                }
                if (assign) {
                    if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr,
                                                       flags, false, true) < 0)
                        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 = tmp_addr.slot;
                    def->controllers[i]->info.addr.pci.function = 0;
                    def->controllers[i]->info.addr.pci.multi
                       = VIR_TRISTATE_SWITCH_ON;
                }
            }
            break;

2112 2113 2114 2115 2116 2117 2118 2119 2120
        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;
2121 2122 2123
                if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
                    if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr,
                                                       flags, true, false) < 0)
2124 2125 2126 2127 2128 2129 2130 2131 2132
                        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;
2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144
        }
    }

    /* 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;
2145
        tmp_addr.multi = VIR_TRISTATE_SWITCH_ON;
2146 2147
        if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,
                                           false, false) < 0)
2148
           goto cleanup;
2149
        tmp_addr.function = 3;
2150
        tmp_addr.multi = VIR_TRISTATE_SWITCH_ABSENT;
2151 2152
        if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,
                                           false, false) < 0)
2153
           goto cleanup;
2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164
    }

    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) {
2165 2166 2167
            memset(&tmp_addr, 0, sizeof(tmp_addr));
            tmp_addr.slot = 1;

2168
            if (!(addrStr = virDomainPCIAddressAsString(&tmp_addr)))
2169
                goto cleanup;
2170 2171
            if (!virDomainPCIAddressValidate(addrs, &tmp_addr,
                                             addrStr, flags, false))
2172
                goto cleanup;
2173

2174
            if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
2175
                if (qemuDeviceVideoUsable) {
2176 2177 2178
                    if (virDomainPCIAddressReserveNextSlot(addrs,
                                                           &primaryVideo->info,
                                                           flags) < 0)
2179
                        goto cleanup;
2180 2181 2182 2183
                } else {
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("PCI address 0:0:1.0 is in use, "
                                     "QEMU needs it for primary video"));
2184
                    goto cleanup;
2185
                }
2186
            } else {
2187
                if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0)
2188 2189 2190
                    goto cleanup;
                primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
                primaryVideo->info.addr.pci = tmp_addr;
2191 2192 2193 2194 2195 2196 2197 2198
            }
        } 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"));
2199
                goto cleanup;
2200
            }
2201
            /* If TYPE == PCI, then qemuCollectPCIAddress() function
2202 2203 2204 2205 2206 2207
             * 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;

2208
        if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
2209 2210 2211 2212
            VIR_DEBUG("PCI address 0:0:1.0 in use, future addition of a video"
                      " device will not be possible without manual"
                      " intervention");
            virResetLastError();
2213
        } else if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0) {
2214
            goto cleanup;
2215 2216
        }
    }
2217
    ret = 0;
2218
 cleanup:
2219 2220
    VIR_FREE(addrStr);
    return ret;
2221 2222
}

2223 2224 2225 2226 2227
static int
qemuValidateDevicePCISlotsChipsets(virDomainDefPtr def,
                                   virQEMUCapsPtr qemuCaps,
                                   virDomainPCIAddressSetPtr addrs)
{
2228
    if (qemuDomainMachineIsI440FX(def) &&
2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239
        qemuValidateDevicePCISlotsPIIX3(def, qemuCaps, addrs) < 0) {
        return -1;
    }

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

    return 0;
}
2240

2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254
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;
2255 2256
        bool buses_reserved = true;

2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274
        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;
2275 2276 2277 2278

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

2279
            for (i = 0; i < addrs->nbuses; i++) {
2280 2281
                if (!qemuDomainPCIBusFullyReserved(&addrs->buses[i]))
                    buses_reserved = false;
2282 2283
            }

2284 2285 2286 2287 2288 2289 2290
            /* 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;

2291
            if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0)
2292 2293
                goto cleanup;

2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319
            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;

2320
        if (qemuDomainSupportsPCI(def, qemuCaps)) {
2321 2322 2323
            if (qemuValidateDevicePCISlotsChipsets(def, qemuCaps, addrs) < 0)
                goto cleanup;

2324
            if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0)
2325
                goto cleanup;
2326 2327

            for (i = 0; i < def->ncontrollers; i++) {
2328 2329 2330
                virDomainControllerDefPtr cont = def->controllers[i];
                int idx = cont->idx;
                virDevicePCIAddressPtr addr;
2331
                virDomainPCIControllerOptsPtr options;
2332 2333 2334 2335 2336

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

                addr = &cont->info.addr.pci;
2337 2338 2339 2340 2341 2342 2343 2344 2345 2346
                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;
2347 2348
                    if (options->chassisNr == -1)
                        options->chassisNr = cont->idx;
2349 2350 2351 2352 2353
                    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;
2354
                case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT:
2355 2356 2357 2358 2359 2360 2361
                    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;
2362
                case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT:
2363 2364 2365
                    if (options->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE)
                        options->modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_X3130_UPSTREAM;
                    break;
2366
                case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT:
2367 2368 2369 2370 2371 2372 2373
                    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;
2374 2375 2376 2377 2378 2379
                case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
                case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
                case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST:
                    break;
                }

2380 2381 2382
                /* check if every PCI bridge controller's ID is greater than
                 * the bus it is placed onto
                 */
2383 2384
                if (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE &&
                    idx <= addr->bus) {
2385 2386 2387 2388
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("failed to create PCI bridge "
                                     "on bus %d: too many devices with fixed "
                                     "addresses"),
2389
                                   addr->bus);
2390 2391 2392
                    goto cleanup;
                }
            }
2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417
        }
    }

    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;
}


2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434
/*
 * 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)
 *
2435 2436 2437
 *  - These integrated devices were already added by
 *    qemuValidateDevicePCISlotsChipsets invoked right before this function
 *
2438 2439 2440 2441 2442 2443 2444 2445
 * Incrementally assign slots from 3 onwards:
 *
 *  - Net
 *  - Sound
 *  - SCSI controllers
 *  - VirtIO block
 *  - VirtIO balloon
 *  - Host device passthrough
2446
 *  - Watchdog
M
Michal Privoznik 已提交
2447
 *  - pci serial devices
2448 2449 2450 2451 2452 2453 2454 2455
 *
 * 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,
2456
                         virQEMUCapsPtr qemuCaps,
2457
                         virDomainPCIAddressSetPtr addrs)
2458 2459
{
    size_t i, j;
2460
    virDomainPCIConnectFlags flags;
2461 2462
    virDevicePCIAddress tmp_addr;

2463 2464 2465 2466 2467
    /* 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;
2468 2469
            switch (def->controllers[i]->model) {
            case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
L
Laine Stump 已提交
2470 2471
            case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
                /* pci-root and pcie-root are implicit in the machine,
2472 2473 2474 2475 2476 2477
                 * 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)
                 */
2478
                flags = VIR_PCI_CONNECT_TYPE_PCI;
2479
                break;
2480 2481 2482 2483
            case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
                /* dmi-to-pci-bridge requires a non-hotplug PCIe
                 * slot
                 */
2484
                flags = VIR_PCI_CONNECT_TYPE_PCIE;
2485
                break;
2486 2487 2488 2489
            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;
2490 2491 2492 2493 2494 2495
            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;
2496 2497 2498 2499
            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;
2500
            default:
2501
                flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI;
2502 2503
                break;
            }
2504 2505 2506
            if (virDomainPCIAddressReserveNextSlot(addrs,
                                                   &def->controllers[i]->info,
                                                   flags) < 0)
2507 2508 2509 2510
                goto error;
        }
    }

2511
    flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI;
2512

2513
    for (i = 0; i < def->nfss; i++) {
2514 2515 2516 2517 2518
        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 */
2519 2520
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->fss[i]->info,
                                               flags) < 0)
2521 2522 2523 2524
            goto error;
    }

    /* Network interfaces */
2525
    for (i = 0; i < def->nnets; i++) {
2526 2527 2528 2529 2530 2531
        /* 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)) {
2532
            continue;
2533
        }
2534 2535
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->nets[i]->info,
                                               flags) < 0)
2536 2537 2538 2539
            goto error;
    }

    /* Sound cards */
2540
    for (i = 0; i < def->nsounds; i++) {
2541 2542
        if (def->sounds[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            continue;
2543
        /* Skip ISA sound card, PCSPK and usb-audio */
2544
        if (def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_SB16 ||
2545 2546
            def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_PCSPK ||
            def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_USB)
2547 2548
            continue;

2549 2550
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->sounds[i]->info,
                                               flags) < 0)
2551 2552 2553
            goto error;
    }

2554
    /* Device controllers (SCSI, USB, but not IDE, FDC or CCID) */
2555
    for (i = 0; i < def->ncontrollers; i++) {
2556
        /* PCI controllers have been dealt with earlier */
2557 2558
        if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI)
            continue;
2559

2560 2561 2562 2563 2564
        /* 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 已提交
2565 2566 2567
        /* 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)
2568 2569 2570 2571 2572 2573 2574 2575 2576 2577
            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;
2578 2579 2580

        /* USB2 needs special handling to put all companions in the same slot */
        if (IS_USB2_CONTROLLER(def->controllers[i])) {
2581
            virDevicePCIAddress addr = { 0, 0, 0, 0, false };
2582 2583
            bool foundAddr = false;

2584
            memset(&tmp_addr, 0, sizeof(tmp_addr));
2585
            for (j = 0; j < def->ncontrollers; j++) {
2586
                if (IS_USB2_CONTROLLER(def->controllers[j]) &&
2587 2588 2589
                    def->controllers[j]->idx == def->controllers[i]->idx &&
                    def->controllers[j]->info.type
                    == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
2590
                    addr = def->controllers[j]->info.addr.pci;
2591
                    foundAddr = true;
2592 2593 2594 2595 2596 2597 2598
                    break;
                }
            }

            switch (def->controllers[i]->model) {
            case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1:
                addr.function = 7;
2599
                addr.multi = VIR_TRISTATE_SWITCH_ABSENT;
2600 2601 2602
                break;
            case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI1:
                addr.function = 0;
J
Ján Tomko 已提交
2603
                addr.multi = VIR_TRISTATE_SWITCH_ON;
2604 2605 2606
                break;
            case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI2:
                addr.function = 1;
2607
                addr.multi = VIR_TRISTATE_SWITCH_ABSENT;
2608 2609 2610
                break;
            case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI3:
                addr.function = 2;
2611
                addr.multi = VIR_TRISTATE_SWITCH_ABSENT;
2612 2613 2614
                break;
            }

2615
            if (!foundAddr) {
2616 2617
                /* This is the first part of the controller, so need
                 * to find a free slot & then reserve a function */
2618
                if (virDomainPCIAddressGetNextSlot(addrs, &tmp_addr, flags) < 0)
2619 2620
                    goto error;

2621 2622
                addr.bus = tmp_addr.bus;
                addr.slot = tmp_addr.slot;
2623 2624 2625

                addrs->lastaddr = addr;
                addrs->lastaddr.function = 0;
2626
                addrs->lastaddr.multi = VIR_TRISTATE_SWITCH_ABSENT;
2627 2628
            }
            /* Finally we can reserve the slot+function */
2629
            if (virDomainPCIAddressReserveAddr(addrs, &addr, flags,
2630
                                               false, foundAddr) < 0)
2631 2632 2633 2634 2635
                goto error;

            def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
            def->controllers[i]->info.addr.pci = addr;
        } else {
2636 2637 2638
            if (virDomainPCIAddressReserveNextSlot(addrs,
                                                   &def->controllers[i]->info,
                                                   flags) < 0)
2639 2640
                goto error;
        }
2641 2642
    }

2643
    /* Disks (VirtIO only for now) */
2644
    for (i = 0; i < def->ndisks; i++) {
2645 2646 2647 2648
        /* Only VirtIO disks use PCI addrs */
        if (def->disks[i]->bus != VIR_DOMAIN_DISK_BUS_VIRTIO)
            continue;

2649 2650 2651
        /* don't touch s390 devices */
        if (def->disks[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI ||
            def->disks[i]->info.type ==
2652 2653 2654
            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 ||
            def->disks[i]->info.type ==
            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
2655 2656
            continue;

2657 2658 2659 2660 2661 2662
        /* 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;

2663
        if (def->disks[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
J
Ján Tomko 已提交
2664 2665 2666
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("virtio disk cannot have an address of type '%s'"),
                           virDomainDeviceAddressTypeToString(def->disks[i]->info.type));
2667 2668 2669
            goto error;
        }

2670 2671
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->disks[i]->info,
                                               flags) < 0)
2672 2673 2674 2675
            goto error;
    }

    /* Host PCI devices */
2676
    for (i = 0; i < def->nhostdevs; i++) {
2677
        if (def->hostdevs[i]->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
2678 2679 2680 2681 2682
            continue;
        if (def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
            def->hostdevs[i]->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
            continue;

2683 2684 2685
        if (virDomainPCIAddressReserveNextSlot(addrs,
                                               def->hostdevs[i]->info,
                                               flags) < 0)
2686 2687 2688 2689 2690 2691 2692
            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) {
2693 2694 2695
        if (virDomainPCIAddressReserveNextSlot(addrs,
                                               &def->memballoon->info,
                                               flags) < 0)
2696 2697 2698
            goto error;
    }

2699
    /* VirtIO RNG */
2700 2701 2702 2703 2704
    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;

2705
        if (virDomainPCIAddressReserveNextSlot(addrs,
2706
                                               &def->rngs[i]->info, flags) < 0)
2707 2708 2709
            goto error;
    }

2710
    /* A watchdog - check if it is a PCI device */
2711
    if (def->watchdog &&
2712
        def->watchdog->model == VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB &&
2713
        def->watchdog->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
2714 2715
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->watchdog->info,
                                               flags) < 0)
2716 2717 2718
            goto error;
    }

2719 2720 2721 2722
    /* 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) {
2723 2724
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->videos[0]->info,
                                               flags) < 0)
2725 2726
            goto error;
    }
2727

2728
    /* Further non-primary video cards which have to be qxl type */
2729
    for (i = 1; i < def->nvideos; i++) {
2730 2731 2732 2733 2734
        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;
        }
2735 2736
        if (def->videos[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            continue;
2737 2738
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->videos[i]->info,
                                               flags) < 0)
2739 2740
            goto error;
    }
2741 2742 2743 2744 2745 2746 2747 2748 2749 2750

    /* 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;
    }
2751
    for (i = 0; i < def->ninputs; i++) {
2752 2753 2754 2755 2756 2757 2758 2759
        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;
2760
    }
2761
    for (i = 0; i < def->nparallels; i++) {
2762 2763
        /* Nada - none are PCI based (yet) */
    }
2764
    for (i = 0; i < def->nserials; i++) {
M
Michal Privoznik 已提交
2765 2766 2767 2768 2769 2770 2771 2772 2773 2774
        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;
2775
    }
2776
    for (i = 0; i < def->nchannels; i++) {
2777 2778
        /* Nada - none are PCI based (yet) */
    }
2779
    for (i = 0; i < def->nhubs; i++) {
M
Marc-André Lureau 已提交
2780 2781
        /* Nada - none are PCI based (yet) */
    }
2782 2783 2784

    return 0;

2785
 error:
2786 2787 2788 2789 2790
    return -1;
}

static int
qemuBuildDeviceAddressStr(virBufferPtr buf,
2791
                          virDomainDefPtr domainDef,
2792
                          virDomainDeviceInfoPtr info,
2793
                          virQEMUCapsPtr qemuCaps)
2794
{
2795 2796
    int ret = -1;
    char *devStr = NULL;
2797
    const char *contAlias = NULL;
2798

2799
    if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
2800 2801
        size_t i;

2802
        if (!(devStr = virDomainPCIAddressAsString(&info->addr.pci)))
2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829
            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;
        }

2830
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIFUNCTION)) {
W
Wen Congyang 已提交
2831
            if (info->addr.pci.function != 0) {
2832 2833 2834
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("Only PCI device addresses with function=0 "
                                 "are supported with this QEMU binary"));
2835
                goto cleanup;
2836
            }
J
Ján Tomko 已提交
2837
            if (info->addr.pci.multi == VIR_TRISTATE_SWITCH_ON) {
2838 2839 2840
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("'multifunction=on' is not supported with "
                                 "this QEMU binary"));
2841
                goto cleanup;
W
Wen Congyang 已提交
2842
            }
2843 2844
        }

2845 2846 2847 2848 2849 2850
        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;
2851
        }
2852 2853
        virBufferAsprintf(buf, ",bus=%s", contAlias);

J
Ján Tomko 已提交
2854
        if (info->addr.pci.multi == VIR_TRISTATE_SWITCH_ON)
2855
            virBufferAddLit(buf, ",multifunction=on");
J
Ján Tomko 已提交
2856
        else if (info->addr.pci.multi == VIR_TRISTATE_SWITCH_OFF)
2857 2858 2859 2860
            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);
2861
    } else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
2862 2863 2864 2865 2866
        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);
2867 2868 2869
    } 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);
2870 2871 2872 2873 2874 2875
    } 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);
2876 2877 2878 2879
    } 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);
2880
    }
2881

2882
    ret = 0;
2883
 cleanup:
2884 2885
    VIR_FREE(devStr);
    return ret;
2886 2887
}

2888 2889 2890
static int
qemuBuildRomStr(virBufferPtr buf,
                virDomainDeviceInfoPtr info,
2891
                virQEMUCapsPtr qemuCaps)
2892
{
2893
    if (info->rombar || info->romfile) {
2894
        if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
2895 2896
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("rombar and romfile are supported only for PCI devices"));
2897 2898
            return -1;
        }
2899
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_ROMBAR)) {
2900 2901
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("rombar and romfile not supported in this QEMU binary"));
2902 2903 2904 2905
            return -1;
        }

        switch (info->rombar) {
J
Ján Tomko 已提交
2906
        case VIR_TRISTATE_SWITCH_OFF:
2907 2908
            virBufferAddLit(buf, ",rombar=0");
            break;
J
Ján Tomko 已提交
2909
        case VIR_TRISTATE_SWITCH_ON:
2910 2911 2912 2913 2914
            virBufferAddLit(buf, ",rombar=1");
            break;
        default:
            break;
        }
2915 2916
        if (info->romfile)
           virBufferAsprintf(buf, ",romfile=%s", info->romfile);
2917 2918 2919 2920
    }
    return 0;
}

2921 2922
static int
qemuBuildIoEventFdStr(virBufferPtr buf,
J
Ján Tomko 已提交
2923
                      virTristateSwitch use,
2924
                      virQEMUCapsPtr qemuCaps)
2925
{
2926
    if (use && virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_IOEVENTFD))
2927
        virBufferAsprintf(buf, ",ioeventfd=%s",
J
Ján Tomko 已提交
2928
                          virTristateSwitchTypeToString(use));
2929 2930
    return 0;
}
2931 2932

#define QEMU_SERIAL_PARAM_ACCEPTED_CHARS \
2933
  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_ "
2934 2935 2936 2937

static int
qemuSafeSerialParamValue(const char *value)
{
2938
    if (strspn(value, QEMU_SERIAL_PARAM_ACCEPTED_CHARS) != strlen(value)) {
2939 2940 2941
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("driver serial '%s' contains unsafe characters"),
                       value);
2942 2943 2944 2945 2946 2947
        return -1;
    }

    return 0;
}

2948 2949 2950 2951
static char *
qemuGetSecretString(virConnectPtr conn,
                    const char *scheme,
                    bool encoded,
2952
                    virStorageAuthDefPtr authdef,
2953 2954 2955 2956 2957
                    virSecretUsageType secretUsageType)
{
    size_t secret_size;
    virSecretPtr sec = NULL;
    char *secret = NULL;
2958
    char uuidStr[VIR_UUID_STRING_BUFLEN];
2959 2960

    /* look up secret */
2961
    switch (authdef->secretType) {
2962
    case VIR_STORAGE_SECRET_TYPE_UUID:
2963 2964
        sec = virSecretLookupByUUID(conn, authdef->secret.uuid);
        virUUIDFormat(authdef->secret.uuid, uuidStr);
2965
        break;
2966
    case VIR_STORAGE_SECRET_TYPE_USAGE:
2967 2968
        sec = virSecretLookupByUsage(conn, secretUsageType,
                                     authdef->secret.usage);
2969 2970 2971 2972
        break;
    }

    if (!sec) {
2973
        if (authdef->secretType == VIR_STORAGE_SECRET_TYPE_UUID) {
2974 2975
            virReportError(VIR_ERR_NO_SECRET,
                           _("%s no secret matches uuid '%s'"),
2976
                           scheme, uuidStr);
2977 2978 2979
        } else {
            virReportError(VIR_ERR_NO_SECRET,
                           _("%s no secret matches usage value '%s'"),
2980
                           scheme, authdef->secret.usage);
2981
        }
2982 2983 2984 2985 2986 2987
        goto cleanup;
    }

    secret = (char *)conn->secretDriver->secretGetValue(sec, &secret_size, 0,
                                                        VIR_SECRET_GET_VALUE_INTERNAL_CALL);
    if (!secret) {
2988
        if (authdef->secretType == VIR_STORAGE_SECRET_TYPE_UUID) {
2989 2990 2991
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("could not get value of the secret for "
                             "username '%s' using uuid '%s'"),
2992
                           authdef->username, uuidStr);
2993 2994 2995 2996
        } else {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("could not get value of the secret for "
                             "username '%s' using usage value '%s'"),
2997
                           authdef->username, authdef->secret.usage);
2998
        }
2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013
        goto cleanup;
    }

    if (encoded) {
        char *base64 = NULL;

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

3014
 cleanup:
3015 3016 3017
    virObjectUnref(sec);
    return secret;
}
3018

3019

3020 3021
static int
qemuParseRBDString(virDomainDiskDefPtr disk)
3022
{
3023 3024
    char *source = disk->src->path;
    int ret;
3025

3026
    disk->src->path = NULL;
3027

3028
    ret = virStorageSourceParseRBDColonString(source, disk->src);
3029

3030 3031
    VIR_FREE(source);
    return ret;
3032 3033
}

3034

3035
static int
P
Paolo Bonzini 已提交
3036 3037
qemuParseDriveURIString(virDomainDiskDefPtr def, virURIPtr uri,
                        const char *scheme)
3038 3039 3040 3041 3042
{
    int ret = -1;
    char *transp = NULL;
    char *sock = NULL;
    char *volimg = NULL;
3043
    char *secret = NULL;
3044
    virStorageAuthDefPtr authdef = NULL;
3045

3046
    if (VIR_ALLOC(def->src->hosts) < 0)
3047
        goto error;
3048

P
Paolo Bonzini 已提交
3049 3050 3051 3052
    transp = strchr(uri->scheme, '+');
    if (transp)
        *transp++ = 0;

3053
    if (STRNEQ(uri->scheme, scheme)) {
P
Paolo Bonzini 已提交
3054 3055 3056 3057 3058 3059
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Invalid transport/scheme '%s'"), uri->scheme);
        goto error;
    }

    if (!transp) {
3060
        def->src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
P
Paolo Bonzini 已提交
3061
    } else {
3062 3063
        def->src->hosts->transport = virStorageNetHostTransportTypeFromString(transp);
        if (def->src->hosts->transport < 0) {
3064
            virReportError(VIR_ERR_INTERNAL_ERROR,
P
Paolo Bonzini 已提交
3065
                           _("Invalid %s transport type '%s'"), scheme, transp);
3066 3067 3068
            goto error;
        }
    }
3069
    def->src->nhosts = 0; /* set to 1 once everything succeeds */
3070

3071 3072
    if (def->src->hosts->transport != VIR_STORAGE_NET_HOST_TRANS_UNIX) {
        if (VIR_STRDUP(def->src->hosts->name, uri->server) < 0)
3073
            goto error;
3074

3075
        if (virAsprintf(&def->src->hosts->port, "%d", uri->port) < 0)
3076
            goto error;
3077
    } else {
3078 3079
        def->src->hosts->name = NULL;
        def->src->hosts->port = 0;
3080 3081 3082
        if (uri->query) {
            if (STRPREFIX(uri->query, "socket=")) {
                sock = strchr(uri->query, '=') + 1;
3083
                if (VIR_STRDUP(def->src->hosts->socket, sock) < 0)
3084
                    goto error;
3085 3086 3087 3088 3089 3090 3091
            } else {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("Invalid query parameter '%s'"), uri->query);
                goto error;
            }
        }
    }
P
Paolo Bonzini 已提交
3092 3093
    if (uri->path) {
        volimg = uri->path + 1; /* skip the prefix slash */
3094 3095
        VIR_FREE(def->src->path);
        if (VIR_STRDUP(def->src->path, volimg) < 0)
3096
            goto error;
P
Paolo Bonzini 已提交
3097
    } else {
3098
        VIR_FREE(def->src->path);
P
Paolo Bonzini 已提交
3099
    }
3100

3101
    if (uri->user) {
3102 3103 3104 3105 3106
        const char *secrettype;
        /* formulate authdef for disk->src->auth */
        if (VIR_ALLOC(authdef) < 0)
            goto error;

3107 3108 3109 3110
        secret = strchr(uri->user, ':');
        if (secret)
            *secret = '\0';

3111
        if (VIR_STRDUP(authdef->username, uri->user) < 0)
3112
            goto error;
3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124
        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.
         */
3125 3126
    }

3127
    def->src->nhosts = 1;
3128 3129
    ret = 0;

3130
 cleanup:
3131 3132 3133 3134
    virURIFree(uri);

    return ret;

3135
 error:
3136 3137
    virStorageNetHostDefClear(def->src->hosts);
    VIR_FREE(def->src->hosts);
3138
    virStorageAuthDefFree(authdef);
3139 3140 3141
    goto cleanup;
}

P
Paolo Bonzini 已提交
3142 3143 3144 3145 3146
static int
qemuParseGlusterString(virDomainDiskDefPtr def)
{
    virURIPtr uri = NULL;

3147
    if (!(uri = virURIParse(def->src->path)))
P
Paolo Bonzini 已提交
3148 3149 3150 3151 3152
        return -1;

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

P
Paolo Bonzini 已提交
3153 3154 3155 3156 3157 3158 3159
static int
qemuParseISCSIString(virDomainDiskDefPtr def)
{
    virURIPtr uri = NULL;
    char *slash;
    unsigned lun;

3160
    if (!(uri = virURIParse(def->src->path)))
P
Paolo Bonzini 已提交
3161 3162 3163 3164 3165
        return -1;

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

3166
        if (slash[1] == '\0') {
P
Paolo Bonzini 已提交
3167
            *slash = '\0';
3168
        } else if (virStrToLong_ui(slash + 1, NULL, 10, &lun) == -1) {
P
Paolo Bonzini 已提交
3169
            virReportError(VIR_ERR_INTERNAL_ERROR,
3170
                           _("invalid name '%s' for iSCSI disk"),
3171
                           def->src->path);
3172
            virURIFree(uri);
P
Paolo Bonzini 已提交
3173 3174 3175 3176 3177 3178 3179
            return -1;
        }
    }

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

3180 3181 3182
static int
qemuParseNBDString(virDomainDiskDefPtr disk)
{
3183
    virStorageNetHostDefPtr h = NULL;
3184
    char *host, *port;
P
Paolo Bonzini 已提交
3185
    char *src;
3186

P
Paolo Bonzini 已提交
3187 3188
    virURIPtr uri = NULL;

3189 3190
    if (strstr(disk->src->path, "://")) {
        if (!(uri = virURIParse(disk->src->path)))
3191 3192
            return -1;
        return qemuParseDriveURIString(disk, uri, "nbd");
P
Paolo Bonzini 已提交
3193 3194
    }

3195
    if (VIR_ALLOC(h) < 0)
3196
        goto error;
3197

3198
    host = disk->src->path + strlen("nbd:");
3199 3200 3201 3202
    if (STRPREFIX(host, "unix:/")) {
        src = strchr(host + strlen("unix:"), ':');
        if (src)
            *src++ = '\0';
3203

3204
        h->transport = VIR_STORAGE_NET_HOST_TRANS_UNIX;
3205 3206
        if (VIR_STRDUP(h->socket, host + strlen("unix:")) < 0)
            goto error;
3207 3208 3209 3210
    } else {
        port = strchr(host, ':');
        if (!port) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
3211
                           _("cannot parse nbd filename '%s'"), disk->src->path);
3212 3213
            goto error;
        }
3214

3215
        *port++ = '\0';
3216 3217
        if (VIR_STRDUP(h->name, host) < 0)
            goto error;
P
Paolo Bonzini 已提交
3218

3219 3220 3221 3222
        src = strchr(port, ':');
        if (src)
            *src++ = '\0';

3223 3224
        if (VIR_STRDUP(h->port, port) < 0)
            goto error;
3225
    }
3226

P
Paolo Bonzini 已提交
3227
    if (src && STRPREFIX(src, "exportname=")) {
3228 3229
        if (VIR_STRDUP(src, strchr(src, '=') + 1) < 0)
            goto error;
P
Paolo Bonzini 已提交
3230 3231 3232 3233
    } else {
        src = NULL;
    }

3234 3235 3236 3237
    VIR_FREE(disk->src->path);
    disk->src->path = src;
    disk->src->nhosts = 1;
    disk->src->hosts = h;
3238 3239
    return 0;

3240
 error:
3241
    virStorageNetHostDefClear(h);
3242 3243 3244 3245
    VIR_FREE(h);
    return -1;
}

3246

3247 3248 3249 3250 3251 3252 3253
static int
qemuNetworkDriveGetPort(int protocol,
                        const char *port)
{
    int ret = 0;

    if (port) {
3254
        if (virStrToLong_i(port, NULL, 10, &ret) < 0 || ret < 0) {
3255 3256 3257 3258 3259 3260 3261 3262 3263
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("failed to parse port number '%s'"),
                           port);
            return -1;
        }

        return ret;
    }

3264
    switch ((virStorageNetProtocol) protocol) {
3265
        case VIR_STORAGE_NET_PROTOCOL_HTTP:
3266 3267
            return 80;

3268
        case VIR_STORAGE_NET_PROTOCOL_HTTPS:
3269 3270
            return 443;

3271
        case VIR_STORAGE_NET_PROTOCOL_FTP:
3272 3273
            return 21;

3274
        case VIR_STORAGE_NET_PROTOCOL_FTPS:
3275 3276
            return 990;

3277
        case VIR_STORAGE_NET_PROTOCOL_TFTP:
3278 3279
            return 69;

3280
        case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
3281 3282
            return 7000;

3283
        case VIR_STORAGE_NET_PROTOCOL_NBD:
3284 3285
            return 10809;

3286 3287
        case VIR_STORAGE_NET_PROTOCOL_ISCSI:
        case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
3288 3289 3290
            /* no default port specified */
            return 0;

3291 3292
        case VIR_STORAGE_NET_PROTOCOL_RBD:
        case VIR_STORAGE_NET_PROTOCOL_LAST:
3293 3294
        case VIR_STORAGE_NET_PROTOCOL_NONE:
            /* not applicable */
3295 3296 3297 3298 3299 3300
            return -1;
    }

    return -1;
}

3301
#define QEMU_DEFAULT_NBD_PORT "10809"
3302

3303
static char *
3304
qemuBuildNetworkDriveURI(virStorageSourcePtr src,
3305 3306 3307 3308
                         const char *username,
                         const char *secret)
{
    char *ret = NULL;
3309
    virBuffer buf = VIR_BUFFER_INITIALIZER;
3310
    virURIPtr uri = NULL;
3311
    size_t i;
3312

3313
    switch ((virStorageNetProtocol) src->protocol) {
3314
        case VIR_STORAGE_NET_PROTOCOL_NBD:
3315
            if (src->nhosts != 1) {
3316 3317
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("protocol '%s' accepts only one host"),
3318
                               virStorageNetProtocolTypeToString(src->protocol));
3319 3320 3321
                goto cleanup;
            }

3322 3323 3324 3325 3326 3327
            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] != '/'))) {
3328 3329 3330

                virBufferAddLit(&buf, "nbd:");

3331
                switch (src->hosts->transport) {
3332
                case VIR_STORAGE_NET_HOST_TRANS_TCP:
3333
                    virBufferStrcat(&buf, src->hosts->name, NULL);
3334
                    virBufferAsprintf(&buf, ":%s",
3335
                                      src->hosts->port ? src->hosts->port :
3336 3337 3338
                                      QEMU_DEFAULT_NBD_PORT);
                    break;

3339
                case VIR_STORAGE_NET_HOST_TRANS_UNIX:
3340
                    if (!src->hosts->socket) {
3341 3342 3343 3344 3345 3346
                        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                       _("socket attribute required for "
                                         "unix transport"));
                        goto cleanup;
                    }

3347
                    virBufferAsprintf(&buf, "unix:%s", src->hosts->socket);
3348 3349 3350 3351 3352
                    break;

                default:
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("nbd does not support transport '%s'"),
3353
                                   virStorageNetHostTransportTypeToString(src->hosts->transport));
3354 3355 3356
                    goto cleanup;
                }

3357 3358
                if (src->path)
                    virBufferAsprintf(&buf, ":exportname=%s", src->path);
3359

3360
                if (virBufferCheckError(&buf) < 0)
3361 3362 3363 3364 3365 3366 3367 3368
                    goto cleanup;

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

3369 3370 3371 3372 3373 3374 3375
        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:
3376
            if (src->nhosts != 1) {
3377 3378
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("protocol '%s' accepts only one host"),
3379
                               virStorageNetProtocolTypeToString(src->protocol));
3380 3381
                goto cleanup;
            }
3382

3383 3384
            if (VIR_ALLOC(uri) < 0)
                goto cleanup;
3385

3386
            if (src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP) {
3387
                if (VIR_STRDUP(uri->scheme,
3388
                               virStorageNetProtocolTypeToString(src->protocol)) < 0)
3389 3390 3391
                    goto cleanup;
            } else {
                if (virAsprintf(&uri->scheme, "%s+%s",
3392 3393
                                virStorageNetProtocolTypeToString(src->protocol),
                                virStorageNetHostTransportTypeToString(src->hosts->transport)) < 0)
3394 3395
                    goto cleanup;
            }
3396

3397
            if ((uri->port = qemuNetworkDriveGetPort(src->protocol, src->hosts->port)) < 0)
3398
                goto cleanup;
3399

3400 3401
            if (src->path) {
                if (src->volume) {
3402
                    if (virAsprintf(&uri->path, "/%s%s",
3403
                                    src->volume, src->path) < 0)
3404 3405 3406
                        goto cleanup;
                } else {
                    if (virAsprintf(&uri->path, "%s%s",
3407 3408
                                    src->path[0] == '/' ? "" : "/",
                                    src->path) < 0)
3409 3410 3411
                        goto cleanup;
                }
            }
3412

3413 3414
            if (src->hosts->socket &&
                virAsprintf(&uri->query, "socket=%s", src->hosts->socket) < 0)
3415
                goto cleanup;
3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426

            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;
                }
            }

3427
            if (VIR_STRDUP(uri->server, src->hosts->name) < 0)
3428 3429
                goto cleanup;

3430
            ret = virURIFormat(uri);
3431

3432 3433
            break;

3434
        case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
3435
            if (!src->path) {
3436 3437 3438 3439 3440
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("missing disk source for 'sheepdog' protocol"));
                goto cleanup;
            }

3441 3442
            if (src->nhosts == 0) {
                if (virAsprintf(&ret, "sheepdog:%s", src->path) < 0)
3443
                    goto cleanup;
3444
            } else if (src->nhosts == 1) {
3445
                if (virAsprintf(&ret, "sheepdog:%s:%s:%s",
3446 3447 3448
                                src->hosts->name,
                                src->hosts->port ? src->hosts->port : "7000",
                                src->path) < 0)
3449 3450 3451 3452 3453 3454 3455 3456 3457
                    goto cleanup;
            } else {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("protocol 'sheepdog' accepts up to one host"));
                goto cleanup;
            }

            break;

3458
        case VIR_STORAGE_NET_PROTOCOL_RBD:
3459
            if (strchr(src->path, ':')) {
3460 3461
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("':' not allowed in RBD source volume name '%s'"),
3462
                               src->path);
3463 3464 3465
                goto cleanup;
            }

3466
            virBufferStrcat(&buf, "rbd:", src->path, NULL);
3467

3468 3469 3470
            if (src->snapshot)
                virBufferEscape(&buf, '\\', ":", "@%s", src->snapshot);

3471 3472 3473 3474 3475 3476 3477 3478 3479
            if (username) {
                virBufferEscape(&buf, '\\', ":", ":id=%s", username);
                virBufferEscape(&buf, '\\', ":",
                                ":key=%s:auth_supported=cephx\\;none",
                                secret);
            } else {
                virBufferAddLit(&buf, ":auth_supported=none");
            }

3480
            if (src->nhosts > 0) {
3481
                virBufferAddLit(&buf, ":mon_host=");
3482
                for (i = 0; i < src->nhosts; i++) {
3483 3484 3485 3486
                    if (i)
                        virBufferAddLit(&buf, "\\;");

                    /* assume host containing : is ipv6 */
3487 3488 3489
                    if (strchr(src->hosts[i].name, ':'))
                        virBufferEscape(&buf, '\\', ":", "[%s]",
                                        src->hosts[i].name);
3490
                    else
3491
                        virBufferAsprintf(&buf, "%s", src->hosts[i].name);
3492

3493 3494
                    if (src->hosts[i].port)
                        virBufferAsprintf(&buf, "\\:%s", src->hosts[i].port);
3495 3496 3497
                }
            }

3498 3499 3500
            if (src->configFile)
                virBufferEscape(&buf, '\\', ":", ":conf=%s", src->configFile);

3501
            if (virBufferCheckError(&buf) < 0)
3502 3503 3504 3505 3506 3507
                goto cleanup;

            ret = virBufferContentAndReset(&buf);
            break;


3508
        case VIR_STORAGE_NET_PROTOCOL_LAST:
3509
        case VIR_STORAGE_NET_PROTOCOL_NONE:
3510 3511 3512
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Unexpected network protocol '%s'"),
                           virStorageNetProtocolTypeToString(src->protocol));
3513 3514
            goto cleanup;
    }
3515

3516
 cleanup:
3517
    virBufferFreeAndReset(&buf);
3518 3519 3520 3521 3522 3523
    virURIFree(uri);

    return ret;
}


3524
int
3525 3526 3527
qemuGetDriveSourceString(virStorageSourcePtr src,
                         virConnectPtr conn,
                         char **source)
3528
{
3529 3530 3531 3532 3533 3534 3535
    int actualType = virStorageSourceGetActualType(src);
    char *secret = NULL;
    char *username = NULL;
    int ret = -1;

    *source = NULL;

3536 3537 3538 3539
    /* return 1 for empty sources */
    if (virStorageSourceIsEmpty(src))
        return 1;

3540 3541
    if (conn) {
        if (actualType == VIR_STORAGE_TYPE_NETWORK &&
3542
            src->auth &&
3543 3544 3545 3546 3547
            (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);
3548
            username = src->auth->username;
3549 3550 3551 3552 3553 3554

            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;
            }
3555

3556 3557 3558
            if (!(secret = qemuGetSecretString(conn,
                                               protocol,
                                               encode,
3559
                                               src->auth,
3560 3561 3562 3563 3564
                                               secretType)))
                goto cleanup;
        }
    }

3565
    switch ((virStorageType) actualType) {
E
Eric Blake 已提交
3566 3567 3568
    case VIR_STORAGE_TYPE_BLOCK:
    case VIR_STORAGE_TYPE_FILE:
    case VIR_STORAGE_TYPE_DIR:
3569 3570
        if (VIR_STRDUP(*source, src->path) < 0)
            goto cleanup;
3571 3572 3573

        break;

E
Eric Blake 已提交
3574
    case VIR_STORAGE_TYPE_NETWORK:
3575
        if (!(*source = qemuBuildNetworkDriveURI(src, username, secret)))
3576
            goto cleanup;
3577 3578
        break;

E
Eric Blake 已提交
3579
    case VIR_STORAGE_TYPE_VOLUME:
3580
    case VIR_STORAGE_TYPE_NONE:
E
Eric Blake 已提交
3581
    case VIR_STORAGE_TYPE_LAST:
3582 3583 3584
        break;
    }

3585
    ret = 0;
3586

3587
 cleanup:
J
John Ferlan 已提交
3588
    VIR_FREE(secret);
3589 3590 3591
    return ret;
}

P
Paolo Bonzini 已提交
3592

3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 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
/* 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;
            }
3636
        } else if (!virDomainDiskSourceIsBlockType(disk->src, true)) {
3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656
            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;
}


3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696
/* 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;
}


3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725
/* 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;
}


3726
char *
3727
qemuBuildDriveStr(virConnectPtr conn,
3728
                  virDomainDiskDefPtr disk,
3729
                  bool bootable,
3730
                  virQEMUCapsPtr qemuCaps)
3731 3732 3733
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;
    const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
3734 3735
    const char *trans =
        virDomainDiskGeometryTransTypeToString(disk->geometry.trans);
3736 3737
    int idx = virDiskNameToIndex(disk->dst);
    int busid = -1, unitid = -1;
3738
    char *source = NULL;
3739
    int actualType = virStorageSourceGetActualType(disk->src);
3740 3741

    if (idx < 0) {
3742 3743
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unsupported disk type '%s'"), disk->dst);
3744 3745 3746 3747 3748 3749
        goto error;
    }

    switch (disk->bus) {
    case VIR_DOMAIN_DISK_BUS_SCSI:
        if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
3750 3751
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("unexpected address type for scsi disk"));
3752 3753 3754 3755 3756 3757 3758
            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) {
3759 3760
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("SCSI controller only supports 1 bus"));
3761 3762 3763 3764 3765 3766 3767 3768
            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) {
3769 3770
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("unexpected address type for ide disk"));
3771 3772 3773 3774
            goto error;
        }
        /* We can only have 1 IDE controller (currently) */
        if (disk->info.addr.drive.controller != 0) {
3775 3776
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Only 1 %s controller is supported"), bus);
3777 3778 3779 3780 3781 3782 3783 3784
            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) {
3785 3786
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("unexpected address type for fdc disk"));
3787 3788 3789 3790
            goto error;
        }
        /* We can only have 1 FDC controller (currently) */
        if (disk->info.addr.drive.controller != 0) {
3791 3792
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Only 1 %s controller is supported"), bus);
3793 3794 3795 3796
            goto error;
        }
        /* We can only have 1 FDC bus (currently) */
        if (disk->info.addr.drive.bus != 0) {
3797 3798
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Only 1 %s bus is supported"), bus);
3799 3800
            goto error;
        }
3801
        if (disk->info.addr.drive.target != 0) {
3802 3803
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("target must be 0 for controller fdc"));
3804 3805
            goto error;
        }
3806 3807 3808 3809 3810 3811 3812 3813 3814
        unitid = disk->info.addr.drive.unit;

        break;

    case VIR_DOMAIN_DISK_BUS_VIRTIO:
        idx = -1;
        break;

    case VIR_DOMAIN_DISK_BUS_XEN:
3815 3816 3817
    case VIR_DOMAIN_DISK_BUS_SD:
        /* Xen and SD have no address type currently, so assign
         * based on index */
3818 3819 3820
        break;
    }

3821
    if (qemuGetDriveSourceString(disk->src, conn, &source) < 0)
3822 3823 3824
        goto error;

    if (source &&
3825 3826 3827
        !((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY ||
           disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
          disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
3828

3829 3830 3831
        virBufferAddLit(&opt, "file=");

        switch (actualType) {
E
Eric Blake 已提交
3832
        case VIR_STORAGE_TYPE_DIR:
3833
            /* QEMU only supports magic FAT format for now */
3834 3835
            if (disk->src->format > 0 &&
                disk->src->format != VIR_STORAGE_FILE_FAT) {
3836 3837
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("unsupported disk driver type for '%s'"),
3838
                               virStorageFileFormatTypeToString(disk->src->format));
3839 3840
                goto error;
            }
3841

3842
            if (!disk->src->readonly) {
3843 3844
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("cannot create virtual FAT disks in read-write mode"));
3845 3846
                goto error;
            }
3847 3848 3849

            virBufferAddLit(&opt, "fat:");

3850
            if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
3851
                virBufferAddLit(&opt, "floppy:");
3852

3853 3854
            break;

E
Eric Blake 已提交
3855
        case VIR_STORAGE_TYPE_BLOCK:
3856
            if (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN) {
3857
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
3858
                               disk->src->type == VIR_STORAGE_TYPE_VOLUME ?
3859 3860
                               _("tray status 'open' is invalid for block type volume") :
                               _("tray status 'open' is invalid for block type disk"));
3861 3862
                goto error;
            }
3863 3864 3865 3866 3867

            break;

        default:
            break;
3868
        }
3869 3870

        virBufferEscape(&opt, ',', ",", "%s,", source);
3871 3872 3873 3874 3875

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

3879
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
3880 3881
        virBufferAddLit(&opt, "if=none");
    else
3882
        virBufferAsprintf(&opt, "if=%s", bus);
3883

3884
    if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
3885
        if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
3886
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD))
3887
                virBufferAddLit(&opt, ",media=cdrom");
3888
        } else if (disk->bus == VIR_DOMAIN_DISK_BUS_IDE) {
3889
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_IDE_CD))
3890
                virBufferAddLit(&opt, ",media=cdrom");
3891 3892 3893 3894
        } else {
            virBufferAddLit(&opt, ",media=cdrom");
        }
    }
3895

3896
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
3897
        virBufferAsprintf(&opt, ",id=%s%s", QEMU_DRIVE_HOST_PREFIX, disk->info.alias);
3898 3899 3900
    } else {
        if (busid == -1 && unitid == -1) {
            if (idx != -1)
3901
                virBufferAsprintf(&opt, ",index=%d", idx);
3902 3903
        } else {
            if (busid != -1)
3904
                virBufferAsprintf(&opt, ",bus=%d", busid);
3905
            if (unitid != -1)
3906
                virBufferAsprintf(&opt, ",unit=%d", unitid);
3907 3908 3909
        }
    }
    if (bootable &&
3910
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_BOOT) &&
3911 3912
        (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK ||
         disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) &&
3913 3914
        disk->bus != VIR_DOMAIN_DISK_BUS_IDE)
        virBufferAddLit(&opt, ",boot=on");
3915
    if (disk->src->readonly &&
3916
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_READONLY)) {
3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927
        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;
            }
3928
        }
3929
        virBufferAddLit(&opt, ",readonly=on");
3930
    }
3931
    if (disk->transient) {
3932 3933
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("transient disks not supported yet"));
3934 3935
        goto error;
    }
3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947

    /* 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)
3948
            virBufferAsprintf(&opt, ",trans=%s", trans);
3949 3950
    }

3951
    if (disk->serial &&
3952
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_SERIAL)) {
3953 3954
        if (qemuSafeSerialParamValue(disk->serial) < 0)
            goto error;
3955 3956 3957 3958 3959 3960 3961
        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;
        }
3962 3963
        virBufferAddLit(&opt, ",serial=");
        virBufferEscape(&opt, '\\', " ", "%s", disk->serial);
3964 3965 3966
    }

    if (disk->cachemode) {
3967 3968
        const char *mode = NULL;

3969
        mode = qemuDiskCacheV2TypeToString(disk->cachemode);
3970

3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982
        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;
3983
        }
3984

3985 3986 3987 3988 3989 3990 3991 3992 3993 3994
        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;
        }

3995
        virBufferAsprintf(&opt, ",cache=%s", mode);
3996
    } else if (disk->src->shared && !disk->src->readonly) {
3997
        virBufferAddLit(&opt, ",cache=none");
3998 3999
    }

O
Osier Yang 已提交
4000
    if (disk->copy_on_read) {
4001
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_COPY_ON_READ)) {
O
Osier Yang 已提交
4002
            virBufferAsprintf(&opt, ",copy-on-read=%s",
J
Ján Tomko 已提交
4003
                              virTristateSwitchTypeToString(disk->copy_on_read));
O
Osier Yang 已提交
4004
        } else {
4005 4006
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("copy_on_read is not supported by this QEMU binary"));
O
Osier Yang 已提交
4007 4008 4009 4010
            goto error;
        }
    }

O
Osier Yang 已提交
4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021
    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;
        }
    }

4022
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MONITOR_JSON)) {
4023 4024 4025 4026
        const char *wpolicy = NULL, *rpolicy = NULL;

        if (disk->error_policy)
            wpolicy = virDomainDiskErrorPolicyTypeToString(disk->error_policy);
4027 4028
        if (disk->rerror_policy)
            rpolicy = virDomainDiskErrorPolicyTypeToString(disk->rerror_policy);
4029 4030

        if (disk->error_policy == VIR_DOMAIN_DISK_ERROR_POLICY_ENOSPACE) {
4031 4032 4033
            /* 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.
4034
             */
4035 4036 4037 4038
            wpolicy = "enospc";
        } else if (!rpolicy) {
            /* for other policies, rpolicy can match wpolicy */
            rpolicy = wpolicy;
4039
        }
4040 4041 4042 4043 4044

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

E
Eric Blake 已提交
4047
    if (disk->iomode) {
4048
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_AIO)) {
4049
            virBufferAsprintf(&opt, ",aio=%s",
E
Eric Blake 已提交
4050 4051
                              virDomainDiskIoTypeToString(disk->iomode));
        } else {
4052 4053 4054
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("disk aio mode not supported with this "
                             "QEMU binary"));
E
Eric Blake 已提交
4055 4056 4057 4058
            goto error;
        }
    }

4059
    /* block I/O throttling */
4060 4061 4062 4063 4064 4065
    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) &&
4066
        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE)) {
4067 4068 4069
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("block I/O throttling not supported with this "
                         "QEMU binary"));
4070 4071 4072
        goto error;
    }

4073 4074 4075 4076 4077 4078
    /* 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 ||
4079 4080
         disk->blkdeviotune.write_iops_sec_max ||
         disk->blkdeviotune.size_iops_sec) &&
4081 4082
        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE_MAX)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
4083 4084
                       _("there are some block I/O throttling parameters "
                         "that are not supported with this QEMU binary"));
4085 4086 4087
        goto error;
    }

4088 4089 4090 4091 4092
    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 ||
4093 4094 4095 4096 4097 4098
        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 ||
4099 4100
        disk->blkdeviotune.write_iops_sec_max > LLONG_MAX ||
        disk->blkdeviotune.size_iops_sec > LLONG_MAX) {
4101 4102 4103 4104 4105 4106
        virReportError(VIR_ERR_OVERFLOW,
                      _("block I/O throttle limit must "
                        "be less than %llu using QEMU"), LLONG_MAX);
        goto error;
    }

4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136
    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);
    }

4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166
    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);
    }

4167
    if (disk->blkdeviotune.size_iops_sec) {
4168 4169 4170 4171
        virBufferAsprintf(&opt, ",iops_size=%llu",
                          disk->blkdeviotune.size_iops_sec);
    }

4172
    if (virBufferCheckError(&opt) < 0)
4173 4174 4175 4176
        goto error;

    return virBufferContentAndReset(&opt);

4177
 error:
4178
    VIR_FREE(source);
4179 4180 4181 4182
    virBufferFreeAndReset(&opt);
    return NULL;
}

4183 4184

static bool
4185
qemuCheckIOThreads(virDomainDefPtr def,
4186 4187 4188
                   virDomainDiskDefPtr disk)
{
    /* Right "type" of disk" */
4189
    if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO ||
4190 4191
        (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
         disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)) {
4192
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
4193 4194
                       _("IOThreads only available for virtio pci and "
                         "virtio ccw disk"));
4195 4196 4197
        return false;
    }

4198 4199
    /* Can we find the disk iothread in the iothreadid list? */
    if (!virDomainIOThreadIDFind(def, disk->iothread)) {
4200
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
4201 4202
                       _("Disk iothread '%u' not defined in iothreadid"),
                       disk->iothread);
4203 4204 4205 4206 4207 4208 4209
        return false;
    }

    return true;
}


4210
char *
4211 4212
qemuBuildDriveDevStr(virDomainDefPtr def,
                     virDomainDiskDefPtr disk,
4213
                     int bootindex,
4214
                     virQEMUCapsPtr qemuCaps)
4215 4216 4217
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;
    const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
4218
    const char *contAlias;
4219
    int controllerModel;
4220

4221 4222 4223
    if (virDomainDiskDefDstDuplicates(def))
        goto error;

4224
    if (qemuCheckDiskConfig(disk) < 0)
4225
        goto error;
4226

4227
    /* Live only checks */
4228
    if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
4229
        /* make sure that the qemu binary supports type='lun' (SG_IO). */
4230
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SG_IO)) {
4231
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
4232 4233
                           _("disk device='lun' is not supported by "
                             "this QEMU"));
4234 4235
            goto error;
        }
4236 4237
    }

4238 4239 4240
    if (!qemuCheckCCWS390AddressSupport(def, disk->info, qemuCaps, disk->dst))
        goto error;

4241
    if (disk->iothread && !qemuCheckIOThreads(def, disk))
4242 4243
        goto error;

4244 4245
    switch (disk->bus) {
    case VIR_DOMAIN_DISK_BUS_IDE:
4246
        if (disk->info.addr.drive.target != 0) {
4247 4248
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("target must be 0 for ide controller"));
4249 4250
            goto error;
        }
4251

4252
        if (disk->wwn &&
4253
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_IDE_DRIVE_WWN)) {
4254 4255 4256 4257 4258 4259
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting wwn for ide disk is not supported "
                             "by this QEMU"));
            goto error;
        }

4260
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_IDE_CD)) {
4261 4262 4263 4264 4265 4266 4267 4268
            if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
                virBufferAddLit(&opt, "ide-cd");
            else
                virBufferAddLit(&opt, "ide-hd");
        } else {
            virBufferAddLit(&opt, "ide-drive");
        }

4269 4270 4271 4272 4273
        if (!(contAlias = virDomainControllerAliasFind(def, VIR_DOMAIN_CONTROLLER_TYPE_IDE,
                                                       disk->info.addr.drive.controller)))
           goto error;
        virBufferAsprintf(&opt, ",bus=%s.%d,unit=%d",
                          contAlias,
4274 4275 4276
                          disk->info.addr.drive.bus,
                          disk->info.addr.drive.unit);
        break;
4277

4278
    case VIR_DOMAIN_DISK_BUS_SCSI:
4279
        if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
4280
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_BLOCK)) {
4281 4282 4283
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("This QEMU doesn't support scsi-block for "
                                 "lun passthrough"));
4284 4285 4286 4287
                goto error;
            }
        }

4288
        if (disk->wwn &&
4289
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_WWN)) {
4290 4291 4292 4293 4294 4295
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting wwn for scsi disk is not supported "
                             "by this QEMU"));
            goto error;
        }

4296 4297 4298 4299
        /* Properties wwn, vendor and product were introduced in the
         * same QEMU release (1.2.0).
         */
        if ((disk->vendor || disk->product) &&
4300
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_WWN)) {
4301 4302 4303 4304 4305 4306
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting vendor or product for scsi disk is not "
                             "supported by this QEMU"));
            goto error;
        }

4307
        controllerModel =
H
Han Cheng 已提交
4308 4309
            virDomainDeviceFindControllerModel(def, &disk->info,
                                               VIR_DOMAIN_CONTROLLER_TYPE_SCSI);
4310
        if ((qemuSetSCSIControllerModel(def, qemuCaps, &controllerModel)) < 0)
4311
            goto error;
4312

4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325
        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");
            }
        }

4326 4327 4328 4329
        if (!(contAlias = virDomainControllerAliasFind(def, VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
                                                       disk->info.addr.drive.controller)))
           goto error;

4330 4331
        if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) {
            if (disk->info.addr.drive.target != 0) {
4332 4333 4334
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("target must be 0 for controller "
                                 "model 'lsilogic'"));
4335 4336 4337
                goto error;
            }

4338 4339
            virBufferAsprintf(&opt, ",bus=%s.%d,scsi-id=%d",
                              contAlias,
4340 4341 4342
                              disk->info.addr.drive.bus,
                              disk->info.addr.drive.unit);
        } else {
4343
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_CHANNEL)) {
4344
                if (disk->info.addr.drive.target > 7) {
4345 4346 4347
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("This QEMU doesn't support target "
                                     "greater than 7"));
4348 4349 4350
                    goto error;
                }

4351 4352
                if (disk->info.addr.drive.bus != 0 &&
                    disk->info.addr.drive.unit != 0) {
4353 4354 4355
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("This QEMU only supports both bus and "
                                     "unit equal to 0"));
4356 4357 4358 4359
                    goto error;
                }
            }

4360 4361
            virBufferAsprintf(&opt, ",bus=%s.0,channel=%d,scsi-id=%d,lun=%d",
                              contAlias,
4362 4363 4364 4365
                              disk->info.addr.drive.bus,
                              disk->info.addr.drive.target,
                              disk->info.addr.drive.unit);
        }
4366
        break;
4367

J
Jim Fehlig 已提交
4368
    case VIR_DOMAIN_DISK_BUS_SATA:
4369
        if (disk->info.addr.drive.bus != 0) {
4370 4371
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("bus must be 0 for ide controller"));
4372 4373 4374
            goto error;
        }
        if (disk->info.addr.drive.target != 0) {
4375 4376
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("target must be 0 for ide controller"));
4377 4378
            goto error;
        }
4379

4380
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_IDE_CD)) {
4381 4382 4383 4384 4385 4386 4387 4388
            if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
                virBufferAddLit(&opt, "ide-cd");
            else
                virBufferAddLit(&opt, "ide-hd");
        } else {
            virBufferAddLit(&opt, "ide-drive");
        }

4389 4390 4391 4392 4393 4394
        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 已提交
4395
        break;
4396

4397
    case VIR_DOMAIN_DISK_BUS_VIRTIO:
4398 4399
        if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
            virBufferAddLit(&opt, "virtio-blk-ccw");
4400 4401
            if (disk->iothread)
                virBufferAsprintf(&opt, ",iothread=iothread%u", disk->iothread);
4402 4403
        } else if (disk->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
4404
            virBufferAddLit(&opt, "virtio-blk-s390");
4405 4406 4407
        } else if (disk->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) {
            virBufferAddLit(&opt, "virtio-blk-device");
4408 4409
        } else {
            virBufferAddLit(&opt, "virtio-blk-pci");
4410 4411
            if (disk->iothread)
                virBufferAsprintf(&opt, ",iothread=iothread%u", disk->iothread);
4412
        }
4413
        qemuBuildIoEventFdStr(&opt, disk->ioeventfd, qemuCaps);
4414
        if (disk->event_idx &&
4415
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_EVENT_IDX)) {
4416
            virBufferAsprintf(&opt, ",event_idx=%s",
J
Ján Tomko 已提交
4417
                              virTristateSwitchTypeToString(disk->event_idx));
4418
        }
4419
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SCSI)) {
4420 4421 4422 4423 4424 4425 4426
            /* 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");
        }
4427
        if (qemuBuildDeviceAddressStr(&opt, def, &disk->info, qemuCaps) < 0)
A
Alex Jia 已提交
4428
            goto error;
4429
        break;
4430

4431
    case VIR_DOMAIN_DISK_BUS_USB:
4432 4433 4434 4435 4436 4437
        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;
        }
4438 4439 4440 4441 4442 4443 4444
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_STORAGE)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("This QEMU doesn't support '-device "
                             "usb-storage'"));
            goto error;

        }
4445
        virBufferAddLit(&opt, "usb-storage");
4446

4447
        if (qemuBuildDeviceAddressStr(&opt, def, &disk->info, qemuCaps) < 0)
4448
            goto error;
4449
        break;
4450

4451
    default:
4452 4453
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unsupported disk bus '%s' with device setup"), bus);
4454 4455
        goto error;
    }
4456

4457 4458
    virBufferAsprintf(&opt, ",drive=%s%s", QEMU_DRIVE_HOST_PREFIX, disk->info.alias);
    virBufferAsprintf(&opt, ",id=%s", disk->info.alias);
4459
    if (bootindex && virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX))
4460
        virBufferAsprintf(&opt, ",bootindex=%d", bootindex);
4461
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKIO)) {
V
Viktor Mihajlovski 已提交
4462
        if (disk->blockio.logical_block_size > 0)
4463
            virBufferAsprintf(&opt, ",logical_block_size=%u",
V
Viktor Mihajlovski 已提交
4464 4465
                              disk->blockio.logical_block_size);
        if (disk->blockio.physical_block_size > 0)
4466
            virBufferAsprintf(&opt, ",physical_block_size=%u",
V
Viktor Mihajlovski 已提交
4467
                              disk->blockio.physical_block_size);
4468
    }
4469

4470 4471 4472 4473 4474 4475
    if (disk->wwn) {
        if (STRPREFIX(disk->wwn, "0x"))
            virBufferAsprintf(&opt, ",wwn=%s", disk->wwn);
        else
            virBufferAsprintf(&opt, ",wwn=0x%s", disk->wwn);
    }
4476

4477 4478 4479 4480 4481 4482
    if (disk->vendor)
        virBufferAsprintf(&opt, ",vendor=%s", disk->vendor);

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

4483 4484
    if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_STORAGE_REMOVABLE)) {
J
Ján Tomko 已提交
4485
            if (disk->removable == VIR_TRISTATE_SWITCH_ON)
4486 4487 4488 4489
                virBufferAddLit(&opt, ",removable=on");
            else
                virBufferAddLit(&opt, ",removable=off");
        } else {
J
Ján Tomko 已提交
4490
            if (disk->removable != VIR_TRISTATE_SWITCH_ABSENT) {
4491 4492 4493 4494 4495 4496 4497 4498
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("This QEMU doesn't support setting the "
                                 "removable flag of USB storage devices"));
                goto error;
            }
        }
    }

4499
    if (virBufferCheckError(&opt) < 0)
4500 4501 4502 4503
        goto error;

    return virBufferContentAndReset(&opt);

4504
 error:
4505 4506 4507 4508 4509 4510
    virBufferFreeAndReset(&opt);
    return NULL;
}


char *qemuBuildFSStr(virDomainFSDefPtr fs,
4511
                     virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED)
4512 4513
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;
4514
    const char *driver = qemuDomainFSDriverTypeToString(fs->fsdriver);
4515
    const char *wrpolicy = virDomainFSWrpolicyTypeToString(fs->wrpolicy);
4516 4517

    if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
4518 4519
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("only supports mount filesystem type"));
4520 4521 4522
        goto error;
    }

4523
    if (!driver) {
4524 4525
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Filesystem driver type not supported"));
4526 4527 4528 4529
        goto error;
    }
    virBufferAdd(&opt, driver, -1);

4530 4531 4532 4533
    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");
4534
        } else if (fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH) {
4535
            virBufferAddLit(&opt, ",security_model=passthrough");
4536
        } else if (fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_SQUASH) {
4537 4538 4539 4540 4541 4542
            virBufferAddLit(&opt, ",security_model=none");
        }
    } else {
        /* For other fs drivers, default(passthru) should always
         * be supported */
        if (fs->accessmode != VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH) {
4543 4544
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("only supports passthrough accessmode"));
4545 4546
            goto error;
        }
4547
    }
4548 4549

    if (fs->wrpolicy) {
4550 4551 4552 4553 4554 4555 4556
        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;
        }
4557 4558
    }

4559 4560
    virBufferAsprintf(&opt, ",id=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
    virBufferAsprintf(&opt, ",path=%s", fs->src);
4561

4562
    if (fs->readonly) {
4563
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_FSDEV_READONLY)) {
4564 4565
            virBufferAddLit(&opt, ",readonly");
        } else {
4566 4567 4568
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("readonly filesystem is not supported by this "
                             "QEMU binary"));
4569 4570 4571 4572
            goto error;
        }
    }

4573
    if (virBufferCheckError(&opt) < 0)
4574 4575 4576 4577
        goto error;

    return virBufferContentAndReset(&opt);

4578
 error:
4579 4580 4581 4582 4583 4584
    virBufferFreeAndReset(&opt);
    return NULL;
}


char *
4585 4586
qemuBuildFSDevStr(virDomainDefPtr def,
                  virDomainFSDefPtr fs,
4587
                  virQEMUCapsPtr qemuCaps)
4588 4589 4590 4591
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;

    if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
4592 4593
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("can only passthrough directories"));
4594 4595 4596
        goto error;
    }

4597 4598 4599 4600 4601
    if (fs->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
        virBufferAddLit(&opt, "virtio-9p-ccw");
    else
        virBufferAddLit(&opt, "virtio-9p-pci");

4602 4603 4604
    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 已提交
4605

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

4609
    if (virBufferCheckError(&opt) < 0)
4610 4611 4612 4613
        goto error;

    return virBufferContentAndReset(&opt);

4614
 error:
4615 4616 4617 4618 4619
    virBufferFreeAndReset(&opt);
    return NULL;
}


4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638
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 已提交
4639 4640
    case VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI:
        return QEMU_CAPS_NEC_USB_XHCI;
4641 4642 4643 4644 4645 4646 4647
    default:
        return -1;
    }
}


static int
4648 4649
qemuBuildUSBControllerDevStr(virDomainDefPtr domainDef,
                             virDomainControllerDefPtr def,
4650
                             virQEMUCapsPtr qemuCaps,
4651 4652 4653
                             virBuffer *buf)
{
    const char *smodel;
4654
    int model, flags;
4655 4656

    model = def->model;
4657

4658
    if (model == -1) {
4659
        if ARCH_IS_PPC64(domainDef->os.arch)
4660 4661 4662 4663
            model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI;
        else
            model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI;
    }
4664 4665

    smodel = qemuControllerModelUSBTypeToString(model);
4666
    flags = qemuControllerModelUSBToCaps(model);
4667

4668
    if (flags == -1 || !virQEMUCapsGet(qemuCaps, flags)) {
4669 4670
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("%s not supported in this QEMU binary"), smodel);
4671 4672 4673
        return -1;
    }

4674 4675
    virBufferAsprintf(buf, "%s", smodel);

4676 4677 4678 4679 4680
    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);
4681

4682 4683 4684
    return 0;
}

4685
char *
4686 4687
qemuBuildControllerDevStr(virDomainDefPtr domainDef,
                          virDomainControllerDefPtr def,
4688
                          virQEMUCapsPtr qemuCaps,
4689
                          int *nusbcontroller)
4690 4691
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4692
    int model = def->model;
4693
    const char *modelName = NULL;
4694

4695 4696 4697 4698
    if (!qemuCheckCCWS390AddressSupport(domainDef, def->info, qemuCaps,
                                        "controller"))
        return NULL;

4699 4700 4701 4702
    if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
        if ((qemuSetSCSIControllerModel(domainDef, qemuCaps, &model)) < 0)
            return NULL;
    }
4703

4704
    if (!(def->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI &&
4705
          model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI)) {
4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720
        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;
        }
4721 4722 4723 4724 4725
        if (def->ioeventfd) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("'ioeventfd' is only supported by virtio-scsi controller"));
            return NULL;
        }
4726 4727
    }

4728 4729
    switch (def->type) {
    case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
4730
        switch (model) {
4731
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI:
4732 4733 4734 4735 4736
            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");
4737 4738 4739
            else if (def->info.type ==
                     VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
                virBufferAddLit(&buf, "virtio-scsi-device");
4740 4741
            else
                virBufferAddLit(&buf, "virtio-scsi-pci");
4742
            break;
4743
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC:
4744
            virBufferAddLit(&buf, "lsi");
4745 4746 4747 4748
            break;
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI:
            virBufferAddLit(&buf, "spapr-vscsi");
            break;
4749 4750 4751
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1078:
            virBufferAddLit(&buf, "megasas");
            break;
4752
        default:
4753 4754 4755
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("Unsupported controller model: %s"),
                           virDomainControllerModelSCSITypeToString(def->model));
4756
        }
4757
        virBufferAsprintf(&buf, ",id=%s", def->info.alias);
4758 4759 4760 4761 4762
        break;

    case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
        if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
            virBufferAddLit(&buf, "virtio-serial-pci");
4763 4764 4765
        } else if (def->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
            virBufferAddLit(&buf, "virtio-serial-ccw");
4766 4767 4768
        } else if (def->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
            virBufferAddLit(&buf, "virtio-serial-s390");
4769 4770 4771
        } else if (def->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) {
            virBufferAddLit(&buf, "virtio-serial-device");
4772 4773 4774
        } else {
            virBufferAddLit(&buf, "virtio-serial");
        }
4775
        virBufferAsprintf(&buf, ",id=%s", def->info.alias);
4776
        if (def->opts.vioserial.ports != -1) {
4777
            virBufferAsprintf(&buf, ",max_ports=%d",
4778 4779 4780
                              def->opts.vioserial.ports);
        }
        if (def->opts.vioserial.vectors != -1) {
4781
            virBufferAsprintf(&buf, ",vectors=%d",
4782 4783 4784 4785
                              def->opts.vioserial.vectors);
        }
        break;

E
Eric Blake 已提交
4786
    case VIR_DOMAIN_CONTROLLER_TYPE_CCID:
4787
        virBufferAsprintf(&buf, "usb-ccid,id=%s", def->info.alias);
E
Eric Blake 已提交
4788 4789
        break;

J
Jim Fehlig 已提交
4790
    case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
4791 4792 4793 4794 4795 4796
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_AHCI)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("SATA is not supported with this "
                             "QEMU binary"));
            goto error;
        }
4797
        virBufferAsprintf(&buf, "ahci,id=%s", def->info.alias);
J
Jim Fehlig 已提交
4798 4799
        break;

4800
    case VIR_DOMAIN_CONTROLLER_TYPE_USB:
4801
        if (qemuBuildUSBControllerDevStr(domainDef, def, qemuCaps, &buf) == -1)
4802 4803 4804 4805 4806 4807 4808
            goto error;

        if (nusbcontroller)
            *nusbcontroller += 1;

        break;

4809
    case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821
        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;
        }
4822 4823
        switch (def->model) {
        case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
4824
            if (def->opts.pciopts.modelName
4825 4826
                == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE ||
                def->opts.pciopts.chassisNr == -1) {
4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853
                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",
4854 4855
                              modelName, def->opts.pciopts.chassisNr,
                              def->info.alias);
4856
            break;
4857
        case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879
            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;
            }
4880 4881
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
4882
                               _("the dmi-to-pci-bridge (i82801b11-bridge) "
4883 4884 4885
                                 "controller is not supported in this QEMU binary"));
                goto error;
            }
4886
            virBufferAsprintf(&buf, "%s,id=%s", modelName, def->info.alias);
4887
            break;
4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920
        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;
4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951
        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;
4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988
        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;
4989 4990 4991
        }
        break;

4992
    case VIR_DOMAIN_CONTROLLER_TYPE_IDE:
4993 4994 4995 4996 4997
        /* 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.
4998
         */
4999
        if (qemuDomainMachineHasBuiltinIDE(domainDef))
5000
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
5001
                           _("Only a single IDE controller is supported "
5002 5003 5004 5005 5006 5007 5008
                             "for this machine type"));
        else
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("IDE controllers are unsupported for "
                             "this QEMU binary or machine type"));
        goto error;

5009
    default:
5010
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
5011
                       _("Unsupported controller type: %s"),
5012
                       virDomainControllerTypeToString(def->type));
5013 5014 5015
        goto error;
    }

5016 5017
    if (def->queues)
        virBufferAsprintf(&buf, ",num_queues=%u", def->queues);
5018

5019 5020 5021 5022 5023 5024
    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);

5025 5026
    qemuBuildIoEventFdStr(&buf, def->ioeventfd, qemuCaps);

5027
    if (qemuBuildDeviceAddressStr(&buf, domainDef, &def->info, qemuCaps) < 0)
5028 5029
        goto error;

5030
    if (virBufferCheckError(&buf) < 0)
5031 5032 5033 5034
        goto error;

    return virBufferContentAndReset(&buf);

5035
 error:
5036 5037 5038 5039 5040
    virBufferFreeAndReset(&buf);
    return NULL;
}


5041 5042 5043 5044
/**
 * qemuBuildMemoryBackendStr:
 * @size: size of the memory device in kibibytes
 * @pagesize: size of the requested memory page in KiB, 0 for default
5045 5046
 * @guestNode: NUMA node in the guest that the memory object will be attached
 *             to, or -1 if NUMA is not used in the guest
5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063
 * @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.
 */
5064
int
5065 5066 5067 5068 5069 5070 5071 5072
qemuBuildMemoryBackendStr(unsigned long long size,
                          unsigned long long pagesize,
                          int guestNode,
                          virBitmapPtr userNodeset,
                          virBitmapPtr autoNodeset,
                          virDomainDefPtr def,
                          virQEMUCapsPtr qemuCaps,
                          virQEMUDriverConfigPtr cfg,
5073 5074
                          const char **backendType,
                          virJSONValuePtr *backendProps,
5075 5076 5077 5078 5079
                          bool force)
{
    virDomainHugePagePtr master_hugepage = NULL;
    virDomainHugePagePtr hugepage = NULL;
    virDomainNumatuneMemMode mode;
5080
    const long system_page_size = virGetSystemPageSizeKB();
5081
    virNumaMemAccess memAccess = VIR_NUMA_MEM_ACCESS_DEFAULT;
5082 5083
    size_t i;
    char *mem_path = NULL;
5084
    virBitmapPtr nodemask = NULL;
5085
    int ret = -1;
5086
    virJSONValuePtr props = NULL;
5087
    bool nodeSpecified = virDomainNumatuneNodeSpecified(def->numa, guestNode);
5088

5089 5090 5091
    *backendProps = NULL;
    *backendType = NULL;

5092 5093 5094 5095 5096 5097 5098 5099 5100
    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;
        }
5101

5102 5103
        memAccess = virDomainNumaGetNodeMemoryAccessMode(def->numa, guestNode);
    }
5104

5105 5106 5107
    if (virDomainNumatuneGetMode(def->numa, guestNode, &mode) < 0 &&
        virDomainNumatuneGetMode(def->numa, -1, &mode) < 0)
        mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
5108

5109
    if (pagesize == 0) {
5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120
        /* 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;
            }

5121 5122 5123 5124
            /* just find the master hugepage in case we don't use NUMA */
            if (guestNode < 0)
                continue;

5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147
            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;
5148
    }
5149

5150 5151 5152 5153 5154 5155
    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;
5156 5157
    }

5158 5159 5160
    if (!(props = virJSONValueNewObject()))
        return -1;

5161 5162
    if (pagesize || hugepage) {
        if (pagesize) {
5163 5164 5165
            /* 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++) {
5166
                if (cfg->hugetlbfs[i].size == pagesize)
5167 5168
                    break;
            }
5169

5170 5171 5172
            if (i == cfg->nhugetlbfs) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("Unable to find any usable hugetlbfs mount for %llu KiB"),
5173
                               pagesize);
5174 5175
                goto cleanup;
            }
5176

5177 5178 5179 5180 5181 5182 5183
            if (!(mem_path = qemuGetHugepagePath(&cfg->hugetlbfs[i])))
                goto cleanup;
        } else {
            if (!(mem_path = qemuGetDefaultHugepath(cfg->hugetlbfs,
                                                    cfg->nhugetlbfs)))
                goto cleanup;
        }
5184

5185 5186 5187 5188 5189 5190 5191
        *backendType = "memory-backend-file";

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

        switch (memAccess) {
5194
        case VIR_NUMA_MEM_ACCESS_SHARED:
5195 5196
            if (virJSONValueObjectAdd(props, "b:share", true, NULL) < 0)
                goto cleanup;
5197 5198
            break;

5199
        case VIR_NUMA_MEM_ACCESS_PRIVATE:
5200 5201
            if (virJSONValueObjectAdd(props, "b:share", false, NULL) < 0)
                goto cleanup;
5202 5203
            break;

5204 5205
        case VIR_NUMA_MEM_ACCESS_DEFAULT:
        case VIR_NUMA_MEM_ACCESS_LAST:
5206 5207 5208 5209 5210 5211 5212 5213 5214 5215
            break;
        }
    } else {
        if (memAccess) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Shared memory mapping is supported "
                             "only with hugepages"));
            goto cleanup;
        }

5216
        *backendType = "memory-backend-ram";
5217 5218
    }

5219 5220
    if (virJSONValueObjectAdd(props, "U:size", size * 1024, NULL) < 0)
        goto cleanup;
5221 5222

    if (userNodeset) {
5223
        nodemask = userNodeset;
5224
    } else {
5225
        if (virDomainNumatuneMaybeGetNodeset(def->numa, autoNodeset,
5226
                                             &nodemask, guestNode) < 0)
5227 5228 5229 5230
            goto cleanup;
    }

    if (nodemask) {
5231 5232
        if (!virNumaNodesetIsAvailable(nodemask))
            goto cleanup;
5233 5234 5235 5236
        if (virJSONValueObjectAdd(props,
                                  "m:host-nodes", nodemask,
                                  "S:policy", qemuNumaPolicyTypeToString(mode),
                                  NULL) < 0)
5237 5238 5239
            goto cleanup;
    }

5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254
    /* 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)) {
5255 5256 5257
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("this qemu doesn't support the "
                             "memory-backend-ram object"));
5258
            goto cleanup;
5259 5260
        }

5261
        ret = 0;
5262 5263
    }

5264 5265
    *backendProps = props;
    props = NULL;
5266 5267

 cleanup:
5268
    virJSONValueFree(props);
5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282
    VIR_FREE(mem_path);

    return ret;
}


static int
qemuBuildMemoryCellBackendStr(virDomainDefPtr def,
                              virQEMUCapsPtr qemuCaps,
                              virQEMUDriverConfigPtr cfg,
                              size_t cell,
                              virBitmapPtr auto_nodeset,
                              char **backendStr)
{
5283 5284 5285 5286 5287
    virJSONValuePtr props = NULL;
    char *alias = NULL;
    const char *backendType;
    int ret = -1;
    int rc;
5288 5289
    unsigned long long memsize = virDomainNumaGetNodeMemorySize(def->numa,
                                                                cell);
5290

5291
    *backendStr = NULL;
5292

5293 5294 5295
    if (virAsprintf(&alias, "ram-node%zu", cell) < 0)
        goto cleanup;

5296 5297 5298
    if ((rc = qemuBuildMemoryBackendStr(memsize, 0, cell, NULL, auto_nodeset,
                                        def, qemuCaps, cfg, &backendType,
                                        &props, false)) < 0)
5299 5300 5301 5302 5303 5304 5305
        goto cleanup;

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

5306
    ret = rc;
5307 5308 5309 5310 5311

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

5312 5313 5314 5315
    return ret;
}


5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351
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;
}


5352
char *
5353
qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem)
5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364
{
    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:
5365 5366 5367 5368 5369 5370 5371
        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);
5372 5373 5374

        if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM) {
            virBufferAsprintf(&buf, ",slot=%d", mem->info.addr.dimm.slot);
5375
            virBufferAsprintf(&buf, ",addr=%llu", mem->info.addr.dimm.base);
5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394
        }

        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);
}


5395 5396 5397 5398 5399 5400
char *
qemuBuildNicStr(virDomainNetDefPtr net,
                const char *prefix,
                int vlan)
{
    char *str;
5401 5402
    char macaddr[VIR_MAC_STRING_BUFLEN];

5403 5404 5405 5406 5407 5408 5409 5410 5411
    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 : "")));
5412 5413 5414 5415 5416
    return str;
}


char *
5417 5418
qemuBuildNicDevStr(virDomainDefPtr def,
                   virDomainNetDefPtr net,
5419
                   int vlan,
5420
                   int bootindex,
5421
                   size_t vhostfdSize,
5422
                   virQEMUCapsPtr qemuCaps)
5423 5424
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
5425
    const char *nic = net->model;
5426
    bool usingVirtio = false;
5427
    char macaddr[VIR_MAC_STRING_BUFLEN];
5428

5429 5430
    if (STREQ(net->model, "virtio")) {
        if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
5431
            nic = "virtio-net-ccw";
5432
        else if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
5433
            nic = "virtio-net-s390";
5434 5435
        else if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
            nic = "virtio-net-device";
5436
        else
5437
            nic = "virtio-net-pci";
5438

5439
        usingVirtio = true;
5440 5441
    }

5442
    virBufferAdd(&buf, nic, -1);
5443
    if (usingVirtio && net->driver.virtio.txmode) {
5444
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_TX_ALG)) {
5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457
            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.
                     */
5458 5459
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("unrecognized virtio-net-pci 'tx' option"));
5460 5461 5462
                    goto error;
            }
        } else {
5463 5464
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("virtio-net-pci 'tx' option not supported in this QEMU binary"));
5465 5466 5467
            goto error;
        }
    }
5468
    if (usingVirtio) {
5469
        qemuBuildIoEventFdStr(&buf, net->driver.virtio.ioeventfd, qemuCaps);
5470
        if (net->driver.virtio.event_idx &&
5471
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_EVENT_IDX)) {
5472
            virBufferAsprintf(&buf, ",event_idx=%s",
J
Ján Tomko 已提交
5473
                              virTristateSwitchTypeToString(net->driver.virtio.event_idx));
5474
        }
5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498
        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 已提交
5499 5500 5501 5502
        if (net->driver.virtio.host.mrg_rxbuf) {
            virBufferAsprintf(&buf, ",mrg_rxbuf=%s",
                              virTristateSwitchTypeToString(net->driver.virtio.host.mrg_rxbuf));
        }
5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522
        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));
        }
5523
    }
5524
    if (usingVirtio && vhostfdSize > 1) {
5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535
        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);
        }
5536
    }
5537
    if (vlan == -1)
5538
        virBufferAsprintf(&buf, ",netdev=host%s", net->info.alias);
5539
    else
5540 5541
        virBufferAsprintf(&buf, ",vlan=%d", vlan);
    virBufferAsprintf(&buf, ",id=%s", net->info.alias);
5542 5543
    virBufferAsprintf(&buf, ",mac=%s",
                      virMacAddrFormat(&net->mac, macaddr));
5544
    if (qemuBuildDeviceAddressStr(&buf, def, &net->info, qemuCaps) < 0)
5545
        goto error;
5546
    if (qemuBuildRomStr(&buf, &net->info, qemuCaps) < 0)
5547
        goto error;
5548
    if (bootindex && virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX))
5549
        virBufferAsprintf(&buf, ",bootindex=%d", bootindex);
5550

5551
    if (virBufferCheckError(&buf) < 0)
5552 5553 5554 5555
        goto error;

    return virBufferContentAndReset(&buf);

5556
 error:
5557 5558 5559 5560 5561 5562 5563
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
qemuBuildHostNetStr(virDomainNetDefPtr net,
5564
                    virQEMUDriverPtr driver,
5565 5566
                    char type_sep,
                    int vlan,
5567
                    char **tapfd,
5568
                    size_t tapfdSize,
5569
                    char **vhostfd,
5570
                    size_t vhostfdSize)
5571
{
5572
    bool is_tap = false;
5573
    virBuffer buf = VIR_BUFFER_INITIALIZER;
5574
    virDomainNetType netType = virDomainNetGetActualType(net);
5575
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
5576
    size_t i;
5577

5578
    if (net->script && netType != VIR_DOMAIN_NET_TYPE_ETHERNET) {
5579 5580 5581
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("scripts are not supported on interfaces of type %s"),
                       virDomainNetTypeToString(netType));
5582
        virObjectUnref(cfg);
5583 5584 5585 5586
        return NULL;
    }

    switch (netType) {
R
Richa Marwaha 已提交
5587 5588 5589 5590 5591
    /*
     * If type='bridge', and we're running as privileged user
     * or -netdev bridge is not supported then it will fall
     * through, -net tap,fd
     */
5592
    case VIR_DOMAIN_NET_TYPE_BRIDGE:
R
Richa Marwaha 已提交
5593
    case VIR_DOMAIN_NET_TYPE_NETWORK:
5594
    case VIR_DOMAIN_NET_TYPE_DIRECT:
5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607
        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);
            }
        }
5608
        type_sep = ',';
5609
        is_tap = true;
5610 5611 5612 5613 5614
        break;

    case VIR_DOMAIN_NET_TYPE_ETHERNET:
        virBufferAddLit(&buf, "tap");
        if (net->ifname) {
5615
            virBufferAsprintf(&buf, "%cifname=%s", type_sep, net->ifname);
5616 5617
            type_sep = ',';
        }
5618
        if (net->script) {
5619
            virBufferAsprintf(&buf, "%cscript=%s", type_sep,
5620
                              net->script);
5621 5622
            type_sep = ',';
        }
5623
        is_tap = true;
5624 5625 5626
        break;

    case VIR_DOMAIN_NET_TYPE_CLIENT:
5627 5628 5629 5630 5631 5632 5633
       virBufferAsprintf(&buf, "socket%cconnect=%s:%d",
                         type_sep,
                         net->data.socket.address,
                         net->data.socket.port);
       type_sep = ',';
       break;

5634
    case VIR_DOMAIN_NET_TYPE_SERVER:
5635 5636
       virBufferAsprintf(&buf, "socket%clisten=%s:%d",
                         type_sep,
5637 5638
                         net->data.socket.address ? net->data.socket.address
                                                  : "",
5639 5640 5641 5642
                         net->data.socket.port);
       type_sep = ',';
       break;

5643
    case VIR_DOMAIN_NET_TYPE_MCAST:
5644 5645 5646 5647 5648 5649
       virBufferAsprintf(&buf, "socket%cmcast=%s:%d",
                         type_sep,
                         net->data.socket.address,
                         net->data.socket.port);
       type_sep = ',';
       break;
5650

5651 5652 5653 5654 5655 5656 5657 5658 5659 5660
    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;

5661 5662 5663 5664 5665 5666 5667
    case VIR_DOMAIN_NET_TYPE_USER:
    default:
        virBufferAddLit(&buf, "user");
        break;
    }

    if (vlan >= 0) {
5668
        virBufferAsprintf(&buf, "%cvlan=%d", type_sep, vlan);
5669
        if (net->info.alias)
5670
            virBufferAsprintf(&buf, ",name=host%s",
5671 5672
                              net->info.alias);
    } else {
5673
        virBufferAsprintf(&buf, "%cid=host%s",
5674 5675 5676
                          type_sep, net->info.alias);
    }

5677
    if (is_tap) {
5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690
        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);
                }
            }
        }
5691
        if (net->tune.sndbuf_specified)
5692
            virBufferAsprintf(&buf, ",sndbuf=%lu", net->tune.sndbuf);
5693 5694
    }

5695 5696
    virObjectUnref(cfg);

5697
    if (virBufferCheckError(&buf) < 0)
5698 5699 5700 5701 5702 5703 5704
        return NULL;

    return virBufferContentAndReset(&buf);
}


char *
5705 5706
qemuBuildWatchdogDevStr(virDomainDefPtr def,
                        virDomainWatchdogDefPtr dev,
5707
                        virQEMUCapsPtr qemuCaps)
5708 5709 5710 5711 5712
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    const char *model = virDomainWatchdogModelTypeToString(dev->model);
    if (!model) {
5713 5714
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("missing watchdog model"));
5715 5716 5717
        goto error;
    }

5718
    virBufferAsprintf(&buf, "%s,id=%s", model, dev->info.alias);
5719
    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
5720 5721
        goto error;

5722
    if (virBufferCheckError(&buf) < 0)
5723 5724 5725 5726
        goto error;

    return virBufferContentAndReset(&buf);

5727
 error:
5728 5729 5730 5731 5732 5733
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
5734 5735
qemuBuildMemballoonDevStr(virDomainDefPtr def,
                          virDomainMemballoonDefPtr dev,
5736
                          virQEMUCapsPtr qemuCaps)
5737 5738 5739
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

5740 5741 5742 5743 5744 5745 5746
    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;
5747 5748 5749
        case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
            virBufferAddLit(&buf, "virtio-balloon-device");
            break;
5750
        default:
5751 5752 5753
            virReportError(VIR_ERR_XML_ERROR,
                           _("memballoon unsupported with address type '%s'"),
                           virDomainDeviceAddressTypeToString(dev->info.type));
5754 5755 5756
            goto error;
    }

5757
    virBufferAsprintf(&buf, ",id=%s", dev->info.alias);
5758
    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
5759 5760
        goto error;

5761
    if (virBufferCheckError(&buf) < 0)
5762 5763 5764 5765
        goto error;

    return virBufferContentAndReset(&buf);

5766
 error:
5767 5768 5769 5770
    virBufferFreeAndReset(&buf);
    return NULL;
}

5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785
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;
    }

5786
    if (virBufferCheckError(&buf) < 0)
5787 5788 5789 5790
        goto error;

    return virBufferContentAndReset(&buf);

5791
 error:
5792 5793 5794
    virBufferFreeAndReset(&buf);
    return NULL;
}
5795

5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839
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;
5840
    case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH:
5841 5842 5843 5844 5845 5846 5847 5848
        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;
5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865
    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;
}

5866
char *
5867 5868
qemuBuildUSBInputDevStr(virDomainDefPtr def,
                        virDomainInputDefPtr dev,
5869
                        virQEMUCapsPtr qemuCaps)
5870 5871 5872
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885
    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;
    }
5886

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

5890
    if (virBufferCheckError(&buf) < 0)
5891 5892 5893 5894
        goto error;

    return virBufferContentAndReset(&buf);

5895
 error:
5896 5897 5898 5899 5900 5901
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
5902 5903
qemuBuildSoundDevStr(virDomainDefPtr def,
                     virDomainSoundDefPtr sound,
5904
                     virQEMUCapsPtr qemuCaps)
5905 5906
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
5907
    const char *model = NULL;
5908

5909
    /* Hack for devices with different names in QEMU and libvirt */
5910
    switch ((virDomainSoundModel) sound->model) {
5911
    case VIR_DOMAIN_SOUND_MODEL_ES1370:
5912
        model = "ES1370";
5913 5914
        break;
    case VIR_DOMAIN_SOUND_MODEL_AC97:
5915
        model = "AC97";
5916 5917
        break;
    case VIR_DOMAIN_SOUND_MODEL_ICH6:
5918
        model = "intel-hda";
5919
        break;
5920 5921 5922 5923 5924 5925 5926 5927 5928
    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;
5929 5930 5931 5932 5933 5934 5935 5936 5937
    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;
5938 5939 5940 5941 5942 5943 5944 5945 5946
    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;
5947
    }
5948

5949
    virBufferAsprintf(&buf, "%s,id=%s", model, sound->info.alias);
5950
    if (qemuBuildDeviceAddressStr(&buf, def, &sound->info, qemuCaps) < 0)
5951 5952
        goto error;

5953
    if (virBufferCheckError(&buf) < 0)
5954 5955 5956 5957
        goto error;

    return virBufferContentAndReset(&buf);

5958
 error:
5959 5960 5961 5962
    virBufferFreeAndReset(&buf);
    return NULL;
}

5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977

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;
    }
}


5978 5979
static char *
qemuBuildSoundCodecStr(virDomainSoundDefPtr sound,
5980
                       virDomainSoundCodecDefPtr codec,
5981
                       virQEMUCapsPtr qemuCaps)
5982 5983
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
5984
    const char *stype;
5985
    int type, flags;
5986

5987 5988
    type = codec->type;
    stype = qemuSoundCodecTypeToString(type);
5989
    flags = qemuSoundCodecTypeToCaps(type);
5990

5991
    if (flags == -1 || !virQEMUCapsGet(qemuCaps, flags)) {
5992 5993
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("%s not supported in this QEMU binary"), stype);
5994 5995 5996
        goto error;
    }

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

6000 6001
    return virBufferContentAndReset(&buf);

6002
 error:
6003 6004 6005
    virBufferFreeAndReset(&buf);
    return NULL;
}
6006 6007

static char *
6008 6009
qemuBuildDeviceVideoStr(virDomainDefPtr def,
                        virDomainVideoDefPtr video,
6010
                        virQEMUCapsPtr qemuCaps,
6011
                        bool primary)
6012 6013
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
6014
    const char *model;
6015

6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030
    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;
        }

6031
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL)) {
6032 6033 6034 6035 6036 6037
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("only one video card is currently supported"));
            goto error;
        }

        model = "qxl";
6038 6039
    }

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

6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053
    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) {
6054
        if (video->vram > (UINT_MAX / 1024)) {
6055
            virReportError(VIR_ERR_OVERFLOW,
6056 6057
                           _("value for 'vram' must be less than '%u'"),
                           UINT_MAX / 1024);
6058 6059
            goto error;
        }
6060 6061 6062 6063 6064 6065 6066
        if (video->ram > (UINT_MAX / 1024)) {
            virReportError(VIR_ERR_OVERFLOW,
                           _("value for 'ram' must be less than '%u'"),
                           UINT_MAX / 1024);
            goto error;
        }

6067 6068 6069 6070
        if (video->ram) {
            /* QEMU accepts bytes for ram_size. */
            virBufferAsprintf(&buf, ",ram_size=%u", video->ram * 1024);
        }
6071

6072 6073 6074 6075
        if (video->vram) {
            /* QEMU accepts bytes for vram_size. */
            virBufferAsprintf(&buf, ",vram_size=%u", video->vram * 1024);
        }
6076 6077 6078 6079 6080 6081

        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);
        }
6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095
    } 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);
6096 6097
    }

6098
    if (qemuBuildDeviceAddressStr(&buf, def, &video->info, qemuCaps) < 0)
6099 6100
        goto error;

6101
    if (virBufferCheckError(&buf) < 0)
6102 6103 6104 6105
        goto error;

    return virBufferContentAndReset(&buf);

6106
 error:
6107 6108 6109 6110 6111 6112 6113 6114
    virBufferFreeAndReset(&buf);
    return NULL;
}


int
qemuOpenPCIConfig(virDomainHostdevDefPtr dev)
{
6115
    virDomainHostdevSubsysPCIPtr pcisrc = &dev->source.subsys.u.pci;
6116 6117 6118 6119
    char *path = NULL;
    int configfd = -1;

    if (virAsprintf(&path, "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/config",
6120 6121
                    pcisrc->addr.domain, pcisrc->addr.bus,
                    pcisrc->addr.slot, pcisrc->addr.function) < 0)
6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134
        return -1;

    configfd = open(path, O_RDWR, 0);

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

    VIR_FREE(path);

    return configfd;
}

char *
6135 6136
qemuBuildPCIHostdevDevStr(virDomainDefPtr def,
                          virDomainHostdevDefPtr dev,
6137
                          int bootIndex, /* used iff dev->info->bootIndex == 0 */
6138
                          const char *configfd,
6139
                          virQEMUCapsPtr qemuCaps)
6140 6141
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
6142 6143
    virDomainHostdevSubsysPCIPtr pcisrc = &dev->source.subsys.u.pci;
    int backend = pcisrc->backend;
6144

6145
    /* caller has to assign proper passthrough backend type */
6146
    switch ((virDomainHostdevSubsysPCIBackendType) backend) {
6147
    case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
6148 6149 6150
        virBufferAddLit(&buf, "pci-assign");
        if (configfd && *configfd)
            virBufferAsprintf(&buf, ",configfd=%s", configfd);
6151 6152 6153 6154 6155 6156
        break;

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

6157
    default:
6158 6159
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("invalid PCI passthrough type '%s'"),
6160
                       virDomainHostdevSubsysPCIBackendTypeToString(backend));
6161
        goto error;
6162
    }
6163

6164
    virBufferAddLit(&buf, ",host=");
6165
    if (pcisrc->addr.domain) {
6166 6167 6168 6169
        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"),
6170
                           pcisrc->addr.domain);
6171 6172
            goto error;
        }
6173
        virBufferAsprintf(&buf, "%.4x:", pcisrc->addr.domain);
6174 6175
    }
    virBufferAsprintf(&buf, "%.2x:%.2x.%.1x",
6176 6177
                      pcisrc->addr.bus, pcisrc->addr.slot,
                      pcisrc->addr.function);
6178 6179
    virBufferAsprintf(&buf, ",id=%s", dev->info->alias);
    if (dev->info->bootIndex)
6180 6181 6182
        bootIndex = dev->info->bootIndex;
    if (bootIndex)
        virBufferAsprintf(&buf, ",bootindex=%d", bootIndex);
6183
    if (qemuBuildDeviceAddressStr(&buf, def, dev->info, qemuCaps) < 0)
6184
        goto error;
6185
    if (qemuBuildRomStr(&buf, dev->info, qemuCaps) < 0)
6186
        goto error;
6187

6188
    if (virBufferCheckError(&buf) < 0)
6189 6190 6191 6192
        goto error;

    return virBufferContentAndReset(&buf);

6193
 error:
6194 6195 6196 6197 6198 6199
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
6200 6201
qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev,
                             virQEMUCapsPtr qemuCaps)
6202 6203
{
    char *ret = NULL;
6204
    virDomainHostdevSubsysPCIPtr pcisrc = &dev->source.subsys.u.pci;
6205

6206
    if (pcisrc->addr.domain) {
6207 6208 6209 6210
        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"),
6211
                           pcisrc->addr.domain);
6212 6213 6214
            goto cleanup;
        }
        ignore_value(virAsprintf(&ret, "host=%.4x:%.2x:%.2x.%.1x",
6215 6216
                                 pcisrc->addr.domain, pcisrc->addr.bus,
                                 pcisrc->addr.slot, pcisrc->addr.function));
6217 6218
    } else {
        ignore_value(virAsprintf(&ret, "host=%.2x:%.2x.%.1x",
6219 6220
                                 pcisrc->addr.bus, pcisrc->addr.slot,
                                 pcisrc->addr.function));
6221 6222
    }
 cleanup:
6223 6224 6225 6226
    return ret;
}


6227
char *
6228 6229
qemuBuildRedirdevDevStr(virDomainDefPtr def,
                        virDomainRedirdevDefPtr dev,
6230
                        virQEMUCapsPtr qemuCaps)
6231
{
6232
    size_t i;
6233
    virBuffer buf = VIR_BUFFER_INITIALIZER;
6234
    virDomainRedirFilterDefPtr redirfilter = def->redirfilter;
6235 6236

    if (dev->bus != VIR_DOMAIN_REDIRDEV_BUS_USB) {
6237 6238 6239
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Redirection bus %s is not supported by QEMU"),
                       virDomainRedirdevBusTypeToString(dev->bus));
6240 6241 6242
        goto error;
    }

6243
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_REDIR)) {
6244 6245 6246
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("USB redirection is not supported "
                         "by this version of QEMU"));
6247 6248 6249 6250
        goto error;
    }

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

6253
    if (redirfilter && redirfilter->nusbdevs) {
6254
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_REDIR_FILTER)) {
6255 6256 6257 6258 6259 6260
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("USB redirection filter is not "
                             "supported by this version of QEMU"));
            goto error;
        }

6261
        virBufferAddLit(&buf, ",filter=");
6262 6263

        for (i = 0; i < redirfilter->nusbdevs; i++) {
6264
            virDomainRedirFilterUSBDevDefPtr usbdev = redirfilter->usbdevs[i];
6265 6266 6267
            if (usbdev->usbClass >= 0)
                virBufferAsprintf(&buf, "0x%02X:", usbdev->usbClass);
            else
6268
                virBufferAddLit(&buf, "-1:");
6269 6270 6271 6272

            if (usbdev->vendor >= 0)
                virBufferAsprintf(&buf, "0x%04X:", usbdev->vendor);
            else
6273
                virBufferAddLit(&buf, "-1:");
6274 6275 6276 6277

            if (usbdev->product >= 0)
                virBufferAsprintf(&buf, "0x%04X:", usbdev->product);
            else
6278
                virBufferAddLit(&buf, "-1:");
6279 6280 6281 6282

            if (usbdev->version >= 0)
                virBufferAsprintf(&buf, "0x%04X:", usbdev->version);
            else
6283
                virBufferAddLit(&buf, "-1:");
6284 6285 6286

            virBufferAsprintf(&buf, "%u", usbdev->allow);
            if (i < redirfilter->nusbdevs -1)
6287
                virBufferAddLit(&buf, "|");
6288 6289 6290
        }
    }

6291
    if (dev->info.bootIndex) {
6292
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_REDIR_BOOTINDEX)) {
6293 6294 6295 6296 6297 6298 6299 6300
            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);
    }

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

6304
    if (virBufferCheckError(&buf) < 0)
6305 6306 6307 6308
        goto error;

    return virBufferContentAndReset(&buf);

6309
 error:
6310 6311 6312 6313
    virBufferFreeAndReset(&buf);
    return NULL;
}

6314
char *
6315 6316
qemuBuildUSBHostdevDevStr(virDomainDefPtr def,
                          virDomainHostdevDefPtr dev,
6317
                          virQEMUCapsPtr qemuCaps)
6318
{
6319
    virBuffer buf = VIR_BUFFER_INITIALIZER;
6320
    virDomainHostdevSubsysUSBPtr usbsrc = &dev->source.subsys.u.usb;
6321

6322
    if (!dev->missing && !usbsrc->bus && !usbsrc->device) {
6323 6324
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("USB host device is missing bus/device information"));
6325 6326 6327
        return NULL;
    }

6328 6329 6330
    virBufferAddLit(&buf, "usb-host");
    if (!dev->missing) {
        virBufferAsprintf(&buf, ",hostbus=%d,hostaddr=%d",
6331
                          usbsrc->bus, usbsrc->device);
6332 6333
    }
    virBufferAsprintf(&buf, ",id=%s", dev->info->alias);
6334 6335
    if (dev->info->bootIndex)
        virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);
6336

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

6340
    if (virBufferCheckError(&buf) < 0)
6341
        goto error;
6342

6343 6344
    return virBufferContentAndReset(&buf);

6345
 error:
6346 6347
    virBufferFreeAndReset(&buf);
    return NULL;
6348 6349 6350
}


M
Marc-André Lureau 已提交
6351
char *
6352 6353
qemuBuildHubDevStr(virDomainDefPtr def,
                   virDomainHubDefPtr dev,
6354
                   virQEMUCapsPtr qemuCaps)
M
Marc-André Lureau 已提交
6355 6356 6357 6358
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if (dev->type != VIR_DOMAIN_HUB_TYPE_USB) {
6359 6360 6361
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("hub type %s not supported"),
                       virDomainHubTypeToString(dev->type));
M
Marc-André Lureau 已提交
6362 6363 6364
        goto error;
    }

6365
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_HUB)) {
6366
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6367
                       _("usb-hub not supported by QEMU binary"));
M
Marc-André Lureau 已提交
6368 6369 6370 6371 6372
        goto error;
    }

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

6376
    if (virBufferCheckError(&buf) < 0)
M
Marc-André Lureau 已提交
6377 6378 6379 6380
        goto error;

    return virBufferContentAndReset(&buf);

6381
 error:
M
Marc-André Lureau 已提交
6382 6383 6384 6385 6386
    virBufferFreeAndReset(&buf);
    return NULL;
}


6387
char *
6388
qemuBuildUSBHostdevUSBDevStr(virDomainHostdevDefPtr dev)
6389 6390
{
    char *ret = NULL;
6391
    virDomainHostdevSubsysUSBPtr usbsrc = &dev->source.subsys.u.usb;
6392

6393 6394 6395 6396 6397 6398
    if (dev->missing) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("This QEMU doesn't not support missing USB devices"));
        return NULL;
    }

6399
    if (!usbsrc->bus && !usbsrc->device) {
6400 6401
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("USB host device is missing bus/device information"));
6402 6403 6404
        return NULL;
    }

6405
    ignore_value(virAsprintf(&ret, "host:%d.%d", usbsrc->bus, usbsrc->device));
6406 6407 6408
    return ret;
}

6409 6410 6411 6412
static char *
qemuBuildSCSIHostHostdevDrvStr(virDomainHostdevDefPtr dev,
                               virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED,
                               qemuBuildCommandLineCallbacksPtr callbacks)
6413
{
6414
    virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
6415
    virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
6416 6417
    char *sg = NULL;

6418
    sg = (callbacks->qemuGetSCSIDeviceSgName)(NULL,
6419 6420 6421 6422
                                              scsihostsrc->adapter,
                                              scsihostsrc->bus,
                                              scsihostsrc->target,
                                              scsihostsrc->unit);
6423 6424 6425 6426 6427 6428 6429 6430 6431 6432
    return sg;
}

static char *
qemuBuildSCSIiSCSIHostdevDrvStr(virConnectPtr conn,
                                virDomainHostdevDefPtr dev)
{
    char *source = NULL;
    char *secret = NULL;
    char *username = NULL;
6433 6434 6435 6436
    virStorageSource src;

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

6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451
    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;
    }

6452 6453 6454 6455 6456
    src.protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
    src.path = iscsisrc->path;
    src.hosts = iscsisrc->hosts;
    src.nhosts = iscsisrc->nhosts;

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

6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484
 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);
    }
6485 6486 6487 6488
    virBufferAsprintf(&buf, ",id=%s-%s",
                      virDomainDeviceAddressTypeToString(dev->info->type),
                      dev->info->alias);

O
Osier Yang 已提交
6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499
    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;
        }
    }

6500
    if (virBufferCheckError(&buf) < 0)
6501 6502
        goto error;

6503
    VIR_FREE(source);
6504
    return virBufferContentAndReset(&buf);
6505
 error:
6506
    VIR_FREE(source);
6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517
    virBufferFreeAndReset(&buf);
    return NULL;
}

char *
qemuBuildSCSIHostdevDevStr(virDomainDefPtr def,
                           virDomainHostdevDefPtr dev,
                           virQEMUCapsPtr qemuCaps)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    int model = -1;
6518
    const char *contAlias;
6519 6520 6521 6522

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

6523
    if (qemuSetSCSIControllerModel(def, qemuCaps, &model) < 0)
6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543
        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");

6544 6545 6546 6547
    if (!(contAlias = virDomainControllerAliasFind(def, VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
                                                   dev->info->addr.drive.controller)))
        goto error;

6548
    if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) {
6549 6550
        virBufferAsprintf(&buf, ",bus=%s.%d,scsi-id=%d",
                          contAlias,
6551 6552 6553
                          dev->info->addr.drive.bus,
                          dev->info->addr.drive.unit);
    } else {
6554 6555
        virBufferAsprintf(&buf, ",bus=%s.0,channel=%d,scsi-id=%d,lun=%d",
                          contAlias,
6556 6557 6558 6559
                          dev->info->addr.drive.bus,
                          dev->info->addr.drive.target,
                          dev->info->addr.drive.unit);
    }
6560

6561 6562 6563 6564
    virBufferAsprintf(&buf, ",drive=%s-%s,id=%s",
                      virDomainDeviceAddressTypeToString(dev->info->type),
                      dev->info->alias, dev->info->alias);

6565 6566 6567
    if (dev->info->bootIndex)
        virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);

6568
    if (virBufferCheckError(&buf) < 0)
6569 6570 6571
        goto error;

    return virBufferContentAndReset(&buf);
6572
 error:
6573 6574 6575
    virBufferFreeAndReset(&buf);
    return NULL;
}
6576 6577 6578

/* This function outputs a -chardev command line option which describes only the
 * host side of the character device */
6579
static char *
6580
qemuBuildChrChardevStr(virDomainChrSourceDefPtr dev, const char *alias,
6581
                       virQEMUCapsPtr qemuCaps)
6582 6583 6584 6585
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    bool telnet;

6586
    switch (dev->type) {
6587
    case VIR_DOMAIN_CHR_TYPE_NULL:
6588
        virBufferAsprintf(&buf, "null,id=char%s", alias);
6589 6590 6591
        break;

    case VIR_DOMAIN_CHR_TYPE_VC:
6592
        virBufferAsprintf(&buf, "vc,id=char%s", alias);
6593 6594 6595
        break;

    case VIR_DOMAIN_CHR_TYPE_PTY:
6596
        virBufferAsprintf(&buf, "pty,id=char%s", alias);
6597 6598 6599
        break;

    case VIR_DOMAIN_CHR_TYPE_DEV:
6600 6601 6602
        virBufferAsprintf(&buf, "%s,id=char%s,path=%s",
                          STRPREFIX(alias, "parallel") ? "parport" : "tty",
                          alias, dev->data.file.path);
6603 6604 6605
        break;

    case VIR_DOMAIN_CHR_TYPE_FILE:
6606
        virBufferAsprintf(&buf, "file,id=char%s,path=%s", alias,
6607
                          dev->data.file.path);
6608
        if (dev->data.file.append != VIR_TRISTATE_SWITCH_ABSENT) {
6609 6610 6611 6612 6613 6614 6615 6616 6617
            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));
        }
6618 6619 6620
        break;

    case VIR_DOMAIN_CHR_TYPE_PIPE:
6621
        virBufferAsprintf(&buf, "pipe,id=char%s,path=%s", alias,
6622
                          dev->data.file.path);
6623 6624 6625
        break;

    case VIR_DOMAIN_CHR_TYPE_STDIO:
6626
        virBufferAsprintf(&buf, "stdio,id=char%s", alias);
6627 6628
        break;

6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640
    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";

6641
        virBufferAsprintf(&buf,
6642 6643
                          "udp,id=char%s,host=%s,port=%s,localaddr=%s,"
                          "localport=%s",
6644
                          alias,
6645
                          connectHost,
6646
                          dev->data.udp.connectService,
6647
                          bindHost, bindService);
6648
        break;
6649
    }
6650 6651
    case VIR_DOMAIN_CHR_TYPE_TCP:
        telnet = dev->data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET;
6652
        virBufferAsprintf(&buf,
6653
                          "socket,id=char%s,host=%s,port=%s%s%s",
6654
                          alias,
6655 6656 6657 6658 6659 6660 6661
                          dev->data.tcp.host,
                          dev->data.tcp.service,
                          telnet ? ",telnet" : "",
                          dev->data.tcp.listen ? ",server,nowait" : "");
        break;

    case VIR_DOMAIN_CHR_TYPE_UNIX:
6662
        virBufferAsprintf(&buf,
6663
                          "socket,id=char%s,path=%s%s",
6664
                          alias,
6665 6666 6667
                          dev->data.nix.path,
                          dev->data.nix.listen ? ",server,nowait" : "");
        break;
6668 6669

    case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
6670
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEVMC)) {
6671
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6672
                           _("spicevmc not supported in this QEMU binary"));
6673 6674
            goto error;
        }
6675
        virBufferAsprintf(&buf, "spicevmc,id=char%s,name=%s", alias,
E
Eric Blake 已提交
6676
                          virDomainChrSpicevmcTypeToString(dev->data.spicevmc));
6677 6678
        break;

6679 6680 6681 6682 6683 6684 6685 6686 6687 6688
    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;

6689
    default:
6690 6691 6692
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unsupported chardev '%s'"),
                       virDomainChrTypeToString(dev->type));
6693
        goto error;
6694 6695
    }

6696
    if (virBufferCheckError(&buf) < 0)
6697 6698 6699 6700
        goto error;

    return virBufferContentAndReset(&buf);

6701
 error:
6702 6703 6704 6705 6706
    virBufferFreeAndReset(&buf);
    return NULL;
}


6707 6708
static char *
qemuBuildChrArgStr(virDomainChrSourceDefPtr dev, const char *prefix)
6709 6710 6711 6712 6713 6714
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

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

6715
    switch ((virDomainChrType)dev->type) {
6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732
    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:
6733
        virBufferAsprintf(&buf, "file:%s", dev->data.file.path);
6734 6735 6736
        break;

    case VIR_DOMAIN_CHR_TYPE_PIPE:
6737
        virBufferAsprintf(&buf, "pipe:%s", dev->data.file.path);
6738 6739 6740 6741 6742 6743
        break;

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

6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755
    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";

6756
        virBufferAsprintf(&buf, "udp:%s:%s@%s:%s",
6757
                          connectHost,
6758
                          dev->data.udp.connectService,
6759 6760
                          bindHost,
                          bindService);
6761
        break;
6762
    }
6763 6764
    case VIR_DOMAIN_CHR_TYPE_TCP:
        if (dev->data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET) {
6765
            virBufferAsprintf(&buf, "telnet:%s:%s%s",
6766 6767 6768 6769
                              dev->data.tcp.host,
                              dev->data.tcp.service,
                              dev->data.tcp.listen ? ",server,nowait" : "");
        } else {
6770
            virBufferAsprintf(&buf, "tcp:%s:%s%s",
6771 6772 6773 6774 6775 6776 6777
                              dev->data.tcp.host,
                              dev->data.tcp.service,
                              dev->data.tcp.listen ? ",server,nowait" : "");
        }
        break;

    case VIR_DOMAIN_CHR_TYPE_UNIX:
6778
        virBufferAsprintf(&buf, "unix:%s%s",
6779 6780 6781
                          dev->data.nix.path,
                          dev->data.nix.listen ? ",server,nowait" : "");
        break;
6782

6783
    case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
6784
    case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
6785
    case VIR_DOMAIN_CHR_TYPE_NMDM:
6786
    case VIR_DOMAIN_CHR_TYPE_LAST:
6787
        break;
6788 6789
    }

6790
    if (virBufferCheckError(&buf) < 0)
6791 6792 6793 6794
        goto error;

    return virBufferContentAndReset(&buf);

6795
 error:
6796 6797 6798 6799 6800
    virBufferFreeAndReset(&buf);
    return NULL;
}


6801
static char *
6802 6803
qemuBuildVirtioSerialPortDevStr(virDomainDefPtr def,
                                virDomainChrDefPtr dev,
6804
                                virQEMUCapsPtr qemuCaps)
6805 6806
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
6807 6808
    const char *contAlias;

6809 6810
    switch (dev->deviceType) {
    case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE:
6811
        virBufferAddLit(&buf, "virtconsole");
6812 6813 6814 6815
        break;
    case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL:
        /* Legacy syntax  '-device spicevmc' */
        if (dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC &&
6816
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC)) {
6817 6818 6819 6820 6821 6822
            virBufferAddLit(&buf, "spicevmc");
        } else {
            virBufferAddLit(&buf, "virtserialport");
        }
        break;
    default:
6823 6824
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Cannot use virtio serial for parallel/serial devices"));
6825 6826
        return NULL;
    }
6827

6828
    if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
6829
        dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW &&
6830
        dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
6831 6832 6833 6834
        /* Check it's a virtio-serial address */
        if (dev->info.type !=
            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL)
        {
6835 6836
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("virtio serial device has invalid address type"));
6837 6838 6839
            goto error;
        }

6840 6841 6842 6843 6844 6845 6846
        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,
6847 6848 6849
                          dev->info.addr.vioserial.port);
    }

6850 6851
    if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
        dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC &&
6852 6853
        dev->target.name &&
        STRNEQ(dev->target.name, "com.redhat.spice.0")) {
6854 6855 6856
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Unsupported spicevmc target name '%s'"),
                       dev->target.name);
6857 6858
        goto error;
    }
6859 6860 6861

    if (!(dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
          dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC &&
6862
          virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC))) {
6863
        virBufferAsprintf(&buf, ",chardev=char%s,id=%s",
6864
                          dev->info.alias, dev->info.alias);
6865 6866 6867
        if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
            (dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC ||
             dev->target.name)) {
6868 6869
            virBufferAsprintf(&buf, ",name=%s", dev->target.name
                              ? dev->target.name : "com.redhat.spice.0");
6870
        }
6871 6872
    } else {
        virBufferAsprintf(&buf, ",id=%s", dev->info.alias);
6873
    }
6874
    if (virBufferCheckError(&buf) < 0)
6875 6876 6877 6878
        goto error;

    return virBufferContentAndReset(&buf);

6879
 error:
6880 6881 6882 6883
    virBufferFreeAndReset(&buf);
    return NULL;
}

6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899 6900 6901 6902 6903
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);
6904
    if (virBufferCheckError(&buf) < 0)
6905 6906 6907 6908
        goto error;

    return virBufferContentAndReset(&buf);

6909
 error:
6910 6911 6912 6913
    virBufferFreeAndReset(&buf);
    return NULL;
}

6914 6915

static int
6916 6917 6918
qemuBuildRNGBackendChrdevStr(virDomainRNGDefPtr rng,
                             virQEMUCapsPtr qemuCaps,
                             char **chr)
6919
{
6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937
    *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;
}


6938
int
6939 6940 6941 6942 6943 6944
qemuBuildRNGBackendProps(virDomainRNGDefPtr rng,
                         virQEMUCapsPtr qemuCaps,
                         const char **type,
                         virJSONValuePtr *props)
{
    char *charBackendAlias = NULL;
6945 6946
    int ret = -1;

6947
    switch ((virDomainRNGBackend) rng->backend) {
6948 6949 6950 6951
    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 "
6952
                             "backend"));
6953 6954 6955
            goto cleanup;
        }

6956
        *type = "rng-random";
6957

6958 6959 6960
        if (virJSONValueObjectCreate(props, "s:filename", rng->source.file,
                                     NULL) < 0)
            goto cleanup;
6961 6962 6963
        break;

    case VIR_DOMAIN_RNG_BACKEND_EGD:
6964 6965 6966 6967 6968 6969 6970
        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;
        }

6971 6972 6973
        *type = "rng-egd";

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

6976 6977 6978
        if (virJSONValueObjectCreate(props, "s:chardev", charBackendAlias,
                                     NULL) < 0)
            goto cleanup;
6979

6980 6981 6982
        break;

    case VIR_DOMAIN_RNG_BACKEND_LAST:
6983 6984 6985
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("unknown rng-random backend"));
        goto cleanup;
6986 6987 6988 6989
    }

    ret = 0;

6990
 cleanup:
6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015
    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);
7016 7017 7018 7019
    return ret;
}


7020 7021 7022 7023
char *
qemuBuildRNGDevStr(virDomainDefPtr def,
                   virDomainRNGDefPtr dev,
                   virQEMUCapsPtr qemuCaps)
7024 7025 7026 7027 7028 7029 7030 7031
{
    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));
7032
        goto error;
7033 7034
    }

7035 7036 7037 7038
    if (!qemuCheckCCWS390AddressSupport(def, dev->info, qemuCaps,
                                        dev->source.file))
        goto error;

7039
    if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
7040 7041
        virBufferAsprintf(&buf, "virtio-rng-ccw,rng=obj%s,id=%s",
                          dev->info.alias, dev->info.alias);
7042
    else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
7043 7044
        virBufferAsprintf(&buf, "virtio-rng-s390,rng=obj%s,id=%s",
                          dev->info.alias, dev->info.alias);
7045
    else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
7046 7047
        virBufferAsprintf(&buf, "virtio-rng-device,rng=obj%s,id=%s",
                          dev->info.alias, dev->info.alias);
7048
    else
7049 7050
        virBufferAsprintf(&buf, "virtio-rng-pci,rng=obj%s,id=%s",
                          dev->info.alias, dev->info.alias);
7051

7052 7053 7054 7055 7056 7057 7058 7059
    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");
    }

7060
    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
7061 7062 7063
        goto error;
    if (virBufferCheckError(&buf) < 0)
        goto error;
7064

7065
    return virBufferContentAndReset(&buf);
7066

7067
 error:
7068
    virBufferFreeAndReset(&buf);
7069
    return NULL;
7070 7071 7072
}


E
Eric Blake 已提交
7073
static char *qemuBuildTPMBackendStr(const virDomainDef *def,
7074
                                    virCommandPtr cmd,
7075
                                    virQEMUCapsPtr qemuCaps,
7076 7077
                                    const char *emulator,
                                    int *tpmfd, int *cancelfd)
7078
{
E
Eric Blake 已提交
7079
    const virDomainTPMDef *tpm = def->tpm;
7080 7081
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    const char *type = virDomainTPMBackendTypeToString(tpm->type);
7082
    char *cancel_path = NULL, *devset = NULL;
7083
    const char *tpmdev;
7084

7085 7086 7087
    *tpmfd = -1;
    *cancelfd = -1;

7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098
    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;

7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127
        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;
        }
7128
        virBufferAddLit(&buf, ",path=");
7129
        virBufferEscape(&buf, ',', ",", "%s", devset ? devset : tpmdev);
7130 7131 7132

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

        VIR_FREE(devset);
7135 7136 7137 7138 7139 7140 7141
        VIR_FREE(cancel_path);

        break;
    case VIR_DOMAIN_TPM_TYPE_LAST:
        goto error;
    }

7142
    if (virBufferCheckError(&buf) < 0)
7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153
        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:
7154 7155 7156
    VIR_FREE(devset);
    VIR_FREE(cancel_path);

7157 7158 7159 7160 7161
    virBufferFreeAndReset(&buf);
    return NULL;
}


E
Eric Blake 已提交
7162
static char *qemuBuildTPMDevStr(const virDomainDef *def,
7163 7164 7165 7166
                                virQEMUCapsPtr qemuCaps,
                                const char *emulator)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
E
Eric Blake 已提交
7167
    const virDomainTPMDef *tpm = def->tpm;
7168 7169 7170 7171 7172 7173 7174 7175 7176 7177 7178 7179 7180
    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);

7181
    if (virBufferCheckError(&buf) < 0)
7182 7183 7184 7185 7186 7187 7188 7189 7190 7191
        goto error;

    return virBufferContentAndReset(&buf);

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


7192
static char *qemuBuildSmbiosBiosStr(virSysinfoBIOSDefPtr def)
7193 7194 7195
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

7196
    if (!def)
7197
        return NULL;
7198 7199 7200 7201

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

    /* 0:Vendor */
7202 7203
    if (def->vendor)
        virBufferAsprintf(&buf, ",vendor=%s", def->vendor);
7204
    /* 0:BIOS Version */
7205 7206
    if (def->version)
        virBufferAsprintf(&buf, ",version=%s", def->version);
7207
    /* 0:BIOS Release Date */
7208 7209
    if (def->date)
        virBufferAsprintf(&buf, ",date=%s", def->date);
7210
    /* 0:System BIOS Major Release and 0:System BIOS Minor Release */
7211 7212
    if (def->release)
        virBufferAsprintf(&buf, ",release=%s", def->release);
7213

7214
    if (virBufferCheckError(&buf) < 0)
7215 7216 7217 7218
        goto error;

    return virBufferContentAndReset(&buf);

7219
 error:
7220
    virBufferFreeAndReset(&buf);
7221
    return NULL;
7222 7223
}

7224 7225
static char *qemuBuildSmbiosSystemStr(virSysinfoSystemDefPtr def,
                                      bool skip_uuid)
7226 7227 7228
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

7229 7230 7231 7232
    if (!def ||
        (!def->manufacturer && !def->product && !def->version &&
         !def->serial && (!def->uuid || skip_uuid) &&
         def->sku && !def->family))
7233 7234 7235 7236 7237
        return NULL;

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

    /* 1:Manufacturer */
7238
    if (def->manufacturer)
7239
        virBufferAsprintf(&buf, ",manufacturer=%s",
7240
                          def->manufacturer);
7241
     /* 1:Product Name */
7242 7243
    if (def->product)
        virBufferAsprintf(&buf, ",product=%s", def->product);
7244
    /* 1:Version */
7245 7246
    if (def->version)
        virBufferAsprintf(&buf, ",version=%s", def->version);
7247
    /* 1:Serial Number */
7248 7249
    if (def->serial)
        virBufferAsprintf(&buf, ",serial=%s", def->serial);
7250
    /* 1:UUID */
7251 7252
    if (def->uuid && !skip_uuid)
        virBufferAsprintf(&buf, ",uuid=%s", def->uuid);
7253
    /* 1:SKU Number */
7254 7255
    if (def->sku)
        virBufferAsprintf(&buf, ",sku=%s", def->sku);
7256
    /* 1:Family */
7257 7258
    if (def->family)
        virBufferAsprintf(&buf, ",family=%s", def->family);
7259

7260
    if (virBufferCheckError(&buf) < 0)
7261 7262 7263 7264
        goto error;

    return virBufferContentAndReset(&buf);

7265
 error:
7266
    virBufferFreeAndReset(&buf);
7267
    return NULL;
7268 7269
}

7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308
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;
}

7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327
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;

7328 7329 7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346
        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;
7347
        }
7348

7349 7350 7351
        now += def->data.variable.adjustment;
        gmtime_r(&now, &nowbits);

7352 7353 7354 7355 7356 7357 7358 7359
        /* 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;

7360
        virBufferAsprintf(&buf, "base=%d-%02d-%02dT%02d:%02d:%02d",
7361 7362 7363 7364 7365 7366 7367 7368 7369
                          nowbits.tm_year + 1900,
                          nowbits.tm_mon + 1,
                          nowbits.tm_mday,
                          nowbits.tm_hour,
                          nowbits.tm_min,
                          nowbits.tm_sec);
    }   break;

    default:
7370 7371 7372
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unsupported clock offset '%s'"),
                       virDomainClockOffsetTypeToString(def->offset));
7373 7374 7375 7376
        goto error;
    }

    /* Look for an 'rtc' timer element, and add in appropriate clock= and driftfix= */
7377
    size_t i;
7378 7379 7380 7381 7382 7383
    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:
7384 7385 7386
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("unsupported rtc timer track '%s'"),
                               virDomainTimerTrackTypeToString(def->timers[i]->track));
7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407
                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:
7408 7409 7410
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("unsupported rtc timer tickpolicy '%s'"),
                               virDomainTimerTickpolicyTypeToString(def->timers[i]->tickpolicy));
7411 7412 7413 7414 7415 7416
                goto error;
            }
            break; /* no need to check other timers - there is only one rtc */
        }
    }

7417
    if (virBufferCheckError(&buf) < 0)
7418 7419 7420 7421
        goto error;

    return virBufferContentAndReset(&buf);

7422
 error:
7423 7424 7425 7426 7427
    virBufferFreeAndReset(&buf);
    return NULL;
}

static int
7428 7429 7430 7431 7432 7433
qemuBuildCpuModelArgStr(virQEMUDriverPtr driver,
                        const virDomainDef *def,
                        virBufferPtr buf,
                        virQEMUCapsPtr qemuCaps,
                        bool *hasHwVirt,
                        bool migrating)
7434
{
7435 7436
    int ret = -1;
    size_t i;
7437
    virCPUDefPtr host = NULL;
7438
    virCPUDefPtr guest = NULL;
7439
    virCPUDefPtr cpu = NULL;
7440
    virCPUDefPtr featCpu = NULL;
7441
    size_t ncpus = 0;
7442
    char **cpus = NULL;
7443
    virCPUDataPtr data = NULL;
7444
    virCPUDataPtr hostData = NULL;
7445
    char *compare_msg = NULL;
7446 7447
    virCPUCompareResult cmp;
    const char *preferred;
7448
    virCapsPtr caps = NULL;
7449 7450 7451
    bool compareAgainstHost = ((def->virtType == VIR_DOMAIN_VIRT_KVM ||
                                def->cpu->mode != VIR_CPU_MODE_CUSTOM) &&
                               def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH);
7452

7453 7454 7455 7456 7457
    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
        goto cleanup;

    host = caps->host.cpu;

7458 7459 7460 7461 7462 7463 7464
    if (!host ||
        !host->model ||
        (ncpus = virQEMUCapsGetCPUDefinitions(qemuCaps, &cpus)) == 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("CPU specification not supported by hypervisor"));
        goto cleanup;
    }
7465

7466 7467 7468
    if (!(cpu = virCPUDefCopy(def->cpu)))
        goto cleanup;

7469
    if (cpu->mode == VIR_CPU_MODE_HOST_MODEL &&
7470 7471 7472
        !migrating &&
        cpuUpdate(cpu, host) < 0)
        goto cleanup;
7473

7474 7475
    /* For non-KVM, CPU features are emulated, so host compat doesn't matter */
    if (compareAgainstHost) {
7476 7477
        bool noTSX = false;

7478 7479 7480
        cmp = cpuGuestData(host, cpu, &data, &compare_msg);
        switch (cmp) {
        case VIR_CPU_COMPARE_INCOMPATIBLE:
7481 7482 7483 7484 7485 7486 7487 7488
            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;

7489
            if (compare_msg) {
7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500
                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);
                }
7501
            } else {
7502 7503 7504 7505 7506 7507 7508 7509 7510 7511
                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"));
                }
7512 7513 7514 7515
            }
            /* fall through */
        case VIR_CPU_COMPARE_ERROR:
            goto cleanup;
7516

7517 7518 7519
        default:
            break;
        }
7520 7521 7522 7523 7524
    }

    /* Only 'svm' requires --enable-nesting. The nested
     * 'vmx' patches now simply hook off the CPU features
     */
7525 7526
    if ((def->os.arch == VIR_ARCH_X86_64 || def->os.arch == VIR_ARCH_I686) &&
         compareAgainstHost) {
7527 7528
        int hasSVM = cpuHasFeature(data, "svm");
        if (hasSVM < 0)
7529
            goto cleanup;
7530 7531
        *hasHwVirt = hasSVM > 0 ? true : false;
    }
7532

7533 7534 7535
    if ((cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) ||
        ((cpu->mode == VIR_CPU_MODE_HOST_MODEL) &&
          ARCH_IS_PPC64(def->os.arch))) {
7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549
        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");
7550

7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563
        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");
        }

7564
        if (ARCH_IS_PPC64(def->os.arch) &&
7565 7566
            cpu->mode == VIR_CPU_MODE_HOST_MODEL &&
            def->cpu->model != NULL) {
7567
            virBufferAsprintf(buf, ",compat=%s", def->cpu->model);
7568 7569
        } else {
            featCpu = cpu;
7570 7571
        }

7572 7573 7574 7575
    } else {
        if (VIR_ALLOC(guest) < 0)
            goto cleanup;
        if (VIR_STRDUP(guest->vendor_id, cpu->vendor_id) < 0)
7576 7577
            goto cleanup;

7578 7579 7580 7581 7582 7583
        if (compareAgainstHost) {
            guest->arch = host->arch;
            if (cpu->match == VIR_CPU_MATCH_MINIMUM)
                preferred = host->model;
            else
                preferred = cpu->model;
7584

7585 7586 7587 7588 7589 7590 7591 7592 7593 7594
            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;
        }
7595 7596 7597
        virBufferAdd(buf, guest->model, -1);
        if (guest->vendor_id)
            virBufferAsprintf(buf, ",vendor=%s", guest->vendor_id);
7598 7599 7600 7601 7602
        featCpu = guest;
    }

    if (featCpu) {
        for (i = 0; i < featCpu->nfeatures; i++) {
7603
            char sign;
7604
            if (featCpu->features[i].policy == VIR_CPU_FEATURE_DISABLE)
7605 7606 7607
                sign = '-';
            else
                sign = '+';
7608

7609
            virBufferAsprintf(buf, ",%c%s", sign, featCpu->features[i].name);
7610
        }
7611
    }
7612

7613
    ret = 0;
7614
 cleanup:
7615 7616 7617
    virObjectUnref(caps);
    VIR_FREE(compare_msg);
    cpuDataFree(data);
7618
    cpuDataFree(hostData);
7619 7620 7621 7622
    virCPUDefFree(guest);
    virCPUDefFree(cpu);
    return ret;
}
7623

7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 7635 7636 7637 7638
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;
7639

7640
    *hasHwVirt = false;
7641

7642 7643 7644 7645 7646 7647 7648 7649 7650 7651
    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;
7652
        have_cpu = true;
7653
    } else {
7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 7665
        /*
         * 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
         */
7666
        if (def->os.arch == VIR_ARCH_I686 &&
7667
            ((hostarch == VIR_ARCH_X86_64 &&
7668
              strstr(emulator, "kvm")) ||
7669 7670 7671 7672 7673 7674
             strstr(emulator, "x86_64"))) {
            virBufferAdd(&buf, default_model, -1);
            have_cpu = true;
        }
    }

7675
    /* Handle paravirtual timers  */
7676
    for (i = 0; i < def->clock.ntimers; i++) {
7677 7678 7679 7680 7681 7682
        virDomainTimerDefPtr timer = def->clock.timers[i];

        if (timer->present == -1)
            continue;

        if (timer->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK) {
7683 7684
            virBufferAsprintf(&buf, "%s,%ckvmclock",
                              have_cpu ? "" : default_model,
7685 7686 7687 7688 7689 7690
                              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 已提交
7691
            have_cpu = true;
7692
        }
7693 7694
    }

7695 7696
    if (def->apic_eoi) {
        char sign;
J
Ján Tomko 已提交
7697
        if (def->apic_eoi == VIR_TRISTATE_SWITCH_ON)
7698 7699 7700 7701 7702 7703 7704
            sign = '+';
        else
            sign = '-';

        virBufferAsprintf(&buf, "%s,%ckvm_pv_eoi",
                          have_cpu ? "" : default_model,
                          sign);
M
Martin Kletzander 已提交
7705
        have_cpu = true;
7706 7707
    }

7708 7709
    if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK]) {
        char sign;
J
Ján Tomko 已提交
7710
        if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK] == VIR_TRISTATE_SWITCH_ON)
7711 7712 7713 7714 7715 7716 7717 7718 7719 7720
            sign = '+';
        else
            sign = '-';

        virBufferAsprintf(&buf, "%s,%ckvm_pv_unhalt",
                          have_cpu ? "" : default_model,
                          sign);
        have_cpu = true;
    }

J
Ján Tomko 已提交
7721
    if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_TRISTATE_SWITCH_ON) {
7722 7723 7724 7725 7726 7727
        if (!have_cpu) {
            virBufferAdd(&buf, default_model, -1);
            have_cpu = true;
        }

        for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
7728
            switch ((virDomainHyperv) i) {
7729
            case VIR_DOMAIN_HYPERV_RELAXED:
7730
            case VIR_DOMAIN_HYPERV_VAPIC:
J
Ján Tomko 已提交
7731
                if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
7732 7733 7734 7735
                    virBufferAsprintf(&buf, ",hv_%s",
                                      virDomainHypervTypeToString(i));
                break;

7736
            case VIR_DOMAIN_HYPERV_SPINLOCKS:
J
Ján Tomko 已提交
7737
                if (def->hyperv_features[i] == VIR_TRISTATE_SWITCH_ON)
7738 7739
                    virBufferAsprintf(&buf, ",hv_spinlocks=0x%x",
                                      def->hyperv_spinlocks);
7740 7741
                break;

7742
            /* coverity[dead_error_begin] */
7743 7744 7745 7746 7747 7748
            case VIR_DOMAIN_HYPERV_LAST:
                break;
            }
        }
    }

D
Dmitry Andreev 已提交
7749 7750 7751 7752 7753 7754
    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;
            }
7755

D
Dmitry Andreev 已提交
7756 7757 7758
            virBufferAddLit(&buf, ",hv_crash");
            break;
        }
7759 7760
    }

7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773
    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 已提交
7774
            /* coverity[dead_error_begin] */
7775 7776 7777 7778 7779 7780
            case VIR_DOMAIN_KVM_LAST:
                break;
            }
        }
    }

7781 7782 7783 7784 7785 7786 7787 7788 7789 7790
    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;
    }

7791
    if (virBufferCheckError(&buf) < 0)
7792
        goto cleanup;
7793 7794 7795 7796 7797

    *opt = virBufferContentAndReset(&buf);

    ret = 0;

7798
 cleanup:
7799 7800 7801
    return ret;
}

7802 7803
static int
qemuBuildObsoleteAccelArg(virCommandPtr cmd,
E
Eric Blake 已提交
7804
                          const virDomainDef *def,
7805 7806
                          virQEMUCapsPtr qemuCaps)
{
7807 7808
    bool disableKVM = false;
    bool enableKVM = false;
7809 7810 7811 7812

    switch (def->virtType) {
    case VIR_DOMAIN_VIRT_QEMU:
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
7813
            disableKVM = true;
7814 7815 7816
        break;

    case VIR_DOMAIN_VIRT_KQEMU:
7817 7818
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("the QEMU binary does not support kqemu"));
7819 7820 7821 7822
        break;

    case VIR_DOMAIN_VIRT_KVM:
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KVM)) {
7823
            enableKVM = true;
7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 7835 7836 7837 7838 7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 7849
        } 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;
}

7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882
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;
}

7883 7884
static int
qemuBuildMachineArgStr(virCommandPtr cmd,
E
Eric Blake 已提交
7885
                       const virDomainDef *def,
7886
                       virQEMUCapsPtr qemuCaps)
7887
{
7888 7889
    bool obsoleteAccel = false;

7890 7891 7892 7893 7894 7895 7896
    /* 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;

7897
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_OPT)) {
7898 7899 7900 7901
        /* 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);
7902 7903 7904 7905
        if (def->mem.dump_core) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("dump-guest-core is not available "
                             "with this QEMU binary"));
7906 7907
            return -1;
        }
7908 7909 7910 7911 7912 7913 7914 7915

        if (def->mem.nosharepages) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("disable shared memory is not available "
                             "with this QEMU binary"));
             return -1;
        }

7916
        obsoleteAccel = true;
7917 7918 7919 7920 7921 7922 7923

        if (def->keywrap) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("key wrap support is not available "
                             "with this QEMU binary"));
            return -1;
        }
7924 7925
    } else {
        virBuffer buf = VIR_BUFFER_INITIALIZER;
7926
        virTristateSwitch vmport = def->features[VIR_DOMAIN_FEATURE_VMPORT];
7927 7928

        virCommandAddArg(cmd, "-machine");
7929 7930
        virBufferAdd(&buf, def->os.machine, -1);

7931 7932 7933 7934 7935 7936 7937
        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 已提交
7938 7939 7940 7941
        /* 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))
7942
            virBufferAddLit(&buf, ",usb=off");
L
Li Zhang 已提交
7943

7944 7945 7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956
        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));
        }

7957 7958 7959 7960 7961
        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"));
7962
                virBufferFreeAndReset(&buf);
7963 7964 7965 7966
                return -1;
            }

            virBufferAsprintf(&buf, ",dump-guest-core=%s",
J
Ján Tomko 已提交
7967
                              virTristateSwitchTypeToString(def->mem.dump_core));
7968 7969
        }

7970 7971 7972 7973 7974 7975 7976 7977 7978 7979 7980 7981
        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;
            }
        }

7982 7983 7984 7985 7986
        if (def->keywrap &&
            !qemuAppendKeyWrapMachineParms(&buf, qemuCaps, def->keywrap)) {
            virBufferFreeAndReset(&buf);
            return -1;
        }
7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017

        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);
                }
            }
        }
8018

8019
        virCommandAddArgBuffer(cmd, &buf);
8020 8021
    }

8022 8023 8024 8025
    if (obsoleteAccel &&
        qemuBuildObsoleteAccelArg(cmd, def, qemuCaps) < 0)
        return -1;

8026 8027 8028
    return 0;
}

8029
static char *
E
Eric Blake 已提交
8030
qemuBuildSmpArgStr(const virDomainDef *def,
8031
                   virQEMUCapsPtr qemuCaps)
8032 8033 8034
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

8035
    virBufferAsprintf(&buf, "%u", virDomainDefGetVcpus(def));
8036

8037
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SMP_TOPOLOGY)) {
8038
        if (virDomainDefHasVcpusOffline(def))
8039
            virBufferAsprintf(&buf, ",maxcpus=%u", virDomainDefGetVcpusMax(def));
8040 8041 8042
        /* 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) {
8043 8044 8045
            virBufferAsprintf(&buf, ",sockets=%u", def->cpu->sockets);
            virBufferAsprintf(&buf, ",cores=%u", def->cpu->cores);
            virBufferAsprintf(&buf, ",threads=%u", def->cpu->threads);
8046
        } else {
8047
            virBufferAsprintf(&buf, ",sockets=%u", virDomainDefGetVcpusMax(def));
8048 8049
            virBufferAsprintf(&buf, ",cores=%u", 1);
            virBufferAsprintf(&buf, ",threads=%u", 1);
8050
        }
8051
    } else if (virDomainDefHasVcpusOffline(def)) {
8052 8053
        virBufferFreeAndReset(&buf);
        /* FIXME - consider hot-unplugging cpus after boot for older qemu */
8054 8055 8056
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("setting current vcpu count less than maximum is "
                         "not supported with this QEMU binary"));
8057 8058 8059
        return NULL;
    }

8060
    if (virBufferCheckError(&buf) < 0)
8061 8062 8063 8064 8065
        return NULL;

    return virBufferContentAndReset(&buf);
}

8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130
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 已提交
8131
static int
8132
qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
8133
                    virDomainDefPtr def,
8134
                    virCommandPtr cmd,
8135
                    virQEMUCapsPtr qemuCaps,
8136
                    virBitmapPtr auto_nodeset)
B
Bharata B Rao 已提交
8137
{
8138
    size_t i;
B
Bharata B Rao 已提交
8139
    virBuffer buf = VIR_BUFFER_INITIALIZER;
8140
    char *cpumask = NULL, *tmpmask = NULL, *next = NULL;
8141 8142 8143
    char **nodeBackends = NULL;
    bool needBackend = false;
    int rc;
8144
    int ret = -1;
8145
    size_t ncells = virDomainNumaGetNodeCount(def->numa);
8146
    const long system_page_size = virGetSystemPageSizeKB();
B
Bharata B Rao 已提交
8147

8148
    if (virDomainNumatuneHasPerNodeBinding(def->numa) &&
8149 8150
        !(virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) ||
          virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE))) {
8151 8152 8153 8154 8155 8156
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Per-node memory binding is not supported "
                         "with this QEMU"));
        goto cleanup;
    }

8157 8158
    if (def->mem.nhugepages &&
        def->mem.hugepages[0].size != system_page_size &&
8159 8160 8161 8162 8163 8164 8165
        !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;
    }

8166
    if (!virDomainNumatuneNodesetIsAvailable(def->numa, auto_nodeset))
8167 8168
        goto cleanup;

8169 8170 8171 8172 8173 8174 8175 8176 8177
    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;
        }

8178
        if (ncells) {
8179 8180
            /* Fortunately, we allow only guest NUMA nodes to be continuous
             * starting from zero. */
8181
            pos = ncells - 1;
8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192
        }

        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;
        }
    }

8193
    if (VIR_ALLOC_N(nodeBackends, ncells) < 0)
8194 8195 8196 8197
        goto cleanup;

    /* using of -numa memdev= cannot be combined with -numa mem=, thus we
     * need to check which approach to use */
8198
    for (i = 0; i < ncells; i++) {
8199 8200
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) ||
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) {
8201 8202 8203
            if ((rc = qemuBuildMemoryCellBackendStr(def, qemuCaps, cfg, i,
                                                    auto_nodeset,
                                                    &nodeBackends[i])) < 0)
8204 8205
                goto cleanup;

8206 8207
            if (rc == 0)
                needBackend = true;
8208
        } else {
8209
            if (virDomainNumaGetNodeMemoryAccessMode(def->numa, i)) {
8210 8211 8212 8213 8214
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("Shared memory mapping is not supported "
                                 "with this QEMU"));
                goto cleanup;
            }
8215
        }
8216 8217
    }

8218 8219 8220 8221
    if (!needBackend &&
        qemuBuildMemPathStr(cfg, def, qemuCaps, cmd) < 0)
        goto cleanup;

8222
    for (i = 0; i < ncells; i++) {
8223
        VIR_FREE(cpumask);
8224
        if (!(cpumask = virBitmapFormat(virDomainNumaGetNodeCpumask(def->numa, i))))
8225 8226 8227 8228 8229 8230 8231 8232 8233 8234 8235 8236
            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);
8237

B
Bharata B Rao 已提交
8238
        virCommandAddArg(cmd, "-numa");
8239
        virBufferAsprintf(&buf, "node,nodeid=%zu", i);
8240

8241 8242 8243 8244 8245 8246 8247
        for (tmpmask = cpumask; tmpmask; tmpmask = next) {
            if ((next = strchr(tmpmask, ',')))
                *(next++) = '\0';
            virBufferAddLit(&buf, ",cpus=");
            virBufferAdd(&buf, tmpmask, -1);
        }

8248
        if (needBackend)
8249
            virBufferAsprintf(&buf, ",memdev=ram-node%zu", i);
8250
        else
8251
            virBufferAsprintf(&buf, ",mem=%llu",
8252
                              virDomainNumaGetNodeMemorySize(def->numa, i) / 1024);
B
Bharata B Rao 已提交
8253 8254 8255

        virCommandAddArgBuffer(cmd, &buf);
    }
8256
    ret = 0;
B
Bharata B Rao 已提交
8257

8258
 cleanup:
8259
    VIR_FREE(cpumask);
8260 8261

    if (nodeBackends) {
8262
        for (i = 0; i < ncells; i++)
8263 8264 8265 8266 8267
            VIR_FREE(nodeBackends[i]);

        VIR_FREE(nodeBackends);
    }

B
Bharata B Rao 已提交
8268
    virBufferFreeAndReset(&buf);
8269
    return ret;
B
Bharata B Rao 已提交
8270
}
8271

8272

8273 8274 8275 8276 8277 8278 8279 8280 8281 8282 8283 8284 8285 8286 8287 8288 8289 8290 8291 8292 8293 8294 8295
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,
8296
                        "%s/domain-%s/vnc.sock", cfg->libDir, def->name) == -1)
8297
            goto error;
8298 8299 8300

        virBufferAsprintf(&opt, "unix:%s", graphics->data.vnc.socket);

8301 8302 8303 8304 8305 8306 8307 8308
    } 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;
        }
8309

8310 8311 8312 8313
        switch (virDomainGraphicsListenGetType(graphics, 0)) {
        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
            listenAddr = virDomainGraphicsListenGetAddress(graphics, 0);
            break;
8314

8315 8316 8317
        case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK:
            listenNetwork = virDomainGraphicsListenGetNetwork(graphics, 0);
            if (!listenNetwork)
8318
                break;
8319 8320 8321 8322 8323 8324
            ret = networkGetNetworkAddress(listenNetwork, &netAddr);
            if (ret <= -2) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("network-based listen not possible, "
                                       "network driver not present"));
                goto error;
8325
            }
8326 8327
            if (ret < 0)
                goto error;
8328

8329 8330 8331 8332 8333 8334 8335 8336
            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;
        }
8337

8338 8339
        if (!listenAddr)
            listenAddr = cfg->vncListen;
8340

8341 8342 8343 8344 8345 8346 8347 8348 8349
        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);
8350 8351
    }

8352 8353 8354 8355 8356 8357 8358 8359 8360 8361
    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);
    }
8362

8363 8364 8365 8366 8367 8368 8369
    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;
        }
8370

8371 8372
        virBufferAsprintf(&opt, ",share=%s",
                          virDomainGraphicsVNCSharePolicyTypeToString(
8373
                              graphics->data.vnc.sharePolicy));
8374
    }
8375

8376 8377
    if (graphics->data.vnc.auth.passwd || cfg->vncPassword)
        virBufferAddLit(&opt, ",password");
8378

8379 8380 8381 8382 8383 8384 8385
    if (cfg->vncTLS) {
        virBufferAddLit(&opt, ",tls");
        if (cfg->vncTLSx509verify)
            virBufferAsprintf(&opt, ",x509verify=%s", cfg->vncTLSx509certdir);
        else
            virBufferAsprintf(&opt, ",x509=%s", cfg->vncTLSx509certdir);
    }
8386

8387 8388
    if (cfg->vncSASL) {
        virBufferAddLit(&opt, ",sasl");
8389

8390 8391
        if (cfg->vncSASLdir)
            virCommandAddEnvPair(cmd, "SASL_CONF_PATH", cfg->vncSASLdir);
8392

8393
        /* TODO: Support ACLs later */
8394 8395 8396 8397 8398 8399 8400 8401 8402 8403 8404 8405
    }

    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)
8406
        virCommandAddEnvPassBlockSUID(cmd, "QEMU_AUDIO_DRV", NULL);
8407 8408 8409 8410 8411
    else
        virCommandAddEnvString(cmd, "QEMU_AUDIO_DRV=none");

    return 0;

8412
 error:
8413 8414 8415 8416 8417 8418
    VIR_FREE(netAddr);
    virBufferFreeAndReset(&opt);
    return -1;
}


8419 8420 8421 8422 8423 8424 8425 8426 8427 8428 8429 8430 8431 8432
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;
8433
    size_t i;
8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453 8454 8455

    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);
    }

8456 8457 8458 8459 8460 8461 8462 8463 8464 8465
    if (cfg->spiceSASL) {
        virBufferAddLit(&opt, ",sasl");

        if (cfg->spiceSASLdir)
            virCommandAddEnvPair(cmd, "SASL_CONF_PATH",
                                 cfg->spiceSASLdir);

        /* TODO: Support ACLs later */
    }

8466 8467 8468 8469 8470 8471 8472 8473 8474 8475 8476 8477 8478 8479 8480 8481
    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;
        }
8482
        if (ret < 0)
8483
            goto error;
8484

8485 8486 8487 8488 8489 8490 8491 8492 8493 8494 8495 8496 8497 8498 8499 8500 8501 8502 8503
        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:
8504
            virBufferAddLit(&opt, ",agent-mouse=off");
8505 8506
            break;
        case VIR_DOMAIN_GRAPHICS_SPICE_MOUSE_MODE_CLIENT:
8507
            virBufferAddLit(&opt, ",agent-mouse=on");
8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520
            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");

8521 8522
    if (tlsPort > 0)
        virBufferAsprintf(&opt, ",x509-dir=%s", cfg->spiceTLSx509certdir);
8523 8524 8525

    switch (defaultMode) {
    case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE:
8526
        virBufferAddLit(&opt, ",tls-channel=default");
8527 8528
        break;
    case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_INSECURE:
8529
        virBufferAddLit(&opt, ",plaintext-channel=default");
8530 8531 8532 8533 8534 8535
        break;
    case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_ANY:
        /* nothing */
        break;
    }

8536
    for (i = 0; i < VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST; i++) {
8537
        switch (graphics->data.spice.channels[i]) {
8538
        case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE:
8539
            if (tlsPort <= 0) {
8540 8541
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("spice secure channels set in XML configuration, "
8542
                                 "but TLS port is not provided"));
8543 8544 8545 8546 8547
                goto error;
            }
            virBufferAsprintf(&opt, ",tls-channel=%s",
                              virDomainGraphicsSpiceChannelNameTypeToString(i));
            break;
8548

8549
        case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_INSECURE:
8550 8551 8552 8553 8554 8555
            if (port <= 0) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("spice insecure channels set in XML "
                                 "configuration, but plain port is not provided"));
                goto error;
            }
8556 8557 8558
            virBufferAsprintf(&opt, ",plaintext-channel=%s",
                              virDomainGraphicsSpiceChannelNameTypeToString(i));
            break;
8559 8560 8561 8562 8563 8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 8575 8576 8577 8578 8579 8580 8581 8582 8583

        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;
            }
8584 8585
        }
    }
8586

8587 8588 8589 8590 8591 8592 8593 8594 8595 8596 8597
    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 已提交
8598
                          virTristateSwitchTypeToString(graphics->data.spice.playback));
8599 8600 8601
    if (graphics->data.spice.streaming)
        virBufferAsprintf(&opt, ",streaming-video=%s",
                          virDomainGraphicsSpiceStreamingModeTypeToString(graphics->data.spice.streaming));
J
Ján Tomko 已提交
8602
    if (graphics->data.spice.copypaste == VIR_TRISTATE_BOOL_NO)
8603
        virBufferAddLit(&opt, ",disable-copy-paste");
J
Ján Tomko 已提交
8604
    if (graphics->data.spice.filetransfer == VIR_TRISTATE_BOOL_NO) {
8605 8606 8607 8608 8609 8610 8611 8612
        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");
        }
    }
8613 8614 8615 8616 8617 8618 8619 8620 8621 8622 8623 8624 8625 8626 8627 8628 8629 8630 8631 8632 8633

    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;

8634
 error:
8635 8636 8637 8638 8639
    VIR_FREE(netAddr);
    virBufferFreeAndReset(&opt);
    return -1;
}

8640
static int
8641
qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg,
8642 8643
                             virCommandPtr cmd,
                             virDomainDefPtr def,
8644
                             virQEMUCapsPtr qemuCaps,
8645
                             virDomainGraphicsDefPtr graphics)
8646
{
8647
    switch ((virDomainGraphicsType) graphics->type) {
8648
    case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
8649
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SDL)) {
8650
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
8651 8652
                           _("sdl not supported by '%s'"), def->emulator);
            return -1;
8653 8654
        }

8655
        if (graphics->data.sdl.xauth)
8656
            virCommandAddEnvPair(cmd, "XAUTHORITY", graphics->data.sdl.xauth);
8657
        if (graphics->data.sdl.display)
8658
            virCommandAddEnvPair(cmd, "DISPLAY", graphics->data.sdl.display);
8659 8660
        if (graphics->data.sdl.fullscreen)
            virCommandAddArg(cmd, "-full-screen");
8661

8662 8663 8664 8665
        /* 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
         */
8666 8667
        virCommandAddEnvPassBlockSUID(cmd, "QEMU_AUDIO_DRV", NULL);
        virCommandAddEnvPassBlockSUID(cmd, "SDL_AUDIODRIVER", NULL);
B
Bharata B Rao 已提交
8668

8669 8670 8671
        /* 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 :-( */
8672
        virCommandAddArg(cmd, "-sdl");
8673

8674 8675 8676 8677 8678 8679 8680 8681 8682 8683 8684
        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:
8685 8686 8687
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unsupported graphics type '%s'"),
                       virDomainGraphicsTypeToString(graphics->type));
8688
        return -1;
8689
    }
8690

8691 8692
    return 0;
}
8693

M
Michele Paolino 已提交
8694 8695 8696 8697
static int
qemuBuildVhostuserCommandLine(virCommandPtr cmd,
                              virDomainDefPtr def,
                              virDomainNetDefPtr net,
8698 8699
                              virQEMUCapsPtr qemuCaps,
                              int bootindex)
M
Michele Paolino 已提交
8700 8701 8702
{
    virBuffer chardev_buf = VIR_BUFFER_INITIALIZER;
    virBuffer netdev_buf = VIR_BUFFER_INITIALIZER;
8703
    unsigned int queues = net->driver.virtio.queues;
M
Michele Paolino 已提交
8704 8705 8706 8707 8708 8709 8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733 8734 8735 8736 8737 8738 8739 8740
    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);

8741
    if (queues > 1) {
J
Ján Tomko 已提交
8742
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VHOSTUSER_MULTIQUEUE)) {
8743 8744 8745 8746 8747 8748 8749 8750
            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 已提交
8751 8752 8753 8754 8755 8756
    virCommandAddArg(cmd, "-chardev");
    virCommandAddArgBuffer(cmd, &chardev_buf);

    virCommandAddArg(cmd, "-netdev");
    virCommandAddArgBuffer(cmd, &netdev_buf);

8757 8758
    if (!(nic = qemuBuildNicDevStr(def, net, -1, bootindex,
                                   queues, qemuCaps))) {
M
Michele Paolino 已提交
8759 8760 8761 8762 8763 8764 8765 8766 8767 8768 8769 8770 8771 8772 8773 8774 8775 8776
        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;
}

8777 8778 8779 8780 8781 8782 8783 8784
static int
qemuBuildInterfaceCommandLine(virCommandPtr cmd,
                              virQEMUDriverPtr driver,
                              virDomainDefPtr def,
                              virDomainNetDefPtr net,
                              virQEMUCapsPtr qemuCaps,
                              int vlan,
                              int bootindex,
8785
                              virNetDevVPortProfileOp vmop,
8786
                              bool standalone,
8787 8788
                              size_t *nnicindexes,
                              int **nicindexes)
8789 8790 8791
{
    int ret = -1;
    char *nic = NULL, *host = NULL;
8792
    int *tapfd = NULL;
8793
    size_t tapfdSize = 0;
8794
    int *vhostfd = NULL;
8795
    size_t vhostfdSize = 0;
8796 8797
    char **tapfdName = NULL;
    char **vhostfdName = NULL;
8798
    int actualType = virDomainNetGetActualType(net);
8799
    virQEMUDriverConfigPtr cfg = NULL;
8800
    virNetDevBandwidthPtr actualBandwidth;
8801
    size_t i;
8802

8803 8804 8805 8806

    if (!bootindex)
        bootindex = net->info.bootIndex;

M
Michele Paolino 已提交
8807
    if (actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER)
8808
        return qemuBuildVhostuserCommandLine(cmd, def, net, qemuCaps, bootindex);
M
Michele Paolino 已提交
8809

8810 8811 8812 8813 8814 8815 8816
    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;
    }

8817 8818 8819
    /* Currently nothing besides TAP devices supports multiqueue. */
    if (net->driver.virtio.queues > 0 &&
        !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
8820 8821
          actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
          actualType == VIR_DOMAIN_NET_TYPE_DIRECT)) {
8822 8823 8824 8825 8826 8827
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Multiqueue network is not supported for: %s"),
                       virDomainNetTypeToString(actualType));
        return -1;
    }

8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838
    /* 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;
    }

8839 8840 8841 8842 8843 8844 8845 8846 8847
    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;
    }

8848 8849
    cfg = virQEMUDriverGetConfig(driver);

8850 8851
    if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
        actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
8852 8853 8854 8855 8856
        tapfdSize = net->driver.virtio.queues;
        if (!tapfdSize)
            tapfdSize = 1;

        if (VIR_ALLOC_N(tapfd, tapfdSize) < 0 ||
8857
            VIR_ALLOC_N(tapfdName, tapfdSize) < 0)
8858 8859
            goto cleanup;

8860 8861
        memset(tapfd, -1, tapfdSize * sizeof(tapfd[0]));

8862
        if (qemuNetworkIfaceConnect(def, driver, net,
8863
                                    tapfd, &tapfdSize) < 0)
8864 8865
            goto cleanup;
    } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
8866 8867 8868 8869 8870 8871
        tapfdSize = net->driver.virtio.queues;
        if (!tapfdSize)
            tapfdSize = 1;

        if (VIR_ALLOC_N(tapfd, tapfdSize) < 0 ||
            VIR_ALLOC_N(tapfdName, tapfdSize) < 0)
8872
            goto cleanup;
8873 8874 8875 8876

        memset(tapfd, -1, tapfdSize * sizeof(tapfd[0]));

        if (qemuPhysIfaceConnect(def, driver, net, tapfd, tapfdSize, vmop) < 0)
8877 8878 8879
            goto cleanup;
    }

8880 8881 8882 8883 8884 8885 8886 8887 8888 8889 8890 8891 8892 8893
    /* 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
         */
8894 8895
        if (virQEMUDriverIsPrivileged(driver) && nicindexes && nnicindexes &&
            net->ifname) {
8896 8897 8898 8899 8900 8901 8902 8903 8904 8905 8906 8907
            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:
8908
    case VIR_DOMAIN_NET_TYPE_UDP:
8909 8910 8911 8912 8913 8914 8915 8916 8917 8918 8919 8920 8921 8922 8923 8924
    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;
    }

8925 8926 8927 8928 8929 8930 8931 8932 8933 8934 8935 8936
    /* 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));
        }
    }
8937

8938 8939 8940 8941 8942
    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) {
8943 8944
        /* Attempt to use vhost-net mode for these types of
           network device */
8945 8946 8947 8948 8949
        vhostfdSize = net->driver.virtio.queues;
        if (!vhostfdSize)
            vhostfdSize = 1;

        if (VIR_ALLOC_N(vhostfd, vhostfdSize) < 0 ||
8950
            VIR_ALLOC_N(vhostfdName, vhostfdSize))
8951 8952
            goto cleanup;

8953 8954
        memset(vhostfd, -1, vhostfdSize * sizeof(vhostfd[0]));

8955
        if (qemuOpenVhostNet(def, net, qemuCaps, vhostfd, &vhostfdSize) < 0)
8956 8957 8958
            goto cleanup;
    }

8959
    for (i = 0; i < tapfdSize; i++) {
M
Michal Privoznik 已提交
8960 8961 8962
        if (virSecurityManagerSetTapFDLabel(driver->securityManager,
                                            def, tapfd[i]) < 0)
            goto cleanup;
8963 8964
        virCommandPassFD(cmd, tapfd[i],
                         VIR_COMMAND_PASS_FD_CLOSE_PARENT);
8965
        if (virAsprintf(&tapfdName[i], "%d", tapfd[i]) < 0)
8966 8967 8968
            goto cleanup;
    }

8969
    for (i = 0; i < vhostfdSize; i++) {
8970 8971
        virCommandPassFD(cmd, vhostfd[i],
                         VIR_COMMAND_PASS_FD_CLOSE_PARENT);
8972
        if (virAsprintf(&vhostfdName[i], "%d", vhostfd[i]) < 0)
8973
            goto cleanup;
8974 8975 8976 8977 8978 8979 8980 8981 8982 8983
    }

    /* 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
     */
8984
    if (qemuDomainSupportsNetdev(def, qemuCaps, net)) {
8985
        if (!(host = qemuBuildHostNetStr(net, driver,
8986 8987 8988
                                         ',', vlan,
                                         tapfdName, tapfdSize,
                                         vhostfdName, vhostfdSize)))
8989 8990 8991
            goto cleanup;
        virCommandAddArgList(cmd, "-netdev", host, NULL);
    }
8992
    if (qemuDomainSupportsNicdev(def, qemuCaps, net)) {
8993
        if (!(nic = qemuBuildNicDevStr(def, net, vlan, bootindex,
8994
                                       vhostfdSize, qemuCaps)))
8995 8996 8997 8998 8999 9000 9001
            goto cleanup;
        virCommandAddArgList(cmd, "-device", nic, NULL);
    } else {
        if (!(nic = qemuBuildNicStr(net, "nic,", vlan)))
            goto cleanup;
        virCommandAddArgList(cmd, "-net", nic, NULL);
    }
9002
    if (!qemuDomainSupportsNetdev(def, qemuCaps, net)) {
9003
        if (!(host = qemuBuildHostNetStr(net, driver,
9004 9005 9006
                                         ',', vlan,
                                         tapfdName, tapfdSize,
                                         vhostfdName, vhostfdSize)))
9007 9008 9009 9010 9011
            goto cleanup;
        virCommandAddArgList(cmd, "-net", host, NULL);
    }

    ret = 0;
9012
 cleanup:
9013 9014
    if (ret < 0) {
        virErrorPtr saved_err = virSaveLastError();
9015
        virDomainConfNWFilterTeardown(net);
9016 9017 9018
        virSetError(saved_err);
        virFreeError(saved_err);
    }
9019
    for (i = 0; tapfd && i < tapfdSize && tapfd[i] >= 0; i++) {
9020 9021
        if (ret < 0)
            VIR_FORCE_CLOSE(tapfd[i]);
9022 9023
        if (tapfdName)
            VIR_FREE(tapfdName[i]);
9024
    }
9025
    for (i = 0; vhostfd && i < vhostfdSize && vhostfd[i] >= 0; i++) {
9026 9027
        if (ret < 0)
            VIR_FORCE_CLOSE(vhostfd[i]);
9028 9029
        if (vhostfdName)
            VIR_FREE(vhostfdName[i]);
9030 9031 9032
    }
    VIR_FREE(tapfd);
    VIR_FREE(vhostfd);
9033 9034 9035 9036
    VIR_FREE(nic);
    VIR_FREE(host);
    VIR_FREE(tapfdName);
    VIR_FREE(vhostfdName);
9037
    virObjectUnref(cfg);
9038 9039 9040
    return ret;
}

9041 9042
char *
qemuBuildShmemDevStr(virDomainDefPtr def,
9043 9044 9045 9046 9047 9048 9049 9050 9051 9052 9053 9054 9055 9056 9057 9058 9059
                     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 已提交
9060
         * But because it may change in the future, the checks are
9061 9062 9063 9064 9065 9066 9067 9068 9069
         * 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",
9070
                           _("shmem size must be at least 1 MiB (1024 KiB)"));
9071 9072
            goto error;
        }
M
Martin Kletzander 已提交
9073
        virBufferAsprintf(&buf, ",size=%llum", shmem->size >> 20);
9074 9075 9076
    }

    if (!shmem->server.enabled) {
9077
        virBufferAsprintf(&buf, ",shm=%s,id=%s", shmem->name, shmem->info.alias);
9078
    } else {
9079
        virBufferAsprintf(&buf, ",chardev=char%s,id=%s", shmem->info.alias, shmem->info.alias);
9080 9081 9082 9083 9084 9085 9086 9087 9088 9089
        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));
        }
    }

9090 9091 9092 9093 9094 9095 9096
    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;
    }

9097 9098 9099 9100 9101 9102
    if (qemuBuildDeviceAddressStr(&buf, def, &shmem->info, qemuCaps) < 0)
        goto error;

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

9103
    return virBufferContentAndReset(&buf);
9104 9105 9106

 error:
    virBufferFreeAndReset(&buf);
9107 9108 9109 9110 9111 9112 9113 9114 9115
    return NULL;
}

char *
qemuBuildShmemBackendStr(virDomainShmemDefPtr shmem,
                         virQEMUCapsPtr qemuCaps)
{
    char *devstr = NULL;

9116 9117
    if (!shmem->server.chr.data.nix.path &&
        virAsprintf(&shmem->server.chr.data.nix.path,
9118 9119 9120 9121
                    "/var/lib/libvirt/shmem-%s-sock",
                    shmem->name) < 0)
        return NULL;

9122
    devstr = qemuBuildChrChardevStr(&shmem->server.chr, shmem->info.alias, qemuCaps);
9123 9124

    return devstr;
9125 9126 9127 9128 9129 9130 9131 9132
}

static int
qemuBuildShmemCommandLine(virCommandPtr cmd,
                          virDomainDefPtr def,
                          virDomainShmemDefPtr shmem,
                          virQEMUCapsPtr qemuCaps)
{
9133 9134 9135
    char *devstr = NULL;

    if (!(devstr = qemuBuildShmemDevStr(def, shmem, qemuCaps)))
9136
        return -1;
9137 9138
    virCommandAddArgList(cmd, "-device", devstr, NULL);
    VIR_FREE(devstr);
9139 9140

    if (shmem->server.enabled) {
9141
        if (!(devstr = qemuBuildShmemBackendStr(shmem, qemuCaps)))
9142 9143
            return -1;

9144
        virCommandAddArgList(cmd, "-chardev", devstr, NULL);
9145 9146 9147 9148 9149 9150
        VIR_FREE(devstr);
    }

    return 0;
}

9151 9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 9162
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);
9163
    VIR_FREE(devstr);
9164 9165 9166
    return 0;
}

9167 9168 9169 9170 9171 9172 9173 9174 9175 9176 9177 9178 9179 9180 9181 9182 9183 9184 9185 9186 9187 9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221 9222 9223 9224 9225 9226 9227 9228 9229 9230 9231 9232 9233 9234 9235
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;
}

9236 9237 9238 9239 9240 9241 9242
static int
qemuBuildTPMCommandLine(virDomainDefPtr def,
                        virCommandPtr cmd,
                        virQEMUCapsPtr qemuCaps,
                        const char *emulator)
{
    char *optstr;
9243 9244 9245
    int tpmfd = -1;
    int cancelfd = -1;
    char *fdset;
9246

9247 9248
    if (!(optstr = qemuBuildTPMBackendStr(def, cmd, qemuCaps, emulator,
                                          &tpmfd, &cancelfd)))
9249 9250 9251 9252 9253
        return -1;

    virCommandAddArgList(cmd, "-tpmdev", optstr, NULL);
    VIR_FREE(optstr);

9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 9270 9271
    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);
    }

9272 9273 9274 9275 9276 9277 9278 9279 9280 9281
    if (!(optstr = qemuBuildTPMDevStr(def, qemuCaps, emulator)))
        return -1;

    virCommandAddArgList(cmd, "-device", optstr, NULL);
    VIR_FREE(optstr);

    return 0;
}


9282 9283 9284 9285
qemuBuildCommandLineCallbacks buildCommandLineCallbacks = {
    .qemuGetSCSIDeviceSgName = virSCSIDeviceGetSgName,
};

9286 9287 9288 9289 9290 9291 9292 9293 9294
/*
 * 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,
9295
                     virQEMUDriverPtr driver,
9296 9297 9298
                     virDomainDefPtr def,
                     virDomainChrSourceDefPtr monitor_chr,
                     bool monitor_json,
9299
                     virQEMUCapsPtr qemuCaps,
9300
                     const char *migrateURI,
9301
                     virDomainSnapshotObjPtr snapshot,
9302
                     virNetDevVPortProfileOp vmop,
C
Cole Robinson 已提交
9303
                     qemuBuildCommandLineCallbacksPtr callbacks,
9304
                     bool standalone,
9305
                     bool enableFips,
9306 9307 9308
                     virBitmapPtr nodeset,
                     size_t *nnicindexes,
                     int **nicindexes)
9309
{
9310
    virErrorPtr originalError = NULL;
9311
    size_t i, j;
9312 9313 9314 9315 9316 9317 9318
    const char *emulator;
    char uuid[VIR_UUID_STRING_BUFLEN];
    char *cpu;
    char *smp;
    int last_good_net = -1;
    bool hasHwVirt = false;
    virCommandPtr cmd = NULL;
9319
    bool allowReboot = true;
9320
    bool emitBootindex = false;
9321 9322 9323
    int sdl = 0;
    int vnc = 0;
    int spice = 0;
9324
    int usbcontroller = 0;
M
Martin Kletzander 已提交
9325
    int actualSerials = 0;
9326 9327
    bool usblegacy = false;
    int contOrder[] = {
9328 9329 9330 9331
        /*
         * List of controller types that we add commandline args for,
         * *in the order we want to add them*.
         *
9332 9333 9334
         * 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.
9335
         *
9336 9337 9338
         * 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
9339 9340 9341
         * 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.
9342
         */
9343
        VIR_DOMAIN_CONTROLLER_TYPE_PCI,
9344 9345
        VIR_DOMAIN_CONTROLLER_TYPE_USB,
        VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
9346
        VIR_DOMAIN_CONTROLLER_TYPE_IDE,
9347 9348 9349 9350
        VIR_DOMAIN_CONTROLLER_TYPE_SATA,
        VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL,
        VIR_DOMAIN_CONTROLLER_TYPE_CCID,
    };
9351
    virArch hostarch = virArchFromHost();
9352
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
J
Ján Tomko 已提交
9353
    virBuffer boot_buf = VIR_BUFFER_INITIALIZER;
9354
    char *boot_order_str = NULL, *boot_opts_str = NULL;
9355 9356
    virBuffer fdc_opts = VIR_BUFFER_INITIALIZER;
    char *fdc_opts_str = NULL;
9357 9358
    int bootCD = 0, bootFloppy = 0, bootDisk = 0, bootHostdevNet = 0;

9359

9360
    VIR_DEBUG("conn=%p driver=%p def=%p mon=%p json=%d "
9361
              "qemuCaps=%p migrateURI=%s snapshot=%p vmop=%d",
9362
              conn, driver, def, monitor_chr, monitor_json,
9363
              qemuCaps, migrateURI, snapshot, vmop);
9364

9365 9366 9367 9368
    virUUIDFormat(def->uuid, uuid);

    emulator = def->emulator;

9369
    if (!virQEMUDriverIsPrivileged(driver)) {
9370
        /* If we have no cgroups then we can have no tunings that
9371 9372
         * require them */

9373 9374 9375 9376
        if (virMemoryLimitIsSet(def->mem.hard_limit) ||
            virMemoryLimitIsSet(def->mem.soft_limit) ||
            def->mem.min_guarantee ||
            virMemoryLimitIsSet(def->mem.swap_hard_limit)) {
9377 9378 9379 9380 9381
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Memory tuning is not available in session mode"));
            goto error;
        }

9382
        if (def->blkio.weight) {
9383 9384 9385 9386 9387
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Block I/O tuning is not available in session mode"));
            goto error;
        }

9388
        if (def->cputune.sharesSpecified || def->cputune.period ||
9389 9390 9391 9392 9393 9394 9395 9396
            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;
        }
    }

9397 9398 9399 9400 9401 9402 9403 9404 9405 9406 9407 9408 9409 9410
    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;
        }
    }

9411 9412 9413 9414
    /*
     * do not use boot=on for drives when not using KVM since this
     * is not supported at all in upstream QEmu.
     */
9415
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) &&
9416
        (def->virtType == VIR_DOMAIN_VIRT_QEMU))
9417
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_DRIVE_BOOT);
9418 9419

    cmd = virCommandNew(emulator);
9420

9421
    virCommandAddEnvPassCommon(cmd);
9422

9423 9424 9425 9426 9427 9428 9429
    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);
9430
    }
C
Cole Robinson 已提交
9431 9432 9433 9434

    if (!standalone)
        virCommandAddArg(cmd, "-S"); /* freeze CPU */

9435
    if (enableFips)
9436
        virCommandAddArg(cmd, "-enable-fips");
9437

9438
    if (qemuBuildMachineArgStr(cmd, def, qemuCaps) < 0)
9439
        goto error;
9440

9441
    if (qemuBuildCpuArgStr(driver, def, emulator, qemuCaps,
9442
                           hostarch, &cpu, &hasHwVirt, !!migrateURI) < 0)
9443
        goto error;
9444

9445 9446 9447 9448
    if (cpu) {
        virCommandAddArgList(cmd, "-cpu", cpu, NULL);
        VIR_FREE(cpu);

9449
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NESTING) &&
9450 9451
            hasHwVirt)
            virCommandAddArg(cmd, "-enable-nesting");
9452
    }
9453

9454 9455
    if (qemuBuildDomainLoaderCommandLine(cmd, def, qemuCaps) < 0)
        goto error;
9456

9457
    if (!migrateURI && !snapshot &&
9458
        qemuDomainAlignMemorySizes(def) < 0)
9459 9460
        goto error;

9461 9462 9463
    if (qemuDomainDefValidateMemoryHotplug(def, qemuCaps, NULL) < 0)
        goto error;

9464
    virCommandAddArg(cmd, "-m");
9465

9466
    if (virDomainDefHasMemoryHotplug(def)) {
9467 9468 9469 9470 9471 9472 9473 9474 9475
        /* 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);
    }
9476

9477 9478 9479 9480 9481 9482 9483
    /*
     * 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;
9484

9485 9486 9487 9488 9489 9490 9491 9492 9493 9494 9495
    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");
    }

9496
    virCommandAddArg(cmd, "-smp");
9497
    if (!(smp = qemuBuildSmpArgStr(def, qemuCaps)))
9498 9499 9500 9501
        goto error;
    virCommandAddArg(cmd, smp);
    VIR_FREE(smp);

9502 9503 9504 9505 9506 9507 9508
    if (def->niothreadids) {
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_IOTHREAD)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("IOThreads not supported for this QEMU"));
            goto error;
        }

9509 9510
        /* Create iothread objects using the defined iothreadids list
         * and the defined id and name from the list. These may be used
J
John Ferlan 已提交
9511
         * by a disk definition which will associate to an iothread by
9512
         * supplying a value of an id from the list
J
John Ferlan 已提交
9513
         */
9514
        for (i = 0; i < def->niothreadids; i++) {
J
John Ferlan 已提交
9515
            virCommandAddArg(cmd, "-object");
9516 9517
            virCommandAddArgFormat(cmd, "iothread,id=iothread%u",
                                   def->iothreadids[i]->iothread_id);
J
John Ferlan 已提交
9518 9519 9520
        }
    }

9521 9522
    if (virDomainNumaGetNodeCount(def->numa) &&
        qemuBuildNumaArgStr(cfg, def, cmd, qemuCaps, nodeset) < 0)
9523 9524
            goto error;

9525 9526
    /* memory hotplug requires NUMA to be enabled - we already checked
     * that memory devices are present only when NUMA is */
9527

9528

9529 9530 9531
    for (i = 0; i < def->nmems; i++) {
        char *backStr;
        char *dimmStr;
9532

9533 9534 9535
        if (!(backStr = qemuBuildMemoryDimmBackendStr(def->mems[i], def,
                                                      qemuCaps, cfg)))
            goto error;
9536

9537
        if (!(dimmStr = qemuBuildMemoryDeviceStr(def->mems[i]))) {
9538
            VIR_FREE(backStr);
9539
            goto error;
9540
        }
9541 9542 9543 9544 9545

        virCommandAddArgList(cmd, "-object", backStr, "-device", dimmStr, NULL);

        VIR_FREE(backStr);
        VIR_FREE(dimmStr);
9546 9547
    }

9548
    virCommandAddArgList(cmd, "-uuid", uuid, NULL);
9549
    if (def->virtType == VIR_DOMAIN_VIRT_XEN ||
9550 9551
        def->os.type == VIR_DOMAIN_OSTYPE_XEN ||
        def->os.type == VIR_DOMAIN_OSTYPE_LINUX) {
9552 9553 9554 9555
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("qemu emulator '%s' does not support xen"),
                       def->emulator);
        goto error;
9556 9557
    }

9558 9559 9560 9561 9562
    if ((def->os.smbios_mode != VIR_DOMAIN_SMBIOS_NONE) &&
        (def->os.smbios_mode != VIR_DOMAIN_SMBIOS_EMULATE)) {
        virSysinfoDefPtr source = NULL;
        bool skip_uuid = false;

9563
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SMBIOS_TYPE)) {
9564 9565 9566
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("the QEMU binary %s does not support smbios settings"),
                           emulator);
9567 9568 9569
            goto error;
        }

9570 9571 9572
        /* should we really error out or just warn in those cases ? */
        if (def->os.smbios_mode == VIR_DOMAIN_SMBIOS_HOST) {
            if (driver->hostsysinfo == NULL) {
9573
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
9574
                               _("Host SMBIOS information is not available"));
9575
                goto error;
9576
            }
9577 9578 9579 9580 9581 9582 9583 9584 9585
            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;
9586
            }
9587 9588
            source = def->sysinfo;
            /* domain_conf guaranteed that system_uuid matches guest uuid. */
9589
        }
9590 9591
        if (source != NULL) {
            char *smbioscmd;
9592

9593
            smbioscmd = qemuBuildSmbiosBiosStr(source->bios);
9594 9595 9596
            if (smbioscmd != NULL) {
                virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
                VIR_FREE(smbioscmd);
9597
            }
9598
            smbioscmd = qemuBuildSmbiosSystemStr(source->system, skip_uuid);
9599 9600 9601
            if (smbioscmd != NULL) {
                virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
                VIR_FREE(smbioscmd);
9602
            }
9603 9604 9605 9606 9607 9608 9609 9610 9611 9612 9613 9614 9615 9616 9617

            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);
            }
9618
        }
9619
    }
9620

9621 9622 9623 9624 9625 9626 9627
    /*
     * 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...
     */
9628
    if (!def->graphics) {
9629
        virCommandAddArg(cmd, "-nographic");
9630

9631
        if (cfg->nogfxAllowHostAudio)
9632
            virCommandAddEnvPassBlockSUID(cmd, "QEMU_AUDIO_DRV", NULL);
9633 9634 9635 9636
        else
            virCommandAddEnvString(cmd, "QEMU_AUDIO_DRV=none");
    }

9637
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
9638
        /* Disable global config files and default devices */
9639
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_USER_CONFIG))
9640
            virCommandAddArg(cmd, "-no-user-config");
9641
        else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NODEFCONFIG))
9642 9643
            virCommandAddArg(cmd, "-nodefconfig");
        virCommandAddArg(cmd, "-nodefaults");
9644 9645
    }

9646
    /* Serial graphics adapter */
J
Ján Tomko 已提交
9647
    if (def->os.bios.useserial == VIR_TRISTATE_BOOL_YES) {
9648
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
9649 9650 9651 9652
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("qemu does not support -device"));
            goto error;
        }
9653
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGA)) {
9654 9655 9656 9657 9658 9659 9660
            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"));
9661 9662
            goto error;
        }
9663
        virCommandAddArgList(cmd, "-device", "sga", NULL);
9664 9665
    }

9666 9667 9668
    if (monitor_chr) {
        char *chrdev;
        /* Use -chardev if it's available */
9669
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV)) {
J
Jim Fehlig 已提交
9670

9671 9672
            virCommandAddArg(cmd, "-chardev");
            if (!(chrdev = qemuBuildChrChardevStr(monitor_chr, "monitor",
9673
                                                  qemuCaps)))
9674 9675 9676
                goto error;
            virCommandAddArg(cmd, chrdev);
            VIR_FREE(chrdev);
9677

9678 9679 9680 9681 9682 9683 9684 9685
            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,";
9686

9687 9688 9689 9690 9691
            virCommandAddArg(cmd, "-monitor");
            if (!(chrdev = qemuBuildChrArgStr(monitor_chr, prefix)))
                goto error;
            virCommandAddArg(cmd, chrdev);
            VIR_FREE(chrdev);
9692 9693 9694
        }
    }

9695
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_RTC)) {
9696
        char *rtcopt;
9697 9698 9699 9700 9701 9702 9703 9704 9705 9706 9707
        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;
9708

9709 9710 9711
        case VIR_DOMAIN_CLOCK_OFFSET_UTC:
            /* Nothing, its the default */
            break;
9712

9713 9714 9715 9716
        default:
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("unsupported clock offset '%s'"),
                           virDomainClockOffsetTypeToString(def->clock.offset));
9717
            goto error;
9718 9719 9720 9721 9722
        }
    }
    if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE &&
        def->clock.data.timezone) {
        virCommandAddEnvPair(cmd, "TZ", def->clock.data.timezone);
9723 9724
    }

9725
    for (i = 0; i < def->clock.ntimers; i++) {
9726
        switch ((virDomainTimerNameType) def->clock.timers[i]->name) {
9727 9728 9729 9730 9731 9732
        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;
9733

9734
        case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
9735 9736 9737
        case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK:
            /* Timers above are handled when building -cpu.  */
        case VIR_DOMAIN_TIMER_NAME_LAST:
9738 9739 9740 9741 9742 9743
            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) */
9744
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_RTC_TD_HACK)) {
9745 9746 9747 9748
                switch (def->clock.timers[i]->tickpolicy) {
                case -1:
                case VIR_DOMAIN_TIMER_TICKPOLICY_DELAY:
                    /* the default - do nothing */
9749
                    break;
9750 9751
                case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP:
                    virCommandAddArg(cmd, "-rtc-td-hack");
9752
                    break;
9753 9754 9755 9756 9757
                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 已提交
9758
                    goto error;
9759
                }
9760 9761 9762 9763
            } else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_RTC) &&
                       (def->clock.timers[i]->tickpolicy
                        != VIR_DOMAIN_TIMER_TICKPOLICY_DELAY) &&
                       (def->clock.timers[i]->tickpolicy != -1)) {
9764 9765 9766 9767 9768 9769
                /* 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;
9770
            }
9771
            break;
9772

9773 9774 9775 9776 9777 9778
        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. */
9779 9780 9781 9782
                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))
9783 9784 9785
                    virCommandAddArg(cmd, "-no-kvm-pit-reinjection");
                break;
            case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP:
9786 9787
                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_KVM_PIT) ||
                    virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM_PIT_TICK_POLICY)) {
9788
                    /* do nothing - this is default for kvm-pit */
9789
                } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_TDF)) {
9790 9791
                    /* -tdf switches to 'catchup' with userspace pit. */
                    virCommandAddArg(cmd, "-tdf");
9792
                } else {
9793 9794 9795 9796
                    /* can't catchup if we have neither pit mode */
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("unsupported pit tickpolicy '%s'"),
                                   virDomainTimerTickpolicyTypeToString(def->clock.timers[i]->tickpolicy));
9797 9798 9799
                    goto error;
                }
                break;
9800 9801 9802 9803 9804 9805 9806
            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;
9807
            }
9808
            break;
9809

9810 9811 9812 9813 9814 9815 9816
        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"! */
9817

9818
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_HPET)) {
9819 9820 9821 9822 9823 9824 9825
                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,
9826 9827
                                   "%s", _("hpet timer is not supported"));
                    goto error;
9828 9829
                }
            }
9830 9831 9832
            break;
        }
    }
9833

9834 9835 9836 9837 9838 9839 9840
    /* 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");
9841
    }
9842

9843 9844 9845 9846
    /* 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.
     */
9847 9848
    if (monitor_json && allowReboot &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) {
9849
        virCommandAddArg(cmd, "-no-shutdown");
9850
    }
9851

9852
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_ACPI)) {
J
Ján Tomko 已提交
9853
        if (def->features[VIR_DOMAIN_FEATURE_ACPI] != VIR_TRISTATE_SWITCH_ON)
9854 9855
            virCommandAddArg(cmd, "-no-acpi");
    }
9856

9857 9858 9859 9860
    /* We fall back to PIIX4_PM even for q35, since it's what we did
       pre-q35-pm support. QEMU starts up fine (with a warning) if
       mixing PIIX PM and -M q35. Starting to reject things here
       could mean we refuse to start existing configs in the wild.*/
9861
    if (def->pm.s3) {
9862 9863 9864 9865 9866 9867
        const char *pm_object = "PIIX4_PM";

        if (qemuDomainMachineIsQ35(def) &&
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_DISABLE_S3)) {
            pm_object = "ICH9-LPC";
        } else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PIIX_DISABLE_S3)) {
9868 9869 9870
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("setting ACPI S3 not supported"));
            goto error;
9871
        }
9872

9873
        virCommandAddArg(cmd, "-global");
9874 9875
        virCommandAddArgFormat(cmd, "%s.disable_s3=%d",
                               pm_object, def->pm.s3 == VIR_TRISTATE_BOOL_NO);
9876 9877 9878
    }

    if (def->pm.s4) {
9879 9880 9881 9882 9883 9884
        const char *pm_object = "PIIX4_PM";

        if (qemuDomainMachineIsQ35(def) &&
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_DISABLE_S4)) {
            pm_object = "ICH9-LPC";
        } else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PIIX_DISABLE_S4)) {
9885
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
9886 9887 9888
                           "%s", _("setting ACPI S4 not supported"));
            goto error;
        }
9889

9890
        virCommandAddArg(cmd, "-global");
9891 9892
        virCommandAddArgFormat(cmd, "%s.disable_s4=%d",
                               pm_object, def->pm.s4 == VIR_TRISTATE_BOOL_NO);
9893
    }
9894

J
Ján Tomko 已提交
9895 9896 9897 9898 9899 9900 9901 9902
    /*
     * 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
9903
         */
J
Ján Tomko 已提交
9904 9905 9906 9907
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("hypervisor lacks deviceboot feature"));
            goto error;
9908
        }
J
Ján Tomko 已提交
9909 9910 9911 9912 9913 9914
        emitBootindex = true;
    } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX) &&
               (def->os.bootmenu != VIR_TRISTATE_BOOL_YES ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_MENU))) {
        emitBootindex = true;
    }
9915

J
Ján Tomko 已提交
9916 9917
    if (!emitBootindex) {
        char boot[VIR_DOMAIN_BOOT_LAST+1];
9918

J
Ján Tomko 已提交
9919 9920 9921 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935
        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;
9936 9937
            }
        }
J
Ján Tomko 已提交
9938
        boot[def->os.nBootDevs] = '\0';
9939

J
Ján Tomko 已提交
9940
        virBufferAsprintf(&boot_buf, "%s", boot);
9941 9942 9943
        if (virBufferCheckError(&boot_buf) < 0)
            goto error;
        boot_order_str = virBufferContentAndReset(&boot_buf);
J
Ján Tomko 已提交
9944
    }
9945

J
Ján Tomko 已提交
9946 9947 9948
    if (def->os.bootmenu) {
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_MENU)) {
            if (def->os.bootmenu == VIR_TRISTATE_BOOL_YES)
9949
                virBufferAddLit(&boot_buf, "menu=on,");
J
Ján Tomko 已提交
9950
            else
9951
                virBufferAddLit(&boot_buf, "menu=off,");
J
Ján Tomko 已提交
9952 9953 9954 9955 9956
        } 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");
9957
        }
J
Ján Tomko 已提交
9958
    }
9959

J
Ján Tomko 已提交
9960 9961 9962 9963 9964 9965 9966
    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;
        }
9967

J
Ján Tomko 已提交
9968
        virBufferAsprintf(&boot_buf,
9969
                          "reboot-timeout=%d,",
J
Ján Tomko 已提交
9970 9971
                          def->os.bios.rt_delay);
    }
9972

J
Ján Tomko 已提交
9973 9974 9975 9976 9977 9978
    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;
9979 9980
        }

9981
        virBufferAsprintf(&boot_buf, "splash-time=%u,", def->os.bm_timeout);
J
Ján Tomko 已提交
9982
    }
9983

9984 9985 9986 9987
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_STRICT))
        virBufferAddLit(&boot_buf, "strict=on,");

    virBufferTrim(&boot_buf, ",", -1);
J
Ján Tomko 已提交
9988

9989 9990
    if (virBufferCheckError(&boot_buf) < 0)
        goto error;
J
Ján Tomko 已提交
9991

9992 9993 9994
    boot_opts_str = virBufferContentAndReset(&boot_buf);
    if (boot_order_str || boot_opts_str) {
        virCommandAddArg(cmd, "-boot");
J
Ján Tomko 已提交
9995

9996 9997 9998 9999 10000 10001 10002
        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);
10003
        }
J
Ján Tomko 已提交
10004
    }
10005
    VIR_FREE(boot_opts_str);
10006
    VIR_FREE(boot_order_str);
10007

J
Ján Tomko 已提交
10008 10009 10010 10011 10012 10013 10014 10015 10016 10017 10018 10019 10020
    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 已提交
10021
        }
10022
    }
10023

10024 10025 10026 10027 10028 10029 10030 10031 10032 10033 10034 10035 10036 10037 10038 10039 10040 10041 10042 10043 10044 10045 10046 10047 10048 10049 10050 10051 10052 10053 10054 10055 10056 10057 10058 10059 10060 10061 10062 10063 10064 10065 10066 10067 10068 10069 10070
    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);
        }
    }

10071
    for (i = 0; i < def->ndisks; i++) {
10072
        virDomainDiskDefPtr disk = def->disks[i];
10073

10074
        if (disk->src->driverName != NULL &&
10075
            STRNEQ(disk->src->driverName, "qemu")) {
10076 10077
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("unsupported driver name '%s' for disk '%s'"),
10078
                           disk->src->driverName, disk->src->path);
10079 10080 10081 10082
            goto error;
        }
    }

10083
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10084 10085 10086
        for (j = 0; j < ARRAY_CARDINALITY(contOrder); j++) {
            for (i = 0; i < def->ncontrollers; i++) {
                virDomainControllerDefPtr cont = def->controllers[i];
10087
                char *devstr;
10088

10089 10090
                if (cont->type != contOrder[j])
                    continue;
10091

10092
                /* skip USB controllers with type none.*/
10093 10094 10095 10096 10097 10098
                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;
                }

10099
                /* skip pci-root/pcie-root */
10100
                if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI &&
L
Laine Stump 已提交
10101
                    (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT ||
10102
                     cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT))
10103 10104
                    continue;

10105 10106 10107
                /* first SATA controller on Q35 machines is implicit */
                if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_SATA &&
                    cont->idx == 0 && qemuDomainMachineIsQ35(def))
10108
                        continue;
10109

10110
                /* first IDE controller is implicit on various machines */
10111
                if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE &&
10112
                    cont->idx == 0 && qemuDomainMachineHasBuiltinIDE(def))
10113 10114
                        continue;

10115 10116
                if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
                    cont->model == -1 &&
10117 10118 10119 10120 10121 10122 10123 10124 10125 10126 10127 10128 10129 10130 10131 10132 10133 10134 10135 10136 10137 10138 10139
                    !qemuDomainMachineIsQ35(def)) {
                    bool need_legacy = false;

                    /* We're not using legacy usb controller for q35 */
                    if (ARCH_IS_PPC64(def->os.arch)) {
                        /* For ppc64 the legacy was OHCI */
                        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_OHCI))
                            need_legacy = true;
                    } else {
                        /* For anything else, we used PIIX3_USB_UHCI */
                        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI))
                            need_legacy = true;
                    }

                    if (need_legacy) {
                        if (usblegacy) {
                            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                           _("Multiple legacy USB controllers are "
                                             "not supported"));
                            goto error;
                        }
                        usblegacy = true;
                        continue;
10140 10141
                    }
                }
10142 10143 10144 10145 10146 10147 10148

                virCommandAddArg(cmd, "-device");
                if (!(devstr = qemuBuildControllerDevStr(def, cont, qemuCaps,
                                                         &usbcontroller)))
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
10149
            }
10150 10151
        }
    }
10152

10153 10154 10155
    if (usbcontroller == 0 &&
        !qemuDomainMachineIsQ35(def) &&
        !ARCH_IS_S390(def->os.arch))
10156
        virCommandAddArg(cmd, "-usb");
10157

10158
    for (i = 0; i < def->nhubs; i++) {
10159 10160
        virDomainHubDefPtr hub = def->hubs[i];
        char *optstr;
10161

10162
        virCommandAddArg(cmd, "-device");
10163
        if (!(optstr = qemuBuildHubDevStr(def, hub, qemuCaps)))
10164 10165 10166 10167
            goto error;
        virCommandAddArg(cmd, optstr);
        VIR_FREE(optstr);
    }
10168

10169 10170 10171 10172 10173 10174 10175 10176 10177 10178 10179 10180 10181 10182
    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;
10183
            }
10184
        }
10185
    }
10186

10187 10188 10189 10190 10191 10192 10193 10194 10195 10196 10197 10198 10199 10200 10201 10202 10203 10204
    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);
10205 10206
                goto error;
            }
10207 10208
            continue;
        }
10209

10210 10211 10212 10213 10214 10215 10216 10217 10218 10219 10220 10221 10222 10223 10224 10225 10226 10227 10228 10229 10230 10231 10232 10233 10234 10235 10236 10237 10238 10239 10240 10241 10242 10243 10244 10245 10246 10247
        /* 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;
10248
            }
10249 10250 10251 10252 10253 10254 10255 10256 10257 10258
        }
        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);
10259

10260 10261 10262 10263
        if (!emitBootindex)
            bootindex = 0;
        else if (disk->info.bootIndex)
            bootindex = disk->info.bootIndex;
10264

10265 10266 10267 10268 10269 10270 10271 10272 10273 10274
        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);
10275
                } else {
10276
                    virBufferAsprintf(&fdc_opts, "%s,", optstr);
10277
                }
10278
                VIR_FREE(optstr);
10279

10280 10281 10282 10283 10284
                if (bootindex) {
                    if (virAsprintf(&optstr, "bootindex%c=%d",
                                    disk->info.addr.drive.unit
                                    ? 'B' : 'A',
                                    bootindex) < 0)
J
Ján Tomko 已提交
10285 10286
                        goto error;

10287 10288 10289 10290 10291 10292
                    if (!qemuDomainMachineNeedsFDC(def)) {
                        virCommandAddArg(cmd, "-global");
                        virCommandAddArgFormat(cmd, "isa-fdc.%s", optstr);
                    } else {
                        virBufferAsprintf(&fdc_opts, "%s,", optstr);
                    }
J
Ján Tomko 已提交
10293
                    VIR_FREE(optstr);
E
Eric Blake 已提交
10294 10295
                }
            } else {
10296
                virCommandAddArg(cmd, "-device");
E
Eric Blake 已提交
10297

10298 10299
                if (!(optstr = qemuBuildDriveDevStr(def, disk, bootindex,
                                                    qemuCaps)))
10300
                    goto error;
10301 10302
                virCommandAddArg(cmd, optstr);
                VIR_FREE(optstr);
E
Eric Blake 已提交
10303 10304 10305
            }
        }
    }
10306 10307 10308 10309 10310 10311 10312
    /* 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 已提交
10313

10314
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_FSDEV)) {
10315
        for (i = 0; i < def->nfss; i++) {
10316 10317
            char *optstr;
            virDomainFSDefPtr fs = def->fss[i];
10318

10319
            virCommandAddArg(cmd, "-fsdev");
10320
            if (!(optstr = qemuBuildFSStr(fs, qemuCaps)))
10321 10322 10323
                goto error;
            virCommandAddArg(cmd, optstr);
            VIR_FREE(optstr);
10324

10325
            virCommandAddArg(cmd, "-device");
10326
            if (!(optstr = qemuBuildFSDevStr(def, fs, qemuCaps)))
10327 10328 10329 10330 10331 10332 10333 10334 10335
                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;
10336 10337 10338
        }
    }

10339
    if (!def->nnets) {
10340
        /* If we have -device, then we set -nodefault already */
10341
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
10342
            virCommandAddArgList(cmd, "-net", "none", NULL);
10343
    } else {
10344
        int bootNet = 0;
10345

10346 10347 10348 10349
        if (emitBootindex) {
            /* convert <boot dev='network'/> to bootindex since we didn't emit
             * -boot n
             */
10350
            for (i = 0; i < def->os.nBootDevs; i++) {
10351 10352 10353 10354
                if (def->os.bootDevs[i] == VIR_DOMAIN_BOOT_NET) {
                    bootNet = i + 1;
                    break;
                }
10355 10356 10357
            }
        }

10358
        for (i = 0; i < def->nnets; i++) {
10359
            virDomainNetDefPtr net = def->nets[i];
10360
            int vlan;
10361

10362
            /* VLANs are not used with -netdev, so don't record them */
10363
            if (qemuDomainSupportsNetdev(def, qemuCaps, net))
10364
                vlan = -1;
10365 10366
            else
                vlan = i;
10367

10368
            if (qemuBuildInterfaceCommandLine(cmd, driver, def, net,
10369
                                              qemuCaps, vlan, bootNet, vmop,
10370
                                              standalone, nnicindexes, nicindexes) < 0)
10371
                goto error;
10372

10373
            last_good_net = i;
10374 10375 10376 10377 10378 10379 10380 10381 10382 10383
            /* 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;
            }
10384
            bootNet = 0;
10385 10386 10387
        }
    }

10388 10389 10390 10391 10392
    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;
10393
        virBuffer opt = VIR_BUFFER_INITIALIZER;
10394
        const char *database;
10395

10396 10397 10398 10399
        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) {
10400
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
10401 10402 10403
                           _("this QEMU binary lacks multiple smartcard "
                             "support"));
            virBufferFreeAndReset(&opt);
10404 10405 10406
            goto error;
        }

10407 10408
        switch (smartcard->type) {
        case VIR_DOMAIN_SMARTCARD_TYPE_HOST:
10409 10410
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) {
10411 10412 10413 10414
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("this QEMU binary lacks smartcard host "
                                 "mode support"));
                goto error;
10415 10416
            }

10417 10418
            virBufferAddLit(&opt, "ccid-card-emulated,backend=nss-emulated");
            break;
10419

10420
        case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES:
10421 10422
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) {
10423 10424 10425 10426 10427
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("this QEMU binary lacks smartcard host "
                                 "mode support"));
                goto error;
            }
10428

10429 10430 10431 10432
            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);
10433
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
10434 10435
                                   _("invalid certificate name: %s"),
                                   smartcard->data.cert.file[j]);
10436 10437
                    goto error;
                }
10438
                virBufferAsprintf(&opt, ",cert%zu=%s", j + 1,
10439 10440 10441 10442 10443 10444 10445 10446
                                  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);
10447 10448
                    goto error;
                }
10449 10450 10451
                database = smartcard->data.cert.database;
            } else {
                database = VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE;
10452
            }
10453
            virBufferAsprintf(&opt, ",db=%s", database);
10454
            break;
10455

10456
        case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
10457 10458
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_PASSTHRU)) {
10459 10460 10461 10462
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("this QEMU binary lacks smartcard "
                                 "passthrough mode support"));
                goto error;
10463 10464
            }

10465 10466 10467
            virCommandAddArg(cmd, "-chardev");
            if (!(devstr = qemuBuildChrChardevStr(&smartcard->data.passthru,
                                                  smartcard->info.alias,
10468
                                                  qemuCaps))) {
10469 10470
                virBufferFreeAndReset(&opt);
                goto error;
10471
            }
10472 10473
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);
10474

10475 10476 10477
            virBufferAsprintf(&opt, "ccid-card-passthru,chardev=char%s",
                              smartcard->info.alias);
            break;
10478

10479 10480 10481 10482 10483
        default:
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("unexpected smartcard type %d"),
                           smartcard->type);
            virBufferFreeAndReset(&opt);
10484 10485
            goto error;
        }
10486 10487 10488 10489
        virCommandAddArg(cmd, "-device");
        virBufferAsprintf(&opt, ",id=%s,bus=ccid0.0", smartcard->info.alias);
        virCommandAddArgBuffer(cmd, &opt);
    }
10490

10491 10492 10493
    for (i = 0; i < def->nserials; i++) {
        virDomainChrDefPtr serial = def->serials[i];
        char *devstr;
10494

10495 10496 10497
        if (serial->source.type == VIR_DOMAIN_CHR_TYPE_SPICEPORT && !spice)
            continue;

10498 10499 10500 10501 10502 10503 10504 10505 10506 10507 10508 10509 10510 10511 10512 10513 10514 10515
        /* 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);
10516
        }
10517
        actualSerials++;
10518
    }
10519

M
Martin Kletzander 已提交
10520 10521 10522 10523
    /* If we have -device, then we set -nodefault already */
    if (!actualSerials && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
            virCommandAddArgList(cmd, "-serial", "none", NULL);

10524 10525
    if (!def->nparallels) {
        /* If we have -device, then we set -nodefault already */
10526
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
10527 10528
            virCommandAddArgList(cmd, "-parallel", "none", NULL);
    } else {
10529
        for (i = 0; i < def->nparallels; i++) {
10530 10531
            virDomainChrDefPtr parallel = def->parallels[i];
            char *devstr;
10532

10533
            /* Use -chardev with -device if they are available */
10534 10535
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) &&
                virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10536 10537 10538
                virCommandAddArg(cmd, "-chardev");
                if (!(devstr = qemuBuildChrChardevStr(&parallel->source,
                                                      parallel->info.alias,
10539
                                                      qemuCaps)))
10540 10541 10542
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
10543

10544 10545
                if (qemuBuildChrDeviceCommandLine(cmd, def, parallel, qemuCaps) < 0)
                    goto error;
10546 10547 10548
            } else {
                virCommandAddArg(cmd, "-parallel");
                if (!(devstr = qemuBuildChrArgStr(&parallel->source, NULL)))
10549
                    goto error;
10550 10551 10552
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
            }
10553
        }
10554
    }
10555

10556
    for (i = 0; i < def->nchannels; i++) {
10557 10558
        virDomainChrDefPtr channel = def->channels[i];
        char *devstr;
10559

10560 10561
        switch (channel->targetType) {
        case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD:
10562 10563
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10564 10565
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("guestfwd requires QEMU to support -chardev & -device"));
10566 10567
                goto error;
            }
10568

10569 10570 10571
            virCommandAddArg(cmd, "-chardev");
            if (!(devstr = qemuBuildChrChardevStr(&channel->source,
                                                  channel->info.alias,
10572
                                                  qemuCaps)))
10573 10574 10575 10576
                goto error;
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);

10577
            if (qemuBuildChrDeviceStr(&devstr, def, channel, qemuCaps) < 0)
10578
                goto error;
10579 10580
            virCommandAddArgList(cmd, "-netdev", devstr, NULL);
            VIR_FREE(devstr);
10581 10582
            break;

10583
        case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO:
10584
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10585 10586
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("virtio channel requires QEMU to support -device"));
10587 10588
                goto error;
            }
10589

10590 10591 10592 10593 10594 10595 10596 10597 10598 10599 10600 10601 10602 10603 10604 10605 10606
            /*
             * 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;
            }

10607
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC) &&
10608 10609 10610 10611 10612 10613 10614 10615 10616
                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,
10617
                                                      qemuCaps)))
10618 10619 10620
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
10621
            }
10622

10623
            if (qemuBuildChrDeviceCommandLine(cmd, def, channel, qemuCaps) < 0)
10624
                goto error;
10625 10626
            break;
        }
10627
    }
10628

10629
    /* Explicit console devices */
10630
    for (i = 0; i < def->nconsoles; i++) {
10631 10632
        virDomainChrDefPtr console = def->consoles[i];
        char *devstr;
10633

10634
        switch (console->targetType) {
10635 10636
        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLP:
        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLPLM:
10637
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10638 10639 10640 10641
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("sclp console requires QEMU to support -device"));
                goto error;
            }
10642
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCLP_S390)) {
10643 10644 10645 10646 10647 10648 10649 10650
                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,
10651
                                                  qemuCaps)))
10652 10653 10654 10655
                goto error;
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);

10656
            if (qemuBuildChrDeviceCommandLine(cmd, def, console, qemuCaps) < 0)
10657 10658 10659
                goto error;
            break;

10660
        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO:
10661
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10662 10663 10664
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("virtio channel requires QEMU to support -device"));
                goto error;
P
Peng Zhou 已提交
10665 10666
            }

10667 10668 10669
            virCommandAddArg(cmd, "-chardev");
            if (!(devstr = qemuBuildChrChardevStr(&console->source,
                                                  console->info.alias,
10670
                                                  qemuCaps)))
10671 10672 10673
                goto error;
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);
10674

10675
            if (qemuBuildChrDeviceCommandLine(cmd, def, console, qemuCaps) < 0)
10676
                goto error;
10677
            break;
10678 10679

        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL:
10680
            break;
10681 10682 10683 10684 10685 10686

        default:
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("unsupported console target type %s"),
                           NULLSTR(virDomainChrConsoleTargetTypeToString(console->targetType)));
            goto error;
10687
        }
10688
    }
10689

10690
    if (def->tpm) {
10691
        if (qemuBuildTPMCommandLine(def, cmd, qemuCaps, emulator) < 0)
10692 10693 10694
            goto error;
    }

10695
    for (i = 0; i < def->ninputs; i++) {
10696 10697 10698
        virDomainInputDefPtr input = def->inputs[i];

        if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) {
10699
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10700 10701
                char *optstr;
                virCommandAddArg(cmd, "-device");
10702
                if (!(optstr = qemuBuildUSBInputDevStr(def, input, qemuCaps)))
10703
                    goto error;
10704 10705 10706
                virCommandAddArg(cmd, optstr);
                VIR_FREE(optstr);
            } else {
10707 10708 10709 10710 10711 10712 10713 10714 10715 10716 10717
                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;
                }
10718
            }
10719 10720 10721 10722 10723 10724 10725
        } 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);
10726
        }
10727
    }
10728

10729 10730 10731 10732
    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"));
10733 10734 10735
        goto error;
    }

10736
    for (i = 0; i < def->ngraphics; ++i) {
10737
        if (qemuBuildGraphicsCommandLine(cfg, cmd, def, qemuCaps,
10738 10739 10740
                                         def->graphics[i]) < 0)
            goto error;
    }
10741

10742
    if (def->nvideos > 0) {
10743
        int primaryVideoType = def->videos[0]->type;
10744
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY) &&
10745
             ((primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_VGA &&
10746
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VGA)) ||
10747
             (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_CIRRUS &&
10748
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_CIRRUS_VGA)) ||
10749
             (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_VMVGA &&
10750
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMWARE_SVGA)) ||
10751
             (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_QXL &&
M
Marc-André Lureau 已提交
10752 10753 10754 10755
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL_VGA)) ||
             (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_VIRTIO &&
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_GPU)))
            ) {
10756
            for (i = 0; i < def->nvideos; i++) {
10757 10758
                char *str;
                virCommandAddArg(cmd, "-device");
10759
                if (!(str = qemuBuildDeviceVideoStr(def, def->videos[i], qemuCaps, !i)))
10760 10761 10762 10763 10764
                    goto error;

                virCommandAddArg(cmd, str);
                VIR_FREE(str);
            }
10765
        } else {
10766
            if (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_XEN) {
10767 10768
                /* nothing - vga has no effect on Xen pvfb */
            } else {
10769
                if ((primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_QXL) &&
10770
                    !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA_QXL)) {
10771 10772
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("This QEMU does not support QXL graphics adapters"));
10773 10774 10775
                    goto error;
                }

10776
                const char *vgastr = qemuVideoTypeToString(primaryVideoType);
10777
                if (!vgastr || STREQ(vgastr, "")) {
10778 10779
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("video type %s is not supported with QEMU"),
10780
                                   virDomainVideoTypeToString(primaryVideoType));
10781 10782 10783 10784
                    goto error;
                }

                virCommandAddArgList(cmd, "-vga", vgastr, NULL);
10785

10786 10787 10788 10789 10790 10791 10792 10793 10794 10795 10796 10797 10798
                /* 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);

10799 10800
                if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_QXL &&
                    (def->videos[0]->vram || def->videos[0]->ram) &&
10801
                    virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10802 10803
                    unsigned int ram = def->videos[0]->ram;
                    unsigned int vram = def->videos[0]->vram;
10804
                    unsigned int vgamem = def->videos[0]->vgamem;
10805 10806 10807 10808 10809 10810 10811 10812 10813 10814 10815 10816 10817

                    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;
                    }
10818

10819
                    if (ram) {
E
Eric Blake 已提交
10820
                        virCommandAddArg(cmd, "-global");
10821 10822 10823 10824 10825 10826 10827
                        virCommandAddArgFormat(cmd, "%s.ram_size=%u",
                                               dev, ram * 1024);
                    }
                    if (vram) {
                        virCommandAddArg(cmd, "-global");
                        virCommandAddArgFormat(cmd, "%s.vram_size=%u",
                                               dev, vram * 1024);
10828
                    }
10829 10830 10831 10832 10833 10834
                    if (vgamem &&
                        virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_VGA_VGAMEM)) {
                        virCommandAddArg(cmd, "-global");
                        virCommandAddArgFormat(cmd, "%s.vgamem_mb=%u",
                                               dev, vgamem / 1024);
                    }
10835
                }
10836 10837 10838 10839 10840 10841 10842 10843 10844 10845 10846 10847 10848 10849 10850 10851 10852 10853 10854 10855

                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);
                }
10856
            }
10857 10858

            if (def->nvideos > 1) {
10859
                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10860
                    for (i = 1; i < def->nvideos; i++) {
10861 10862 10863 10864 10865 10866 10867 10868 10869 10870
                        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");

10871
                        if (!(str = qemuBuildDeviceVideoStr(def, def->videos[i], qemuCaps, false)))
10872 10873 10874 10875 10876 10877 10878 10879 10880 10881 10882
                            goto error;

                        virCommandAddArg(cmd, str);
                        VIR_FREE(str);
                    }
                } else {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   "%s", _("only one video card is currently supported"));
                    goto error;
                }
            }
10883 10884 10885 10886
        }

    } else {
        /* If we have -device, then we set -nodefault already */
10887 10888
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) &&
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA_NONE))
10889 10890 10891 10892 10893
            virCommandAddArgList(cmd, "-vga", "none", NULL);
    }

    /* Add sound hardware */
    if (def->nsounds) {
10894
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10895
            for (i = 0; i < def->nsounds; i++) {
10896 10897 10898 10899 10900 10901 10902 10903 10904 10905
                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");
10906
                    if (!(str = qemuBuildSoundDevStr(def, sound, qemuCaps)))
10907 10908 10909
                        goto error;

                    virCommandAddArg(cmd, str);
10910
                    VIR_FREE(str);
10911 10912
                    if (sound->model == VIR_DOMAIN_SOUND_MODEL_ICH6 ||
                        sound->model == VIR_DOMAIN_SOUND_MODEL_ICH9) {
10913 10914
                        char *codecstr = NULL;

10915
                        for (j = 0; j < sound->ncodecs; j++) {
10916
                            virCommandAddArg(cmd, "-device");
10917
                            if (!(codecstr = qemuBuildSoundCodecStr(sound, sound->codecs[j], qemuCaps))) {
10918
                                goto error;
10919

10920 10921 10922 10923
                            }
                            virCommandAddArg(cmd, codecstr);
                            VIR_FREE(codecstr);
                        }
10924
                        if (j == 0) {
10925 10926 10927 10928 10929
                            virDomainSoundCodecDef codec = {
                                VIR_DOMAIN_SOUND_CODEC_TYPE_DUPLEX,
                                0
                            };
                            virCommandAddArg(cmd, "-device");
10930
                            if (!(codecstr = qemuBuildSoundCodecStr(sound, &codec, qemuCaps))) {
10931 10932 10933 10934 10935 10936
                                goto error;

                            }
                            virCommandAddArg(cmd, codecstr);
                            VIR_FREE(codecstr);
                        }
10937
                    }
10938 10939 10940 10941 10942
                }
            }
        } else {
            int size = 100;
            char *modstr;
10943
            if (VIR_ALLOC_N(modstr, size+1) < 0)
10944
                goto error;
10945

10946
            for (i = 0; i < def->nsounds && size > 0; i++) {
10947 10948 10949 10950
                virDomainSoundDefPtr sound = def->sounds[i];
                const char *model = virDomainSoundModelTypeToString(sound->model);
                if (!model) {
                    VIR_FREE(modstr);
10951 10952
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   "%s", _("invalid sound model"));
10953 10954
                    goto error;
                }
10955

10956 10957
                if (sound->model == VIR_DOMAIN_SOUND_MODEL_ICH6 ||
                    sound->model == VIR_DOMAIN_SOUND_MODEL_ICH9) {
A
Alex Jia 已提交
10958
                    VIR_FREE(modstr);
10959 10960
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("this QEMU binary lacks hda support"));
10961 10962 10963
                    goto error;
                }

10964 10965 10966 10967 10968 10969 10970 10971 10972 10973 10974 10975 10976 10977 10978
                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;

10979
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
10980 10981
            virCommandAddArg(cmd, "-device");

10982
            optstr = qemuBuildWatchdogDevStr(def, watchdog, qemuCaps);
10983 10984 10985 10986 10987 10988 10989
            if (!optstr)
                goto error;
        } else {
            virCommandAddArg(cmd, "-watchdog");

            const char *model = virDomainWatchdogModelTypeToString(watchdog->model);
            if (!model) {
10990 10991
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               "%s", _("missing watchdog model"));
10992 10993 10994
                goto error;
            }

10995 10996
            if (VIR_STRDUP(optstr, model) < 0)
                goto error;
10997 10998 10999 11000 11001 11002 11003 11004 11005
        }
        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) {
11006 11007
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("invalid watchdog action"));
11008 11009 11010 11011 11012
            goto error;
        }
        virCommandAddArgList(cmd, "-watchdog-action", action, NULL);
    }

11013
    /* Add redirected devices */
11014
    for (i = 0; i < def->nredirdevs; i++) {
11015 11016 11017 11018 11019 11020
        virDomainRedirdevDefPtr redirdev = def->redirdevs[i];
        char *devstr;

        virCommandAddArg(cmd, "-chardev");
        if (!(devstr = qemuBuildChrChardevStr(&redirdev->source.chr,
                                              redirdev->info.alias,
11021
                                              qemuCaps))) {
11022 11023 11024 11025 11026 11027
            goto error;
        }

        virCommandAddArg(cmd, devstr);
        VIR_FREE(devstr);

11028 11029 11030
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("redirected devices are not supported by this QEMU"));
11031
            goto error;
11032 11033
        }

11034 11035

        virCommandAddArg(cmd, "-device");
11036
        if (!(devstr = qemuBuildRedirdevDevStr(def, redirdev, qemuCaps)))
11037 11038 11039 11040 11041
            goto error;
        virCommandAddArg(cmd, devstr);
        VIR_FREE(devstr);
    }

11042
    /* Add host passthrough hardware */
11043
    for (i = 0; i < def->nhostdevs; i++) {
11044 11045 11046
        virDomainHostdevDefPtr hostdev = def->hostdevs[i];
        char *devstr;

11047
        if (hostdev->info->bootIndex) {
11048
            if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
11049
                (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
11050 11051
                 hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
                 hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)) {
11052
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
11053
                               _("booting from assigned devices is only "
11054
                                 "supported for PCI, USB and SCSI devices"));
11055
                goto error;
11056
            } else {
11057 11058
                if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
                    if (hostdev->source.subsys.u.pci.backend
11059
                        == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
11060 11061 11062 11063 11064 11065 11066 11067 11068 11069 11070 11071 11072 11073
                        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;
                        }
                    }
11074 11075
                }
                if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
11076
                    !virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_HOST_BOOTINDEX)) {
11077
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
11078 11079
                                   _("booting from assigned USB devices is not "
                                     "supported with this version of qemu"));
11080 11081
                    goto error;
                }
11082 11083 11084 11085 11086 11087 11088
                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;
                }
11089 11090 11091
            }
        }

11092 11093 11094 11095
        /* USB */
        if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
            hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {

11096
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
11097
                virCommandAddArg(cmd, "-device");
11098
                if (!(devstr = qemuBuildUSBHostdevDevStr(def, hostdev, qemuCaps)))
11099 11100 11101 11102 11103
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
            } else {
                virCommandAddArg(cmd, "-usbdevice");
11104
                if (!(devstr = qemuBuildUSBHostdevUSBDevStr(hostdev)))
11105 11106 11107 11108 11109 11110 11111 11112 11113
                    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) {
11114
            int backend = hostdev->source.subsys.u.pci.backend;
11115

11116
            if (backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
11117 11118 11119 11120 11121 11122
                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;
                }
11123 11124
            }

11125
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
11126
                char *configfd_name = NULL;
11127 11128 11129 11130 11131 11132 11133 11134 11135 11136
                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;
                }
11137
                if ((backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) &&
11138
                    virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
11139 11140 11141 11142 11143
                    int configfd = qemuOpenPCIConfig(hostdev);

                    if (configfd >= 0) {
                        if (virAsprintf(&configfd_name, "%d", configfd) < 0) {
                            VIR_FORCE_CLOSE(configfd);
11144
                            goto error;
11145 11146
                        }

11147 11148
                        virCommandPassFD(cmd, configfd,
                                         VIR_COMMAND_PASS_FD_CLOSE_PARENT);
11149 11150 11151
                    }
                }
                virCommandAddArg(cmd, "-device");
11152 11153
                devstr = qemuBuildPCIHostdevDevStr(def, hostdev, bootIndex,
                                                   configfd_name, qemuCaps);
11154 11155 11156 11157 11158
                VIR_FREE(configfd_name);
                if (!devstr)
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
11159
            } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCIDEVICE)) {
11160
                virCommandAddArg(cmd, "-pcidevice");
11161
                if (!(devstr = qemuBuildPCIHostdevPCIDevStr(hostdev, qemuCaps)))
11162 11163 11164 11165
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
            } else {
11166 11167
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("PCI device assignment is not supported by this version of qemu"));
11168 11169 11170
                goto error;
            }
        }
11171 11172 11173 11174

        /* SCSI */
        if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
            hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {
11175
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) &&
11176 11177 11178 11179
                virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SCSI_GENERIC)) {
                char *drvstr;

                virCommandAddArg(cmd, "-drive");
11180
                if (!(drvstr = qemuBuildSCSIHostdevDrvStr(conn, hostdev, qemuCaps, callbacks)))
11181 11182 11183 11184 11185 11186 11187 11188 11189 11190 11191 11192 11193 11194 11195
                    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;
            }
        }
11196 11197
    }

11198
    if (migrateURI)
11199
        virCommandAddArgList(cmd, "-incoming", migrateURI, NULL);
11200 11201 11202 11203 11204 11205 11206

    /* 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
     */
11207 11208
    if (STREQLEN(def->os.machine, "s390-virtio", 10) &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390) && def->memballoon)
11209 11210 11211 11212
        def->memballoon->model = VIR_DOMAIN_MEMBALLOON_MODEL_NONE;

    if (def->memballoon &&
        def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_NONE) {
11213
        if (def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO) {
11214 11215 11216
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("Memory balloon device type '%s' is not supported by this version of qemu"),
                           virDomainMemballoonModelTypeToString(def->memballoon->model));
11217 11218
            goto error;
        }
11219
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
11220 11221 11222
            char *optstr;
            virCommandAddArg(cmd, "-device");

11223
            optstr = qemuBuildMemballoonDevStr(def, def->memballoon, qemuCaps);
11224 11225 11226 11227
            if (!optstr)
                goto error;
            virCommandAddArg(cmd, optstr);
            VIR_FREE(optstr);
11228
        } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BALLOON)) {
11229 11230 11231 11232
            virCommandAddArgList(cmd, "-balloon", "virtio", NULL);
        }
    }

11233
    for (i = 0; i < def->nrngs; i++) {
11234 11235 11236 11237 11238 11239 11240 11241 11242 11243 11244 11245 11246 11247 11248 11249 11250 11251
        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);
        }

11252
        /* add the RNG source backend */
11253
        if (!(tmp = qemuBuildRNGBackendStr(rng, qemuCaps)))
11254 11255
            goto error;

11256 11257 11258
        virCommandAddArgList(cmd, "-object", tmp, NULL);
        VIR_FREE(tmp);

11259
        /* add the device */
11260
        if (!(tmp = qemuBuildRNGDevStr(def, rng, qemuCaps)))
11261
            goto error;
11262 11263
        virCommandAddArgList(cmd, "-device", tmp, NULL);
        VIR_FREE(tmp);
11264 11265
    }

11266
    if (def->nvram) {
11267
        if (ARCH_IS_PPC64(def->os.arch) &&
11268
            STRPREFIX(def->os.machine, "pseries")) {
11269 11270 11271 11272 11273 11274 11275 11276 11277 11278 11279 11280 11281 11282 11283 11284 11285 11286 11287 11288 11289
            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;
        }
    }
11290 11291
    if (snapshot)
        virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL);
11292 11293 11294 11295 11296 11297 11298 11299 11300 11301 11302 11303 11304

    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] : "");
    }

11305
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SECCOMP_SANDBOX)) {
11306
        if (cfg->seccompSandbox == 0)
11307
            virCommandAddArgList(cmd, "-sandbox", "off", NULL);
11308
        else if (cfg->seccompSandbox > 0)
11309
            virCommandAddArgList(cmd, "-sandbox", "on", NULL);
11310
    } else if (cfg->seccompSandbox > 0) {
11311 11312 11313 11314 11315
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("QEMU does not support seccomp sandboxes"));
        goto error;
    }

D
Dmitry Andreev 已提交
11316 11317
    for (i = 0; i < def->npanics; i++) {
        switch ((virDomainPanicModel) def->panics[i]->model) {
11318 11319 11320 11321 11322 11323 11324 11325 11326 11327
        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 已提交
11328
            if (def->panics[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
11329 11330 11331 11332 11333 11334 11335 11336
                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:
11337 11338 11339
            /* For pSeries guests, the firmware provides the same
             * functionality as the pvpanic device. The address
             * cannot be configured by the user */
11340 11341 11342 11343 11344 11345 11346
            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 已提交
11347
            if (def->panics[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
11348 11349
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("setting the panic device address is not "
11350
                                 "supported for model 'pseries'"));
11351 11352
                goto error;
            }
11353 11354 11355
            break;

        case VIR_DOMAIN_PANIC_MODEL_ISA:
11356 11357 11358 11359 11360 11361 11362
            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 已提交
11363
            switch (def->panics[i]->info.type) {
11364
            case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA:
H
Hu Tao 已提交
11365 11366
                virCommandAddArg(cmd, "-device");
                virCommandAddArgFormat(cmd, "pvpanic,ioport=%d",
D
Dmitry Andreev 已提交
11367
                                       def->panics[i]->info.addr.isa.iobase);
11368 11369 11370
                break;

            case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE:
H
Hu Tao 已提交
11371
                virCommandAddArgList(cmd, "-device", "pvpanic", NULL);
11372 11373 11374
                break;

            default:
11375 11376 11377 11378
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("panic is supported only "
                                 "with ISA address type"));
                goto error;
H
Hu Tao 已提交
11379
            }
11380 11381 11382 11383 11384

        /* 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 已提交
11385 11386 11387
        }
    }

11388 11389 11390 11391 11392
    for (i = 0; i < def->nshmems; i++) {
        if (qemuBuildShmemCommandLine(cmd, def, def->shmems[i], qemuCaps))
            goto error;
    }

11393 11394
    /* In some situations, eg. VFIO passthrough, QEMU might need to lock a
     * significant amount of memory, so we need to set the limit accordingly */
11395 11396
    if (qemuDomainRequiresMemLock(def))
        virCommandSetMaxMemLock(cmd, qemuDomainGetMemLockLimitBytes(def));
11397

11398 11399 11400 11401
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSG_TIMESTAMP) &&
        cfg->logTimestamp)
        virCommandAddArgList(cmd, "-msg", "timestamp=on", NULL);

11402
    virObjectUnref(cfg);
11403 11404
    return cmd;

11405
 error:
11406
    VIR_FREE(boot_order_str);
11407
    VIR_FREE(boot_opts_str);
J
Ján Tomko 已提交
11408
    virBufferFreeAndReset(&boot_buf);
11409
    virObjectUnref(cfg);
11410 11411 11412
    /* free up any resources in the network driver
     * but don't overwrite the original error */
    originalError = virSaveLastError();
11413
    for (i = 0; last_good_net != -1 && i <= last_good_net; i++)
11414
        virDomainConfNWFilterTeardown(def->nets[i]);
11415
    virSetError(originalError);
J
John Ferlan 已提交
11416
    virFreeError(originalError);
11417 11418 11419 11420
    virCommandFree(cmd);
    return NULL;
}

11421 11422 11423
/* This function generates the correct '-device' string for character
 * devices of each architecture.
 */
11424 11425
static int
qemuBuildSerialChrDeviceStr(char **deviceStr,
11426
                            virDomainDefPtr def,
11427 11428 11429 11430
                            virDomainChrDefPtr serial,
                            virQEMUCapsPtr qemuCaps,
                            virArch arch,
                            char *machine)
11431 11432 11433
{
    virBuffer cmd = VIR_BUFFER_INITIALIZER;

11434
    if (ARCH_IS_PPC64(arch) && STRPREFIX(machine, "pseries")) {
11435 11436 11437 11438
        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);
11439
            if (qemuBuildDeviceAddressStr(&cmd, def, &serial->info, qemuCaps) < 0)
11440 11441
                goto error;
        }
G
Guannan Ren 已提交
11442 11443 11444
    } else {
        virBufferAsprintf(&cmd, "%s,chardev=char%s,id=%s",
                          virDomainChrSerialTargetTypeToString(serial->targetType),
11445 11446
                          serial->info.alias, serial->info.alias);

11447 11448
        switch (serial->targetType) {
        case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB:
11449
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_SERIAL)) {
G
Guannan Ren 已提交
11450 11451 11452 11453 11454 11455 11456 11457 11458 11459 11460 11461
                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;
            }

11462
            if (qemuBuildDeviceAddressStr(&cmd, def, &serial->info, qemuCaps) < 0)
11463
                goto error;
11464 11465 11466
            break;

        case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_ISA:
11467 11468
            if (serial->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
                serial->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA) {
11469
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
11470
                               _("isa-serial requires address of isa type"));
11471 11472
                goto error;
            }
11473 11474 11475

            if (qemuBuildDeviceAddressStr(&cmd, def, &serial->info, qemuCaps) < 0)
                goto error;
11476
            break;
M
Michal Privoznik 已提交
11477 11478 11479 11480 11481 11482 11483 11484 11485 11486 11487 11488 11489 11490 11491 11492 11493 11494

        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 已提交
11495 11496 11497
        }
    }

11498
    if (virBufferCheckError(&cmd) < 0)
11499 11500
        goto error;

11501 11502
    *deviceStr = virBufferContentAndReset(&cmd);
    return 0;
11503

11504
 error:
11505
    virBufferFreeAndReset(&cmd);
11506 11507 11508 11509 11510 11511 11512 11513
    return -1;
}

static int
qemuBuildParallelChrDeviceStr(char **deviceStr,
                              virDomainChrDefPtr chr)
{
    if (virAsprintf(deviceStr, "isa-parallel,chardev=char%s,id=%s",
J
Ján Tomko 已提交
11514
                    chr->info.alias, chr->info.alias) < 0)
11515 11516
        return -1;
    return 0;
11517
}
11518

11519 11520
static int
qemuBuildChannelChrDeviceStr(char **deviceStr,
11521
                             virDomainDefPtr def,
11522 11523 11524 11525 11526 11527 11528
                             virDomainChrDefPtr chr,
                             virQEMUCapsPtr qemuCaps)
{
    int ret = -1;
    char *addr = NULL;
    int port;

11529
    switch ((virDomainChrChannelTargetType) chr->targetType) {
11530 11531 11532 11533 11534 11535 11536 11537
    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,
11538
                        "user,guestfwd=tcp:%s:%i-chardev:char%s,id=user-%s",
J
Ján Tomko 已提交
11539
                        addr, port, chr->info.alias, chr->info.alias) < 0)
11540 11541 11542 11543
            goto cleanup;
        break;

    case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO:
11544
        if (!(*deviceStr = qemuBuildVirtioSerialPortDevStr(def, chr, qemuCaps)))
11545
            goto cleanup;
11546 11547 11548 11549 11550 11551 11552 11553
        break;

    case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_NONE:
    case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST:
        return ret;
    }

    ret = 0;
11554
 cleanup:
11555 11556 11557 11558 11559 11560
    VIR_FREE(addr);
    return ret;
}

static int
qemuBuildConsoleChrDeviceStr(char **deviceStr,
11561
                             virDomainDefPtr def,
11562 11563 11564 11565 11566
                             virDomainChrDefPtr chr,
                             virQEMUCapsPtr qemuCaps)
{
    int ret = -1;

11567
    switch ((virDomainChrConsoleTargetType) chr->targetType) {
11568 11569 11570 11571 11572 11573 11574
    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:
11575
        if (!(*deviceStr = qemuBuildVirtioSerialPortDevStr(def, chr, qemuCaps)))
11576 11577 11578 11579
            goto cleanup;
        break;

    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL:
11580 11581
        break;

11582 11583 11584 11585 11586 11587
    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:
11588 11589 11590 11591
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unsupported console target type %s"),
                       NULLSTR(virDomainChrConsoleTargetTypeToString(chr->targetType)));
        goto cleanup;
11592 11593 11594
    }

    ret = 0;
11595
 cleanup:
11596 11597 11598 11599 11600 11601 11602 11603 11604 11605 11606
    return ret;
}

int
qemuBuildChrDeviceStr(char **deviceStr,
                      virDomainDefPtr vmdef,
                      virDomainChrDefPtr chr,
                      virQEMUCapsPtr qemuCaps)
{
    int ret = -1;

11607
    switch ((virDomainChrDeviceType) chr->deviceType) {
11608
    case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL:
11609
        ret = qemuBuildSerialChrDeviceStr(deviceStr, vmdef, chr, qemuCaps,
11610 11611 11612 11613 11614 11615 11616 11617 11618
                                          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:
11619
        ret = qemuBuildChannelChrDeviceStr(deviceStr, vmdef, chr, qemuCaps);
11620 11621 11622
        break;

    case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE:
11623
        ret = qemuBuildConsoleChrDeviceStr(deviceStr, vmdef, chr, qemuCaps);
11624 11625 11626 11627 11628 11629 11630 11631 11632 11633
        break;

    case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST:
        return ret;
    }

    return ret;
}


11634 11635 11636 11637 11638 11639 11640
/*
 * 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 已提交
11641 11642
                               char ***retenv,
                               char ***retargv)
11643 11644
{
    char **arglist = NULL;
11645 11646 11647
    size_t argcount = 0;
    size_t argalloc = 0;
    size_t envend;
11648
    size_t i;
11649 11650
    const char *curr = args;
    const char *start;
E
Eric Blake 已提交
11651 11652
    char **progenv = NULL;
    char **progargv = NULL;
11653 11654 11655 11656 11657 11658 11659 11660

    /* Iterate over string, splitting on sequences of ' ' */
    while (curr && *curr != '\0') {
        char *arg;
        const char *next;

        start = curr;
        /* accept a space in CEPH_ARGS */
11661
        if (STRPREFIX(curr, "CEPH_ARGS=-m "))
11662 11663 11664 11665 11666 11667 11668 11669 11670 11671 11672 11673 11674 11675 11676
            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');

11677
        if (VIR_STRNDUP(arg, curr, next ? next - curr : -1) < 0)
11678
            goto error;
11679

11680 11681
        if (next && (*next == '\'' || *next == '"'))
            next++;
11682

11683 11684 11685
        if (VIR_RESIZE_N(arglist, argalloc, argcount, 2) < 0) {
            VIR_FREE(arg);
            goto error;
11686 11687 11688
        }

        arglist[argcount++] = arg;
11689
        arglist[argcount] = NULL;
11690 11691 11692 11693 11694 11695 11696 11697 11698

        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) */
11699
    for (envend = 0; ((envend < argcount) &&
11700 11701 11702 11703 11704 11705 11706
                       (strchr(arglist[envend], '=') != NULL));
         envend++)
        ; /* nada */

    /* Copy the list of env vars */
    if (envend > 0) {
        if (VIR_REALLOC_N(progenv, envend+1) < 0)
11707
            goto error;
11708
        for (i = 0; i < envend; i++)
11709 11710 11711 11712 11713 11714
            progenv[i] = arglist[i];
        progenv[i] = NULL;
    }

    /* Copy the list of argv */
    if (VIR_REALLOC_N(progargv, argcount-envend + 1) < 0)
11715
        goto error;
11716
    for (i = envend; i < argcount; i++)
11717 11718 11719 11720 11721 11722 11723 11724 11725 11726
        progargv[i-envend] = arglist[i];
    progargv[i-envend] = NULL;

    VIR_FREE(arglist);

    *retenv = progenv;
    *retargv = progargv;

    return 0;

11727
 error:
11728 11729
    VIR_FREE(progenv);
    VIR_FREE(progargv);
E
Eric Blake 已提交
11730
    virStringFreeList(arglist);
11731 11732 11733 11734 11735 11736 11737
    return -1;
}


/*
 * Search for a named env variable, and return the value part
 */
E
Eric Blake 已提交
11738
static const char *qemuFindEnv(char **progenv,
11739 11740
                               const char *name)
{
11741
    size_t i;
11742 11743
    int len = strlen(name);

11744
    for (i = 0; progenv && progenv[i]; i++) {
11745 11746 11747 11748 11749 11750 11751 11752 11753 11754 11755 11756 11757 11758 11759 11760 11761 11762
        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,
11763
                  int *retnkeywords,
11764 11765 11766 11767 11768 11769 11770 11771
                  int allowEmptyValue)
{
    int keywordCount = 0;
    int keywordAlloc = 0;
    char **keywords = NULL;
    char **values = NULL;
    const char *start = str;
    const char *end;
11772
    size_t i;
11773 11774 11775

    *retkeywords = NULL;
    *retvalues = NULL;
11776
    *retnkeywords = 0;
11777 11778 11779 11780 11781 11782 11783 11784
    end = start + strlen(str);

    while (start) {
        const char *separator;
        const char *endmark;
        char *keyword;
        char *value = NULL;

11785 11786 11787 11788 11789 11790 11791 11792
        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)
11793 11794 11795 11796 11797 11798
            endmark = end;
        if (!(separator = strchr(start, '=')))
            separator = end;

        if (separator >= endmark) {
            if (!allowEmptyValue) {
11799 11800
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("malformed keyword arguments in '%s'"), str);
11801 11802 11803 11804 11805
                goto error;
            }
            separator = endmark;
        }

11806 11807
        if (VIR_STRNDUP(keyword, start, separator - start) < 0)
            goto error;
11808 11809 11810

        if (separator < endmark) {
            separator++;
11811
            if (VIR_STRNDUP(value, separator, endmark - separator) < 0) {
11812
                VIR_FREE(keyword);
11813
                goto error;
11814
            }
11815 11816 11817 11818 11819 11820 11821 11822 11823 11824
            if (strchr(value, ',')) {
                char *p = strchr(value, ',') + 1;
                char *q = p + 1;
                while (*q) {
                    if (*q == ',')
                        q++;
                    *p++ = *q++;
                }
                *p = '\0';
            }
11825 11826 11827 11828 11829 11830 11831
        }

        if (keywordAlloc == keywordCount) {
            if (VIR_REALLOC_N(keywords, keywordAlloc + 10) < 0 ||
                VIR_REALLOC_N(values, keywordAlloc + 10) < 0) {
                VIR_FREE(keyword);
                VIR_FREE(value);
11832
                goto error;
11833 11834 11835 11836 11837 11838 11839 11840 11841 11842 11843 11844 11845
            }
            keywordAlloc += 10;
        }

        keywords[keywordCount] = keyword;
        values[keywordCount] = value;
        keywordCount++;

        start = endmark < end ? endmark + 1 : NULL;
    }

    *retkeywords = keywords;
    *retvalues = values;
11846 11847
    *retnkeywords = keywordCount;
    return 0;
11848

11849
 error:
11850
    for (i = 0; i < keywordCount; i++) {
11851 11852 11853 11854 11855 11856 11857 11858 11859 11860 11861 11862 11863 11864 11865 11866
        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
11867
qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt,
11868
                         const char *val,
11869
                         virDomainDefPtr dom,
11870 11871
                         int nvirtiodisk,
                         bool old_style_ceph_args)
11872 11873 11874 11875 11876
{
    virDomainDiskDefPtr def = NULL;
    char **keywords;
    char **values;
    int nkeywords;
11877
    size_t i;
11878 11879 11880 11881
    int idx = -1;
    int busid = -1;
    int unitid = -1;

11882 11883 11884 11885 11886
    if (qemuParseKeywords(val,
                          &keywords,
                          &values,
                          &nkeywords,
                          0) < 0)
11887 11888
        return NULL;

11889
    if (VIR_ALLOC(def) < 0)
11890
        goto cleanup;
11891 11892
    if (VIR_ALLOC(def->src) < 0)
        goto error;
11893

11894
    if ((ARCH_IS_PPC64(dom->os.arch) &&
11895
        dom->os.machine && STRPREFIX(dom->os.machine, "pseries")))
11896 11897 11898
        def->bus = VIR_DOMAIN_DISK_BUS_SCSI;
    else
       def->bus = VIR_DOMAIN_DISK_BUS_IDE;
11899
    def->device = VIR_DOMAIN_DISK_DEVICE_DISK;
11900
    def->src->type = VIR_STORAGE_TYPE_FILE;
11901

11902
    for (i = 0; i < nkeywords; i++) {
11903 11904
        if (STREQ(keywords[i], "file")) {
            if (values[i] && STRNEQ(values[i], "")) {
11905
                def->src->path = values[i];
11906
                values[i] = NULL;
11907 11908 11909 11910 11911 11912
                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;
11913

11914 11915
                    if (qemuParseNBDString(def) < 0)
                        goto error;
11916 11917
                } else if (STRPREFIX(def->src->path, "rbd:")) {
                    char *p = def->src->path;
11918

11919 11920 11921
                    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)
11922
                        goto error;
11923
                    /* old-style CEPH_ARGS env variable is parsed later */
11924 11925 11926 11927
                    if (!old_style_ceph_args && qemuParseRBDString(def) < 0) {
                        VIR_FREE(p);
                        goto error;
                    }
11928 11929

                    VIR_FREE(p);
11930 11931 11932 11933
                } 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;
11934 11935

                    if (qemuParseGlusterString(def) < 0)
11936
                        goto error;
11937 11938 11939
                } 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 已提交
11940 11941 11942

                    if (qemuParseISCSIString(def) < 0)
                        goto error;
11943 11944
                } else if (STRPREFIX(def->src->path, "sheepdog:")) {
                    char *p = def->src->path;
11945 11946
                    char *port, *vdi;

11947 11948 11949
                    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)
11950
                        goto error;
11951
                    VIR_FREE(p);
11952

11953 11954
                    /* def->src->path must be [vdiname] or [host]:[port]:[vdiname] */
                    port = strchr(def->src->path, ':');
11955
                    if (port) {
11956 11957
                        *port = '\0';
                        vdi = strchr(port + 1, ':');
11958
                        if (!vdi) {
11959
                            *port = ':';
11960
                            virReportError(VIR_ERR_INTERNAL_ERROR,
11961
                                           _("cannot parse sheepdog filename '%s'"),
11962
                                           def->src->path);
11963
                            goto error;
11964
                        }
11965
                        port++;
11966
                        *vdi++ = '\0';
11967
                        if (VIR_ALLOC(def->src->hosts) < 0)
11968
                            goto error;
11969 11970 11971
                        def->src->nhosts = 1;
                        def->src->hosts->name = def->src->path;
                        if (VIR_STRDUP(def->src->hosts->port, port) < 0)
11972
                            goto error;
11973 11974 11975
                        def->src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
                        def->src->hosts->socket = NULL;
                        if (VIR_STRDUP(def->src->path, vdi) < 0)
11976
                            goto error;
11977
                    }
11978
                } else {
11979
                    def->src->type = VIR_STORAGE_TYPE_FILE;
11980
                }
11981
            } else {
11982
                def->src->type = VIR_STORAGE_TYPE_FILE;
11983 11984
            }
        } else if (STREQ(keywords[i], "if")) {
11985
            if (STREQ(values[i], "ide")) {
11986
                def->bus = VIR_DOMAIN_DISK_BUS_IDE;
11987
                if ((ARCH_IS_PPC64(dom->os.arch) &&
11988
                     dom->os.machine && STRPREFIX(dom->os.machine, "pseries"))) {
11989 11990 11991 11992
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("pseries systems do not support ide devices '%s'"), val);
                    goto error;
                }
11993
            } else if (STREQ(values[i], "scsi")) {
11994
                def->bus = VIR_DOMAIN_DISK_BUS_SCSI;
11995 11996 11997
            } else if (STREQ(values[i], "floppy")) {
                def->bus = VIR_DOMAIN_DISK_BUS_FDC;
                def->device = VIR_DOMAIN_DISK_DEVICE_FLOPPY;
11998
            } else if (STREQ(values[i], "virtio")) {
11999
                def->bus = VIR_DOMAIN_DISK_BUS_VIRTIO;
12000
            } else if (STREQ(values[i], "xen")) {
12001
                def->bus = VIR_DOMAIN_DISK_BUS_XEN;
12002
            } else if (STREQ(values[i], "sd")) {
12003
                def->bus = VIR_DOMAIN_DISK_BUS_SD;
12004
            }
12005 12006 12007
        } else if (STREQ(keywords[i], "media")) {
            if (STREQ(values[i], "cdrom")) {
                def->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
12008
                def->src->readonly = true;
12009
            } else if (STREQ(values[i], "floppy")) {
12010
                def->device = VIR_DOMAIN_DISK_DEVICE_FLOPPY;
12011
            }
12012
        } else if (STREQ(keywords[i], "format")) {
12013
            if (VIR_STRDUP(def->src->driverName, "qemu") < 0)
12014
                goto error;
12015
            def->src->format = virStorageFileFormatTypeFromString(values[i]);
12016 12017 12018 12019 12020 12021 12022 12023 12024
        } 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;
12025 12026
            else if (STREQ(values[i], "directsync"))
                def->cachemode = VIR_DOMAIN_DISK_CACHE_DIRECTSYNC;
12027 12028
            else if (STREQ(values[i], "unsafe"))
                def->cachemode = VIR_DOMAIN_DISK_CACHE_UNSAFE;
12029
        } else if (STREQ(keywords[i], "werror")) {
12030 12031
            if (STREQ(values[i], "stop"))
                def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_STOP;
12032 12033
            else if (STREQ(values[i], "report"))
                def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_REPORT;
12034 12035
            else if (STREQ(values[i], "ignore"))
                def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_IGNORE;
12036
            else if (STREQ(values[i], "enospc"))
12037
                def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_ENOSPACE;
12038 12039 12040 12041 12042 12043 12044
        } 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;
12045 12046
        } else if (STREQ(keywords[i], "index")) {
            if (virStrToLong_i(values[i], NULL, 10, &idx) < 0) {
12047 12048
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse drive index '%s'"), val);
12049
                goto error;
12050 12051 12052
            }
        } else if (STREQ(keywords[i], "bus")) {
            if (virStrToLong_i(values[i], NULL, 10, &busid) < 0) {
12053 12054
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse drive bus '%s'"), val);
12055
                goto error;
12056 12057 12058
            }
        } else if (STREQ(keywords[i], "unit")) {
            if (virStrToLong_i(values[i], NULL, 10, &unitid) < 0) {
12059 12060
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse drive unit '%s'"), val);
12061
                goto error;
12062 12063 12064
            }
        } else if (STREQ(keywords[i], "readonly")) {
            if ((values[i] == NULL) || STREQ(values[i], "on"))
12065
                def->src->readonly = true;
E
Eric Blake 已提交
12066 12067
        } else if (STREQ(keywords[i], "aio")) {
            if ((def->iomode = virDomainDiskIoTypeFromString(values[i])) < 0) {
12068 12069
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse io mode '%s'"), values[i]);
12070
                goto error;
E
Eric Blake 已提交
12071
            }
12072 12073 12074 12075 12076 12077 12078 12079
        } 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]);
12080
                goto error;
12081 12082 12083 12084 12085 12086 12087 12088 12089
            }
        } 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]);
12090
                goto error;
12091 12092 12093 12094 12095 12096 12097 12098 12099
            }
        } 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]);
12100
                goto error;
12101 12102 12103 12104
            }
        } else if (STREQ(keywords[i], "trans")) {
            def->geometry.trans =
                virDomainDiskGeometryTransTypeFromString(values[i]);
12105 12106
            if ((def->geometry.trans < VIR_DOMAIN_DISK_TRANS_DEFAULT) ||
                (def->geometry.trans >= VIR_DOMAIN_DISK_TRANS_LAST)) {
12107 12108 12109
                virDomainDiskDefFree(def);
                def = NULL;
                virReportError(VIR_ERR_INTERNAL_ERROR,
12110
                               _("cannot parse translation value '%s'"),
12111
                               values[i]);
12112
                goto error;
12113
            }
12114 12115 12116
        }
    }

12117 12118 12119
    if (def->rerror_policy == def->error_policy)
        def->rerror_policy = 0;

12120
    if (!def->src->path &&
12121
        def->device == VIR_DOMAIN_DISK_DEVICE_DISK &&
12122
        def->src->type != VIR_STORAGE_TYPE_NETWORK) {
12123 12124
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("missing file parameter in drive '%s'"), val);
12125
        goto error;
12126 12127 12128 12129 12130 12131 12132 12133
    }
    if (idx == -1 &&
        def->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
        idx = nvirtiodisk;

    if (idx == -1 &&
        unitid == -1 &&
        busid == -1) {
12134
        virReportError(VIR_ERR_INTERNAL_ERROR,
12135 12136 12137
                       _("missing index/unit/bus parameter in drive '%s'"),
                       val);
        goto error;
12138 12139 12140 12141 12142 12143 12144 12145 12146 12147 12148 12149 12150 12151 12152 12153 12154 12155 12156 12157 12158
    }

    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) {
12159
        ignore_value(VIR_STRDUP(def->dst, "hda"));
12160 12161
    } else if (def->bus == VIR_DOMAIN_DISK_BUS_SCSI ||
               def->bus == VIR_DOMAIN_DISK_BUS_SD) {
12162
        ignore_value(VIR_STRDUP(def->dst, "sda"));
12163
    } else if (def->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
12164
        ignore_value(VIR_STRDUP(def->dst, "vda"));
12165
    } else if (def->bus == VIR_DOMAIN_DISK_BUS_XEN) {
12166
        ignore_value(VIR_STRDUP(def->dst, "xvda"));
12167 12168
    } else if (def->bus == VIR_DOMAIN_DISK_BUS_FDC) {
        ignore_value(VIR_STRDUP(def->dst, "fda"));
12169
    } else {
12170
        ignore_value(VIR_STRDUP(def->dst, "hda"));
12171 12172
    }

12173
    if (!def->dst)
12174
        goto error;
12175 12176 12177 12178 12179
    if (STREQ(def->dst, "xvda"))
        def->dst[3] = 'a' + idx;
    else
        def->dst[2] = 'a' + idx;

12180
    if (virDomainDiskDefAssignAddress(xmlopt, def, dom) < 0) {
12181 12182
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("invalid device name '%s'"), def->dst);
12183 12184
        virDomainDiskDefFree(def);
        def = NULL;
12185
        goto cleanup;
12186 12187
    }

12188
 cleanup:
12189
    for (i = 0; i < nkeywords; i++) {
12190 12191 12192 12193 12194 12195
        VIR_FREE(keywords[i]);
        VIR_FREE(values[i]);
    }
    VIR_FREE(keywords);
    VIR_FREE(values);
    return def;
12196

12197
 error:
12198 12199 12200
    virDomainDiskDefFree(def);
    def = NULL;
    goto cleanup;
12201 12202 12203 12204 12205 12206 12207 12208 12209 12210
}

/*
 * Tries to find a NIC definition matching a vlan we want
 */
static const char *
qemuFindNICForVLAN(int nnics,
                   const char **nics,
                   int wantvlan)
{
12211
    size_t i;
12212
    for (i = 0; i < nnics; i++) {
12213 12214 12215 12216 12217 12218 12219 12220 12221
        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) {
12222 12223
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot parse NIC vlan in '%s'"), nics[i]);
12224 12225 12226 12227 12228 12229 12230 12231 12232 12233
            return NULL;
        }

        if (gotvlan == wantvlan)
            return nics[i];
    }

    if (wantvlan == 0 && nnics > 0)
        return nics[0];

12234 12235
    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("cannot find NIC definition for vlan %d"), wantvlan);
12236 12237 12238 12239 12240 12241 12242 12243 12244 12245
    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
12246
qemuParseCommandLineNet(virDomainXMLOptionPtr xmlopt,
12247 12248 12249 12250 12251 12252 12253 12254 12255 12256 12257
                        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;
12258
    bool genmac = true;
12259
    size_t i;
12260 12261 12262 12263

    tmp = strchr(val, ',');

    if (tmp) {
12264 12265 12266 12267 12268
        if (qemuParseKeywords(tmp+1,
                              &keywords,
                              &values,
                              &nkeywords,
                              0) < 0)
12269 12270 12271 12272 12273
            return NULL;
    } else {
        nkeywords = 0;
    }

12274
    if (VIR_ALLOC(def) < 0)
12275 12276 12277 12278 12279 12280 12281 12282 12283 12284 12285 12286 12287
        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;

12288
    for (i = 0; i < nkeywords; i++) {
12289 12290
        if (STREQ(keywords[i], "vlan")) {
            if (virStrToLong_i(values[i], NULL, 10, &wantvlan) < 0) {
12291 12292
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse vlan in '%s'"), val);
12293 12294 12295 12296 12297 12298
                virDomainNetDefFree(def);
                def = NULL;
                goto cleanup;
            }
        } else if (def->type == VIR_DOMAIN_NET_TYPE_ETHERNET &&
                   STREQ(keywords[i], "script") && STRNEQ(values[i], "")) {
12299
            def->script = values[i];
12300 12301 12302 12303 12304 12305 12306 12307 12308 12309 12310 12311 12312 12313 12314 12315 12316 12317 12318 12319 12320
            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")) {
12321 12322
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot parse NIC definition '%s'"), nic);
12323 12324 12325 12326 12327
        virDomainNetDefFree(def);
        def = NULL;
        goto cleanup;
    }

12328
    for (i = 0; i < nkeywords; i++) {
12329 12330 12331 12332 12333 12334 12335
        VIR_FREE(keywords[i]);
        VIR_FREE(values[i]);
    }
    VIR_FREE(keywords);
    VIR_FREE(values);

    if (STRPREFIX(nic, "nic,")) {
12336 12337 12338 12339 12340
        if (qemuParseKeywords(nic + strlen("nic,"),
                              &keywords,
                              &values,
                              &nkeywords,
                              0) < 0) {
12341 12342 12343 12344 12345 12346 12347 12348
            virDomainNetDefFree(def);
            def = NULL;
            goto cleanup;
        }
    } else {
        nkeywords = 0;
    }

12349
    for (i = 0; i < nkeywords; i++) {
12350
        if (STREQ(keywords[i], "macaddr")) {
12351
            genmac = false;
12352
            if (virMacAddrParse(values[i], &def->mac) < 0) {
12353 12354 12355
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("unable to parse mac address '%s'"),
                               values[i]);
12356 12357 12358 12359 12360 12361 12362
                virDomainNetDefFree(def);
                def = NULL;
                goto cleanup;
            }
        } else if (STREQ(keywords[i], "model")) {
            def->model = values[i];
            values[i] = NULL;
12363 12364
        } else if (STREQ(keywords[i], "vhost")) {
            if ((values[i] == NULL) || STREQ(values[i], "on")) {
12365
                def->driver.virtio.name = VIR_DOMAIN_NET_BACKEND_TYPE_VHOST;
12366
            } else if (STREQ(keywords[i], "off")) {
12367
                def->driver.virtio.name = VIR_DOMAIN_NET_BACKEND_TYPE_QEMU;
12368
            }
12369 12370
        } else if (STREQ(keywords[i], "sndbuf") && values[i]) {
            if (virStrToLong_ul(values[i], NULL, 10, &def->tune.sndbuf) < 0) {
12371 12372
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse sndbuf size in '%s'"), val);
12373 12374 12375 12376 12377
                virDomainNetDefFree(def);
                def = NULL;
                goto cleanup;
            }
            def->tune.sndbuf_specified = true;
12378 12379 12380 12381
        }
    }

    if (genmac)
12382
        virDomainNetGenerateMAC(xmlopt, &def->mac);
12383

12384
 cleanup:
12385
    for (i = 0; i < nkeywords; i++) {
12386 12387 12388 12389 12390 12391 12392 12393 12394 12395 12396 12397 12398 12399 12400 12401 12402 12403
        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;
12404 12405 12406
    virDomainHostdevDefPtr def = virDomainHostdevDefAlloc();

    if (!def)
12407
        goto error;
12408 12409

    if (!STRPREFIX(val, "host=")) {
12410 12411
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown PCI device syntax '%s'"), val);
12412
        goto error;
12413 12414 12415 12416
    }

    start = val + strlen("host=");
    if (virStrToLong_i(start, &end, 16, &bus) < 0 || *end != ':') {
12417 12418
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot extract PCI device bus '%s'"), val);
12419
        goto error;
12420 12421 12422
    }
    start = end + 1;
    if (virStrToLong_i(start, &end, 16, &slot) < 0 || *end != '.') {
12423 12424
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot extract PCI device slot '%s'"), val);
12425
        goto error;
12426 12427 12428
    }
    start = end + 1;
    if (virStrToLong_i(start, NULL, 16, &func) < 0) {
12429 12430
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot extract PCI device function '%s'"), val);
12431
        goto error;
12432 12433 12434
    }

    def->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
12435
    def->managed = true;
12436
    def->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
12437 12438 12439
    def->source.subsys.u.pci.addr.bus = bus;
    def->source.subsys.u.pci.addr.slot = slot;
    def->source.subsys.u.pci.addr.function = func;
12440
    return def;
12441 12442 12443 12444

 error:
    virDomainHostdevDefFree(def);
    return NULL;
12445 12446 12447 12448 12449 12450 12451 12452 12453
}


/*
 * Tries to parse a QEMU USB device
 */
static virDomainHostdevDefPtr
qemuParseCommandLineUSB(const char *val)
{
12454
    virDomainHostdevDefPtr def = virDomainHostdevDefAlloc();
12455
    virDomainHostdevSubsysUSBPtr usbsrc;
12456 12457 12458 12459
    int first = 0, second = 0;
    const char *start;
    char *end;

12460
    if (!def)
12461
        goto error;
12462
    usbsrc = &def->source.subsys.u.usb;
12463

12464
    if (!STRPREFIX(val, "host:")) {
12465 12466
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown USB device syntax '%s'"), val);
12467
        goto error;
12468 12469 12470 12471 12472
    }

    start = val + strlen("host:");
    if (strchr(start, ':')) {
        if (virStrToLong_i(start, &end, 16, &first) < 0 || *end != ':') {
12473 12474
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot extract USB device vendor '%s'"), val);
12475
            goto error;
12476 12477 12478
        }
        start = end + 1;
        if (virStrToLong_i(start, NULL, 16, &second) < 0) {
12479 12480
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot extract USB device product '%s'"), val);
12481
            goto error;
12482 12483 12484
        }
    } else {
        if (virStrToLong_i(start, &end, 10, &first) < 0 || *end != '.') {
12485 12486
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot extract USB device bus '%s'"), val);
12487
            goto error;
12488 12489 12490
        }
        start = end + 1;
        if (virStrToLong_i(start, NULL, 10, &second) < 0) {
12491 12492
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot extract USB device address '%s'"), val);
12493
            goto error;
12494 12495 12496 12497
        }
    }

    def->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
12498
    def->managed = false;
12499 12500
    def->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB;
    if (*end == '.') {
12501 12502
        usbsrc->bus = first;
        usbsrc->device = second;
12503
    } else {
12504 12505
        usbsrc->vendor = first;
        usbsrc->product = second;
12506 12507
    }
    return def;
12508 12509 12510 12511

 error:
    virDomainHostdevDefFree(def);
    return NULL;
12512 12513 12514 12515 12516 12517
}


/*
 * Tries to parse a QEMU serial/parallel device
 */
12518 12519 12520
static int
qemuParseCommandLineChr(virDomainChrSourceDefPtr source,
                        const char *val)
12521 12522
{
    if (STREQ(val, "null")) {
12523
        source->type = VIR_DOMAIN_CHR_TYPE_NULL;
12524
    } else if (STREQ(val, "vc")) {
12525
        source->type = VIR_DOMAIN_CHR_TYPE_VC;
12526
    } else if (STREQ(val, "pty")) {
12527
        source->type = VIR_DOMAIN_CHR_TYPE_PTY;
12528
    } else if (STRPREFIX(val, "file:")) {
12529
        source->type = VIR_DOMAIN_CHR_TYPE_FILE;
12530 12531
        if (VIR_STRDUP(source->data.file.path, val + strlen("file:")) < 0)
            goto error;
12532
    } else if (STRPREFIX(val, "pipe:")) {
12533
        source->type = VIR_DOMAIN_CHR_TYPE_PIPE;
12534 12535
        if (VIR_STRDUP(source->data.file.path, val + strlen("pipe:")) < 0)
            goto error;
12536
    } else if (STREQ(val, "stdio")) {
12537
        source->type = VIR_DOMAIN_CHR_TYPE_STDIO;
12538 12539
    } else if (STRPREFIX(val, "udp:")) {
        const char *svc1, *host2, *svc2;
12540
        source->type = VIR_DOMAIN_CHR_TYPE_UDP;
12541 12542 12543 12544 12545
        val += strlen("udp:");
        svc1 = strchr(val, ':');
        host2 = svc1 ? strchr(svc1, '@') : NULL;
        svc2 = host2 ? strchr(host2, ':') : NULL;

12546 12547 12548
        if (svc1 && svc1 != val &&
            VIR_STRNDUP(source->data.udp.connectHost, val, svc1 - val) < 0)
            goto error;
12549 12550 12551

        if (svc1) {
            svc1++;
12552 12553 12554
            if (VIR_STRNDUP(source->data.udp.connectService, svc1,
                            host2 ? host2 - svc1 : strlen(svc1)) < 0)
                goto error;
12555 12556 12557 12558
        }

        if (host2) {
            host2++;
12559 12560
            if (svc2 && svc2 != host2 &&
                VIR_STRNDUP(source->data.udp.bindHost, host2, svc2 - host2) < 0)
12561
                goto error;
12562
        }
12563

12564 12565
        if (svc2) {
            svc2++;
12566
            if (STRNEQ(svc2, "0")) {
12567 12568
                if (VIR_STRDUP(source->data.udp.bindService, svc2) < 0)
                    goto error;
12569
            }
12570 12571 12572 12573
        }
    } else if (STRPREFIX(val, "tcp:") ||
               STRPREFIX(val, "telnet:")) {
        const char *opt, *svc;
12574
        source->type = VIR_DOMAIN_CHR_TYPE_TCP;
12575 12576 12577 12578
        if (STRPREFIX(val, "tcp:")) {
            val += strlen("tcp:");
        } else {
            val += strlen("telnet:");
12579
            source->data.tcp.protocol = VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET;
12580 12581 12582
        }
        svc = strchr(val, ':');
        if (!svc) {
12583 12584
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot find port number in character device %s"), val);
12585 12586 12587 12588
            goto error;
        }
        opt = strchr(svc, ',');
        if (opt && strstr(opt, "server"))
12589
            source->data.tcp.listen = true;
12590

12591 12592
        if (VIR_STRNDUP(source->data.tcp.host, val, svc - val) < 0)
            goto error;
12593
        svc++;
12594
        if (VIR_STRNDUP(source->data.tcp.service, svc, opt ? opt - svc : -1) < 0)
12595
            goto error;
12596 12597 12598 12599
    } else if (STRPREFIX(val, "unix:")) {
        const char *opt;
        val += strlen("unix:");
        opt = strchr(val, ',');
12600
        source->type = VIR_DOMAIN_CHR_TYPE_UNIX;
12601
        if (VIR_STRNDUP(source->data.nix.path, val, opt ? opt - val : -1) < 0)
12602
            goto error;
12603 12604

    } else if (STRPREFIX(val, "/dev")) {
12605
        source->type = VIR_DOMAIN_CHR_TYPE_DEV;
12606 12607
        if (VIR_STRDUP(source->data.file.path, val) < 0)
            goto error;
12608
    } else {
12609 12610
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown character device syntax %s"), val);
12611 12612 12613
        goto error;
    }

12614
    return 0;
12615

12616
 error:
12617
    return -1;
12618 12619 12620 12621 12622 12623 12624 12625 12626
}


static virCPUDefPtr
qemuInitGuestCPU(virDomainDefPtr dom)
{
    if (!dom->cpu) {
        virCPUDefPtr cpu;

12627
        if (VIR_ALLOC(cpu) < 0)
12628 12629 12630 12631 12632 12633 12634 12635 12636 12637 12638 12639 12640 12641 12642
            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)
{
12643
    virCPUDefPtr cpu = NULL;
12644
    char **tokens;
12645
    char **hv_tokens = NULL;
12646
    char *model = NULL;
12647
    int ret = -1;
12648
    size_t i;
12649

12650 12651
    if (!(tokens = virStringSplit(val, ",", 0)))
        goto cleanup;
12652

12653 12654
    if (tokens[0] == NULL)
        goto syntax;
12655

12656 12657 12658 12659 12660 12661 12662
    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;
12663

12664
            if (STRNEQ(model, "qemu32") && STRNEQ(model, "qemu64")) {
12665
                if (!(cpu = qemuInitGuestCPU(dom)))
12666
                    goto cleanup;
12667 12668 12669 12670

                cpu->model = model;
                model = NULL;
            }
12671 12672
        } else if (*tokens[i] == '+' || *tokens[i] == '-') {
            const char *feature = tokens[i] + 1; /* '+' or '-' */
12673 12674
            int policy;

12675
            if (*tokens[i] == '+')
12676 12677 12678 12679
                policy = VIR_CPU_FEATURE_REQUIRE;
            else
                policy = VIR_CPU_FEATURE_DISABLE;

12680
            if (*feature == '\0')
12681 12682
                goto syntax;

12683 12684 12685 12686 12687 12688 12689 12690
            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;
             }

12691 12692
            if (STREQ(feature, "kvmclock")) {
                bool present = (policy == VIR_CPU_FEATURE_REQUIRE);
12693
                size_t j;
12694

12695 12696
                for (j = 0; j < dom->clock.ntimers; j++) {
                    if (dom->clock.timers[j]->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK)
12697 12698 12699
                        break;
                }

12700
                if (j == dom->clock.ntimers) {
12701 12702 12703 12704 12705
                    virDomainTimerDefPtr timer;
                    if (VIR_ALLOC(timer) < 0 ||
                        VIR_APPEND_ELEMENT_COPY(dom->clock.timers,
                                                dom->clock.ntimers, timer) < 0) {
                        VIR_FREE(timer);
12706
                        goto cleanup;
12707 12708 12709 12710 12711 12712
                    }
                    timer->name = VIR_DOMAIN_TIMER_NAME_KVMCLOCK;
                    timer->present = present;
                    timer->tickpolicy = -1;
                    timer->track = -1;
                    timer->mode = -1;
12713 12714
                } else if (dom->clock.timers[j]->present != -1 &&
                    dom->clock.timers[j]->present != present) {
12715 12716
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("conflicting occurrences of kvmclock feature"));
12717
                    goto cleanup;
12718
                }
12719 12720
            } else if (STREQ(feature, "kvm_pv_eoi")) {
                if (policy == VIR_CPU_FEATURE_REQUIRE)
J
Ján Tomko 已提交
12721
                    dom->apic_eoi = VIR_TRISTATE_SWITCH_ON;
12722
                else
J
Ján Tomko 已提交
12723
                    dom->apic_eoi = VIR_TRISTATE_SWITCH_OFF;
12724 12725 12726
            } else {
                if (!cpu) {
                    if (!(cpu = qemuInitGuestCPU(dom)))
12727
                        goto cleanup;
12728

12729 12730 12731 12732
                    cpu->model = model;
                    model = NULL;
                }

12733 12734
                if (virCPUDefAddFeature(cpu, feature, policy) < 0)
                    goto cleanup;
12735
            }
12736
        } else if (STREQ(tokens[i], "hv_crash")) {
D
Dmitry Andreev 已提交
12737 12738 12739 12740 12741 12742 12743 12744 12745 12746 12747 12748 12749 12750 12751 12752
            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;
            }
12753
        } else if (STRPREFIX(tokens[i], "hv_")) {
12754 12755
            const char *token = tokens[i] + 3; /* "hv_" */
            const char *feature, *value;
12756 12757
            int f;

12758 12759 12760 12761 12762 12763 12764 12765 12766
            if (*token == '\0')
                goto syntax;

            if (!(hv_tokens = virStringSplit(token, "=", 2)))
                goto cleanup;

            feature = hv_tokens[0];
            value = hv_tokens[1];

12767
            if (*feature == '\0')
12768 12769
                goto syntax;

J
Ján Tomko 已提交
12770
            dom->features[VIR_DOMAIN_FEATURE_HYPERV] = VIR_TRISTATE_SWITCH_ON;
12771 12772 12773 12774 12775

            if ((f = virDomainHypervTypeFromString(feature)) < 0) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("unsupported HyperV Enlightenment feature "
                                 "'%s'"), feature);
12776
                goto cleanup;
12777 12778
            }

12779
            switch ((virDomainHyperv) f) {
12780
            case VIR_DOMAIN_HYPERV_RELAXED:
12781 12782 12783 12784 12785 12786 12787
            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 已提交
12788
                dom->hyperv_features[f] = VIR_TRISTATE_SWITCH_ON;
12789 12790
                break;

12791
            case VIR_DOMAIN_HYPERV_SPINLOCKS:
J
Ján Tomko 已提交
12792
                dom->hyperv_features[f] = VIR_TRISTATE_SWITCH_ON;
12793 12794 12795 12796 12797 12798 12799 12800 12801 12802 12803 12804 12805 12806
                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;
12807 12808
                break;

12809 12810 12811
            case VIR_DOMAIN_HYPERV_LAST:
                break;
            }
12812 12813
            virStringFreeList(hv_tokens);
            hv_tokens = NULL;
12814 12815 12816
        } 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;
12817
        }
12818
    }
12819

12820
    if (dom->os.arch == VIR_ARCH_X86_64) {
12821
        bool is_32bit = false;
12822
        if (cpu) {
12823
            virCPUDataPtr cpuData = NULL;
12824

12825 12826 12827
            if (cpuEncode(VIR_ARCH_X86_64, cpu, NULL, &cpuData,
                          NULL, NULL, NULL, NULL) < 0)
                goto cleanup;
12828

J
Jiri Denemark 已提交
12829 12830
            is_32bit = (cpuHasFeature(cpuData, "lm") != 1);
            cpuDataFree(cpuData);
12831 12832 12833
        } else if (model) {
            is_32bit = STREQ(model, "qemu32");
        }
12834

12835
        if (is_32bit)
12836
            dom->os.arch = VIR_ARCH_I686;
12837
    }
12838 12839 12840

    ret = 0;

12841
 cleanup:
12842
    VIR_FREE(model);
12843
    virStringFreeList(tokens);
12844
    virStringFreeList(hv_tokens);
12845
    return ret;
12846

12847
 syntax:
12848 12849
    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("unknown CPU syntax '%s'"), val);
12850
    goto cleanup;
12851 12852 12853 12854 12855 12856 12857 12858 12859 12860 12861
}


static int
qemuParseCommandLineSmp(virDomainDefPtr dom,
                        const char *val)
{
    unsigned int sockets = 0;
    unsigned int cores = 0;
    unsigned int threads = 0;
    unsigned int maxcpus = 0;
12862
    unsigned int vcpus = 0;
12863
    size_t i;
12864 12865 12866 12867 12868 12869 12870
    int nkws;
    char **kws;
    char **vals;
    int n;
    char *end;
    int ret;

12871
    if (qemuParseKeywords(val, &kws, &vals, &nkws, 1) < 0)
12872 12873 12874 12875 12876
        return -1;

    for (i = 0; i < nkws; i++) {
        if (vals[i] == NULL) {
            if (i > 0 ||
12877
                virStrToLong_ui(kws[i], &end, 10, &vcpus) < 0 || *end != '\0')
12878 12879 12880 12881 12882 12883 12884 12885 12886 12887 12888 12889 12890 12891 12892 12893 12894
                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;
        }
    }

12895
    if (maxcpus == 0)
12896
        maxcpus = vcpus;
12897 12898 12899

    if (virDomainDefSetVcpusMax(dom, maxcpus) < 0)
        goto error;
12900

12901 12902 12903
    if (virDomainDefSetVcpus(dom, vcpus) < 0)
        goto error;

12904 12905 12906 12907 12908 12909 12910 12911
    if (sockets && cores && threads) {
        virCPUDefPtr cpu;

        if (!(cpu = qemuInitGuestCPU(dom)))
            goto error;
        cpu->sockets = sockets;
        cpu->cores = cores;
        cpu->threads = threads;
12912
    } else if (sockets || cores || threads) {
12913
        goto syntax;
12914
    }
12915 12916 12917

    ret = 0;

12918
 cleanup:
12919 12920 12921 12922 12923 12924 12925 12926 12927
    for (i = 0; i < nkws; i++) {
        VIR_FREE(kws[i]);
        VIR_FREE(vals[i]);
    }
    VIR_FREE(kws);
    VIR_FREE(vals);

    return ret;

12928
 syntax:
12929 12930
    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("cannot parse CPU topology '%s'"), val);
12931
 error:
12932 12933 12934 12935 12936
    ret = -1;
    goto cleanup;
}


12937
static void
12938 12939
qemuParseCommandLineBootDevs(virDomainDefPtr def, const char *str)
{
12940 12941
    int n, b = 0;

12942
    for (n = 0; str[n] && b < VIR_DOMAIN_BOOT_LAST; n++) {
12943 12944 12945 12946 12947 12948 12949 12950 12951 12952 12953 12954 12955 12956 12957
        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;
}


12958 12959 12960 12961 12962
/*
 * 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 已提交
12963 12964 12965 12966 12967 12968 12969 12970
static virDomainDefPtr
qemuParseCommandLine(virCapsPtr qemuCaps,
                     virDomainXMLOptionPtr xmlopt,
                     char **progenv,
                     char **progargv,
                     char **pidfile,
                     virDomainChrSourceDefPtr *monConfig,
                     bool *monJSON)
12971 12972
{
    virDomainDefPtr def;
12973
    size_t i;
12974
    bool nographics = false;
12975
    bool fullscreen = false;
12976
    char **list = NULL;
12977
    char *path;
12978
    size_t nnics = 0;
12979 12980 12981
    const char **nics = NULL;
    int video = VIR_DOMAIN_VIDEO_TYPE_CIRRUS;
    int nvirtiodisk = 0;
W
Wen Congyang 已提交
12982
    qemuDomainCmdlineDefPtr cmd = NULL;
E
Eric Blake 已提交
12983
    virDomainDiskDefPtr disk = NULL;
12984
    const char *ceph_args = qemuFindEnv(progenv, "CEPH_ARGS");
D
Daniel P. Berrange 已提交
12985
    bool have_sdl = false;
12986

12987 12988 12989 12990 12991 12992 12993
    if (pidfile)
        *pidfile = NULL;
    if (monConfig)
        *monConfig = NULL;
    if (monJSON)
        *monJSON = false;

12994
    if (!progargv[0]) {
12995 12996
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("no emulator path found"));
12997 12998 12999
        return NULL;
    }

13000
    if (!(def = virDomainDefNew()))
13001
        goto error;
13002 13003 13004

    /* allocate the cmdlinedef up-front; if it's unused, we'll free it later */
    if (VIR_ALLOC(cmd) < 0)
13005
        goto error;
13006

E
Eric Blake 已提交
13007
    if (virUUIDGenerate(def->uuid) < 0) {
13008 13009
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to generate uuid"));
E
Eric Blake 已提交
13010 13011
        goto error;
    }
13012 13013

    def->id = -1;
13014
    def->mem.cur_balloon = 64 * 1024;
13015
    virDomainDefSetMemoryTotal(def, def->mem.cur_balloon);
13016 13017
    if (virDomainDefSetVcpusMax(def, 1) < 0)
        goto error;
13018 13019
    if (virDomainDefSetVcpus(def, 1) < 0)
        goto error;
13020
    def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC;
13021

13022
    def->onReboot = VIR_DOMAIN_LIFECYCLE_RESTART;
13023
    def->onCrash = VIR_DOMAIN_LIFECYCLE_CRASH_DESTROY;
13024 13025
    def->onPoweroff = VIR_DOMAIN_LIFECYCLE_DESTROY;
    def->virtType = VIR_DOMAIN_VIRT_QEMU;
13026 13027
    if (VIR_STRDUP(def->emulator, progargv[0]) < 0)
        goto error;
13028

13029 13030
    if (!(path = last_component(def->emulator)))
        goto error;
13031

13032 13033
    def->os.type = VIR_DOMAIN_OSTYPE_HVM;
    if (strstr(path, "kvm")) {
13034
        def->virtType = VIR_DOMAIN_VIRT_KVM;
13035
        def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_TRISTATE_SWITCH_ON;
13036 13037
    }

13038
    if (def->virtType == VIR_DOMAIN_VIRT_KVM)
13039
        def->os.arch = qemuCaps->host.arch;
13040
    else if (STRPREFIX(path, "qemu-system-"))
13041
        def->os.arch = virArchFromString(path + strlen("qemu-system-"));
13042
    else
13043
        def->os.arch = VIR_ARCH_I686;
13044

13045 13046
    if ((def->os.arch == VIR_ARCH_I686) ||
        (def->os.arch == VIR_ARCH_X86_64))
J
Ján Tomko 已提交
13047
        def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_TRISTATE_SWITCH_ON;
13048

13049 13050 13051
#define WANT_VALUE()                                                   \
    const char *val = progargv[++i];                                   \
    if (!val) {                                                        \
13052
        virReportError(VIR_ERR_INTERNAL_ERROR,                         \
13053
                       _("missing value for %s argument"), arg);       \
13054 13055 13056 13057 13058
        goto error;                                                    \
    }

    /* One initial loop to get list of NICs, so we
     * can correlate them later */
13059
    for (i = 1; progargv[i]; i++) {
13060 13061 13062 13063 13064 13065 13066 13067
        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();
13068 13069 13070
            if (STRPREFIX(val, "nic") &&
                VIR_APPEND_ELEMENT(nics, nnics, val) < 0)
                goto error;
13071 13072 13073 13074
        }
    }

    /* Now the real processing loop */
13075
    for (i = 1; progargv[i]; i++) {
13076
        const char *arg = progargv[i];
L
Laine Stump 已提交
13077 13078
        bool argRecognized = true;

13079 13080 13081 13082 13083 13084 13085 13086 13087 13088
        /* 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)
13089
                goto error;
13090 13091
            vnc->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;

13092
            if (STRPREFIX(val, "unix:")) {
13093
                /* -vnc unix:/some/big/path */
13094
                if (VIR_STRDUP(vnc->data.vnc.socket, val + 5) < 0) {
13095
                    virDomainGraphicsDefFree(vnc);
13096
                    goto error;
13097 13098
                }
            } else {
13099 13100 13101 13102 13103 13104
                /*
                 * -vnc 127.0.0.1:4
                 * -vnc [2001:1:2:3:4:5:1234:1234]:4
                 * -vnc some.host.name:4
                 */
                char *opts;
13105
                char *port;
13106 13107 13108 13109 13110
                const char *sep = ":";
                if (val[0] == '[')
                    sep = "]:";
                tmp = strstr(val, sep);
                if (!tmp) {
13111
                    virDomainGraphicsDefFree(vnc);
13112 13113
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("missing VNC port number in '%s'"), val);
13114 13115
                    goto error;
                }
13116 13117
                port = tmp + strlen(sep);
                if (virStrToLong_i(port, &opts, 10,
13118
                                   &vnc->data.vnc.port) < 0) {
13119
                    virDomainGraphicsDefFree(vnc);
13120
                    virReportError(VIR_ERR_INTERNAL_ERROR,
13121
                                   _("cannot parse VNC port '%s'"), port);
13122 13123 13124
                    goto error;
                }
                if (val[0] == '[')
13125 13126
                    virDomainGraphicsListenSetAddress(vnc, 0,
                                                      val+1, tmp-(val+1), true);
13127
                else
13128 13129 13130 13131
                    virDomainGraphicsListenSetAddress(vnc, 0,
                                                      val, tmp-val, true);
                if (!virDomainGraphicsListenGetAddress(vnc, 0)) {
                    virDomainGraphicsDefFree(vnc);
13132
                    goto error;
13133
                }
13134 13135

                if (*opts == ',') {
13136 13137 13138
                    char *orig_opts;

                    if (VIR_STRDUP(orig_opts, opts + 1) < 0) {
13139
                        virDomainGraphicsDefFree(vnc);
13140
                        goto error;
13141 13142 13143 13144 13145 13146 13147 13148 13149 13150 13151 13152 13153 13154 13155 13156 13157 13158 13159 13160 13161 13162 13163 13164 13165 13166 13167 13168 13169 13170 13171 13172
                    }
                    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;
                            }
13173 13174 13175 13176 13177 13178 13179 13180 13181 13182 13183 13184 13185 13186 13187 13188 13189 13190 13191 13192 13193 13194 13195
                        } 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;
                            }
13196 13197 13198 13199 13200 13201
                        }

                        opts = nextopt;
                    }
                    VIR_FREE(orig_opts);
                }
13202
                vnc->data.vnc.port += 5900;
13203
                vnc->data.vnc.autoport = false;
13204 13205
            }

13206
            if (VIR_APPEND_ELEMENT(def->graphics, def->ngraphics, vnc) < 0) {
13207
                virDomainGraphicsDefFree(vnc);
13208
                goto error;
13209
            }
13210
        } else if (STREQ(arg, "-sdl")) {
D
Daniel P. Berrange 已提交
13211
            have_sdl = true;
13212 13213 13214 13215
        } else if (STREQ(arg, "-m")) {
            int mem;
            WANT_VALUE();
            if (virStrToLong_i(val, NULL, 10, &mem) < 0) {
13216 13217
                virReportError(VIR_ERR_INTERNAL_ERROR, \
                               _("cannot parse memory level '%s'"), val);
13218 13219
                goto error;
            }
13220
            virDomainDefSetMemoryTotal(def, mem * 1024);
13221
            def->mem.cur_balloon = mem * 1024;
13222 13223 13224 13225 13226 13227 13228
        } 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) {
13229 13230
                virReportError(VIR_ERR_INTERNAL_ERROR, \
                               _("cannot parse UUID '%s'"), val);
13231 13232 13233 13234 13235 13236 13237
                goto error;
            }
        } else if (STRPREFIX(arg, "-hd") ||
                   STRPREFIX(arg, "-sd") ||
                   STRPREFIX(arg, "-fd") ||
                   STREQ(arg, "-cdrom")) {
            WANT_VALUE();
13238
            if (!(disk = virDomainDiskDefNew(xmlopt)))
13239
                goto error;
13240

13241
            if (STRPREFIX(val, "/dev/")) {
13242
                disk->src->type = VIR_STORAGE_TYPE_BLOCK;
13243
            } else if (STRPREFIX(val, "nbd:")) {
13244 13245
                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_NBD;
13246
            } else if (STRPREFIX(val, "rbd:")) {
13247 13248
                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_RBD;
13249
                val += strlen("rbd:");
13250
            } else if (STRPREFIX(val, "gluster")) {
13251 13252
                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_GLUSTER;
13253
            } else if (STRPREFIX(val, "sheepdog:")) {
13254 13255
                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_SHEEPDOG;
13256
                val += strlen("sheepdog:");
13257
            } else {
13258
                disk->src->type = VIR_STORAGE_TYPE_FILE;
13259
            }
13260 13261
            if (STREQ(arg, "-cdrom")) {
                disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
13262
                if ((ARCH_IS_PPC64(def->os.arch) &&
13263
                    def->os.machine && STRPREFIX(def->os.machine, "pseries")))
13264
                    disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
13265 13266
                if (VIR_STRDUP(disk->dst, "hdc") < 0)
                    goto error;
13267
                disk->src->readonly = true;
13268 13269 13270 13271 13272 13273 13274 13275 13276 13277
            } 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;
13278
                   if ((ARCH_IS_PPC64(def->os.arch) &&
13279
                       def->os.machine && STRPREFIX(def->os.machine, "pseries")))
13280
                       disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
13281
                }
13282 13283
                if (VIR_STRDUP(disk->dst, arg + 1) < 0)
                    goto error;
13284
            }
13285
            if (VIR_STRDUP(disk->src->path, val) < 0)
13286
                goto error;
13287

13288
            if (disk->src->type == VIR_STORAGE_TYPE_NETWORK) {
13289
                char *port;
13290

13291
                switch ((virStorageNetProtocol) disk->src->protocol) {
13292
                case VIR_STORAGE_NET_PROTOCOL_NBD:
13293
                    if (qemuParseNBDString(disk) < 0)
13294 13295
                        goto error;
                    break;
13296
                case VIR_STORAGE_NET_PROTOCOL_RBD:
13297 13298 13299
                    /* old-style CEPH_ARGS env variable is parsed later */
                    if (!ceph_args && qemuParseRBDString(disk) < 0)
                        goto error;
13300
                    break;
13301
                case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
13302
                    /* disk->src must be [vdiname] or [host]:[port]:[vdiname] */
13303
                    port = strchr(disk->src->path, ':');
13304 13305 13306 13307 13308 13309
                    if (port) {
                        char *vdi;

                        *port++ = '\0';
                        vdi = strchr(port, ':');
                        if (!vdi) {
13310 13311
                            virReportError(VIR_ERR_INTERNAL_ERROR,
                                           _("cannot parse sheepdog filename '%s'"), val);
13312 13313 13314
                            goto error;
                        }
                        *vdi++ = '\0';
13315
                        if (VIR_ALLOC(disk->src->hosts) < 0)
13316
                            goto error;
13317 13318 13319
                        disk->src->nhosts = 1;
                        disk->src->hosts->name = disk->src->path;
                        if (VIR_STRDUP(disk->src->hosts->port, port) < 0)
13320
                            goto error;
13321
                        if (VIR_STRDUP(disk->src->path, vdi) < 0)
13322
                            goto error;
13323 13324
                    }
                    break;
13325
                case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
13326 13327 13328
                    if (qemuParseGlusterString(disk) < 0)
                        goto error;

P
Paolo Bonzini 已提交
13329
                    break;
13330
                case VIR_STORAGE_NET_PROTOCOL_ISCSI:
P
Paolo Bonzini 已提交
13331 13332 13333
                    if (qemuParseISCSIString(disk) < 0)
                        goto error;

13334
                    break;
13335 13336 13337 13338 13339 13340
                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:
13341
                case VIR_STORAGE_NET_PROTOCOL_NONE:
13342 13343
                    /* ignored for now */
                    break;
13344 13345 13346
                }
            }

13347
            if (virDomainDiskDefAssignAddress(xmlopt, disk, def) < 0) {
13348 13349 13350
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("Cannot assign address for device name '%s'"),
                               disk->dst);
13351
                goto error;
13352
            }
13353

13354
            if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
13355
                goto error;
13356
        } else if (STREQ(arg, "-no-acpi")) {
J
Ján Tomko 已提交
13357
            def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_TRISTATE_SWITCH_ABSENT;
13358 13359 13360 13361
        } 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 已提交
13362 13363
        } else if (STREQ(arg, "-enable-kvm")) {
            def->virtType = VIR_DOMAIN_VIRT_KVM;
13364
        } else if (STREQ(arg, "-nographic")) {
13365
            nographics = true;
13366
        } else if (STREQ(arg, "-full-screen")) {
13367
            fullscreen = true;
13368 13369 13370 13371
        } else if (STREQ(arg, "-localtime")) {
            def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME;
        } else if (STREQ(arg, "-kernel")) {
            WANT_VALUE();
13372 13373
            if (VIR_STRDUP(def->os.kernel, val) < 0)
                goto error;
13374 13375
        } else if (STREQ(arg, "-bios")) {
            WANT_VALUE();
13376 13377
            if (VIR_ALLOC(def->os.loader) < 0 ||
                VIR_STRDUP(def->os.loader->path, val) < 0)
13378
                goto error;
13379 13380
        } else if (STREQ(arg, "-initrd")) {
            WANT_VALUE();
13381 13382
            if (VIR_STRDUP(def->os.initrd, val) < 0)
                goto error;
13383 13384
        } else if (STREQ(arg, "-append")) {
            WANT_VALUE();
13385 13386
            if (VIR_STRDUP(def->os.cmdline, val) < 0)
                goto error;
O
Olivia Yin 已提交
13387 13388
        } else if (STREQ(arg, "-dtb")) {
            WANT_VALUE();
13389 13390
            if (VIR_STRDUP(def->os.dtb, val) < 0)
                goto error;
13391
        } else if (STREQ(arg, "-boot")) {
13392
            const char *token = NULL;
13393 13394
            WANT_VALUE();

13395
            if (!strchr(val, ',')) {
13396
                qemuParseCommandLineBootDevs(def, val);
13397
            } else {
13398 13399 13400 13401 13402 13403 13404
                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;
13405 13406 13407 13408 13409 13410 13411 13412 13413 13414 13415 13416 13417 13418 13419 13420
                    } 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;
13421 13422 13423 13424 13425 13426 13427 13428
                    }
                    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++;
                }
            }
13429 13430 13431 13432 13433
        } else if (STREQ(arg, "-name")) {
            char *process;
            WANT_VALUE();
            process = strstr(val, ",process=");
            if (process == NULL) {
13434 13435
                if (VIR_STRDUP(def->name, val) < 0)
                    goto error;
13436
            } else {
13437 13438
                if (VIR_STRNDUP(def->name, val, process - val) < 0)
                    goto error;
13439
            }
13440 13441
            if (STREQ(def->name, ""))
                VIR_FREE(def->name);
13442 13443
        } else if (STREQ(arg, "-M") ||
                   STREQ(arg, "-machine")) {
13444 13445 13446 13447 13448 13449
            char *param;
            size_t j = 0;

            /* -machine [type=]name[,prop[=value][,...]]
             * Set os.machine only if first parameter lacks '=' or
             * contains explicit type='...' */
13450
            WANT_VALUE();
13451 13452
            if (!(list = virStringSplit(val, ",", 0)))
                goto error;
13453 13454 13455 13456 13457
            param = list[0];

            if (STRPREFIX(param, "type="))
                param += strlen("type=");
            if (!strchr(param, '=')) {
13458
                if (VIR_STRDUP(def->os.machine, param) < 0)
13459
                    goto error;
13460 13461 13462 13463 13464 13465 13466
                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 已提交
13467
                    def->mem.dump_core = virTristateSwitchTypeFromString(param);
13468
                    if (def->mem.dump_core <= 0)
J
Ján Tomko 已提交
13469
                        def->mem.dump_core = VIR_TRISTATE_SWITCH_ABSENT;
13470 13471 13472 13473
                } 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 已提交
13474
                    def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_TRISTATE_SWITCH_ON;
13475 13476 13477 13478 13479 13480 13481 13482 13483 13484 13485 13486 13487 13488 13489 13490 13491 13492 13493 13494 13495 13496 13497 13498 13499 13500
                } 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;
13501 13502
                }
            }
13503
            virStringFreeList(list);
13504
            list = NULL;
13505 13506 13507 13508
        } else if (STREQ(arg, "-serial")) {
            WANT_VALUE();
            if (STRNEQ(val, "none")) {
                virDomainChrDefPtr chr;
13509 13510 13511 13512

                if (!(chr = virDomainChrDefNew()))
                    goto error;

E
Eric Blake 已提交
13513 13514
                if (qemuParseCommandLineChr(&chr->source, val) < 0) {
                    virDomainChrDefFree(chr);
13515
                    goto error;
E
Eric Blake 已提交
13516
                }
13517 13518 13519
                chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
                chr->target.port = def->nserials;
                if (VIR_APPEND_ELEMENT(def->serials, def->nserials, chr) < 0) {
13520
                    virDomainChrDefFree(chr);
13521
                    goto error;
13522 13523 13524 13525 13526 13527
                }
            }
        } else if (STREQ(arg, "-parallel")) {
            WANT_VALUE();
            if (STRNEQ(val, "none")) {
                virDomainChrDefPtr chr;
13528 13529 13530 13531

                if (!(chr = virDomainChrDefNew()))
                    goto error;

E
Eric Blake 已提交
13532 13533
                if (qemuParseCommandLineChr(&chr->source, val) < 0) {
                    virDomainChrDefFree(chr);
13534
                    goto error;
E
Eric Blake 已提交
13535
                }
13536 13537 13538
                chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL;
                chr->target.port = def->nparallels;
                if (VIR_APPEND_ELEMENT(def->parallels, def->nparallels, chr) < 0) {
13539
                    virDomainChrDefFree(chr);
13540
                    goto error;
13541 13542 13543 13544 13545
                }
            }
        } else if (STREQ(arg, "-usbdevice")) {
            WANT_VALUE();
            if (STREQ(val, "tablet") ||
13546 13547
                STREQ(val, "mouse") ||
                STREQ(val, "keyboard")) {
13548 13549
                virDomainInputDefPtr input;
                if (VIR_ALLOC(input) < 0)
13550
                    goto error;
13551 13552 13553
                input->bus = VIR_DOMAIN_INPUT_BUS_USB;
                if (STREQ(val, "tablet"))
                    input->type = VIR_DOMAIN_INPUT_TYPE_TABLET;
13554
                else if (STREQ(val, "mouse"))
13555
                    input->type = VIR_DOMAIN_INPUT_TYPE_MOUSE;
13556 13557 13558 13559
                else
                    input->type = VIR_DOMAIN_INPUT_TYPE_KBD;

                if (VIR_APPEND_ELEMENT(def->inputs, def->ninputs, input) < 0) {
13560
                    virDomainInputDefFree(input);
13561
                    goto error;
13562 13563
                }
            } else if (STRPREFIX(val, "disk:")) {
13564
                if (!(disk = virDomainDiskDefNew(xmlopt)))
13565
                    goto error;
13566
                if (VIR_STRDUP(disk->src->path, val + strlen("disk:")) < 0)
13567
                    goto error;
13568 13569
                if (STRPREFIX(disk->src->path, "/dev/"))
                    disk->src->type = VIR_STORAGE_TYPE_BLOCK;
13570
                else
13571
                    disk->src->type = VIR_STORAGE_TYPE_FILE;
13572 13573
                disk->device = VIR_DOMAIN_DISK_DEVICE_DISK;
                disk->bus = VIR_DOMAIN_DISK_BUS_USB;
J
Ján Tomko 已提交
13574
                disk->removable = VIR_TRISTATE_SWITCH_ABSENT;
13575 13576
                if (VIR_STRDUP(disk->dst, "sda") < 0)
                    goto error;
13577
                if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
13578
                    goto error;
13579 13580 13581 13582
            } else {
                virDomainHostdevDefPtr hostdev;
                if (!(hostdev = qemuParseCommandLineUSB(val)))
                    goto error;
13583
                if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev) < 0) {
13584
                    virDomainHostdevDefFree(hostdev);
13585
                    goto error;
13586 13587 13588 13589 13590 13591
                }
            }
        } else if (STREQ(arg, "-net")) {
            WANT_VALUE();
            if (!STRPREFIX(val, "nic") && STRNEQ(val, "none")) {
                virDomainNetDefPtr net;
13592
                if (!(net = qemuParseCommandLineNet(xmlopt, val, nnics, nics)))
13593
                    goto error;
13594
                if (VIR_APPEND_ELEMENT(def->nets, def->nnets, net) < 0) {
13595
                    virDomainNetDefFree(net);
13596
                    goto error;
13597 13598 13599 13600
                }
            }
        } else if (STREQ(arg, "-drive")) {
            WANT_VALUE();
13601
            if (!(disk = qemuParseCommandLineDisk(xmlopt, val, def,
13602
                                                  nvirtiodisk,
13603
                                                  ceph_args != NULL)))
13604 13605 13606
                goto error;
            if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
                nvirtiodisk++;
13607 13608
            if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
                goto error;
13609 13610 13611 13612 13613
        } else if (STREQ(arg, "-pcidevice")) {
            virDomainHostdevDefPtr hostdev;
            WANT_VALUE();
            if (!(hostdev = qemuParseCommandLinePCI(val)))
                goto error;
13614
            if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev) < 0) {
13615
                virDomainHostdevDefFree(hostdev);
13616
                goto error;
13617 13618 13619 13620 13621 13622 13623 13624 13625 13626 13627 13628 13629 13630 13631 13632
            }
        } 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;
13633 13634
                } else if (STRPREFIX(start, "hda")) {
                    type = VIR_DOMAIN_SOUND_MODEL_ICH6;
13635 13636 13637 13638 13639
                }

                if (type != -1) {
                    virDomainSoundDefPtr snd;
                    if (VIR_ALLOC(snd) < 0)
13640
                        goto error;
13641
                    snd->model = type;
13642
                    if (VIR_APPEND_ELEMENT(def->sounds, def->nsounds, snd) < 0) {
13643
                        VIR_FREE(snd);
13644
                        goto error;
13645 13646 13647 13648 13649 13650 13651
                    }
                }

                start = tmp ? tmp + 1 : NULL;
            }
        } else if (STREQ(arg, "-watchdog")) {
            WANT_VALUE();
13652
            int model = virDomainWatchdogModelTypeFromString(val);
13653 13654 13655 13656

            if (model != -1) {
                virDomainWatchdogDefPtr wd;
                if (VIR_ALLOC(wd) < 0)
13657
                    goto error;
13658 13659 13660 13661 13662 13663
                wd->model = model;
                wd->action = VIR_DOMAIN_WATCHDOG_ACTION_RESET;
                def->watchdog = wd;
            }
        } else if (STREQ(arg, "-watchdog-action") && def->watchdog) {
            WANT_VALUE();
13664
            int action = virDomainWatchdogActionTypeFromString(val);
13665 13666 13667 13668 13669

            if (action != -1)
                def->watchdog->action = action;
        } else if (STREQ(arg, "-bootloader")) {
            WANT_VALUE();
13670 13671
            if (VIR_STRDUP(def->os.bootloader, val) < 0)
                goto error;
13672 13673 13674 13675 13676 13677 13678 13679 13680
        } 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) {
13681 13682
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("unknown video adapter type '%s'"), val);
13683 13684 13685 13686 13687 13688 13689 13690 13691 13692 13693
                    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")) {
13694 13695
            virDomainControllerDefPtr ctldef;
            if (VIR_ALLOC(ctldef) < 0)
13696
                goto error;
13697 13698 13699
            ctldef->type = VIR_DOMAIN_CONTROLLER_TYPE_USB;
            ctldef->idx = 0;
            ctldef->model = -1;
13700 13701
            if (virDomainControllerInsert(def, ctldef) < 0) {
                VIR_FREE(ctldef);
13702
                goto error;
13703
            }
13704 13705
        } else if (STREQ(arg, "-pidfile")) {
            WANT_VALUE();
13706
            if (pidfile)
13707 13708
                if (VIR_STRDUP(*pidfile, val) < 0)
                    goto error;
13709 13710 13711 13712 13713
        } else if (STREQ(arg, "-incoming")) {
            WANT_VALUE();
            /* ignore, used via restore/migrate APIs */
        } else if (STREQ(arg, "-monitor")) {
            WANT_VALUE();
13714 13715 13716 13717
            if (monConfig) {
                virDomainChrSourceDefPtr chr;

                if (VIR_ALLOC(chr) < 0)
13718
                    goto error;
13719

E
Eric Blake 已提交
13720 13721
                if (qemuParseCommandLineChr(chr, val) < 0) {
                    virDomainChrSourceDefFree(chr);
13722
                    goto error;
E
Eric Blake 已提交
13723
                }
13724 13725 13726

                *monConfig = chr;
            }
13727 13728 13729 13730 13731 13732 13733 13734
        } 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=");
13735
            if (STREQ(val, "0")) {
J
Ján Tomko 已提交
13736
                def->pm.s3 = VIR_TRISTATE_BOOL_YES;
13737
            } else if (STREQ(val, "1")) {
J
Ján Tomko 已提交
13738
                def->pm.s3 = VIR_TRISTATE_BOOL_NO;
13739
            } else {
13740 13741 13742 13743 13744 13745 13746 13747 13748 13749 13750 13751
                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=");
13752
            if (STREQ(val, "0")) {
J
Ján Tomko 已提交
13753
                def->pm.s4 = VIR_TRISTATE_BOOL_YES;
13754
            } else if (STREQ(val, "1")) {
J
Ján Tomko 已提交
13755
                def->pm.s4 = VIR_TRISTATE_BOOL_NO;
13756
            } else {
13757 13758 13759 13760 13761 13762
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("invalid value for disable_s4 parameter: "
                                 "'%s'"), val);
                goto error;
            }

13763 13764 13765 13766 13767
        } else if (STREQ(arg, "-global") &&
                   STRPREFIX(progargv[i + 1], "spapr-nvram.reg=")) {
            WANT_VALUE();

            if (VIR_ALLOC(def->nvram) < 0)
13768
                goto error;
13769 13770 13771 13772 13773 13774 13775 13776 13777 13778 13779

            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;
            }
13780 13781 13782
        } else if (STREQ(arg, "-S") ||
                   STREQ(arg, "-nodefaults") ||
                   STREQ(arg, "-nodefconfig")) {
13783
            /* ignore, always added by libvirt */
L
Laine Stump 已提交
13784 13785 13786 13787 13788 13789 13790 13791 13792 13793 13794 13795 13796 13797 13798 13799 13800 13801
        } 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;
            }
13802
        } else {
L
Laine Stump 已提交
13803 13804 13805 13806
            argRecognized = false;
        }

        if (!argRecognized) {
13807
            char *tmp = NULL;
13808 13809 13810 13811 13812
            /* 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);
13813 13814 13815
            if (VIR_STRDUP(tmp, arg) < 0 ||
                VIR_APPEND_ELEMENT(cmd->args, cmd->num_args, tmp) < 0) {
                VIR_FREE(tmp);
13816
                goto error;
13817
            }
13818 13819 13820 13821
        }
    }

#undef WANT_VALUE
13822 13823 13824
    if (def->ndisks > 0 && ceph_args) {
        char *hosts, *port, *saveptr = NULL, *token;
        virDomainDiskDefPtr first_rbd_disk = NULL;
13825
        for (i = 0; i < def->ndisks; i++) {
13826 13827
            if (def->disks[i]->src->type == VIR_STORAGE_TYPE_NETWORK &&
                def->disks[i]->src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) {
13828 13829
                first_rbd_disk = def->disks[i];
                break;
13830
            }
13831
        }
13832

13833
        if (!first_rbd_disk) {
13834 13835
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("CEPH_ARGS was set without an rbd disk"));
13836 13837
            goto error;
        }
13838

13839 13840
        /* CEPH_ARGS should be: -m host1[:port1][,host2[:port2]]... */
        if (!STRPREFIX(ceph_args, "-m ")) {
13841 13842
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("could not parse CEPH_ARGS '%s'"), ceph_args);
13843 13844
            goto error;
        }
13845 13846
        if (VIR_STRDUP(hosts, strchr(ceph_args, ' ') + 1) < 0)
            goto error;
13847
        first_rbd_disk->src->nhosts = 0;
13848 13849
        token = strtok_r(hosts, ",", &saveptr);
        while (token != NULL) {
13850 13851
            if (VIR_REALLOC_N(first_rbd_disk->src->hosts,
                              first_rbd_disk->src->nhosts + 1) < 0) {
13852
                VIR_FREE(hosts);
13853
                goto error;
13854 13855 13856 13857
            }
            port = strchr(token, ':');
            if (port) {
                *port++ = '\0';
13858
                if (VIR_STRDUP(port, port) < 0) {
13859
                    VIR_FREE(hosts);
13860
                    goto error;
13861 13862
                }
            }
13863 13864
            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,
13865
                           token) < 0) {
13866
                VIR_FREE(hosts);
13867
                goto error;
13868
            }
13869 13870
            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;
13871

13872
            first_rbd_disk->src->nhosts++;
13873 13874 13875 13876
            token = strtok_r(NULL, ",", &saveptr);
        }
        VIR_FREE(hosts);

13877
        if (first_rbd_disk->src->nhosts == 0) {
13878 13879
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("found no rbd hosts in CEPH_ARGS '%s'"), ceph_args);
13880
            goto error;
13881 13882 13883
        }
    }

13884
    if (!def->os.machine) {
13885 13886 13887 13888 13889 13890 13891 13892 13893 13894 13895
        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);
13896 13897
    }

D
Daniel P. Berrange 已提交
13898
    if (!nographics && (def->ngraphics == 0 || have_sdl)) {
13899 13900 13901 13902
        virDomainGraphicsDefPtr sdl;
        const char *display = qemuFindEnv(progenv, "DISPLAY");
        const char *xauth = qemuFindEnv(progenv, "XAUTHORITY");
        if (VIR_ALLOC(sdl) < 0)
13903
            goto error;
13904 13905
        sdl->type = VIR_DOMAIN_GRAPHICS_TYPE_SDL;
        sdl->data.sdl.fullscreen = fullscreen;
13906
        if (VIR_STRDUP(sdl->data.sdl.display, display) < 0) {
13907
            VIR_FREE(sdl);
13908
            goto error;
13909
        }
13910
        if (VIR_STRDUP(sdl->data.sdl.xauth, xauth) < 0) {
13911
            VIR_FREE(sdl);
13912
            goto error;
13913 13914
        }

13915
        if (VIR_APPEND_ELEMENT(def->graphics, def->ngraphics, sdl) < 0) {
13916
            virDomainGraphicsDefFree(sdl);
13917
            goto error;
13918 13919 13920 13921 13922 13923
        }
    }

    if (def->ngraphics) {
        virDomainVideoDefPtr vid;
        if (VIR_ALLOC(vid) < 0)
13924
            goto error;
13925 13926 13927 13928 13929
        if (def->virtType == VIR_DOMAIN_VIRT_XEN)
            vid->type = VIR_DOMAIN_VIDEO_TYPE_XEN;
        else
            vid->type = video;
        vid->vram = virDomainVideoDefaultRAM(def, vid->type);
13930 13931
        if (vid->type == VIR_DOMAIN_VIDEO_TYPE_QXL) {
            vid->ram = virDomainVideoDefaultRAM(def, vid->type);
13932
            vid->vgamem = QEMU_QXL_VGAMEM_DEFAULT;
13933 13934 13935 13936
        } else {
            vid->ram = 0;
            vid->vgamem = 0;
        }
13937 13938
        vid->heads = 1;

13939
        if (VIR_APPEND_ELEMENT(def->videos, def->nvideos, vid) < 0) {
13940
            virDomainVideoDefFree(vid);
13941
            goto error;
13942 13943 13944 13945 13946 13947 13948 13949 13950
        }
    }

    /*
     * having a balloon is the default, define one with type="none" to avoid it
     */
    if (!def->memballoon) {
        virDomainMemballoonDefPtr memballoon;
        if (VIR_ALLOC(memballoon) < 0)
13951
            goto error;
L
Laine Stump 已提交
13952
        memballoon->model = VIR_DOMAIN_MEMBALLOON_MODEL_NONE;
13953 13954 13955 13956 13957 13958 13959 13960 13961

        def->memballoon = memballoon;
    }

    VIR_FREE(nics);

    if (virDomainDefAddImplicitControllers(def) < 0)
        goto error;

13962 13963
    if (virDomainDefPostParse(def, qemuCaps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
                              xmlopt) < 0)
13964 13965
        goto error;

13966
    if (cmd->num_args || cmd->num_env) {
13967
        def->ns = *virDomainXMLOptionGetNamespace(xmlopt);
13968 13969 13970
        def->namespaceData = cmd;
    }
    else
13971
        qemuDomainCmdlineDefFree(cmd);
13972 13973 13974

    return def;

13975
 error:
E
Eric Blake 已提交
13976
    virDomainDiskDefFree(disk);
13977
    qemuDomainCmdlineDefFree(cmd);
13978
    virDomainDefFree(def);
13979
    virStringFreeList(list);
13980
    VIR_FREE(nics);
13981 13982 13983 13984 13985 13986
    if (monConfig) {
        virDomainChrSourceDefFree(*monConfig);
        *monConfig = NULL;
    }
    if (pidfile)
        VIR_FREE(*pidfile);
13987 13988 13989 13990
    return NULL;
}


13991
virDomainDefPtr qemuParseCommandLineString(virCapsPtr qemuCaps,
13992
                                           virDomainXMLOptionPtr xmlopt,
13993 13994 13995 13996
                                           const char *args,
                                           char **pidfile,
                                           virDomainChrSourceDefPtr *monConfig,
                                           bool *monJSON)
13997
{
E
Eric Blake 已提交
13998 13999
    char **progenv = NULL;
    char **progargv = NULL;
14000 14001 14002 14003 14004
    virDomainDefPtr def = NULL;

    if (qemuStringToArgvEnv(args, &progenv, &progargv) < 0)
        goto cleanup;

14005
    def = qemuParseCommandLine(qemuCaps, xmlopt, progenv, progargv,
14006
                               pidfile, monConfig, monJSON);
14007

14008
 cleanup:
E
Eric Blake 已提交
14009 14010
    virStringFreeList(progargv);
    virStringFreeList(progenv);
14011 14012 14013

    return def;
}
14014 14015


14016
static int qemuParseProcFileStrings(int pid_value,
14017
                                    const char *name,
E
Eric Blake 已提交
14018
                                    char ***list)
14019 14020 14021 14022 14023 14024 14025
{
    char *path = NULL;
    int ret = -1;
    char *data = NULL;
    ssize_t len;
    char *tmp;
    size_t nstr = 0;
14026
    char **str = NULL;
14027

14028
    if (virAsprintf(&path, "/proc/%d/%s", pid_value, name) < 0)
14029 14030 14031 14032 14033 14034 14035
        goto cleanup;

    if ((len = virFileReadAll(path, 1024*128, &data)) < 0)
        goto cleanup;

    tmp = data;
    while (tmp < (data + len)) {
14036
        if (VIR_EXPAND_N(str, nstr, 1) < 0)
14037 14038
            goto cleanup;

14039
        if (VIR_STRDUP(str[nstr-1], tmp) < 0)
14040 14041 14042 14043 14044 14045 14046
            goto cleanup;
        /* Skip arg */
        tmp += strlen(tmp);
        /* Skip \0 separator */
        tmp++;
    }

14047
    if (VIR_EXPAND_N(str, nstr, 1) < 0)
14048 14049 14050 14051 14052
        goto cleanup;

    str[nstr-1] = NULL;

    ret = nstr-1;
E
Eric Blake 已提交
14053
    *list = str;
14054

14055
 cleanup:
E
Eric Blake 已提交
14056 14057
    if (ret < 0)
        virStringFreeList(str);
14058 14059 14060 14061 14062
    VIR_FREE(data);
    VIR_FREE(path);
    return ret;
}

14063
virDomainDefPtr qemuParseCommandLinePid(virCapsPtr qemuCaps,
14064
                                        virDomainXMLOptionPtr xmlopt,
14065
                                        pid_t pid,
14066 14067 14068 14069 14070
                                        char **pidfile,
                                        virDomainChrSourceDefPtr *monConfig,
                                        bool *monJSON)
{
    virDomainDefPtr def = NULL;
E
Eric Blake 已提交
14071 14072
    char **progargv = NULL;
    char **progenv = NULL;
14073 14074 14075
    char *exepath = NULL;
    char *emulator;

14076 14077 14078 14079
    /* 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 ||
14080 14081 14082
        qemuParseProcFileStrings(pid, "environ", &progenv) < 0)
        goto cleanup;

14083
    if (!(def = qemuParseCommandLine(qemuCaps, xmlopt, progenv, progargv,
14084 14085 14086
                                     pidfile, monConfig, monJSON)))
        goto cleanup;

14087
    if (virAsprintf(&exepath, "/proc/%d/exe", (int) pid) < 0)
14088 14089 14090 14091 14092
        goto cleanup;

    if (virFileResolveLink(exepath, &emulator) < 0) {
        virReportSystemError(errno,
                             _("Unable to resolve %s for pid %u"),
14093
                             exepath, (int) pid);
14094 14095 14096 14097 14098
        goto cleanup;
    }
    VIR_FREE(def->emulator);
    def->emulator = emulator;

14099
 cleanup:
14100
    VIR_FREE(exepath);
E
Eric Blake 已提交
14101 14102
    virStringFreeList(progargv);
    virStringFreeList(progenv);
14103 14104
    return def;
}