qemu_command.c 404.5 KB
Newer Older
1 2 3
/*
 * qemu_command.c: QEMU command generation
 *
M
Martin Kletzander 已提交
4
 * Copyright (C) 2006-2014 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 "virstring.h"
39
#include "virtime.h"
40
#include "viruuid.h"
41 42
#include "c-ctype.h"
#include "domain_nwfilter.h"
43
#include "domain_addr.h"
44
#include "domain_audit.h"
M
Michal Novotny 已提交
45
#include "domain_conf.h"
46
#include "snapshot_conf.h"
47
#include "storage_conf.h"
48
#include "network/bridge_driver.h"
49
#include "virnetdevtap.h"
50
#include "base64.h"
51
#include "device_conf.h"
52
#include "virstoragefile.h"
53
#include "virtpm.h"
54
#include "virscsi.h"
55 56 57
#if defined(__linux__)
# include <linux/capability.h>
#endif
58 59 60 61 62 63

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

#define VIR_FROM_THIS VIR_FROM_QEMU

64 65
VIR_LOG_INIT("qemu.qemu_command");

66 67 68 69
#define VIO_ADDR_NET 0x1000ul
#define VIO_ADDR_SCSI 0x2000ul
#define VIO_ADDR_SERIAL 0x30000000ul
#define VIO_ADDR_NVRAM 0x3000ul
70 71 72 73 74 75 76 77 78 79

VIR_ENUM_DECL(virDomainDiskQEMUBus)
VIR_ENUM_IMPL(virDomainDiskQEMUBus, VIR_DOMAIN_DISK_BUS_LAST,
              "ide",
              "floppy",
              "scsi",
              "virtio",
              "xen",
              "usb",
              "uml",
80 81
              "sata",
              "sd")
82 83 84 85 86 87 88 89


VIR_ENUM_DECL(qemuDiskCacheV1)
VIR_ENUM_DECL(qemuDiskCacheV2)

VIR_ENUM_IMPL(qemuDiskCacheV1, VIR_DOMAIN_DISK_CACHE_LAST,
              "default",
              "off",
90 91
              "off",  /* writethrough not supported, so for safety, disable */
              "on",   /* Old 'on' was equivalent to 'writeback' */
92 93
              "off",  /* directsync not supported, for safety, disable */
              "off"); /* unsafe not supported, for safety, disable */
94 95 96 97 98

VIR_ENUM_IMPL(qemuDiskCacheV2, VIR_DOMAIN_DISK_CACHE_LAST,
              "default",
              "none",
              "writethrough",
99
              "writeback",
100 101
              "directsync",
              "unsafe");
102 103 104 105 106 107 108 109 110 111 112

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 */
              "qxl");

113 114 115 116 117 118 119 120 121 122
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 */
              "qxl-vga");

123 124 125 126 127 128
VIR_ENUM_DECL(qemuSoundCodec)

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

129 130 131 132 133 134 135 136 137 138 139
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 已提交
140
              "pci-ohci",
141 142
              "nec-usb-xhci",
              "none");
143

144 145 146 147
VIR_ENUM_DECL(qemuDomainFSDriver)
VIR_ENUM_IMPL(qemuDomainFSDriver, VIR_DOMAIN_FS_DRIVER_TYPE_LAST,
              "local",
              "local",
148
              "handle",
149
              NULL,
150
              NULL);
151

152

153 154
/**
 * qemuPhysIfaceConnect:
155
 * @def: the definition of the VM (needed by 802.1Qbh and audit)
156
 * @driver: pointer to the driver instance
157
 * @net: pointer to he VM's interface description with direct device type
158
 * @qemuCaps: flags for qemu
M
Michael Wood 已提交
159
 * @vmop: VM operation type
160 161 162 163
 *
 * Returns a filedescriptor on success or -1 in case of error.
 */
int
164
qemuPhysIfaceConnect(virDomainDefPtr def,
165
                     virQEMUDriverPtr driver,
166
                     virDomainNetDefPtr net,
167
                     virQEMUCapsPtr qemuCaps,
168
                     virNetDevVPortProfileOp vmop)
169 170 171 172
{
    int rc;
    char *res_ifname = NULL;
    int vnet_hdr = 0;
173
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
174

175
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VNET_HDR) &&
176 177 178
        net->model && STREQ(net->model, "virtio"))
        vnet_hdr = 1;

179
    rc = virNetDevMacVLanCreateWithVPortProfile(
180
        net->ifname, &net->mac,
181 182
        virDomainNetGetActualDirectDev(net),
        virDomainNetGetActualDirectMode(net),
183
        true, vnet_hdr, def->uuid,
184
        virDomainNetGetActualVirtPortProfile(net),
185
        &res_ifname,
186
        vmop, cfg->stateDir,
187
        virDomainNetGetActualBandwidth(net));
188
    if (rc >= 0) {
189 190 191 192
        if (virSecurityManagerSetTapFDLabel(driver->securityManager,
                                            def, rc) < 0)
            goto error;

193
        virDomainAuditNetDevice(def, net, res_ifname, true);
194 195 196 197
        VIR_FREE(net->ifname);
        net->ifname = res_ifname;
    }

198
    virObjectUnref(cfg);
199
    return rc;
200

201
 error:
202 203 204 205 206
    ignore_value(virNetDevMacVLanDeleteWithVPortProfile(
                     res_ifname, &net->mac,
                     virDomainNetGetActualDirectDev(net),
                     virDomainNetGetActualDirectMode(net),
                     virDomainNetGetActualVirtPortProfile(net),
207
                     cfg->stateDir));
208
    VIR_FREE(res_ifname);
209
    virObjectUnref(cfg);
210
    return -1;
211 212 213
}


214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
/**
 * 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;
    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;
    }

    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]);
253 254
    virCommandPassFD(cmd, pair[1],
                     VIR_COMMAND_PASS_FD_CLOSE_PARENT);
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
    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);
    if (*tapfd < 0) {
        virReportSystemError(errno, "%s",
                             _("failed to retrieve file descriptor for interface"));
        goto cleanup;
    }

    if (virNetDevTapGetName(*tapfd, ifname) < 0 ||
274
        virCommandWait(cmd, NULL) < 0) {
275 276 277 278
        VIR_FORCE_CLOSE(*tapfd);
        *tapfd = -1;
    }

279
 cleanup:
280 281 282 283 284
    virCommandFree(cmd);
    VIR_FORCE_CLOSE(pair[0]);
    return *tapfd < 0 ? -1 : 0;
}

285
int
286 287
qemuNetworkIfaceConnect(virDomainDefPtr def,
                        virConnectPtr conn,
288
                        virQEMUDriverPtr driver,
289
                        virDomainNetDefPtr net,
290 291 292
                        virQEMUCapsPtr qemuCaps,
                        int *tapfd,
                        int *tapfdSize)
293 294
{
    char *brname = NULL;
295
    int ret = -1;
296
    unsigned int tap_create_flags = VIR_NETDEV_TAP_CREATE_IFUP;
E
Eric Blake 已提交
297
    bool template_ifname = false;
298
    int actualType = virDomainNetGetActualType(net);
299
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
300

301
    if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
302
        bool fail = false;
303 304 305 306
        virErrorPtr errobj;
        virNetworkPtr network = virNetworkLookupByName(conn,
                                                       net->data.network.name);
        if (!network)
307
            return ret;
308

309 310
        if (!(brname = virNetworkGetBridgeName(network)))
           fail = true;
311 312 313 314 315 316 317 318

        /* Make sure any above failure is preserved */
        errobj = virSaveLastError();
        virNetworkFree(network);
        virSetError(errobj);
        virFreeError(errobj);

        if (fail)
319
            return ret;
320

321
    } else if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
322
        if (VIR_STRDUP(brname, virDomainNetGetActualBridgeName(net)) < 0)
323
            return ret;
324
    } else {
325 326 327
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Network type %d is not supported"),
                       virDomainNetGetActualType(net));
328
        return ret;
329 330 331
    }

    if (!net->ifname ||
E
Eric Blake 已提交
332
        STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) ||
333 334
        strchr(net->ifname, '%')) {
        VIR_FREE(net->ifname);
335
        if (VIR_STRDUP(net->ifname, VIR_NET_GENERATED_PREFIX "%d") < 0)
336
            goto cleanup;
337
        /* avoid exposing vnet%d in getXMLDesc or error outputs */
E
Eric Blake 已提交
338
        template_ifname = true;
339 340
    }

341
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VNET_HDR) &&
342 343 344
        net->model && STREQ(net->model, "virtio")) {
        tap_create_flags |= VIR_NETDEV_TAP_CREATE_VNET_HDR;
    }
345

346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
    if (cfg->privileged) {
        if (virNetDevTapCreateInBridgePort(brname, &net->ifname, &net->mac,
                                           def->uuid, tapfd, *tapfdSize,
                                           virDomainNetGetActualVirtPortProfile(net),
                                           virDomainNetGetActualVlan(net),
                                           tap_create_flags) < 0) {
            virDomainAuditNetDevice(def, net, "/dev/net/tun", false);
            goto cleanup;
        }
    } else {
        if (qemuCreateInBridgePortWithHelper(cfg, brname,
                                             &net->ifname,
                                             tapfd, tap_create_flags) < 0) {
            virDomainAuditNetDevice(def, net, "/dev/net/tun", false);
            goto cleanup;
        }
        /* qemuCreateInBridgePortWithHelper can only create a single FD */
        if (*tapfdSize > 1) {
            VIR_WARN("Ignoring multiqueue network request");
            *tapfdSize = 1;
        }
367 368
    }

369 370 371
    virDomainAuditNetDevice(def, net, "/dev/net/tun", true);

    if (cfg->macFilter &&
372 373 374 375
        ebtablesAddForwardAllowIn(driver->ebtables,
                                  net->ifname,
                                  &net->mac) < 0)
        goto cleanup;
376

377
    if (virNetDevBandwidthSet(net->ifname,
378 379
                              virDomainNetGetActualBandwidth(net),
                              false) < 0) {
380 381 382
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot set bandwidth limits on %s"),
                       net->ifname);
383 384 385
        goto cleanup;
    }

386 387 388
    if (net->filter && net->ifname &&
        virDomainConfNWFilterInstantiate(conn, def->uuid, net) < 0) {
        goto cleanup;
389 390
    }

391 392
    ret = 0;

393
 cleanup:
394
    if (ret < 0) {
395
        size_t i;
396
        for (i = 0; i < *tapfdSize && tapfd[i] >= 0; i++)
397 398 399 400
            VIR_FORCE_CLOSE(tapfd[i]);
        if (template_ifname)
            VIR_FREE(net->ifname);
    }
401
    VIR_FREE(brname);
402
    virObjectUnref(cfg);
403

404
    return ret;
405 406
}

407
static bool
408 409 410
qemuDomainSupportsNicdev(virDomainDefPtr def,
                         virQEMUCapsPtr qemuCaps,
                         virDomainNetDefPtr net)
411 412 413 414
{
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
        return false;

415
    /* non-virtio ARM nics require legacy -net nic */
416 417
    if (((def->os.arch == VIR_ARCH_ARMV7L) ||
        (def->os.arch == VIR_ARCH_AARCH64)) &&
418
        net->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
419 420 421 422 423 424
        return false;

    return true;
}

static bool
425 426 427
qemuDomainSupportsNetdev(virDomainDefPtr def,
                         virQEMUCapsPtr qemuCaps,
                         virDomainNetDefPtr net)
428
{
429
    if (!qemuDomainSupportsNicdev(def, qemuCaps, net))
430 431 432
        return false;
    return virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV);
}
433

434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
/**
 * 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
 */
449
int
450 451
qemuOpenVhostNet(virDomainDefPtr def,
                 virDomainNetDefPtr net,
452
                 virQEMUCapsPtr qemuCaps,
453 454
                 int *vhostfd,
                 int *vhostfdSize)
455
{
456
    size_t i;
457

458 459 460 461
    /* 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) {
462 463
        *vhostfdSize = 0;
        return 0;
464 465 466 467 468
    }

    /* If qemu doesn't support vhost-net mode (including the -netdev command
     * option), don't try to open the device.
     */
469
    if (!(virQEMUCapsGet(qemuCaps, QEMU_CAPS_VHOST_NET) &&
470
          qemuDomainSupportsNetdev(def, qemuCaps, net))) {
471
        if (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST) {
472 473 474
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("vhost-net is not supported with "
                                   "this QEMU binary"));
475 476
            return -1;
        }
477
        *vhostfdSize = 0;
478 479
        return 0;
    }
480

481 482
    /* If the nic model isn't virtio, don't try to open. */
    if (!(net->model && STREQ(net->model, "virtio"))) {
483
        if (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST) {
484 485 486
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("vhost-net is only supported for "
                                   "virtio network interfaces"));
487 488
            return -1;
        }
489
        *vhostfdSize = 0;
490 491 492
        return 0;
    }

493 494
    for (i = 0; i < *vhostfdSize; i++) {
        vhostfd[i] = open("/dev/vhost-net", O_RDWR);
495

496 497 498 499 500 501 502 503 504 505 506
        /* If the config says explicitly to use vhost and we couldn't open it,
         * report an error.
         */
        if (vhostfd[i] < 0) {
            virDomainAuditNetDevice(def, net, "/dev/vhost-net", false);
            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;
            }
507
            VIR_WARN("Unable to open vhost-net. Opened so far %zu, requested %d",
508 509 510
                     i, *vhostfdSize);
            *vhostfdSize = i;
            break;
511
        }
512
    }
513
    virDomainAuditNetDevice(def, net, "/dev/vhost-net", *vhostfdSize);
514
    return 0;
515

516
 error:
517 518 519 520
    while (i--)
        VIR_FORCE_CLOSE(vhostfd[i]);

    return -1;
521 522
}

523 524 525 526
int
qemuNetworkPrepareDevices(virDomainDefPtr def)
{
    int ret = -1;
527
    size_t i;
528

529 530
    for (i = 0; i < def->nnets; i++) {
        virDomainNetDefPtr net = def->nets[i];
531 532 533 534 535 536
        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.
         */
537
        if (networkAllocateActualDevice(def, net) < 0)
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
            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);

            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"),
                               hostdev->source.subsys.u.pci.addr.domain,
                               hostdev->source.subsys.u.pci.addr.bus,
                               hostdev->source.subsys.u.pci.addr.slot,
                               hostdev->source.subsys.u.pci.addr.function,
                               net->data.network.name,
                               def->name);
                goto cleanup;
            }
565
            if (virDomainHostdevInsert(def, hostdev) < 0)
566 567 568 569
                goto cleanup;
        }
    }
    ret = 0;
570
 cleanup:
571 572
    return ret;
}
573

574
static int qemuDomainDeviceAliasIndex(const virDomainDeviceInfo *info,
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
                                      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");
}


/* Names used before -drive existed */
static int qemuAssignDeviceDiskAliasLegacy(virDomainDiskDefPtr disk)
{
600
    char *dev_name;
601

602 603 604
    if (VIR_STRDUP(dev_name,
                   disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
                   STREQ(disk->dst, "hdc") ? "cdrom" : disk->dst) < 0)
605
        return -1;
606
    disk->info.alias = dev_name;
607 608 609 610 611
    return 0;
}


char *qemuDeviceDriveHostAlias(virDomainDiskDefPtr disk,
612
                               virQEMUCapsPtr qemuCaps)
613 614 615
{
    char *ret;

616
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
617 618
        ignore_value(virAsprintf(&ret, "%s%s", QEMU_DRIVE_HOST_PREFIX,
                                 disk->info.alias));
619
    } else {
620
        ignore_value(VIR_STRDUP(ret, disk->info.alias));
621 622 623 624 625 626 627 628 629 630
    }
    return ret;
}


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

    if (virDiskNameToBusDeviceIndex(disk, &busid, &devid) < 0) {
634 635 636
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot convert disk '%s' to bus/device index"),
                       disk->dst);
637 638 639 640 641
        return -1;
    }

    switch (disk->bus) {
    case VIR_DOMAIN_DISK_BUS_IDE:
642
        if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK)
643
            ret = virAsprintf(&dev_name, "ide%d-hd%d", busid, devid);
644
        else
645
            ret = virAsprintf(&dev_name, "ide%d-cd%d", busid, devid);
646 647 648
        break;
    case VIR_DOMAIN_DISK_BUS_SCSI:
        if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK)
649
            ret = virAsprintf(&dev_name, "scsi%d-hd%d", busid, devid);
650
        else
651
            ret = virAsprintf(&dev_name, "scsi%d-cd%d", busid, devid);
652 653
        break;
    case VIR_DOMAIN_DISK_BUS_FDC:
654
        ret = virAsprintf(&dev_name, "floppy%d", devid);
655 656
        break;
    case VIR_DOMAIN_DISK_BUS_VIRTIO:
657
        ret = virAsprintf(&dev_name, "virtio%d", devid);
658 659
        break;
    case VIR_DOMAIN_DISK_BUS_XEN:
660
        ret = virAsprintf(&dev_name, "xenblk%d", devid);
661
        break;
662 663 664
    case VIR_DOMAIN_DISK_BUS_SD:
        ret = virAsprintf(&dev_name, "sd%d", devid);
        break;
665
    default:
666 667 668
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Unsupported disk name mapping for bus '%s'"),
                       virDomainDiskBusTypeToString(disk->bus));
669 670 671
        return -1;
    }

672
    if (ret == -1)
673 674
        return -1;

675
    disk->info.alias = dev_name;
676 677 678 679

    return 0;
}

680
static int
681
qemuSetSCSIControllerModel(virDomainDefPtr def,
682
                           virQEMUCapsPtr qemuCaps,
683
                           int *model)
684 685 686 687
{
    if (*model > 0) {
        switch (*model) {
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC:
688
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_LSI)) {
689 690
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("This QEMU doesn't support "
691
                                 "the LSI 53C895A SCSI controller"));
692 693 694 695
                return -1;
            }
            break;
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI:
696
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_SCSI)) {
697 698 699 700 701 702 703 704 705
                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;
706 707 708 709 710 711 712 713
        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;
714 715 716 717 718 719
        default:
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("Unsupported controller model: %s"),
                           virDomainControllerModelSCSITypeToString(*model));
            return -1;
        }
720
    } else {
721
        if ((def->os.arch == VIR_ARCH_PPC64) &&
722 723
            STREQ(def->os.machine, "pseries")) {
            *model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI;
724
        } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_LSI)) {
725
            *model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC;
726 727
        } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_SCSI)) {
            *model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI;
728 729 730 731 732
        } else {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Unable to determine model for scsi controller"));
            return -1;
        }
733
    }
734 735

    return 0;
736
}
737 738

/* Our custom -drive naming scheme used with id= */
739 740
static int
qemuAssignDeviceDiskAliasCustom(virDomainDefPtr def,
741
                                virDomainDiskDefPtr disk,
742
                                virQEMUCapsPtr qemuCaps)
743 744
{
    const char *prefix = virDomainDiskBusTypeToString(disk->bus);
745 746
    int controllerModel = -1;

747
    if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
748 749
        if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
            controllerModel =
H
Han Cheng 已提交
750 751
                virDomainDeviceFindControllerModel(def, &disk->info,
                                                   VIR_DOMAIN_CONTROLLER_TYPE_SCSI);
752

753
            if ((qemuSetSCSIControllerModel(def, qemuCaps, &controllerModel)) < 0)
754 755
                return -1;
        }
756 757 758 759 760 761 762

        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)
763
                return -1;
764 765 766 767 768 769
        } 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)
770
                return -1;
771
        }
772 773 774
    } else {
        int idx = virDiskNameToIndex(disk->dst);
        if (virAsprintf(&disk->info.alias, "%s-disk%d", prefix, idx) < 0)
775
            return -1;
776 777 778 779 780 781 782
    }

    return 0;
}


int
783 784
qemuAssignDeviceDiskAlias(virDomainDefPtr vmdef,
                          virDomainDiskDefPtr def,
785
                          virQEMUCapsPtr qemuCaps)
786
{
787 788 789
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) {
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
            return qemuAssignDeviceDiskAliasCustom(vmdef, def, qemuCaps);
790 791 792 793 794 795 796 797 798 799 800 801
        else
            return qemuAssignDeviceDiskAliasFixed(def);
    } else {
        return qemuAssignDeviceDiskAliasLegacy(def);
    }
}


int
qemuAssignDeviceNetAlias(virDomainDefPtr def, virDomainNetDefPtr net, int idx)
{
    if (idx == -1) {
802
        size_t i;
803
        idx = 0;
804
        for (i = 0; i < def->nnets; i++) {
805
            int thisidx;
806

807 808
            if (virDomainNetGetActualType(def->nets[i])
                == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
809 810 811
                /* type='hostdev' interfaces have a hostdev%d alias */
               continue;
            }
812
            if ((thisidx = qemuDomainDeviceAliasIndex(&def->nets[i]->info, "net")) < 0) {
813 814
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("Unable to determine device index for network device"));
815 816 817 818 819 820 821
                return -1;
            }
            if (thisidx >= idx)
                idx = thisidx + 1;
        }
    }

822 823 824
    if (virAsprintf(&net->info.alias, "net%d", idx) < 0)
        return -1;
    return 0;
825 826 827 828 829 830 831
}


int
qemuAssignDeviceHostdevAlias(virDomainDefPtr def, virDomainHostdevDefPtr hostdev, int idx)
{
    if (idx == -1) {
832
        size_t i;
833
        idx = 0;
834
        for (i = 0; i < def->nhostdevs; i++) {
835
            int thisidx;
836
            if ((thisidx = qemuDomainDeviceAliasIndex(def->hostdevs[i]->info, "hostdev")) < 0) {
837 838
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("Unable to determine device index for hostdev device"));
839 840 841 842 843 844 845
                return -1;
            }
            if (thisidx >= idx)
                idx = thisidx + 1;
        }
    }

846
    if (virAsprintf(&hostdev->info->alias, "hostdev%d", idx) < 0)
847 848 849 850 851 852
        return -1;

    return 0;
}


853 854 855 856
int
qemuAssignDeviceRedirdevAlias(virDomainDefPtr def, virDomainRedirdevDefPtr redirdev, int idx)
{
    if (idx == -1) {
857
        size_t i;
858
        idx = 0;
859
        for (i = 0; i < def->nredirdevs; i++) {
860 861
            int thisidx;
            if ((thisidx = qemuDomainDeviceAliasIndex(&def->redirdevs[i]->info, "redir")) < 0) {
862 863
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("Unable to determine device index for redirected device"));
864 865 866 867 868 869 870
                return -1;
            }
            if (thisidx >= idx)
                idx = thisidx + 1;
        }
    }

871 872 873
    if (virAsprintf(&redirdev->info.alias, "redir%d", idx) < 0)
        return -1;
    return 0;
874 875 876
}


877 878 879 880 881
int
qemuAssignDeviceControllerAlias(virDomainControllerDefPtr controller)
{
    const char *prefix = virDomainControllerTypeToString(controller->type);

882 883 884 885 886 887 888 889 890 891 892 893
    if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) {
        /* only pcie-root uses a different naming convention
         * ("pcie.0"), because it is hardcoded that way in qemu. All
         * other buses use the consistent "pci.%u".
         */
        if (controller->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT)
            return virAsprintf(&controller->info.alias, "pcie.%d", controller->idx);
        else
            return virAsprintf(&controller->info.alias, "pci.%d", controller->idx);
    }

    return virAsprintf(&controller->info.alias, "%s%d", prefix, controller->idx);
894 895
}

896 897 898 899 900
static ssize_t
qemuGetNextChrDevIndex(virDomainDefPtr def,
                       virDomainChrDefPtr chr,
                       const char *prefix)
{
901 902
    const virDomainChrDef **arrPtr;
    size_t cnt;
903 904 905 906 907 908 909
    size_t i;
    ssize_t idx = 0;
    const char *prefix2 = NULL;

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

910
    virDomainChrGetDomainPtrs(def, chr->deviceType, &arrPtr, &cnt);
911

912
    for (i = 0; i < cnt; i++) {
913
        ssize_t thisidx;
914
        if (((thisidx = qemuDomainDeviceAliasIndex(&arrPtr[i]->info, prefix)) < 0) &&
915
            (prefix2 &&
916
             (thisidx = qemuDomainDeviceAliasIndex(&arrPtr[i]->info, prefix2)) < 0)) {
917 918 919 920 921 922 923 924 925 926 927 928
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Unable to determine device index for character device"));
            return -1;
        }
        if (thisidx >= idx)
            idx = thisidx + 1;
    }

    return idx;
}


929
int
930
qemuAssignDeviceChrAlias(virDomainDefPtr def,
931 932 933 934 935
                         virDomainChrDefPtr chr,
                         ssize_t idx)
{
    const char *prefix = NULL;

936
    switch ((virDomainChrDeviceType) chr->deviceType) {
937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956
    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;
    }

957 958 959
    if (idx == -1 && (idx = qemuGetNextChrDevIndex(def, chr, prefix)) < 0)
        return -1;

960 961
    return virAsprintf(&chr->info.alias, "%s%zd", prefix, idx);
}
962

963
int
964
qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
965
{
966
    size_t i;
967

968
    for (i = 0; i < def->ndisks; i++) {
969
        if (qemuAssignDeviceDiskAlias(def, def->disks[i], qemuCaps) < 0)
970 971
            return -1;
    }
972 973
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NET_NAME) ||
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
974
        for (i = 0; i < def->nnets; i++) {
975 976 977
            /* type='hostdev' interfaces are also on the hostdevs list,
             * and will have their alias assigned with other hostdevs.
             */
978 979 980
            if (virDomainNetGetActualType(def->nets[i])
                != VIR_DOMAIN_NET_TYPE_HOSTDEV &&
                qemuAssignDeviceNetAlias(def, def->nets[i], i) < 0) {
981
                return -1;
982
            }
983 984 985
        }
    }

986
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
987 988
        return 0;

989
    for (i = 0; i < def->nfss; i++) {
990
        if (virAsprintf(&def->fss[i]->info.alias, "fs%zu", i) < 0)
991
            return -1;
992
    }
993
    for (i = 0; i < def->nsounds; i++) {
994
        if (virAsprintf(&def->sounds[i]->info.alias, "sound%zu", i) < 0)
995
            return -1;
996
    }
997
    for (i = 0; i < def->nhostdevs; i++) {
998 999 1000
        if (qemuAssignDeviceHostdevAlias(def, def->hostdevs[i], i) < 0)
            return -1;
    }
1001
    for (i = 0; i < def->nredirdevs; i++) {
1002 1003 1004
        if (qemuAssignDeviceRedirdevAlias(def, def->redirdevs[i], i) < 0)
            return -1;
    }
1005
    for (i = 0; i < def->nvideos; i++) {
1006
        if (virAsprintf(&def->videos[i]->info.alias, "video%zu", i) < 0)
1007
            return -1;
1008
    }
1009
    for (i = 0; i < def->ncontrollers; i++) {
1010 1011 1012
        if (qemuAssignDeviceControllerAlias(def->controllers[i]) < 0)
            return -1;
    }
1013
    for (i = 0; i < def->ninputs; i++) {
1014
        if (virAsprintf(&def->inputs[i]->info.alias, "input%zu", i) < 0)
1015
            return -1;
1016
    }
1017
    for (i = 0; i < def->nparallels; i++) {
1018
        if (qemuAssignDeviceChrAlias(def, def->parallels[i], i) < 0)
1019
            return -1;
1020
    }
1021
    for (i = 0; i < def->nserials; i++) {
1022
        if (qemuAssignDeviceChrAlias(def, def->serials[i], i) < 0)
1023
            return -1;
1024
    }
1025
    for (i = 0; i < def->nchannels; i++) {
1026
        if (qemuAssignDeviceChrAlias(def, def->channels[i], i) < 0)
1027
            return -1;
1028
    }
1029
    for (i = 0; i < def->nconsoles; i++) {
1030
        if (qemuAssignDeviceChrAlias(def, def->consoles[i], i) < 0)
1031
            return -1;
E
Eric Blake 已提交
1032
    }
1033
    for (i = 0; i < def->nhubs; i++) {
1034
        if (virAsprintf(&def->hubs[i]->info.alias, "hub%zu", i) < 0)
1035
            return -1;
M
Marc-André Lureau 已提交
1036
    }
1037
    for (i = 0; i < def->nsmartcards; i++) {
1038
        if (virAsprintf(&def->smartcards[i]->info.alias, "smartcard%zu", i) < 0)
1039
            return -1;
1040 1041 1042
    }
    if (def->watchdog) {
        if (virAsprintf(&def->watchdog->info.alias, "watchdog%d", 0) < 0)
1043
            return -1;
1044 1045 1046
    }
    if (def->memballoon) {
        if (virAsprintf(&def->memballoon->info.alias, "balloon%d", 0) < 0)
1047
            return -1;
1048
    }
1049 1050
    if (def->rng) {
        if (virAsprintf(&def->rng->info.alias, "rng%d", 0) < 0)
1051
            return -1;
1052
    }
1053 1054
    if (def->tpm) {
        if (virAsprintf(&def->tpm->info.alias, "tpm%d", 0) < 0)
1055
            return -1;
1056
    }
1057 1058 1059 1060

    return 0;
}

1061

1062
static void
1063
qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def,
1064
                                     virDomainDeviceAddressType type)
1065 1066 1067
{
    /*
       declare address-less virtio devices to be of address type 'type'
1068 1069
       disks, networks, consoles, controllers, memballoon and rng in this
       order
1070
    */
1071
    size_t i;
1072

1073
    for (i = 0; i < def->ndisks; i++) {
1074 1075 1076 1077 1078
        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;
    }

1079
    for (i = 0; i < def->nnets; i++) {
E
Eric Blake 已提交
1080
        if (STREQ(def->nets[i]->model, "virtio") &&
1081
            def->nets[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
1082
            def->nets[i]->info.type = type;
1083
        }
1084 1085
    }

1086
    for (i = 0; i < def->ncontrollers; i++) {
1087 1088 1089 1090
        if ((def->controllers[i]->type ==
             VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL ||
             def->controllers[i]->type ==
             VIR_DOMAIN_CONTROLLER_TYPE_SCSI) &&
1091 1092 1093 1094 1095
            def->controllers[i]->info.type ==
            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            def->controllers[i]->info.type = type;
    }

1096 1097 1098 1099
    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;
1100 1101 1102 1103 1104

    if (def->rng &&
        def->rng->model == VIR_DOMAIN_RNG_MODEL_VIRTIO &&
        def->rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
        def->rng->info.type = type;
1105 1106
}

1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117

/*
 * 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)
1118
{
1119
    int ret = -1;
J
Ján Tomko 已提交
1120
    virDomainCCWAddressSetPtr addrs = NULL;
1121 1122 1123 1124
    qemuDomainObjPrivatePtr priv = NULL;

    if (STREQLEN(def->os.machine, "s390-ccw", 8) &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
1125
        qemuDomainPrimeVirtioDeviceAddresses(
1126 1127
            def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW);

J
Ján Tomko 已提交
1128
        if (!(addrs = virDomainCCWAddressSetCreate()))
1129 1130
            goto cleanup;

J
Ján Tomko 已提交
1131
        if (virDomainDeviceInfoIterate(def, virDomainCCWAddressValidate,
1132 1133 1134
                                       addrs) < 0)
            goto cleanup;

J
Ján Tomko 已提交
1135
        if (virDomainDeviceInfoIterate(def, virDomainCCWAddressAllocate,
1136 1137 1138 1139
                                       addrs) < 0)
            goto cleanup;
    } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390)) {
        /* deal with legacy virtio-s390 */
1140
        qemuDomainPrimeVirtioDeviceAddresses(
1141
            def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390);
1142 1143 1144 1145 1146 1147
    }

    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 已提交
1148
            virDomainCCWAddressSetFree(priv->ccwaddrs);
1149 1150 1151 1152 1153 1154 1155 1156 1157
            priv->persistentAddrs = 1;
            priv->ccwaddrs = addrs;
            addrs = NULL;
        } else {
            priv->persistentAddrs = 0;
        }
    }
    ret = 0;

1158
 cleanup:
J
Ján Tomko 已提交
1159
    virDomainCCWAddressSetFree(addrs);
1160 1161

    return ret;
1162
}
1163

1164 1165 1166 1167
static int
qemuDomainAssignARMVirtioMMIOAddresses(virDomainDefPtr def,
                                       virQEMUCapsPtr qemuCaps)
{
1168 1169
    if (((def->os.arch == VIR_ARCH_ARMV7L) ||
        (def->os.arch == VIR_ARCH_AARCH64)) &&
1170 1171
        (STRPREFIX(def->os.machine, "vexpress-") ||
            STREQ(def->os.machine, "virt")) &&
1172 1173 1174 1175 1176 1177
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_MMIO)) {
        qemuDomainPrimeVirtioDeviceAddresses(
            def, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO);
    }
    return 0;
}
1178

1179 1180
static int
qemuSpaprVIOFindByReg(virDomainDefPtr def ATTRIBUTE_UNUSED,
1181
                      virDomainDeviceDefPtr device ATTRIBUTE_UNUSED,
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202
                      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;
1203
    int ret;
1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214

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

1215 1216
    ret = virDomainDeviceInfoIterate(def, qemuSpaprVIOFindByReg, info);
    while (ret != 0) {
1217
        if (user_reg) {
1218 1219 1220
            virReportError(VIR_ERR_XML_ERROR,
                           _("spapr-vio address %#llx already in use"),
                           info->addr.spaprvio.reg);
1221 1222 1223 1224 1225
            return -EEXIST;
        }

        /* We assigned the reg, so try a new value */
        info->addr.spaprvio.reg += 0x1000;
1226
        ret = virDomainDeviceInfoIterate(def, qemuSpaprVIOFindByReg, info);
1227 1228 1229 1230 1231
    }

    return 0;
}

1232
int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
1233
                                      virQEMUCapsPtr qemuCaps)
1234
{
1235 1236
    size_t i;
    int ret = -1;
1237
    int model;
1238 1239 1240

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

1241
    for (i = 0; i < def->nnets; i++) {
1242 1243 1244
        if (def->nets[i]->model &&
            STREQ(def->nets[i]->model, "spapr-vlan"))
            def->nets[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
1245
        if (qemuAssignSpaprVIOAddress(def, &def->nets[i]->info,
1246
                                      VIO_ADDR_NET) < 0)
1247
            goto cleanup;
1248 1249
    }

1250
    for (i = 0; i < def->ncontrollers; i++) {
1251
        model = def->controllers[i]->model;
1252
        if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
1253
            if (qemuSetSCSIControllerModel(def, qemuCaps, &model) < 0)
1254 1255 1256
                goto cleanup;
        }

1257
        if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI &&
1258
            def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
1259
            def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
1260
        if (qemuAssignSpaprVIOAddress(def, &def->controllers[i]->info,
1261
                                      VIO_ADDR_SCSI) < 0)
1262
            goto cleanup;
1263 1264
    }

1265
    for (i = 0; i < def->nserials; i++) {
1266
        if (def->serials[i]->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
1267
            (def->os.arch == VIR_ARCH_PPC64) &&
1268 1269
            STREQ(def->os.machine, "pseries"))
            def->serials[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
1270
        if (qemuAssignSpaprVIOAddress(def, &def->serials[i]->info,
1271 1272 1273 1274 1275 1276 1277 1278 1279 1280
                                      VIO_ADDR_SERIAL) < 0)
            goto cleanup;
    }

    if (def->nvram) {
        if (def->os.arch == VIR_ARCH_PPC64 &&
            STREQ(def->os.machine, "pseries"))
            def->nvram->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
        if (qemuAssignSpaprVIOAddress(def, &def->nvram->info,
                                      VIO_ADDR_NVRAM) < 0)
1281
            goto cleanup;
1282 1283 1284 1285
    }

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

1286
    ret = 0;
1287

1288
 cleanup:
1289
    return ret;
1290
}
1291 1292


1293 1294 1295 1296 1297
static int
qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
                      virDomainDeviceDefPtr device,
                      virDomainDeviceInfoPtr info,
                      void *opaque)
1298
{
1299
    virDomainPCIAddressSetPtr addrs = opaque;
1300
    int ret = -1;
1301
    virDevicePCIAddressPtr addr = &info->addr.pci;
1302
    bool entireSlot;
1303
    /* flags may be changed from default below */
1304 1305
    virDomainPCIConnectFlags flags = (VIR_PCI_CONNECT_HOTPLUGGABLE |
                                      VIR_PCI_CONNECT_TYPE_PCI);
1306

1307 1308 1309 1310 1311 1312 1313
    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.
        */
1314
        return 0;
1315
    }
1316

1317 1318 1319
    /* Change flags according to differing requirements of different
     * devices.
     */
1320 1321 1322 1323 1324 1325 1326 1327 1328
    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.
                 */
1329
                flags = VIR_PCI_CONNECT_TYPE_PCI;
1330 1331 1332 1333 1334
                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.
                 */
1335
                flags = VIR_PCI_CONNECT_TYPE_PCIE;
1336 1337 1338 1339
                break;
            default:
                break;
            }
1340
            break;
1341 1342 1343 1344

        case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
            /* SATA controllers aren't hot-plugged, and can be put in
             * either a PCI or PCIe slot
1345
             */
1346
            flags = VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE;
1347
            break;
1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359

        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:
1360 1361
              flags = (VIR_PCI_CONNECT_TYPE_PCI |
                       VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG);
1362 1363 1364 1365 1366
              break;
           case VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI:
              /* should this be PCIE-only? Or do we need to allow PCI
               * for backward compatibility?
               */
1367
              flags = VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE;
1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380
              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:
1381
        case VIR_DOMAIN_SOUND_MODEL_ICH9:
1382 1383
            flags = (VIR_PCI_CONNECT_TYPE_PCI |
                     VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG);
1384
            break;
1385
        }
1386
        break;
1387

1388 1389 1390 1391
    case VIR_DOMAIN_DEVICE_VIDEO:
        /* video cards aren't hot-plugged, and can be put in either a
         * PCI or PCIe slot
         */
1392
        flags = VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE;
1393 1394
        break;
    }
1395

1396 1397 1398 1399 1400 1401
    /* 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().
1402 1403 1404 1405 1406
     */

    /* 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.
1407 1408 1409 1410
     */
    if (device->type == VIR_DOMAIN_DEVICE_CONTROLLER && addr->domain == 0 &&
        addr->bus == 0 && addr->slot == 1) {
        virDomainControllerDefPtr cont = device->data.controller;
1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423

        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 &&
1424
                !(addrs->buses[0].flags & VIR_PCI_CONNECT_TYPE_PCI)) {
1425 1426 1427 1428 1429 1430 1431 1432
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("Bus 0 must be PCI for integrated PIIX3 "
                                 "USB or IDE controllers"));
                return -1;
            } else {
                return 0;
            }
        }
1433 1434
    }

1435 1436
    entireSlot = (addr->function == 0 &&
                  addr->multi != VIR_DEVICE_ADDRESS_PCI_MULTI_ON);
1437

1438 1439
    if (virDomainPCIAddressReserveAddr(addrs, addr, flags,
                                       entireSlot, true) < 0)
1440
        goto cleanup;
1441

1442
    ret = 0;
1443
 cleanup:
1444
    return ret;
1445 1446
}

1447
static bool
1448 1449
qemuDomainSupportsPCI(virDomainDefPtr def)
{
1450
    if ((def->os.arch != VIR_ARCH_ARMV7L) && (def->os.arch != VIR_ARCH_AARCH64))
1451 1452 1453 1454 1455 1456 1457
        return true;

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

    return false;
}
1458

1459
int
1460
qemuDomainAssignPCIAddresses(virDomainDefPtr def,
1461
                             virQEMUCapsPtr qemuCaps,
1462
                             virDomainObjPtr obj)
1463 1464
{
    int ret = -1;
1465
    virDomainPCIAddressSetPtr addrs = NULL;
1466
    qemuDomainObjPrivatePtr priv = NULL;
1467

1468
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
1469
        int max_idx = -1;
1470
        int nbuses = 0;
1471
        size_t i;
1472
        int rv;
1473
        virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPE_PCI;
1474 1475

        for (i = 0; i < def->ncontrollers; i++) {
1476
            if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) {
1477
                if ((int) def->controllers[i]->idx > max_idx)
1478 1479 1480 1481 1482 1483 1484 1485 1486
                    max_idx = def->controllers[i]->idx;
            }
        }

        nbuses = max_idx + 1;

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

1488 1489 1490 1491 1492 1493
            /* 1st pass to figure out how many PCI bridges we need */
            if (!(addrs = qemuDomainPCIAddressSetCreate(def, nbuses, true)))
                goto cleanup;
            if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0)
                goto cleanup;
            /* Reserve 1 extra slot for a (potential) bridge */
1494
            if (virDomainPCIAddressReserveNextSlot(addrs, &info, flags) < 0)
1495 1496 1497
                goto cleanup;

            for (i = 1; i < addrs->nbuses; i++) {
1498
                virDomainPCIAddressBusPtr bus = &addrs->buses[i];
1499

1500
                if ((rv = virDomainDefMaybeAddController(
1501 1502
                         def, VIR_DOMAIN_CONTROLLER_TYPE_PCI,
                         i, bus->model)) < 0)
1503 1504
                    goto cleanup;
                /* If we added a new bridge, we will need one more address */
1505 1506
                if (rv > 0 && virDomainPCIAddressReserveNextSlot(addrs, &info,
                                                                 flags) < 0)
1507 1508 1509
                        goto cleanup;
            }
            nbuses = addrs->nbuses;
1510
            virDomainPCIAddressSetFree(addrs);
1511 1512 1513 1514 1515 1516 1517
            addrs = NULL;

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

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

1523 1524 1525 1526
        if (qemuDomainSupportsPCI(def)) {
            if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0)
                goto cleanup;
        }
1527 1528
    }

1529 1530 1531 1532
    if (obj && obj->privateData) {
        priv = obj->privateData;
        if (addrs) {
            /* if this is the live domain object, we persist the PCI addresses*/
1533
            virDomainPCIAddressSetFree(priv->pciaddrs);
1534 1535 1536 1537 1538 1539 1540 1541
            priv->persistentAddrs = 1;
            priv->pciaddrs = addrs;
            addrs = NULL;
        } else {
            priv->persistentAddrs = 0;
        }
    }

1542 1543
    ret = 0;

1544
 cleanup:
1545
    virDomainPCIAddressSetFree(addrs);
1546 1547 1548 1549

    return ret;
}

1550
int qemuDomainAssignAddresses(virDomainDefPtr def,
1551
                              virQEMUCapsPtr qemuCaps,
1552
                              virDomainObjPtr obj)
1553
{
1554 1555
    int rc;

1556
    rc = qemuDomainAssignSpaprVIOAddresses(def, qemuCaps);
1557 1558 1559
    if (rc)
        return rc;

1560 1561 1562
    rc = qemuDomainAssignS390Addresses(def, qemuCaps, obj);
    if (rc)
        return rc;
1563

1564 1565 1566 1567
    rc = qemuDomainAssignARMVirtioMMIOAddresses(def, qemuCaps);
    if (rc)
        return rc;

1568
    return qemuDomainAssignPCIAddresses(def, qemuCaps, obj);
1569
}
1570

1571

1572
virDomainPCIAddressSetPtr
1573 1574 1575
qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
                              unsigned int nbuses,
                              bool dryRun)
1576
{
1577
    virDomainPCIAddressSetPtr addrs;
1578
    size_t i;
1579

1580 1581
    if ((addrs = virDomainPCIAddressSetAlloc(nbuses)) == NULL)
        return NULL;
1582

1583
    addrs->nbuses = nbuses;
1584
    addrs->dryRun = dryRun;
1585

1586 1587 1588 1589 1590 1591 1592 1593
    /* 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)
1594 1595
       virDomainPCIAddressBusSetModel(&addrs->buses[0],
                                      VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT);
1596
    for (i = 1; i < nbuses; i++) {
1597 1598
        virDomainPCIAddressBusSetModel(&addrs->buses[i],
                                       VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE);
1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613
    }

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

1614 1615
        if (virDomainPCIAddressBusSetModel(&addrs->buses[idx],
                                           def->controllers[i]->model) < 0)
1616 1617
            goto error;
        }
1618

1619 1620 1621 1622 1623
    if (virDomainDeviceInfoIterate(def, qemuCollectPCIAddress, addrs) < 0)
        goto error;

    return addrs;

1624
 error:
1625
    virDomainPCIAddressSetFree(addrs);
1626 1627 1628
    return NULL;
}

1629

1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642
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 &&
        STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
        virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW) &&
J
Ján Tomko 已提交
1643
        virDomainCCWAddressReleaseAddr(priv->ccwaddrs, info) < 0)
1644 1645 1646 1647
        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) &&
1648 1649
             virDomainPCIAddressReleaseSlot(priv->pciaddrs,
                                            &info->addr.pci) < 0)
1650 1651 1652 1653 1654
        VIR_WARN("Unable to release PCI address on %s",
                 NULLSTR(devstr));
}


1655 1656 1657 1658 1659 1660 1661
#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))

1662 1663 1664 1665

static int
qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
                                virQEMUCapsPtr qemuCaps,
1666
                                virDomainPCIAddressSetPtr addrs)
1667
{
1668
    int ret = -1;
1669
    size_t i;
1670
    virDevicePCIAddress tmp_addr;
1671
    bool qemuDeviceVideoUsable = virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
1672
    char *addrStr = NULL;
1673
    virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI;
1674

1675
    /* Verify that first IDE and USB controllers (if any) is on the PIIX3, fn 1 */
1676
    for (i = 0; i < def->ncontrollers; i++) {
1677 1678 1679 1680 1681 1682 1683 1684
        /* 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) {
1685 1686
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("Primary IDE controller must have PCI address 0:0:1.1"));
1687
                    goto cleanup;
1688 1689 1690 1691 1692 1693 1694 1695
                }
            } 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;
            }
1696 1697
        } else if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
                   def->controllers[i]->idx == 0 &&
1698 1699
                   (def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI ||
                    def->controllers[i]->model == -1)) {
1700 1701 1702 1703 1704
            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) {
1705 1706
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("PIIX3 USB controller must have PCI address 0:0:1.2"));
1707
                    goto cleanup;
1708 1709 1710 1711 1712 1713 1714 1715
                }
            } 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;
            }
1716 1717 1718 1719 1720 1721
        }
    }

    /* PIIX3 (ISA bridge, IDE controller, something else unknown, USB controller)
     * hardcoded slot=1, multifunction device
     */
1722 1723 1724
    if (addrs->nbuses) {
        memset(&tmp_addr, 0, sizeof(tmp_addr));
        tmp_addr.slot = 1;
1725
        if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0)
1726
            goto cleanup;
W
Wen Congyang 已提交
1727
    }
1728 1729

    if (def->nvideos > 0) {
1730 1731 1732 1733 1734 1735
        /* 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.
         */
1736 1737
        virDomainVideoDefPtr primaryVideo = def->videos[0];
        if (primaryVideo->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
1738 1739 1740
            memset(&tmp_addr, 0, sizeof(tmp_addr));
            tmp_addr.slot = 2;

1741
            if (!(addrStr = virDomainPCIAddressAsString(&tmp_addr)))
1742
                goto cleanup;
1743 1744
            if (!virDomainPCIAddressValidate(addrs, &tmp_addr,
                                             addrStr, flags, false))
1745
                goto cleanup;
1746

1747
            if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
1748
                if (qemuDeviceVideoUsable) {
1749 1750 1751
                    if (virDomainPCIAddressReserveNextSlot(addrs,
                                                           &primaryVideo->info,
                                                           flags) < 0)
1752
                        goto cleanup;
1753 1754 1755 1756
                } else {
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("PCI address 0:0:2.0 is in use, "
                                     "QEMU needs it for primary video"));
1757
                    goto cleanup;
1758
                }
1759
            } else {
1760
                if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0)
1761 1762 1763
                    goto cleanup;
                primaryVideo->info.addr.pci = tmp_addr;
                primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
1764 1765 1766 1767 1768 1769
            }
        } 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) {
1770 1771
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("Primary video card must have PCI address 0:0:2.0"));
1772
                goto cleanup;
1773
            }
1774
            /* If TYPE == PCI, then qemuCollectPCIAddress() function
1775
             * has already reserved the address, so we must skip */
1776
        }
1777
    } else if (addrs->nbuses && !qemuDeviceVideoUsable) {
1778 1779
        memset(&tmp_addr, 0, sizeof(tmp_addr));
        tmp_addr.slot = 2;
1780

1781
        if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
1782 1783 1784 1785
            VIR_DEBUG("PCI address 0:0:2.0 in use, future addition of a video"
                      " device will not be possible without manual"
                      " intervention");
            virResetLastError();
1786
        } else if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0) {
1787
            goto cleanup;
1788 1789
        }
    }
1790
    ret = 0;
1791
 cleanup:
1792 1793
    VIR_FREE(addrStr);
    return ret;
1794 1795 1796
}


1797 1798 1799 1800 1801 1802 1803 1804
static bool
qemuDomainMachineIsQ35(virDomainDefPtr def)
{
    return (STRPREFIX(def->os.machine, "pc-q35") ||
            STREQ(def->os.machine, "q35"));
}


1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815
static bool
qemuDomainMachineIsI440FX(virDomainDefPtr def)
{
    return (STREQ(def->os.machine, "pc") ||
            STRPREFIX(def->os.machine, "pc-0.") ||
            STRPREFIX(def->os.machine, "pc-1.") ||
            STRPREFIX(def->os.machine, "pc-i440") ||
            STRPREFIX(def->os.machine, "rhel"));
}


1816 1817 1818
static int
qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
                                    virQEMUCapsPtr qemuCaps,
1819
                                    virDomainPCIAddressSetPtr addrs)
1820
{
1821
    int ret = -1;
1822 1823 1824
    size_t i;
    virDevicePCIAddress tmp_addr;
    bool qemuDeviceVideoUsable = virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
1825
    char *addrStr = NULL;
1826
    virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPE_PCIE;
1827 1828

    for (i = 0; i < def->ncontrollers; i++) {
1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850
        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;
1851 1852
                }
            }
1853
            break;
1854 1855 1856 1857 1858 1859 1860 1861 1862 1863

        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;
1864 1865 1866
                if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
                    if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr,
                                                       flags, true, false) < 0)
1867 1868 1869 1870 1871 1872 1873 1874 1875
                        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;
1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888
        }
    }

    /* Reserve slot 0x1F function 0 (ISA bridge, not in config model)
     * and function 3 (SMBus, also not (yet) in config model). As with
     * the SATA controller, these devices are always present in a q35
     * machine; there is no way to not have them.
     */
    if (addrs->nbuses) {
        memset(&tmp_addr, 0, sizeof(tmp_addr));
        tmp_addr.slot = 0x1F;
        tmp_addr.function = 0;
        tmp_addr.multi = 1;
1889 1890
        if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,
                                           false, false) < 0)
1891
           goto cleanup;
1892 1893
        tmp_addr.function = 3;
        tmp_addr.multi = 0;
1894 1895
        if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,
                                           false, false) < 0)
1896
           goto cleanup;
1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907
    }

    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) {
1908 1909 1910
            memset(&tmp_addr, 0, sizeof(tmp_addr));
            tmp_addr.slot = 1;

1911
            if (!(addrStr = virDomainPCIAddressAsString(&tmp_addr)))
1912
                goto cleanup;
1913 1914
            if (!virDomainPCIAddressValidate(addrs, &tmp_addr,
                                             addrStr, flags, false))
1915
                goto cleanup;
1916

1917
            if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
1918
                if (qemuDeviceVideoUsable) {
1919 1920 1921
                    if (virDomainPCIAddressReserveNextSlot(addrs,
                                                           &primaryVideo->info,
                                                           flags) < 0)
1922
                        goto cleanup;
1923 1924 1925 1926
                } else {
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("PCI address 0:0:1.0 is in use, "
                                     "QEMU needs it for primary video"));
1927
                    goto cleanup;
1928
                }
1929
            } else {
1930
                if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0)
1931 1932 1933
                    goto cleanup;
                primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
                primaryVideo->info.addr.pci = tmp_addr;
1934 1935 1936 1937 1938 1939 1940 1941
            }
        } 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"));
1942
                goto cleanup;
1943
            }
1944
            /* If TYPE == PCI, then qemuCollectPCIAddress() function
1945 1946 1947 1948 1949 1950
             * 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;

1951
        if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
1952 1953 1954 1955
            VIR_DEBUG("PCI address 0:0:1.0 in use, future addition of a video"
                      " device will not be possible without manual"
                      " intervention");
            virResetLastError();
1956
        } else if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0) {
1957
            goto cleanup;
1958 1959
        }
    }
1960
    ret = 0;
1961
 cleanup:
1962 1963
    VIR_FREE(addrStr);
    return ret;
1964 1965 1966
}


1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001
/*
 * 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)
 *
 * Incrementally assign slots from 3 onwards:
 *
 *  - Net
 *  - Sound
 *  - SCSI controllers
 *  - VirtIO block
 *  - VirtIO balloon
 *  - Host device passthrough
 *  - Watchdog (not IB700)
 *
 * 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,
                         virQEMUCapsPtr qemuCaps,
2002
                         virDomainPCIAddressSetPtr addrs)
2003 2004
{
    size_t i, j;
2005
    virDomainPCIConnectFlags flags;
2006 2007 2008 2009 2010 2011 2012 2013 2014 2015
    virDevicePCIAddress tmp_addr;

    if ((STRPREFIX(def->os.machine, "pc-0.") ||
        STRPREFIX(def->os.machine, "pc-1.") ||
        STRPREFIX(def->os.machine, "pc-i440") ||
        STREQ(def->os.machine, "pc") ||
        STRPREFIX(def->os.machine, "rhel")) &&
        qemuValidateDevicePCISlotsPIIX3(def, qemuCaps, addrs) < 0) {
        goto error;
    }
2016

2017 2018 2019 2020 2021
    if (qemuDomainMachineIsQ35(def) &&
        qemuDomainValidateDevicePCISlotsQ35(def, qemuCaps, addrs) < 0) {
        goto error;
    }

2022 2023 2024 2025 2026
    /* 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;
2027 2028
            switch (def->controllers[i]->model) {
            case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
L
Laine Stump 已提交
2029 2030
            case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
                /* pci-root and pcie-root are implicit in the machine,
2031 2032 2033 2034 2035 2036
                 * 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)
                 */
2037
                flags = VIR_PCI_CONNECT_TYPE_PCI;
2038
                break;
2039 2040 2041 2042
            case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
                /* dmi-to-pci-bridge requires a non-hotplug PCIe
                 * slot
                 */
2043
                flags = VIR_PCI_CONNECT_TYPE_PCIE;
2044
                break;
2045
            default:
2046
                flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI;
2047 2048
                break;
            }
2049 2050 2051
            if (virDomainPCIAddressReserveNextSlot(addrs,
                                                   &def->controllers[i]->info,
                                                   flags) < 0)
2052 2053 2054 2055
                goto error;
        }
    }

2056
    flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI;
2057

2058
    for (i = 0; i < def->nfss; i++) {
2059 2060 2061 2062 2063
        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 */
2064 2065
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->fss[i]->info,
                                               flags) < 0)
2066 2067 2068 2069
            goto error;
    }

    /* Network interfaces */
2070
    for (i = 0; i < def->nnets; i++) {
2071 2072 2073 2074 2075 2076
        /* 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)) {
2077
            continue;
2078
        }
2079 2080
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->nets[i]->info,
                                               flags) < 0)
2081 2082 2083 2084
            goto error;
    }

    /* Sound cards */
2085
    for (i = 0; i < def->nsounds; i++) {
2086 2087 2088 2089 2090 2091 2092
        if (def->sounds[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            continue;
        /* Skip ISA sound card, and PCSPK */
        if (def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_SB16 ||
            def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_PCSPK)
            continue;

2093 2094
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->sounds[i]->info,
                                               flags) < 0)
2095 2096 2097
            goto error;
    }

2098
    /* Device controllers (SCSI, USB, but not IDE, FDC or CCID) */
2099
    for (i = 0; i < def->ncontrollers; i++) {
2100
        /* PCI controllers have been dealt with earlier */
2101 2102
        if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI)
            continue;
2103

2104 2105 2106 2107 2108
        /* 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 已提交
2109 2110 2111
        /* 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)
2112 2113 2114 2115 2116 2117 2118 2119
            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;

2120 2121
        if (def->controllers[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO)
            continue;
2122 2123
        if (def->controllers[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            continue;
2124 2125 2126

        /* USB2 needs special handling to put all companions in the same slot */
        if (IS_USB2_CONTROLLER(def->controllers[i])) {
2127
            virDevicePCIAddress addr = { 0, 0, 0, 0, false };
2128
            memset(&tmp_addr, 0, sizeof(tmp_addr));
2129
            for (j = 0; j < i; j++) {
2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142
                if (IS_USB2_CONTROLLER(def->controllers[j]) &&
                    def->controllers[j]->idx == def->controllers[i]->idx) {
                    addr = def->controllers[j]->info.addr.pci;
                    break;
                }
            }

            switch (def->controllers[i]->model) {
            case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1:
                addr.function = 7;
                break;
            case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI1:
                addr.function = 0;
2143
                addr.multi = VIR_DEVICE_ADDRESS_PCI_MULTI_ON;
2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155
                break;
            case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI2:
                addr.function = 1;
                break;
            case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI3:
                addr.function = 2;
                break;
            }

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

2159 2160
                addr.bus = tmp_addr.bus;
                addr.slot = tmp_addr.slot;
2161 2162 2163 2164

                addrs->lastaddr = addr;
                addrs->lastaddr.function = 0;
                addrs->lastaddr.multi = 0;
2165 2166
            }
            /* Finally we can reserve the slot+function */
2167 2168
            if (virDomainPCIAddressReserveAddr(addrs, &addr, flags,
                                               false, false) < 0)
2169 2170 2171 2172 2173
                goto error;

            def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
            def->controllers[i]->info.addr.pci = addr;
        } else {
2174 2175 2176
            if (virDomainPCIAddressReserveNextSlot(addrs,
                                                   &def->controllers[i]->info,
                                                   flags) < 0)
2177 2178
                goto error;
        }
2179 2180
    }

2181
    /* Disks (VirtIO only for now) */
2182
    for (i = 0; i < def->ndisks; i++) {
2183 2184 2185 2186
        /* Only VirtIO disks use PCI addrs */
        if (def->disks[i]->bus != VIR_DOMAIN_DISK_BUS_VIRTIO)
            continue;

2187 2188 2189
        /* don't touch s390 devices */
        if (def->disks[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI ||
            def->disks[i]->info.type ==
2190 2191 2192
            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 ||
            def->disks[i]->info.type ==
            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
2193 2194 2195
            continue;

        if (def->disks[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
2196 2197
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("virtio only support device address type 'PCI'"));
2198 2199 2200
            goto error;
        }

2201 2202
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->disks[i]->info,
                                               flags) < 0)
2203 2204 2205 2206
            goto error;
    }

    /* Host PCI devices */
2207
    for (i = 0; i < def->nhostdevs; i++) {
2208
        if (def->hostdevs[i]->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
2209 2210 2211 2212 2213
            continue;
        if (def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
            def->hostdevs[i]->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
            continue;

2214 2215 2216
        if (virDomainPCIAddressReserveNextSlot(addrs,
                                               def->hostdevs[i]->info,
                                               flags) < 0)
2217 2218 2219 2220 2221 2222 2223
            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) {
2224 2225 2226
        if (virDomainPCIAddressReserveNextSlot(addrs,
                                               &def->memballoon->info,
                                               flags) < 0)
2227 2228 2229
            goto error;
    }

2230 2231 2232 2233
    /* VirtIO RNG */
    if (def->rng &&
        def->rng->model == VIR_DOMAIN_RNG_MODEL_VIRTIO &&
        def->rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
2234 2235
        if (virDomainPCIAddressReserveNextSlot(addrs,
                                               &def->rng->info, flags) < 0)
2236 2237 2238
            goto error;
    }

2239
    /* A watchdog - skip IB700, it is not a PCI device */
2240
    if (def->watchdog &&
2241
        def->watchdog->model != VIR_DOMAIN_WATCHDOG_MODEL_IB700 &&
2242
        def->watchdog->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
2243 2244
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->watchdog->info,
                                               flags) < 0)
2245 2246 2247
            goto error;
    }

2248 2249 2250 2251
    /* 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) {
2252 2253
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->videos[0]->info,
                                               flags) < 0)
2254 2255
            goto error;
    }
2256
    /* Further non-primary video cards which have to be qxl type */
2257
    for (i = 1; i < def->nvideos; i++) {
2258 2259 2260 2261 2262
        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;
        }
2263 2264
        if (def->videos[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
            continue;
2265 2266
        if (virDomainPCIAddressReserveNextSlot(addrs, &def->videos[i]->info,
                                               flags) < 0)
2267 2268
            goto error;
    }
2269
    for (i = 0; i < def->ninputs; i++) {
2270 2271
        /* Nada - none are PCI based (yet) */
    }
2272
    for (i = 0; i < def->nparallels; i++) {
2273 2274
        /* Nada - none are PCI based (yet) */
    }
2275
    for (i = 0; i < def->nserials; i++) {
2276 2277
        /* Nada - none are PCI based (yet) */
    }
2278
    for (i = 0; i < def->nchannels; i++) {
2279 2280
        /* Nada - none are PCI based (yet) */
    }
2281
    for (i = 0; i < def->nhubs; i++) {
M
Marc-André Lureau 已提交
2282 2283
        /* Nada - none are PCI based (yet) */
    }
2284 2285 2286

    return 0;

2287
 error:
2288 2289 2290
    return -1;
}

2291
static void
2292
qemuUSBId(virBufferPtr buf, int idx)
2293 2294
{
    if (idx == 0)
2295
        virBufferAddLit(buf, "usb");
2296 2297 2298
    else
        virBufferAsprintf(buf, "usb%d", idx);
}
2299 2300 2301

static int
qemuBuildDeviceAddressStr(virBufferPtr buf,
2302
                          virDomainDefPtr domainDef,
2303
                          virDomainDeviceInfoPtr info,
2304
                          virQEMUCapsPtr qemuCaps)
2305
{
2306 2307 2308
    int ret = -1;
    char *devStr = NULL;

2309
    if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
2310 2311 2312
        const char *contAlias = NULL;
        size_t i;

2313
        if (!(devStr = virDomainPCIAddressAsString(&info->addr.pci)))
2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340
            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;
        }

2341
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIFUNCTION)) {
W
Wen Congyang 已提交
2342
            if (info->addr.pci.function != 0) {
2343 2344 2345
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("Only PCI device addresses with function=0 "
                                 "are supported with this QEMU binary"));
2346
                goto cleanup;
2347
            }
2348
            if (info->addr.pci.multi == VIR_DEVICE_ADDRESS_PCI_MULTI_ON) {
2349 2350 2351
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("'multifunction=on' is not supported with "
                                 "this QEMU binary"));
2352
                goto cleanup;
W
Wen Congyang 已提交
2353
            }
2354 2355
        }

2356 2357 2358 2359 2360 2361 2362
        /*
         * PCI bridge support is required for multiple buses
         * 'pci.%u' is the ID of the bridge as specified in
         * qemuBuildControllerDevStr
         *
         * PCI_MULTIBUS capability indicates that the implicit
         * PCI bus is named 'pci.0' instead of 'pci'.
2363
         */
2364 2365
        if (info->addr.pci.bus != 0) {
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCI_BRIDGE)) {
2366
                virBufferAsprintf(buf, ",bus=%s", contAlias);
2367 2368 2369 2370
            } else {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("Multiple PCI buses are not supported "
                                 "with this QEMU binary"));
2371
                goto cleanup;
2372 2373
            }
        } else {
D
Daniel P. Berrange 已提交
2374
            if (virQEMUCapsHasPCIMultiBus(qemuCaps, domainDef)) {
2375 2376
                virBufferAsprintf(buf, ",bus=%s", contAlias);
            } else {
2377
                virBufferAddLit(buf, ",bus=pci");
2378
            }
2379
        }
2380
        if (info->addr.pci.multi == VIR_DEVICE_ADDRESS_PCI_MULTI_ON)
2381
            virBufferAddLit(buf, ",multifunction=on");
2382
        else if (info->addr.pci.multi == VIR_DEVICE_ADDRESS_PCI_MULTI_OFF)
2383 2384 2385 2386
            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);
2387
    } else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
2388
        virBufferAddLit(buf, ",bus=");
2389
        qemuUSBId(buf, info->addr.usb.bus);
2390
        virBufferAsprintf(buf, ".0,port=%s", info->addr.usb.port);
2391 2392 2393
    } 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);
2394 2395 2396 2397 2398 2399
    } 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);
2400
    }
2401

2402
    ret = 0;
2403
 cleanup:
2404 2405
    VIR_FREE(devStr);
    return ret;
2406 2407
}

2408 2409 2410
static int
qemuBuildRomStr(virBufferPtr buf,
                virDomainDeviceInfoPtr info,
2411
                virQEMUCapsPtr qemuCaps)
2412
{
2413
    if (info->rombar || info->romfile) {
2414
        if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
2415 2416
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("rombar and romfile are supported only for PCI devices"));
2417 2418
            return -1;
        }
2419
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_ROMBAR)) {
2420 2421
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("rombar and romfile not supported in this QEMU binary"));
2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434
            return -1;
        }

        switch (info->rombar) {
        case VIR_DOMAIN_PCI_ROMBAR_OFF:
            virBufferAddLit(buf, ",rombar=0");
            break;
        case VIR_DOMAIN_PCI_ROMBAR_ON:
            virBufferAddLit(buf, ",rombar=1");
            break;
        default:
            break;
        }
2435 2436
        if (info->romfile)
           virBufferAsprintf(buf, ",romfile=%s", info->romfile);
2437 2438 2439 2440
    }
    return 0;
}

2441 2442
static int
qemuBuildIoEventFdStr(virBufferPtr buf,
2443
                      virDomainIoEventFd use,
2444
                      virQEMUCapsPtr qemuCaps)
2445
{
2446
    if (use && virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_IOEVENTFD))
2447 2448 2449 2450
        virBufferAsprintf(buf, ",ioeventfd=%s",
                          virDomainIoEventFdTypeToString(use));
    return 0;
}
2451 2452 2453 2454 2455 2456 2457

#define QEMU_SERIAL_PARAM_ACCEPTED_CHARS \
  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"

static int
qemuSafeSerialParamValue(const char *value)
{
2458
    if (strspn(value, QEMU_SERIAL_PARAM_ACCEPTED_CHARS) != strlen(value)) {
2459 2460 2461
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("driver serial '%s' contains unsafe characters"),
                       value);
2462 2463 2464 2465 2466 2467
        return -1;
    }

    return 0;
}

2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479
static char *
qemuGetSecretString(virConnectPtr conn,
                    const char *scheme,
                    bool encoded,
                    int diskSecretType,
                    char *username,
                    unsigned char *uuid, char *usage,
                    virSecretUsageType secretUsageType)
{
    size_t secret_size;
    virSecretPtr sec = NULL;
    char *secret = NULL;
2480
    char uuidStr[VIR_UUID_STRING_BUFLEN];
2481 2482 2483

    /* look up secret */
    switch (diskSecretType) {
2484
    case VIR_STORAGE_SECRET_TYPE_UUID:
2485
        sec = virSecretLookupByUUID(conn, uuid);
2486
        virUUIDFormat(uuid, uuidStr);
2487
        break;
2488
    case VIR_STORAGE_SECRET_TYPE_USAGE:
2489 2490 2491 2492 2493
        sec = virSecretLookupByUsage(conn, secretUsageType, usage);
        break;
    }

    if (!sec) {
2494
        if (diskSecretType == VIR_STORAGE_SECRET_TYPE_UUID) {
2495 2496
            virReportError(VIR_ERR_NO_SECRET,
                           _("%s no secret matches uuid '%s'"),
2497
                           scheme, uuidStr);
2498 2499 2500 2501 2502
        } else {
            virReportError(VIR_ERR_NO_SECRET,
                           _("%s no secret matches usage value '%s'"),
                           scheme, usage);
        }
2503 2504 2505 2506 2507 2508
        goto cleanup;
    }

    secret = (char *)conn->secretDriver->secretGetValue(sec, &secret_size, 0,
                                                        VIR_SECRET_GET_VALUE_INTERNAL_CALL);
    if (!secret) {
2509
        if (diskSecretType == VIR_STORAGE_SECRET_TYPE_UUID) {
2510 2511 2512
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("could not get value of the secret for "
                             "username '%s' using uuid '%s'"),
2513
                           username, uuidStr);
2514 2515 2516 2517 2518 2519
        } else {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("could not get value of the secret for "
                             "username '%s' using usage value '%s'"),
                           username, usage);
        }
2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534
        goto cleanup;
    }

    if (encoded) {
        char *base64 = NULL;

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

2535
 cleanup:
2536 2537 2538
    virObjectUnref(sec);
    return secret;
}
2539

2540 2541 2542 2543

static int qemuAddRBDHost(virDomainDiskDefPtr disk, char *hostport)
{
    char *port;
2544 2545
    size_t skip;
    char **parts;
2546

2547
    if (VIR_EXPAND_N(disk->src->hosts, disk->src->nhosts, 1) < 0)
2548
        return -1;
2549

2550 2551 2552 2553 2554 2555 2556 2557 2558
    if ((port = strchr(hostport, ']'))) {
        /* ipv6, strip brackets */
        hostport += 1;
        skip = 3;
    } else {
        port = strstr(hostport, "\\:");
        skip = 2;
    }

2559 2560
    if (port) {
        *port = '\0';
2561
        port += skip;
2562
        if (VIR_STRDUP(disk->src->hosts[disk->src->nhosts - 1].port, port) < 0)
2563
            goto error;
2564
    } else {
2565
        if (VIR_STRDUP(disk->src->hosts[disk->src->nhosts - 1].port, "6789") < 0)
2566
            goto error;
2567
    }
2568 2569 2570

    parts = virStringSplit(hostport, "\\:", 0);
    if (!parts)
2571
        goto error;
2572
    disk->src->hosts[disk->src->nhosts-1].name = virStringJoin((const char **)parts, ":");
2573
    virStringFreeList(parts);
2574
    if (!disk->src->hosts[disk->src->nhosts-1].name)
2575
        goto error;
2576

2577 2578
    disk->src->hosts[disk->src->nhosts-1].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
    disk->src->hosts[disk->src->nhosts-1].socket = NULL;
2579

2580 2581
    return 0;

2582
 error:
2583 2584
    VIR_FREE(disk->src->hosts[disk->src->nhosts-1].port);
    VIR_FREE(disk->src->hosts[disk->src->nhosts-1].name);
2585 2586 2587 2588 2589 2590 2591 2592 2593
    return -1;
}

/* disk->src initially has everything after the rbd: prefix */
static int qemuParseRBDString(virDomainDiskDefPtr disk)
{
    char *options = NULL;
    char *p, *e, *next;

2594
    p = strchr(disk->src->path, ':');
2595
    if (p) {
2596 2597
        if (VIR_STRDUP(options, p + 1) < 0)
            goto error;
2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621
        *p = '\0';
    }

    /* options */
    if (!options)
        return 0; /* all done */

    p = options;
    while (*p) {
        /* find : delimiter or end of string */
        for (e = p; *e && *e != ':'; ++e) {
            if (*e == '\\') {
                e++;
                if (*e == '\0')
                    break;
            }
        }
        if (*e == '\0') {
            next = e;    /* last kv pair */
        } else {
            next = e + 1;
            *e = '\0';
        }

2622
        if (STRPREFIX(p, "id=") &&
2623
            VIR_STRDUP(disk->src->auth.username, p + strlen("id=")) < 0)
2624
            goto error;
2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638
        if (STRPREFIX(p, "mon_host=")) {
            char *h, *sep;

            h = p + strlen("mon_host=");
            while (h < e) {
                for (sep = h; sep < e; ++sep) {
                    if (*sep == '\\' && (sep[1] == ',' ||
                                         sep[1] == ';' ||
                                         sep[1] == ' ')) {
                        *sep = '\0';
                        sep += 2;
                        break;
                    }
                }
2639 2640 2641
                if (qemuAddRBDHost(disk, h) < 0)
                    goto error;

2642 2643 2644 2645 2646 2647
                h = sep;
            }
        }

        p = next;
    }
2648
    VIR_FREE(options);
2649 2650
    return 0;

2651
 error:
2652
    VIR_FREE(options);
2653 2654
    return -1;
}
2655

2656
static int
P
Paolo Bonzini 已提交
2657 2658
qemuParseDriveURIString(virDomainDiskDefPtr def, virURIPtr uri,
                        const char *scheme)
2659 2660 2661 2662 2663
{
    int ret = -1;
    char *transp = NULL;
    char *sock = NULL;
    char *volimg = NULL;
2664
    char *secret = NULL;
2665

2666
    if (VIR_ALLOC(def->src->hosts) < 0)
2667
        goto error;
2668

P
Paolo Bonzini 已提交
2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679
    transp = strchr(uri->scheme, '+');
    if (transp)
        *transp++ = 0;

    if (!STREQ(uri->scheme, scheme)) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Invalid transport/scheme '%s'"), uri->scheme);
        goto error;
    }

    if (!transp) {
2680
        def->src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
P
Paolo Bonzini 已提交
2681
    } else {
2682 2683
        def->src->hosts->transport = virStorageNetHostTransportTypeFromString(transp);
        if (def->src->hosts->transport < 0) {
2684
            virReportError(VIR_ERR_INTERNAL_ERROR,
P
Paolo Bonzini 已提交
2685
                           _("Invalid %s transport type '%s'"), scheme, transp);
2686 2687 2688
            goto error;
        }
    }
2689
    def->src->nhosts = 0; /* set to 1 once everything succeeds */
2690

2691 2692
    if (def->src->hosts->transport != VIR_STORAGE_NET_HOST_TRANS_UNIX) {
        if (VIR_STRDUP(def->src->hosts->name, uri->server) < 0)
2693
            goto error;
2694

2695
        if (virAsprintf(&def->src->hosts->port, "%d", uri->port) < 0)
2696
            goto error;
2697
    } else {
2698 2699
        def->src->hosts->name = NULL;
        def->src->hosts->port = 0;
2700 2701 2702
        if (uri->query) {
            if (STRPREFIX(uri->query, "socket=")) {
                sock = strchr(uri->query, '=') + 1;
2703
                if (VIR_STRDUP(def->src->hosts->socket, sock) < 0)
2704
                    goto error;
2705 2706 2707 2708 2709 2710 2711
            } else {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("Invalid query parameter '%s'"), uri->query);
                goto error;
            }
        }
    }
P
Paolo Bonzini 已提交
2712 2713
    if (uri->path) {
        volimg = uri->path + 1; /* skip the prefix slash */
2714 2715
        VIR_FREE(def->src->path);
        if (VIR_STRDUP(def->src->path, volimg) < 0)
2716
            goto error;
P
Paolo Bonzini 已提交
2717
    } else {
2718
        VIR_FREE(def->src->path);
P
Paolo Bonzini 已提交
2719
    }
2720

2721 2722 2723 2724 2725
    if (uri->user) {
        secret = strchr(uri->user, ':');
        if (secret)
            *secret = '\0';

2726
        if (VIR_STRDUP(def->src->auth.username, uri->user) < 0)
2727
            goto error;
2728 2729
    }

2730
    def->src->nhosts = 1;
2731 2732
    ret = 0;

2733
 cleanup:
2734 2735 2736 2737
    virURIFree(uri);

    return ret;

2738
 error:
2739 2740
    virStorageNetHostDefClear(def->src->hosts);
    VIR_FREE(def->src->hosts);
2741 2742 2743
    goto cleanup;
}

P
Paolo Bonzini 已提交
2744 2745 2746 2747 2748
static int
qemuParseGlusterString(virDomainDiskDefPtr def)
{
    virURIPtr uri = NULL;

2749
    if (!(uri = virURIParse(def->src->path)))
P
Paolo Bonzini 已提交
2750 2751 2752 2753 2754
        return -1;

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

P
Paolo Bonzini 已提交
2755 2756 2757 2758 2759 2760 2761
static int
qemuParseISCSIString(virDomainDiskDefPtr def)
{
    virURIPtr uri = NULL;
    char *slash;
    unsigned lun;

2762
    if (!(uri = virURIParse(def->src->path)))
P
Paolo Bonzini 已提交
2763 2764 2765 2766 2767 2768 2769 2770 2771
        return -1;

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

        if (slash[1] == '\0')
            *slash = '\0';
        else if (virStrToLong_ui(slash + 1, NULL, 10, &lun) == -1) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
2772
                           _("invalid name '%s' for iSCSI disk"),
2773
                           def->src->path);
P
Paolo Bonzini 已提交
2774 2775 2776 2777 2778 2779 2780
            return -1;
        }
    }

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

2781 2782 2783
static int
qemuParseNBDString(virDomainDiskDefPtr disk)
{
2784
    virStorageNetHostDefPtr h = NULL;
2785
    char *host, *port;
P
Paolo Bonzini 已提交
2786
    char *src;
2787

P
Paolo Bonzini 已提交
2788 2789
    virURIPtr uri = NULL;

2790 2791
    if (strstr(disk->src->path, "://")) {
        if (!(uri = virURIParse(disk->src->path)))
2792 2793
            return -1;
        return qemuParseDriveURIString(disk, uri, "nbd");
P
Paolo Bonzini 已提交
2794 2795
    }

2796
    if (VIR_ALLOC(h) < 0)
2797
        goto error;
2798

2799
    host = disk->src->path + strlen("nbd:");
2800 2801 2802 2803
    if (STRPREFIX(host, "unix:/")) {
        src = strchr(host + strlen("unix:"), ':');
        if (src)
            *src++ = '\0';
2804

2805
        h->transport = VIR_STORAGE_NET_HOST_TRANS_UNIX;
2806 2807
        if (VIR_STRDUP(h->socket, host + strlen("unix:")) < 0)
            goto error;
2808 2809 2810 2811
    } else {
        port = strchr(host, ':');
        if (!port) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
2812
                           _("cannot parse nbd filename '%s'"), disk->src->path);
2813 2814
            goto error;
        }
2815

2816
        *port++ = '\0';
2817 2818
        if (VIR_STRDUP(h->name, host) < 0)
            goto error;
P
Paolo Bonzini 已提交
2819

2820 2821 2822 2823
        src = strchr(port, ':');
        if (src)
            *src++ = '\0';

2824 2825
        if (VIR_STRDUP(h->port, port) < 0)
            goto error;
2826
    }
2827

P
Paolo Bonzini 已提交
2828
    if (src && STRPREFIX(src, "exportname=")) {
2829 2830
        if (VIR_STRDUP(src, strchr(src, '=') + 1) < 0)
            goto error;
P
Paolo Bonzini 已提交
2831 2832 2833 2834
    } else {
        src = NULL;
    }

2835 2836 2837 2838
    VIR_FREE(disk->src->path);
    disk->src->path = src;
    disk->src->nhosts = 1;
    disk->src->hosts = h;
2839 2840
    return 0;

2841
 error:
2842
    virStorageNetHostDefClear(h);
2843 2844 2845 2846
    VIR_FREE(h);
    return -1;
}

2847

2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864
static int
qemuNetworkDriveGetPort(int protocol,
                        const char *port)
{
    int ret = 0;

    if (port) {
        if (virStrToLong_i(port, NULL, 10, &ret) < 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("failed to parse port number '%s'"),
                           port);
            return -1;
        }

        return ret;
    }

2865
    switch ((virStorageNetProtocol) protocol) {
2866
        case VIR_STORAGE_NET_PROTOCOL_HTTP:
2867 2868
            return 80;

2869
        case VIR_STORAGE_NET_PROTOCOL_HTTPS:
2870 2871
            return 443;

2872
        case VIR_STORAGE_NET_PROTOCOL_FTP:
2873 2874
            return 21;

2875
        case VIR_STORAGE_NET_PROTOCOL_FTPS:
2876 2877
            return 990;

2878
        case VIR_STORAGE_NET_PROTOCOL_TFTP:
2879 2880
            return 69;

2881
        case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
2882 2883
            return 7000;

2884
        case VIR_STORAGE_NET_PROTOCOL_NBD:
2885 2886
            return 10809;

2887 2888
        case VIR_STORAGE_NET_PROTOCOL_ISCSI:
        case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
2889 2890 2891
            /* no default port specified */
            return 0;

2892 2893
        case VIR_STORAGE_NET_PROTOCOL_RBD:
        case VIR_STORAGE_NET_PROTOCOL_LAST:
2894 2895
        case VIR_STORAGE_NET_PROTOCOL_NONE:
            /* not applicable */
2896 2897 2898 2899 2900 2901
            return -1;
    }

    return -1;
}

2902
#define QEMU_DEFAULT_NBD_PORT "10809"
2903

2904
static char *
2905 2906
qemuBuildNetworkDriveURI(int protocol,
                         const char *src,
2907
                         const char *volume,
2908
                         size_t nhosts,
2909
                         virStorageNetHostDefPtr hosts,
2910 2911 2912 2913
                         const char *username,
                         const char *secret)
{
    char *ret = NULL;
2914
    virBuffer buf = VIR_BUFFER_INITIALIZER;
2915
    virURIPtr uri = NULL;
2916
    size_t i;
2917

2918
    switch ((virStorageNetProtocol) protocol) {
2919
        case VIR_STORAGE_NET_PROTOCOL_NBD:
2920 2921 2922
            if (nhosts != 1) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("protocol '%s' accepts only one host"),
2923
                               virStorageNetProtocolTypeToString(protocol));
2924 2925 2926 2927
                goto cleanup;
            }

            if (!((hosts->name && strchr(hosts->name, ':')) ||
2928
                  (hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP &&
2929
                   !hosts->name) ||
2930
                  (hosts->transport == VIR_STORAGE_NET_HOST_TRANS_UNIX &&
2931 2932 2933 2934 2935 2936
                   hosts->socket &&
                   hosts->socket[0] != '/'))) {

                virBufferAddLit(&buf, "nbd:");

                switch (hosts->transport) {
2937
                case VIR_STORAGE_NET_HOST_TRANS_TCP:
2938 2939 2940 2941 2942 2943
                    virBufferStrcat(&buf, hosts->name, NULL);
                    virBufferAsprintf(&buf, ":%s",
                                      hosts->port ? hosts->port :
                                      QEMU_DEFAULT_NBD_PORT);
                    break;

2944
                case VIR_STORAGE_NET_HOST_TRANS_UNIX:
2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957
                    if (!hosts->socket) {
                        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                       _("socket attribute required for "
                                         "unix transport"));
                        goto cleanup;
                    }

                    virBufferAsprintf(&buf, "unix:%s", hosts->socket);
                    break;

                default:
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("nbd does not support transport '%s'"),
2958
                                   virStorageNetHostTransportTypeToString(hosts->transport));
2959 2960 2961 2962 2963 2964
                    goto cleanup;
                }

                if (src)
                    virBufferAsprintf(&buf, ":exportname=%s", src);

2965
                if (virBufferCheckError(&buf) < 0)
2966 2967 2968 2969 2970 2971 2972 2973
                    goto cleanup;

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

2974 2975 2976 2977 2978 2979 2980
        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:
2981 2982 2983
            if (nhosts != 1) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("protocol '%s' accepts only one host"),
2984
                               virStorageNetProtocolTypeToString(protocol));
2985 2986
                goto cleanup;
            }
2987

2988 2989
            if (VIR_ALLOC(uri) < 0)
                goto cleanup;
2990

2991
            if (hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP) {
2992
                if (VIR_STRDUP(uri->scheme,
2993
                               virStorageNetProtocolTypeToString(protocol)) < 0)
2994 2995 2996
                    goto cleanup;
            } else {
                if (virAsprintf(&uri->scheme, "%s+%s",
2997
                                virStorageNetProtocolTypeToString(protocol),
2998
                                virStorageNetHostTransportTypeToString(hosts->transport)) < 0)
2999 3000
                    goto cleanup;
            }
3001

3002 3003
            if ((uri->port = qemuNetworkDriveGetPort(protocol, hosts->port)) < 0)
                goto cleanup;
3004

3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016
            if (src) {
                if (volume) {
                    if (virAsprintf(&uri->path, "/%s%s",
                                    volume, src) < 0)
                        goto cleanup;
                } else {
                    if (virAsprintf(&uri->path, "%s%s",
                                    src[0] == '/' ? "" : "/",
                                    src) < 0)
                        goto cleanup;
                }
            }
3017

3018 3019
            if (hosts->socket &&
                virAsprintf(&uri->query, "socket=%s", hosts->socket) < 0)
3020
                goto cleanup;
3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032

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

            if (VIR_STRDUP(uri->server, hosts->name) < 0)
3033 3034
                goto cleanup;

3035
            ret = virURIFormat(uri);
3036

3037 3038
            break;

3039
        case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062
            if (!src) {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("missing disk source for 'sheepdog' protocol"));
                goto cleanup;
            }

            if (nhosts == 0) {
                if (virAsprintf(&ret, "sheepdog:%s", src) < 0)
                    goto cleanup;
            } else if (nhosts == 1) {
                if (virAsprintf(&ret, "sheepdog:%s:%s:%s",
                                hosts->name,
                                hosts->port ? hosts->port : "7000",
                                src) < 0)
                    goto cleanup;
            } else {
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("protocol 'sheepdog' accepts up to one host"));
                goto cleanup;
            }

            break;

3063
        case VIR_STORAGE_NET_PROTOCOL_RBD:
3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098
            if (strchr(src, ':')) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("':' not allowed in RBD source volume name '%s'"),
                               src);
                goto cleanup;
            }

            virBufferStrcat(&buf, "rbd:", src, NULL);

            if (username) {
                virBufferEscape(&buf, '\\', ":", ":id=%s", username);
                virBufferEscape(&buf, '\\', ":",
                                ":key=%s:auth_supported=cephx\\;none",
                                secret);
            } else {
                virBufferAddLit(&buf, ":auth_supported=none");
            }

            if (nhosts > 0) {
                virBufferAddLit(&buf, ":mon_host=");
                for (i = 0; i < nhosts; i++) {
                    if (i)
                        virBufferAddLit(&buf, "\\;");

                    /* assume host containing : is ipv6 */
                    if (strchr(hosts[i].name, ':'))
                        virBufferEscape(&buf, '\\', ":", "[%s]", hosts[i].name);
                    else
                        virBufferAsprintf(&buf, "%s", hosts[i].name);

                    if (hosts[i].port)
                        virBufferAsprintf(&buf, "\\:%s", hosts[i].port);
                }
            }

3099
            if (virBufferCheckError(&buf) < 0)
3100 3101 3102 3103 3104 3105
                goto cleanup;

            ret = virBufferContentAndReset(&buf);
            break;


3106
        case VIR_STORAGE_NET_PROTOCOL_LAST:
3107
        case VIR_STORAGE_NET_PROTOCOL_NONE:
3108 3109
            goto cleanup;
    }
3110

3111
 cleanup:
3112
    virBufferFreeAndReset(&buf);
3113 3114 3115 3116 3117 3118
    virURIFree(uri);

    return ret;
}


3119
int
3120 3121 3122
qemuGetDriveSourceString(virStorageSourcePtr src,
                         virConnectPtr conn,
                         char **source)
3123
{
3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146
    int actualType = virStorageSourceGetActualType(src);
    char *secret = NULL;
    char *username = NULL;
    int ret = -1;

    *source = NULL;

    if (conn) {
        if (actualType == VIR_STORAGE_TYPE_NETWORK &&
            src->auth.username &&
            (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);

            username = src->auth.username;

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

3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159
            if (!(secret = qemuGetSecretString(conn,
                                               protocol,
                                               encode,
                                               src->auth.secretType,
                                               username,
                                               src->auth.secret.uuid,
                                               src->auth.secret.usage,
                                               secretType)))
                goto cleanup;
        }
    }

3160
    switch ((virStorageType) actualType) {
E
Eric Blake 已提交
3161 3162 3163
    case VIR_STORAGE_TYPE_BLOCK:
    case VIR_STORAGE_TYPE_FILE:
    case VIR_STORAGE_TYPE_DIR:
3164 3165 3166 3167
        if (!src->path) {
            ret = 1;
            goto cleanup;
        }
3168

3169 3170
        if (VIR_STRDUP(*source, src->path) < 0)
            goto cleanup;
3171 3172 3173

        break;

E
Eric Blake 已提交
3174
    case VIR_STORAGE_TYPE_NETWORK:
3175 3176
        if (!(*source = qemuBuildNetworkDriveURI(src->protocol,
                                                 src->path,
3177
                                                 src->volume,
3178 3179 3180 3181 3182
                                                 src->nhosts,
                                                 src->hosts,
                                                 username,
                                                 secret)))
            goto cleanup;
3183 3184
        break;

E
Eric Blake 已提交
3185
    case VIR_STORAGE_TYPE_VOLUME:
3186
    case VIR_STORAGE_TYPE_NONE:
E
Eric Blake 已提交
3187
    case VIR_STORAGE_TYPE_LAST:
3188 3189 3190
        break;
    }

3191
    ret = 0;
3192

3193
 cleanup:
J
John Ferlan 已提交
3194
    VIR_FREE(secret);
3195 3196 3197
    return ret;
}

P
Paolo Bonzini 已提交
3198

3199
char *
3200
qemuBuildDriveStr(virConnectPtr conn,
3201
                  virDomainDiskDefPtr disk,
3202
                  bool bootable,
3203
                  virQEMUCapsPtr qemuCaps)
3204 3205 3206
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;
    const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
3207 3208
    const char *trans =
        virDomainDiskGeometryTransTypeToString(disk->geometry.trans);
3209 3210
    int idx = virDiskNameToIndex(disk->dst);
    int busid = -1, unitid = -1;
3211
    char *source = NULL;
3212
    int actualType = virStorageSourceGetActualType(disk->src);
3213 3214

    if (idx < 0) {
3215 3216
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unsupported disk type '%s'"), disk->dst);
3217 3218 3219 3220 3221 3222
        goto error;
    }

    switch (disk->bus) {
    case VIR_DOMAIN_DISK_BUS_SCSI:
        if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
3223 3224
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("unexpected address type for scsi disk"));
3225 3226 3227 3228 3229 3230 3231
            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) {
3232 3233
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("SCSI controller only supports 1 bus"));
3234 3235 3236 3237 3238 3239 3240 3241
            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) {
3242 3243
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("unexpected address type for ide disk"));
3244 3245 3246 3247
            goto error;
        }
        /* We can only have 1 IDE controller (currently) */
        if (disk->info.addr.drive.controller != 0) {
3248 3249
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Only 1 %s controller is supported"), bus);
3250 3251 3252 3253 3254 3255 3256 3257
            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) {
3258 3259
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("unexpected address type for fdc disk"));
3260 3261 3262 3263
            goto error;
        }
        /* We can only have 1 FDC controller (currently) */
        if (disk->info.addr.drive.controller != 0) {
3264 3265
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Only 1 %s controller is supported"), bus);
3266 3267 3268 3269
            goto error;
        }
        /* We can only have 1 FDC bus (currently) */
        if (disk->info.addr.drive.bus != 0) {
3270 3271
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Only 1 %s bus is supported"), bus);
3272 3273
            goto error;
        }
3274
        if (disk->info.addr.drive.target != 0) {
3275 3276
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("target must be 0 for controller fdc"));
3277 3278
            goto error;
        }
3279 3280 3281 3282 3283 3284 3285 3286 3287
        unitid = disk->info.addr.drive.unit;

        break;

    case VIR_DOMAIN_DISK_BUS_VIRTIO:
        idx = -1;
        break;

    case VIR_DOMAIN_DISK_BUS_XEN:
3288 3289 3290
    case VIR_DOMAIN_DISK_BUS_SD:
        /* Xen and SD have no address type currently, so assign
         * based on index */
3291 3292 3293
        break;
    }

3294
    if (qemuGetDriveSourceString(disk->src, conn, &source) < 0)
3295 3296 3297
        goto error;

    if (source &&
3298 3299 3300
        !((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY ||
           disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
          disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
3301

3302 3303 3304
        virBufferAddLit(&opt, "file=");

        switch (actualType) {
E
Eric Blake 已提交
3305
        case VIR_STORAGE_TYPE_DIR:
3306
            /* QEMU only supports magic FAT format for now */
3307 3308
            if (disk->src->format > 0 &&
                disk->src->format != VIR_STORAGE_FILE_FAT) {
3309 3310
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("unsupported disk driver type for '%s'"),
3311
                               virStorageFileFormatTypeToString(disk->src->format));
3312 3313
                goto error;
            }
3314

3315
            if (!disk->readonly) {
3316 3317
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("cannot create virtual FAT disks in read-write mode"));
3318 3319
                goto error;
            }
3320 3321 3322

            virBufferAddLit(&opt, "fat:");

3323
            if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
3324
                virBufferAddLit(&opt, "floppy:");
3325

3326 3327
            break;

E
Eric Blake 已提交
3328
        case VIR_STORAGE_TYPE_BLOCK:
3329
            if (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN) {
3330
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
3331
                               disk->src->type == VIR_STORAGE_TYPE_VOLUME ?
3332 3333
                               _("tray status 'open' is invalid for block type volume") :
                               _("tray status 'open' is invalid for block type disk"));
3334 3335
                goto error;
            }
3336 3337 3338 3339 3340

            break;

        default:
            break;
3341
        }
3342 3343

        virBufferEscape(&opt, ',', ",", "%s,", source);
3344
    }
3345
    VIR_FREE(source);
3346

3347
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
3348 3349
        virBufferAddLit(&opt, "if=none");
    else
3350
        virBufferAsprintf(&opt, "if=%s", bus);
3351

3352
    if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
3353
        if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
3354
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD))
3355
                virBufferAddLit(&opt, ",media=cdrom");
3356
        } else if (disk->bus == VIR_DOMAIN_DISK_BUS_IDE) {
3357
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_IDE_CD))
3358
                virBufferAddLit(&opt, ",media=cdrom");
3359 3360 3361 3362
        } else {
            virBufferAddLit(&opt, ",media=cdrom");
        }
    }
3363

3364
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
3365
        virBufferAsprintf(&opt, ",id=%s%s", QEMU_DRIVE_HOST_PREFIX, disk->info.alias);
3366 3367 3368
    } else {
        if (busid == -1 && unitid == -1) {
            if (idx != -1)
3369
                virBufferAsprintf(&opt, ",index=%d", idx);
3370 3371
        } else {
            if (busid != -1)
3372
                virBufferAsprintf(&opt, ",bus=%d", busid);
3373
            if (unitid != -1)
3374
                virBufferAsprintf(&opt, ",unit=%d", unitid);
3375 3376 3377
        }
    }
    if (bootable &&
3378
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_BOOT) &&
3379 3380
        (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK ||
         disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) &&
3381 3382 3383
        disk->bus != VIR_DOMAIN_DISK_BUS_IDE)
        virBufferAddLit(&opt, ",boot=on");
    if (disk->readonly &&
3384 3385 3386 3387 3388 3389 3390
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_READONLY)) {
        if (disk->bus == VIR_DOMAIN_DISK_BUS_IDE &&
            disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("readonly ide disks are not supported"));
            goto error;
        }
3391
        virBufferAddLit(&opt, ",readonly=on");
3392
    }
3393
    if (disk->transient) {
3394 3395
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("transient disks not supported yet"));
3396 3397
        goto error;
    }
3398 3399
    if (disk->src->format > 0 &&
        disk->src->type != VIR_STORAGE_TYPE_DIR &&
3400
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_FORMAT))
3401
        virBufferAsprintf(&opt, ",format=%s",
3402
                          virStorageFileFormatTypeToString(disk->src->format));
3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417

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

3418
    if (disk->serial &&
3419
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_SERIAL)) {
3420 3421
        if (qemuSafeSerialParamValue(disk->serial) < 0)
            goto error;
3422
        virBufferAsprintf(&opt, ",serial=%s", disk->serial);
3423 3424 3425
    }

    if (disk->cachemode) {
3426 3427
        const char *mode = NULL;

3428
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_V2)) {
3429 3430 3431
            mode = qemuDiskCacheV2TypeToString(disk->cachemode);

            if (disk->cachemode == VIR_DOMAIN_DISK_CACHE_DIRECTSYNC &&
3432
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC)) {
3433 3434 3435
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("disk cache mode 'directsync' is not "
                                 "supported by this QEMU"));
3436
                goto error;
3437
            } else if (disk->cachemode == VIR_DOMAIN_DISK_CACHE_UNSAFE &&
3438
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_UNSAFE)) {
3439 3440 3441
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("disk cache mode 'unsafe' is not "
                                 "supported by this QEMU"));
3442
                goto error;
3443 3444 3445 3446
            }
        } else {
            mode = qemuDiskCacheV1TypeToString(disk->cachemode);
        }
3447

3448
        virBufferAsprintf(&opt, ",cache=%s", mode);
3449 3450 3451 3452
    } else if (disk->shared && !disk->readonly) {
        virBufferAddLit(&opt, ",cache=off");
    }

O
Osier Yang 已提交
3453
    if (disk->copy_on_read) {
3454
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_COPY_ON_READ)) {
O
Osier Yang 已提交
3455 3456 3457
            virBufferAsprintf(&opt, ",copy-on-read=%s",
                              virDomainDiskCopyOnReadTypeToString(disk->copy_on_read));
        } else {
3458 3459
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("copy_on_read is not supported by this QEMU binary"));
O
Osier Yang 已提交
3460 3461 3462 3463
            goto error;
        }
    }

O
Osier Yang 已提交
3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474
    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;
        }
    }

3475
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MONITOR_JSON)) {
3476 3477 3478 3479
        const char *wpolicy = NULL, *rpolicy = NULL;

        if (disk->error_policy)
            wpolicy = virDomainDiskErrorPolicyTypeToString(disk->error_policy);
3480 3481
        if (disk->rerror_policy)
            rpolicy = virDomainDiskErrorPolicyTypeToString(disk->rerror_policy);
3482 3483

        if (disk->error_policy == VIR_DOMAIN_DISK_ERROR_POLICY_ENOSPACE) {
3484 3485 3486
            /* 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.
3487
             */
3488 3489 3490 3491
            wpolicy = "enospc";
        } else if (!rpolicy) {
            /* for other policies, rpolicy can match wpolicy */
            rpolicy = wpolicy;
3492
        }
3493 3494 3495 3496 3497

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

E
Eric Blake 已提交
3500
    if (disk->iomode) {
3501
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_AIO)) {
3502
            virBufferAsprintf(&opt, ",aio=%s",
E
Eric Blake 已提交
3503 3504
                              virDomainDiskIoTypeToString(disk->iomode));
        } else {
3505 3506 3507
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("disk aio mode not supported with this "
                             "QEMU binary"));
E
Eric Blake 已提交
3508 3509 3510 3511
            goto error;
        }
    }

3512
    /* block I/O throttling */
3513 3514 3515 3516 3517 3518
    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) &&
3519
        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE)) {
3520 3521 3522
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("block I/O throttling not supported with this "
                         "QEMU binary"));
3523 3524 3525
        goto error;
    }

3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555
    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);
    }

3556
    if (virBufferCheckError(&opt) < 0)
3557 3558 3559 3560
        goto error;

    return virBufferContentAndReset(&opt);

3561
 error:
3562
    VIR_FREE(source);
3563 3564 3565 3566 3567
    virBufferFreeAndReset(&opt);
    return NULL;
}

char *
3568 3569
qemuBuildDriveDevStr(virDomainDefPtr def,
                     virDomainDiskDefPtr disk,
3570
                     int bootindex,
3571
                     virQEMUCapsPtr qemuCaps)
3572 3573 3574 3575
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;
    const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
    int idx = virDiskNameToIndex(disk->dst);
3576
    int controllerModel;
3577 3578

    if (idx < 0) {
3579 3580
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unsupported disk type '%s'"), disk->dst);
3581 3582 3583
        goto error;
    }

3584 3585 3586 3587 3588 3589 3590 3591 3592
    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;
        }
    }

3593 3594 3595 3596 3597 3598 3599
    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;
    }

3600 3601 3602 3603
    if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
        /* make sure that both the bus and the qemu binary support
         *  type='lun' (SG_IO).
         */
3604 3605
        if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO &&
            disk->bus != VIR_DOMAIN_DISK_BUS_SCSI) {
3606 3607 3608
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("disk device='lun' is not supported for bus='%s'"),
                           bus);
3609 3610
            goto error;
        }
3611 3612
        if (disk->src->type == VIR_STORAGE_TYPE_NETWORK) {
            if (disk->src->protocol != VIR_STORAGE_NET_PROTOCOL_ISCSI) {
3613 3614
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("disk device='lun' is not supported for protocol='%s'"),
3615
                               virStorageNetProtocolTypeToString(disk->src->protocol));
3616 3617
                goto error;
            }
3618
        } else if (!virDomainDiskSourceIsBlockType(disk)) {
3619 3620
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("disk device='lun' is only valid for block type disk source"));
3621 3622
            goto error;
        }
3623
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SG_IO)) {
3624 3625
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("disk device='lun' is not supported by this QEMU"));
3626 3627
            goto error;
        }
3628 3629 3630 3631 3632
        if (disk->wwn) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting wwn is not supported for lun device"));
            goto error;
        }
3633 3634 3635 3636 3637 3638
        if (disk->vendor || disk->product) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting vendor or product is not supported "
                             "for lun device"));
            goto error;
        }
3639 3640
    }

3641 3642
    switch (disk->bus) {
    case VIR_DOMAIN_DISK_BUS_IDE:
3643
        if (disk->info.addr.drive.target != 0) {
3644 3645
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("target must be 0 for ide controller"));
3646 3647
            goto error;
        }
3648

3649
        if (disk->wwn &&
3650
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_IDE_DRIVE_WWN)) {
3651 3652 3653 3654 3655 3656
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting wwn for ide disk is not supported "
                             "by this QEMU"));
            goto error;
        }

3657
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_IDE_CD)) {
3658 3659 3660 3661 3662 3663 3664 3665
            if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
                virBufferAddLit(&opt, "ide-cd");
            else
                virBufferAddLit(&opt, "ide-hd");
        } else {
            virBufferAddLit(&opt, "ide-drive");
        }

3666
        virBufferAsprintf(&opt, ",bus=ide.%d,unit=%d",
3667 3668 3669 3670
                          disk->info.addr.drive.bus,
                          disk->info.addr.drive.unit);
        break;
    case VIR_DOMAIN_DISK_BUS_SCSI:
3671
        if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
3672
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_BLOCK)) {
3673 3674 3675
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("This QEMU doesn't support scsi-block for "
                                 "lun passthrough"));
3676 3677 3678 3679
                goto error;
            }
        }

3680
        if (disk->wwn &&
3681
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_WWN)) {
3682 3683 3684 3685 3686 3687
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting wwn for scsi disk is not supported "
                             "by this QEMU"));
            goto error;
        }

3688 3689 3690 3691
        /* Properties wwn, vendor and product were introduced in the
         * same QEMU release (1.2.0).
         */
        if ((disk->vendor || disk->product) &&
3692
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_WWN)) {
3693 3694 3695 3696 3697 3698
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting vendor or product for scsi disk is not "
                             "supported by this QEMU"));
            goto error;
        }

3699
        controllerModel =
H
Han Cheng 已提交
3700 3701
            virDomainDeviceFindControllerModel(def, &disk->info,
                                               VIR_DOMAIN_CONTROLLER_TYPE_SCSI);
3702
        if ((qemuSetSCSIControllerModel(def, qemuCaps, &controllerModel)) < 0)
3703
            goto error;
3704 3705 3706

        if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) {
            if (disk->info.addr.drive.target != 0) {
3707 3708 3709
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("target must be 0 for controller "
                                 "model 'lsilogic'"));
3710 3711 3712
                goto error;
            }

3713
            if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
3714
                virBufferAddLit(&opt, "scsi-block");
3715
            } else {
3716
                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) {
3717 3718 3719 3720 3721 3722 3723 3724 3725
                    if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
                        virBufferAddLit(&opt, "scsi-cd");
                    else
                        virBufferAddLit(&opt, "scsi-hd");
                } else {
                    virBufferAddLit(&opt, "scsi-disk");
                }
            }

3726 3727 3728 3729 3730
            virBufferAsprintf(&opt, ",bus=scsi%d.%d,scsi-id=%d",
                              disk->info.addr.drive.controller,
                              disk->info.addr.drive.bus,
                              disk->info.addr.drive.unit);
        } else {
3731
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_CHANNEL)) {
3732
                if (disk->info.addr.drive.target > 7) {
3733 3734 3735
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("This QEMU doesn't support target "
                                     "greater than 7"));
3736 3737 3738 3739 3740
                    goto error;
                }

                if ((disk->info.addr.drive.bus != disk->info.addr.drive.unit) &&
                    (disk->info.addr.drive.bus != 0)) {
3741 3742 3743
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("This QEMU only supports both bus and "
                                     "unit equal to 0"));
3744 3745 3746 3747
                    goto error;
                }
            }

3748
            if (disk->device != VIR_DOMAIN_DISK_DEVICE_LUN) {
3749
                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) {
3750 3751 3752 3753 3754 3755 3756 3757
                    if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
                        virBufferAddLit(&opt, "scsi-cd");
                    else
                        virBufferAddLit(&opt, "scsi-hd");
                } else {
                    virBufferAddLit(&opt, "scsi-disk");
                }
            } else {
3758
                virBufferAddLit(&opt, "scsi-block");
3759
            }
3760

3761 3762 3763 3764 3765 3766
            virBufferAsprintf(&opt, ",bus=scsi%d.0,channel=%d,scsi-id=%d,lun=%d",
                              disk->info.addr.drive.controller,
                              disk->info.addr.drive.bus,
                              disk->info.addr.drive.target,
                              disk->info.addr.drive.unit);
        }
3767
        break;
J
Jim Fehlig 已提交
3768
    case VIR_DOMAIN_DISK_BUS_SATA:
3769
        if (disk->info.addr.drive.bus != 0) {
3770 3771
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("bus must be 0 for ide controller"));
3772 3773 3774
            goto error;
        }
        if (disk->info.addr.drive.target != 0) {
3775 3776
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("target must be 0 for ide controller"));
3777 3778
            goto error;
        }
3779

3780
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_IDE_CD)) {
3781 3782 3783 3784 3785 3786 3787 3788
            if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
                virBufferAddLit(&opt, "ide-cd");
            else
                virBufferAddLit(&opt, "ide-hd");
        } else {
            virBufferAddLit(&opt, "ide-drive");
        }

3789 3790 3791
        if (qemuDomainMachineIsQ35(def) &&
            disk->info.addr.drive.controller == 0) {
            /* Q35 machines have an implicit ahci (sata) controller at
3792 3793 3794
             * 00:1F.2 which for some reason is hardcoded with the id
             * "ide" instead of the seemingly more reasonable "ahci0"
             * or "sata0".
3795
             */
3796
            virBufferAsprintf(&opt, ",bus=ide.%d", disk->info.addr.drive.unit);
3797 3798
        } else {
            /* All other ahci controllers have been created by
3799 3800
             * libvirt, and we gave them the id "ahci${n}" where ${n}
             * is the controller number. So we identify them that way.
3801 3802 3803 3804 3805
             */
            virBufferAsprintf(&opt, ",bus=ahci%d.%d",
                              disk->info.addr.drive.controller,
                              disk->info.addr.drive.unit);
        }
J
Jim Fehlig 已提交
3806
        break;
3807
    case VIR_DOMAIN_DISK_BUS_VIRTIO:
3808 3809 3810 3811
        if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
            virBufferAddLit(&opt, "virtio-blk-ccw");
        } else if (disk->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
3812
            virBufferAddLit(&opt, "virtio-blk-s390");
3813 3814 3815
        } else if (disk->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) {
            virBufferAddLit(&opt, "virtio-blk-device");
3816 3817 3818
        } else {
            virBufferAddLit(&opt, "virtio-blk-pci");
        }
3819
        qemuBuildIoEventFdStr(&opt, disk->ioeventfd, qemuCaps);
3820
        if (disk->event_idx &&
3821
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_EVENT_IDX)) {
3822 3823 3824
            virBufferAsprintf(&opt, ",event_idx=%s",
                              virDomainVirtioEventIdxTypeToString(disk->event_idx));
        }
3825
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SCSI)) {
3826 3827 3828 3829 3830 3831 3832
            /* 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");
        }
3833
        if (qemuBuildDeviceAddressStr(&opt, def, &disk->info, qemuCaps) < 0)
A
Alex Jia 已提交
3834
            goto error;
3835 3836
        break;
    case VIR_DOMAIN_DISK_BUS_USB:
3837 3838 3839 3840 3841 3842 3843
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_STORAGE)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("This QEMU doesn't support '-device "
                             "usb-storage'"));
            goto error;

        }
3844
        virBufferAddLit(&opt, "usb-storage");
3845

3846
        if (qemuBuildDeviceAddressStr(&opt, def, &disk->info, qemuCaps) < 0)
3847
            goto error;
3848 3849
        break;
    default:
3850 3851
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unsupported disk bus '%s' with device setup"), bus);
3852 3853
        goto error;
    }
3854 3855
    virBufferAsprintf(&opt, ",drive=%s%s", QEMU_DRIVE_HOST_PREFIX, disk->info.alias);
    virBufferAsprintf(&opt, ",id=%s", disk->info.alias);
3856
    if (bootindex && virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX))
3857
        virBufferAsprintf(&opt, ",bootindex=%d", bootindex);
3858
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKIO)) {
V
Viktor Mihajlovski 已提交
3859
        if (disk->blockio.logical_block_size > 0)
3860
            virBufferAsprintf(&opt, ",logical_block_size=%u",
V
Viktor Mihajlovski 已提交
3861 3862
                              disk->blockio.logical_block_size);
        if (disk->blockio.physical_block_size > 0)
3863
            virBufferAsprintf(&opt, ",physical_block_size=%u",
V
Viktor Mihajlovski 已提交
3864
                              disk->blockio.physical_block_size);
3865
    }
3866

3867 3868 3869 3870 3871 3872
    if (disk->wwn) {
        if (STRPREFIX(disk->wwn, "0x"))
            virBufferAsprintf(&opt, ",wwn=%s", disk->wwn);
        else
            virBufferAsprintf(&opt, ",wwn=0x%s", disk->wwn);
    }
3873

3874 3875 3876 3877 3878 3879
    if (disk->vendor)
        virBufferAsprintf(&opt, ",vendor=%s", disk->vendor);

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

3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895
    if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_STORAGE_REMOVABLE)) {
            if (disk->removable == VIR_DOMAIN_FEATURE_STATE_ON)
                virBufferAddLit(&opt, ",removable=on");
            else
                virBufferAddLit(&opt, ",removable=off");
        } else {
            if (disk->removable != VIR_DOMAIN_FEATURE_STATE_DEFAULT) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("This QEMU doesn't support setting the "
                                 "removable flag of USB storage devices"));
                goto error;
            }
        }
    }

3896
    if (virBufferCheckError(&opt) < 0)
3897 3898 3899 3900
        goto error;

    return virBufferContentAndReset(&opt);

3901
 error:
3902 3903 3904 3905 3906 3907
    virBufferFreeAndReset(&opt);
    return NULL;
}


char *qemuBuildFSStr(virDomainFSDefPtr fs,
3908
                     virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED)
3909 3910
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;
3911
    const char *driver = qemuDomainFSDriverTypeToString(fs->fsdriver);
3912
    const char *wrpolicy = virDomainFSWrpolicyTypeToString(fs->wrpolicy);
3913 3914

    if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
3915 3916
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("only supports mount filesystem type"));
3917 3918 3919
        goto error;
    }

3920
    if (!driver) {
3921 3922
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Filesystem driver type not supported"));
3923 3924 3925 3926
        goto error;
    }
    virBufferAdd(&opt, driver, -1);

3927 3928 3929 3930
    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");
3931
        } else if (fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH) {
3932
            virBufferAddLit(&opt, ",security_model=passthrough");
3933
        } else if (fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_SQUASH) {
3934 3935 3936 3937 3938 3939
            virBufferAddLit(&opt, ",security_model=none");
        }
    } else {
        /* For other fs drivers, default(passthru) should always
         * be supported */
        if (fs->accessmode != VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH) {
3940 3941
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("only supports passthrough accessmode"));
3942 3943
            goto error;
        }
3944
    }
3945 3946

    if (fs->wrpolicy) {
3947
       if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_FSDEV_WRITEOUT)) {
3948 3949
           virBufferAsprintf(&opt, ",writeout=%s", wrpolicy);
       } else {
3950
           virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
3951 3952 3953 3954 3955
                          _("filesystem writeout not supported"));
           goto error;
       }
    }

3956 3957
    virBufferAsprintf(&opt, ",id=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
    virBufferAsprintf(&opt, ",path=%s", fs->src);
3958

3959
    if (fs->readonly) {
3960
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_FSDEV_READONLY)) {
3961 3962
            virBufferAddLit(&opt, ",readonly");
        } else {
3963 3964 3965
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("readonly filesystem is not supported by this "
                             "QEMU binary"));
3966 3967 3968 3969
            goto error;
        }
    }

3970
    if (virBufferCheckError(&opt) < 0)
3971 3972 3973 3974
        goto error;

    return virBufferContentAndReset(&opt);

3975
 error:
3976 3977 3978 3979 3980 3981
    virBufferFreeAndReset(&opt);
    return NULL;
}


char *
3982 3983
qemuBuildFSDevStr(virDomainDefPtr def,
                  virDomainFSDefPtr fs,
3984
                  virQEMUCapsPtr qemuCaps)
3985 3986 3987 3988
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;

    if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
3989 3990
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("can only passthrough directories"));
3991 3992 3993 3994
        goto error;
    }

    virBufferAddLit(&opt, "virtio-9p-pci");
3995 3996 3997
    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 已提交
3998

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

4002
    if (virBufferCheckError(&opt) < 0)
4003 4004 4005 4006
        goto error;

    return virBufferContentAndReset(&opt);

4007
 error:
4008 4009 4010 4011 4012
    virBufferFreeAndReset(&opt);
    return NULL;
}


4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031
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 已提交
4032 4033
    case VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI:
        return QEMU_CAPS_NEC_USB_XHCI;
4034 4035 4036 4037 4038 4039 4040
    default:
        return -1;
    }
}


static int
4041 4042
qemuBuildUSBControllerDevStr(virDomainDefPtr domainDef,
                             virDomainControllerDefPtr def,
4043
                             virQEMUCapsPtr qemuCaps,
4044 4045 4046
                             virBuffer *buf)
{
    const char *smodel;
4047
    int model, flags;
4048 4049

    model = def->model;
4050

4051
    if (model == -1) {
4052
        if (domainDef->os.arch == VIR_ARCH_PPC64)
4053 4054 4055 4056
            model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI;
        else
            model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI;
    }
4057 4058

    smodel = qemuControllerModelUSBTypeToString(model);
4059
    flags = qemuControllerModelUSBToCaps(model);
4060

4061
    if (flags == -1 || !virQEMUCapsGet(qemuCaps, flags)) {
4062 4063
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("%s not supported in this QEMU binary"), smodel);
4064 4065 4066
        return -1;
    }

4067 4068 4069
    virBufferAsprintf(buf, "%s", smodel);

    if (def->info.mastertype == VIR_DOMAIN_CONTROLLER_MASTER_USB) {
4070
        virBufferAddLit(buf, ",masterbus=");
4071
        qemuUSBId(buf, def->idx);
4072
        virBufferAsprintf(buf, ".0,firstport=%d", def->info.master.usb.startport);
4073
    } else {
4074
        virBufferAddLit(buf, ",id=");
4075
        qemuUSBId(buf, def->idx);
4076 4077
    }

4078 4079 4080
    return 0;
}

4081
char *
4082 4083
qemuBuildControllerDevStr(virDomainDefPtr domainDef,
                          virDomainControllerDefPtr def,
4084
                          virQEMUCapsPtr qemuCaps,
4085
                          int *nusbcontroller)
4086 4087
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4088
    int model;
4089

4090
    if (!(def->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI &&
4091
          def->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI)) {
4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106
        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;
        }
4107 4108
    }

4109 4110
    switch (def->type) {
    case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
4111
        model = def->model;
4112
        if ((qemuSetSCSIControllerModel(domainDef, qemuCaps, &model)) < 0)
4113 4114
            return NULL;

4115
        switch (model) {
4116
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI:
4117 4118 4119 4120 4121
            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");
4122 4123 4124
            else if (def->info.type ==
                     VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
                virBufferAddLit(&buf, "virtio-scsi-device");
4125 4126
            else
                virBufferAddLit(&buf, "virtio-scsi-pci");
4127
            break;
4128
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC:
4129
            virBufferAddLit(&buf, "lsi");
4130 4131 4132 4133
            break;
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI:
            virBufferAddLit(&buf, "spapr-vscsi");
            break;
4134 4135 4136
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1078:
            virBufferAddLit(&buf, "megasas");
            break;
4137
        default:
4138 4139 4140
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("Unsupported controller model: %s"),
                           virDomainControllerModelSCSITypeToString(def->model));
4141
        }
4142
        virBufferAsprintf(&buf, ",id=scsi%d", def->idx);
4143 4144 4145 4146 4147
        break;

    case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
        if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
            virBufferAddLit(&buf, "virtio-serial-pci");
4148 4149 4150
        } else if (def->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
            virBufferAddLit(&buf, "virtio-serial-ccw");
4151 4152 4153
        } else if (def->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
            virBufferAddLit(&buf, "virtio-serial-s390");
4154 4155 4156
        } else if (def->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) {
            virBufferAddLit(&buf, "virtio-serial-device");
4157 4158 4159
        } else {
            virBufferAddLit(&buf, "virtio-serial");
        }
4160
        virBufferAsprintf(&buf, ",id=" QEMU_VIRTIO_SERIAL_PREFIX "%d",
4161 4162
                          def->idx);
        if (def->opts.vioserial.ports != -1) {
4163
            virBufferAsprintf(&buf, ",max_ports=%d",
4164 4165 4166
                              def->opts.vioserial.ports);
        }
        if (def->opts.vioserial.vectors != -1) {
4167
            virBufferAsprintf(&buf, ",vectors=%d",
4168 4169 4170 4171
                              def->opts.vioserial.vectors);
        }
        break;

E
Eric Blake 已提交
4172
    case VIR_DOMAIN_CONTROLLER_TYPE_CCID:
4173
        virBufferAsprintf(&buf, "usb-ccid,id=ccid%d", def->idx);
E
Eric Blake 已提交
4174 4175
        break;

J
Jim Fehlig 已提交
4176 4177 4178 4179
    case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
        virBufferAsprintf(&buf, "ahci,id=ahci%d", def->idx);
        break;

4180
    case VIR_DOMAIN_CONTROLLER_TYPE_USB:
4181
        if (qemuBuildUSBControllerDevStr(domainDef, def, qemuCaps, &buf) == -1)
4182 4183 4184 4185 4186 4187 4188
            goto error;

        if (nusbcontroller)
            *nusbcontroller += 1;

        break;

4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199
    case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
        switch (def->model) {
        case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
            if (def->idx == 0) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("PCI bridge index should be > 0"));
                goto error;
            }
            virBufferAsprintf(&buf, "pci-bridge,chassis_nr=%d,id=pci.%d",
                              def->idx, def->idx);
            break;
4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213
        case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE)) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("The dmi-to-pci-bridge (i82801b11-bridge) "
                                 "controller is not supported in this QEMU binary"));
                goto error;
            }
            if (def->idx == 0) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("dmi-to-pci-bridge index should be > 0"));
                goto error;
            }
            virBufferAsprintf(&buf, "i82801b11-bridge,id=pci.%d", def->idx);
            break;
4214
        case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
L
Laine Stump 已提交
4215
        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
4216
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
L
Laine Stump 已提交
4217
                           _("wrong function called for pci-root/pcie-root"));
4218 4219 4220 4221
            return NULL;
        }
        break;

4222 4223 4224
    /* We always get an IDE controller, whether we want it or not. */
    case VIR_DOMAIN_CONTROLLER_TYPE_IDE:
    default:
4225 4226 4227
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Unknown controller type: %s"),
                       virDomainControllerTypeToString(def->type));
4228 4229 4230
        goto error;
    }

4231 4232
    if (def->queues)
        virBufferAsprintf(&buf, ",num_queues=%u", def->queues);
4233

4234 4235 4236 4237 4238 4239
    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);

4240
    if (qemuBuildDeviceAddressStr(&buf, domainDef, &def->info, qemuCaps) < 0)
4241 4242
        goto error;

4243
    if (virBufferCheckError(&buf) < 0)
4244 4245 4246 4247
        goto error;

    return virBufferContentAndReset(&buf);

4248
 error:
4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
qemuBuildNicStr(virDomainNetDefPtr net,
                const char *prefix,
                int vlan)
{
    char *str;
4260 4261
    char macaddr[VIR_MAC_STRING_BUFLEN];

4262 4263 4264 4265 4266 4267 4268 4269 4270
    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 : "")));
4271 4272 4273 4274 4275
    return str;
}


char *
4276 4277
qemuBuildNicDevStr(virDomainDefPtr def,
                   virDomainNetDefPtr net,
4278
                   int vlan,
4279
                   int bootindex,
4280
                   int vhostfdSize,
4281
                   virQEMUCapsPtr qemuCaps)
4282 4283
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4284
    const char *nic = net->model;
4285
    bool usingVirtio = false;
4286
    char macaddr[VIR_MAC_STRING_BUFLEN];
4287

4288 4289
    if (STREQ(net->model, "virtio")) {
        if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
4290
            nic = "virtio-net-ccw";
4291
        else if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
4292
            nic = "virtio-net-s390";
4293 4294
        else if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
            nic = "virtio-net-device";
4295
        else
4296
            nic = "virtio-net-pci";
4297

4298
        usingVirtio = true;
4299 4300
    }

4301
    virBufferAdd(&buf, nic, -1);
4302
    if (usingVirtio && net->driver.virtio.txmode) {
4303
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_TX_ALG)) {
4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316
            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.
                     */
4317 4318
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("unrecognized virtio-net-pci 'tx' option"));
4319 4320 4321
                    goto error;
            }
        } else {
4322 4323
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("virtio-net-pci 'tx' option not supported in this QEMU binary"));
4324 4325 4326
            goto error;
        }
    }
4327
    if (usingVirtio) {
4328
        qemuBuildIoEventFdStr(&buf, net->driver.virtio.ioeventfd, qemuCaps);
4329
        if (net->driver.virtio.event_idx &&
4330
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_EVENT_IDX)) {
4331 4332 4333 4334
            virBufferAsprintf(&buf, ",event_idx=%s",
                              virDomainVirtioEventIdxTypeToString(net->driver.virtio.event_idx));
        }
    }
4335 4336
    if (usingVirtio && vhostfdSize > 1) {
        /* As advised at http://www.linux-kvm.org/page/Multiqueue
4337 4338
         * we should add vectors=2*N+2 where N is the vhostfdSize */
        virBufferAsprintf(&buf, ",mq=on,vectors=%d", 2 * vhostfdSize + 2);
4339
    }
4340
    if (vlan == -1)
4341
        virBufferAsprintf(&buf, ",netdev=host%s", net->info.alias);
4342
    else
4343 4344
        virBufferAsprintf(&buf, ",vlan=%d", vlan);
    virBufferAsprintf(&buf, ",id=%s", net->info.alias);
4345 4346
    virBufferAsprintf(&buf, ",mac=%s",
                      virMacAddrFormat(&net->mac, macaddr));
4347
    if (qemuBuildDeviceAddressStr(&buf, def, &net->info, qemuCaps) < 0)
4348
        goto error;
4349
    if (qemuBuildRomStr(&buf, &net->info, qemuCaps) < 0)
4350
       goto error;
4351
    if (bootindex && virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX))
4352
        virBufferAsprintf(&buf, ",bootindex=%d", bootindex);
4353

4354
    if (virBufferCheckError(&buf) < 0)
4355 4356 4357 4358
        goto error;

    return virBufferContentAndReset(&buf);

4359
 error:
4360 4361 4362 4363 4364 4365 4366
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
qemuBuildHostNetStr(virDomainNetDefPtr net,
4367
                    virQEMUDriverPtr driver,
4368 4369
                    char type_sep,
                    int vlan,
4370 4371 4372 4373
                    char **tapfd,
                    int tapfdSize,
                    char **vhostfd,
                    int vhostfdSize)
4374
{
4375
    bool is_tap = false;
4376
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4377
    virDomainNetType netType = virDomainNetGetActualType(net);
4378
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
4379
    size_t i;
4380

4381
    if (net->script && netType != VIR_DOMAIN_NET_TYPE_ETHERNET) {
4382 4383 4384
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("scripts are not supported on interfaces of type %s"),
                       virDomainNetTypeToString(netType));
4385
        virObjectUnref(cfg);
4386 4387 4388 4389
        return NULL;
    }

    switch (netType) {
R
Richa Marwaha 已提交
4390 4391 4392 4393 4394
    /*
     * If type='bridge', and we're running as privileged user
     * or -netdev bridge is not supported then it will fall
     * through, -net tap,fd
     */
4395
    case VIR_DOMAIN_NET_TYPE_BRIDGE:
R
Richa Marwaha 已提交
4396
    case VIR_DOMAIN_NET_TYPE_NETWORK:
4397
    case VIR_DOMAIN_NET_TYPE_DIRECT:
4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410
        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);
            }
        }
4411
        type_sep = ',';
4412
        is_tap = true;
4413 4414 4415 4416 4417
        break;

    case VIR_DOMAIN_NET_TYPE_ETHERNET:
        virBufferAddLit(&buf, "tap");
        if (net->ifname) {
4418
            virBufferAsprintf(&buf, "%cifname=%s", type_sep, net->ifname);
4419 4420
            type_sep = ',';
        }
4421
        if (net->script) {
4422
            virBufferAsprintf(&buf, "%cscript=%s", type_sep,
4423
                              net->script);
4424 4425
            type_sep = ',';
        }
4426
        is_tap = true;
4427 4428 4429
        break;

    case VIR_DOMAIN_NET_TYPE_CLIENT:
4430 4431 4432 4433 4434 4435 4436
       virBufferAsprintf(&buf, "socket%cconnect=%s:%d",
                         type_sep,
                         net->data.socket.address,
                         net->data.socket.port);
       type_sep = ',';
       break;

4437
    case VIR_DOMAIN_NET_TYPE_SERVER:
4438 4439 4440 4441 4442 4443 4444
       virBufferAsprintf(&buf, "socket%clisten=%s:%d",
                         type_sep,
                         net->data.socket.address,
                         net->data.socket.port);
       type_sep = ',';
       break;

4445
    case VIR_DOMAIN_NET_TYPE_MCAST:
4446 4447 4448 4449 4450 4451
       virBufferAsprintf(&buf, "socket%cmcast=%s:%d",
                         type_sep,
                         net->data.socket.address,
                         net->data.socket.port);
       type_sep = ',';
       break;
4452 4453 4454 4455 4456 4457 4458 4459

    case VIR_DOMAIN_NET_TYPE_USER:
    default:
        virBufferAddLit(&buf, "user");
        break;
    }

    if (vlan >= 0) {
4460
        virBufferAsprintf(&buf, "%cvlan=%d", type_sep, vlan);
4461
        if (net->info.alias)
4462
            virBufferAsprintf(&buf, ",name=host%s",
4463 4464
                              net->info.alias);
    } else {
4465
        virBufferAsprintf(&buf, "%cid=host%s",
4466 4467 4468
                          type_sep, net->info.alias);
    }

4469
    if (is_tap) {
4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482
        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);
                }
            }
        }
4483
        if (net->tune.sndbuf_specified)
4484
            virBufferAsprintf(&buf, ",sndbuf=%lu", net->tune.sndbuf);
4485 4486
    }

4487 4488
    virObjectUnref(cfg);

4489
    if (virBufferCheckError(&buf) < 0)
4490 4491 4492 4493 4494 4495 4496
        return NULL;

    return virBufferContentAndReset(&buf);
}


char *
4497 4498
qemuBuildWatchdogDevStr(virDomainDefPtr def,
                        virDomainWatchdogDefPtr dev,
4499
                        virQEMUCapsPtr qemuCaps)
4500 4501 4502 4503 4504
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    const char *model = virDomainWatchdogModelTypeToString(dev->model);
    if (!model) {
4505 4506
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("missing watchdog model"));
4507 4508 4509
        goto error;
    }

4510
    virBufferAsprintf(&buf, "%s,id=%s", model, dev->info.alias);
4511
    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
4512 4513
        goto error;

4514
    if (virBufferCheckError(&buf) < 0)
4515 4516 4517 4518
        goto error;

    return virBufferContentAndReset(&buf);

4519
 error:
4520 4521 4522 4523 4524 4525
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
4526 4527
qemuBuildMemballoonDevStr(virDomainDefPtr def,
                          virDomainMemballoonDefPtr dev,
4528
                          virQEMUCapsPtr qemuCaps)
4529 4530 4531
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

4532 4533 4534 4535 4536 4537 4538
    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;
4539 4540 4541
        case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
            virBufferAddLit(&buf, "virtio-balloon-device");
            break;
4542
        default:
4543 4544 4545
            virReportError(VIR_ERR_XML_ERROR,
                           _("memballoon unsupported with address type '%s'"),
                           virDomainDeviceAddressTypeToString(dev->info.type));
4546 4547 4548
            goto error;
    }

4549
    virBufferAsprintf(&buf, ",id=%s", dev->info.alias);
4550
    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
4551 4552
        goto error;

4553
    if (virBufferCheckError(&buf) < 0)
4554 4555 4556 4557
        goto error;

    return virBufferContentAndReset(&buf);

4558
 error:
4559 4560 4561 4562
    virBufferFreeAndReset(&buf);
    return NULL;
}

4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577
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;
    }

4578
    if (virBufferCheckError(&buf) < 0)
4579 4580 4581 4582
        goto error;

    return virBufferContentAndReset(&buf);

4583
 error:
4584 4585 4586
    virBufferFreeAndReset(&buf);
    return NULL;
}
4587 4588

char *
4589 4590
qemuBuildUSBInputDevStr(virDomainDefPtr def,
                        virDomainInputDefPtr dev,
4591
                        virQEMUCapsPtr qemuCaps)
4592 4593 4594
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607
    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;
    }
4608

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

4612
    if (virBufferCheckError(&buf) < 0)
4613 4614 4615 4616
        goto error;

    return virBufferContentAndReset(&buf);

4617
 error:
4618 4619 4620 4621 4622 4623
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
4624 4625
qemuBuildSoundDevStr(virDomainDefPtr def,
                     virDomainSoundDefPtr sound,
4626
                     virQEMUCapsPtr qemuCaps)
4627 4628 4629 4630 4631
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    const char *model = virDomainSoundModelTypeToString(sound->model);

    if (!model) {
4632 4633
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("invalid sound model"));
4634 4635 4636
        goto error;
    }

4637 4638 4639
    /* Hack for devices with different names in QEMU and libvirt */
    switch (sound->model) {
    case VIR_DOMAIN_SOUND_MODEL_ES1370:
4640
        model = "ES1370";
4641 4642
        break;
    case VIR_DOMAIN_SOUND_MODEL_AC97:
4643
        model = "AC97";
4644 4645
        break;
    case VIR_DOMAIN_SOUND_MODEL_ICH6:
4646
        model = "intel-hda";
4647
        break;
4648 4649 4650 4651 4652 4653 4654 4655 4656
    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;
4657
    }
4658

4659
    virBufferAsprintf(&buf, "%s,id=%s", model, sound->info.alias);
4660
    if (qemuBuildDeviceAddressStr(&buf, def, &sound->info, qemuCaps) < 0)
4661 4662
        goto error;

4663
    if (virBufferCheckError(&buf) < 0)
4664 4665 4666 4667
        goto error;

    return virBufferContentAndReset(&buf);

4668
 error:
4669 4670 4671 4672
    virBufferFreeAndReset(&buf);
    return NULL;
}

4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687

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


4688 4689
static char *
qemuBuildSoundCodecStr(virDomainSoundDefPtr sound,
4690
                       virDomainSoundCodecDefPtr codec,
4691
                       virQEMUCapsPtr qemuCaps)
4692 4693
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4694
    const char *stype;
4695
    int type, flags;
4696

4697 4698
    type = codec->type;
    stype = qemuSoundCodecTypeToString(type);
4699
    flags = qemuSoundCodecTypeToCaps(type);
4700

4701
    if (flags == -1 || !virQEMUCapsGet(qemuCaps, flags)) {
4702 4703
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("%s not supported in this QEMU binary"), stype);
4704 4705 4706
        goto error;
    }

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

4710 4711
    return virBufferContentAndReset(&buf);

4712
 error:
4713 4714 4715
    virBufferFreeAndReset(&buf);
    return NULL;
}
4716 4717

static char *
4718 4719
qemuBuildDeviceVideoStr(virDomainDefPtr def,
                        virDomainVideoDefPtr video,
4720
                        virQEMUCapsPtr qemuCaps,
4721
                        bool primary)
4722 4723
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4724
    const char *model;
4725

4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740
    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;
        }

4741
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL)) {
4742 4743 4744 4745 4746 4747
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("only one video card is currently supported"));
            goto error;
        }

        model = "qxl";
4748 4749
    }

4750
    virBufferAsprintf(&buf, "%s,id=%s", model, video->info.alias);
4751 4752

    if (video->type == VIR_DOMAIN_VIDEO_TYPE_QXL) {
4753
        if (video->vram > (UINT_MAX / 1024)) {
4754
            virReportError(VIR_ERR_OVERFLOW,
4755 4756
                           _("value for 'vram' must be less than '%u'"),
                           UINT_MAX / 1024);
4757 4758
            goto error;
        }
4759 4760 4761 4762 4763 4764 4765 4766 4767
        if (video->ram > (UINT_MAX / 1024)) {
            virReportError(VIR_ERR_OVERFLOW,
                           _("value for 'ram' must be less than '%u'"),
                           UINT_MAX / 1024);
            goto error;
        }

        /* QEMU accepts bytes for ram_size. */
        virBufferAsprintf(&buf, ",ram_size=%u", video->ram * 1024);
4768

4769
        /* QEMU accepts bytes for vram_size. */
4770
        virBufferAsprintf(&buf, ",vram_size=%u", video->vram * 1024);
4771 4772
    }

4773
    if (qemuBuildDeviceAddressStr(&buf, def, &video->info, qemuCaps) < 0)
4774 4775
        goto error;

4776
    if (virBufferCheckError(&buf) < 0)
4777 4778 4779 4780
        goto error;

    return virBufferContentAndReset(&buf);

4781
 error:
4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793
    virBufferFreeAndReset(&buf);
    return NULL;
}


int
qemuOpenPCIConfig(virDomainHostdevDefPtr dev)
{
    char *path = NULL;
    int configfd = -1;

    if (virAsprintf(&path, "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/config",
4794 4795 4796
                    dev->source.subsys.u.pci.addr.domain,
                    dev->source.subsys.u.pci.addr.bus,
                    dev->source.subsys.u.pci.addr.slot,
4797
                    dev->source.subsys.u.pci.addr.function) < 0)
4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810
        return -1;

    configfd = open(path, O_RDWR, 0);

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

    VIR_FREE(path);

    return configfd;
}

char *
4811 4812 4813
qemuBuildPCIHostdevDevStr(virDomainDefPtr def,
                          virDomainHostdevDefPtr dev,
                          const char *configfd,
4814
                          virQEMUCapsPtr qemuCaps)
4815 4816
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4817
    int backend = dev->source.subsys.u.pci.backend;
4818

4819
    /* caller has to assign proper passthrough backend type */
4820
    switch ((virDomainHostdevSubsysPCIBackendType) backend) {
4821
    case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
4822 4823 4824
        virBufferAddLit(&buf, "pci-assign");
        if (configfd && *configfd)
            virBufferAsprintf(&buf, ",configfd=%s", configfd);
4825 4826 4827 4828 4829 4830
        break;

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

4831
    default:
4832 4833
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("invalid PCI passthrough type '%s'"),
4834
                       virDomainHostdevSubsysPCIBackendTypeToString(backend));
4835
        break;
4836
    }
4837

4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849
    virBufferAddLit(&buf, ",host=");
    if (dev->source.subsys.u.pci.addr.domain) {
        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"),
                           dev->source.subsys.u.pci.addr.domain);
            goto error;
        }
        virBufferAsprintf(&buf, "%.4x:", dev->source.subsys.u.pci.addr.domain);
    }
    virBufferAsprintf(&buf, "%.2x:%.2x.%.1x",
4850 4851 4852
                      dev->source.subsys.u.pci.addr.bus,
                      dev->source.subsys.u.pci.addr.slot,
                      dev->source.subsys.u.pci.addr.function);
4853 4854 4855
    virBufferAsprintf(&buf, ",id=%s", dev->info->alias);
    if (dev->info->bootIndex)
        virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);
4856
    if (qemuBuildDeviceAddressStr(&buf, def, dev->info, qemuCaps) < 0)
4857
        goto error;
4858
    if (qemuBuildRomStr(&buf, dev->info, qemuCaps) < 0)
4859
       goto error;
4860

4861
    if (virBufferCheckError(&buf) < 0)
4862 4863 4864 4865
        goto error;

    return virBufferContentAndReset(&buf);

4866
 error:
4867 4868 4869 4870 4871 4872
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
4873 4874
qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev,
                             virQEMUCapsPtr qemuCaps)
4875 4876 4877
{
    char *ret = NULL;

4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897
    if (dev->source.subsys.u.pci.addr.domain) {
        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"),
                           dev->source.subsys.u.pci.addr.domain);
            goto cleanup;
        }
        ignore_value(virAsprintf(&ret, "host=%.4x:%.2x:%.2x.%.1x",
                                 dev->source.subsys.u.pci.addr.domain,
                                 dev->source.subsys.u.pci.addr.bus,
                                 dev->source.subsys.u.pci.addr.slot,
                                 dev->source.subsys.u.pci.addr.function));
    } else {
        ignore_value(virAsprintf(&ret, "host=%.2x:%.2x.%.1x",
                                 dev->source.subsys.u.pci.addr.bus,
                                 dev->source.subsys.u.pci.addr.slot,
                                 dev->source.subsys.u.pci.addr.function));
    }
 cleanup:
4898 4899 4900 4901
    return ret;
}


4902
char *
4903 4904
qemuBuildRedirdevDevStr(virDomainDefPtr def,
                        virDomainRedirdevDefPtr dev,
4905
                        virQEMUCapsPtr qemuCaps)
4906
{
4907
    size_t i;
4908
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4909
    virDomainRedirFilterDefPtr redirfilter = def->redirfilter;
4910 4911

    if (dev->bus != VIR_DOMAIN_REDIRDEV_BUS_USB) {
4912 4913 4914
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Redirection bus %s is not supported by QEMU"),
                       virDomainRedirdevBusTypeToString(dev->bus));
4915 4916 4917
        goto error;
    }

4918
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_REDIR)) {
4919 4920 4921
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("USB redirection is not supported "
                         "by this version of QEMU"));
4922 4923 4924 4925 4926 4927 4928
        goto error;
    }

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

4929
    if (redirfilter && redirfilter->nusbdevs) {
4930
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_REDIR_FILTER)) {
4931 4932 4933 4934 4935 4936
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("USB redirection filter is not "
                             "supported by this version of QEMU"));
            goto error;
        }

4937
        virBufferAddLit(&buf, ",filter=");
4938 4939

        for (i = 0; i < redirfilter->nusbdevs; i++) {
4940
            virDomainRedirFilterUSBDevDefPtr usbdev = redirfilter->usbdevs[i];
4941 4942 4943
            if (usbdev->usbClass >= 0)
                virBufferAsprintf(&buf, "0x%02X:", usbdev->usbClass);
            else
4944
                virBufferAddLit(&buf, "-1:");
4945 4946 4947 4948

            if (usbdev->vendor >= 0)
                virBufferAsprintf(&buf, "0x%04X:", usbdev->vendor);
            else
4949
                virBufferAddLit(&buf, "-1:");
4950 4951 4952 4953

            if (usbdev->product >= 0)
                virBufferAsprintf(&buf, "0x%04X:", usbdev->product);
            else
4954
                virBufferAddLit(&buf, "-1:");
4955 4956 4957 4958

            if (usbdev->version >= 0)
                virBufferAsprintf(&buf, "0x%04X:", usbdev->version);
            else
4959
                virBufferAddLit(&buf, "-1:");
4960 4961 4962

            virBufferAsprintf(&buf, "%u", usbdev->allow);
            if (i < redirfilter->nusbdevs -1)
4963
                virBufferAddLit(&buf, "|");
4964 4965 4966
        }
    }

4967
    if (dev->info.bootIndex) {
4968
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_REDIR_BOOTINDEX)) {
4969 4970 4971 4972 4973 4974 4975 4976
            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);
    }

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

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

    return virBufferContentAndReset(&buf);

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

4990
char *
4991 4992
qemuBuildUSBHostdevDevStr(virDomainDefPtr def,
                          virDomainHostdevDefPtr dev,
4993
                          virQEMUCapsPtr qemuCaps)
4994
{
4995
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4996

4997 4998
    if (!dev->missing &&
        !dev->source.subsys.u.usb.bus &&
4999
        !dev->source.subsys.u.usb.device) {
5000 5001
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("USB host device is missing bus/device information"));
5002 5003 5004
        return NULL;
    }

5005 5006 5007 5008 5009 5010 5011
    virBufferAddLit(&buf, "usb-host");
    if (!dev->missing) {
        virBufferAsprintf(&buf, ",hostbus=%d,hostaddr=%d",
                          dev->source.subsys.u.usb.bus,
                          dev->source.subsys.u.usb.device);
    }
    virBufferAsprintf(&buf, ",id=%s", dev->info->alias);
5012 5013
    if (dev->info->bootIndex)
        virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);
5014

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

5018
    if (virBufferCheckError(&buf) < 0)
5019
        goto error;
5020

5021 5022
    return virBufferContentAndReset(&buf);

5023
 error:
5024 5025
    virBufferFreeAndReset(&buf);
    return NULL;
5026 5027 5028
}


M
Marc-André Lureau 已提交
5029
char *
5030 5031
qemuBuildHubDevStr(virDomainDefPtr def,
                   virDomainHubDefPtr dev,
5032
                   virQEMUCapsPtr qemuCaps)
M
Marc-André Lureau 已提交
5033 5034 5035 5036
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if (dev->type != VIR_DOMAIN_HUB_TYPE_USB) {
5037 5038 5039
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("hub type %s not supported"),
                       virDomainHubTypeToString(dev->type));
M
Marc-André Lureau 已提交
5040 5041 5042
        goto error;
    }

5043
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_HUB)) {
5044
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
5045
                       _("usb-hub not supported by QEMU binary"));
M
Marc-André Lureau 已提交
5046 5047 5048 5049 5050
        goto error;
    }

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

5054
    if (virBufferCheckError(&buf) < 0)
M
Marc-André Lureau 已提交
5055 5056 5057 5058
        goto error;

    return virBufferContentAndReset(&buf);

5059
 error:
M
Marc-André Lureau 已提交
5060 5061 5062 5063 5064
    virBufferFreeAndReset(&buf);
    return NULL;
}


5065
char *
5066
qemuBuildUSBHostdevUSBDevStr(virDomainHostdevDefPtr dev)
5067 5068 5069
{
    char *ret = NULL;

5070 5071 5072 5073 5074 5075
    if (dev->missing) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("This QEMU doesn't not support missing USB devices"));
        return NULL;
    }

5076 5077
    if (!dev->source.subsys.u.usb.bus &&
        !dev->source.subsys.u.usb.device) {
5078 5079
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("USB host device is missing bus/device information"));
5080 5081 5082
        return NULL;
    }

5083 5084 5085
    ignore_value(virAsprintf(&ret, "host:%d.%d",
                             dev->source.subsys.u.usb.bus,
                             dev->source.subsys.u.usb.device));
5086 5087 5088
    return ret;
}

5089 5090
char *
qemuBuildSCSIHostdevDrvStr(virDomainHostdevDefPtr dev,
5091 5092
                           virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED,
                           qemuBuildCommandLineCallbacksPtr callbacks)
5093 5094 5095 5096
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    char *sg = NULL;

5097 5098
    sg = (callbacks->qemuGetSCSIDeviceSgName)(NULL,
                                              dev->source.subsys.u.scsi.adapter,
5099 5100 5101 5102
                                              dev->source.subsys.u.scsi.bus,
                                              dev->source.subsys.u.scsi.target,
                                              dev->source.subsys.u.scsi.unit);
    if (!sg)
5103 5104 5105 5106 5107 5108 5109
        goto error;

    virBufferAsprintf(&buf, "file=/dev/%s,if=none", sg);
    virBufferAsprintf(&buf, ",id=%s-%s",
                      virDomainDeviceAddressTypeToString(dev->info->type),
                      dev->info->alias);

O
Osier Yang 已提交
5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120
    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;
        }
    }

5121
    if (virBufferCheckError(&buf) < 0)
5122 5123 5124 5125
        goto error;

    VIR_FREE(sg);
    return virBufferContentAndReset(&buf);
5126
 error:
5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142
    VIR_FREE(sg);
    virBufferFreeAndReset(&buf);
    return NULL;
}

char *
qemuBuildSCSIHostdevDevStr(virDomainDefPtr def,
                           virDomainHostdevDefPtr dev,
                           virQEMUCapsPtr qemuCaps)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    int model = -1;

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

5143
    if (qemuSetSCSIControllerModel(def, qemuCaps, &model) < 0)
5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175
        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");

    if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) {
        virBufferAsprintf(&buf, ",bus=scsi%d.%d,scsi-id=%d",
                          dev->info->addr.drive.controller,
                          dev->info->addr.drive.bus,
                          dev->info->addr.drive.unit);
    } else {
        virBufferAsprintf(&buf, ",bus=scsi%d.0,channel=%d,scsi-id=%d,lun=%d",
                          dev->info->addr.drive.controller,
                          dev->info->addr.drive.bus,
                          dev->info->addr.drive.target,
                          dev->info->addr.drive.unit);
    }
5176

5177 5178 5179 5180
    virBufferAsprintf(&buf, ",drive=%s-%s,id=%s",
                      virDomainDeviceAddressTypeToString(dev->info->type),
                      dev->info->alias, dev->info->alias);

5181 5182 5183
    if (dev->info->bootIndex)
        virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);

5184
    if (virBufferCheckError(&buf) < 0)
5185 5186 5187
        goto error;

    return virBufferContentAndReset(&buf);
5188
 error:
5189 5190 5191
    virBufferFreeAndReset(&buf);
    return NULL;
}
5192 5193 5194

/* This function outputs a -chardev command line option which describes only the
 * host side of the character device */
5195
static char *
5196
qemuBuildChrChardevStr(virDomainChrSourceDefPtr dev, const char *alias,
5197
                       virQEMUCapsPtr qemuCaps)
5198 5199 5200 5201
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    bool telnet;

5202
    switch (dev->type) {
5203
    case VIR_DOMAIN_CHR_TYPE_NULL:
5204
        virBufferAsprintf(&buf, "null,id=char%s", alias);
5205 5206 5207
        break;

    case VIR_DOMAIN_CHR_TYPE_VC:
5208
        virBufferAsprintf(&buf, "vc,id=char%s", alias);
5209 5210 5211
        break;

    case VIR_DOMAIN_CHR_TYPE_PTY:
5212
        virBufferAsprintf(&buf, "pty,id=char%s", alias);
5213 5214 5215
        break;

    case VIR_DOMAIN_CHR_TYPE_DEV:
5216 5217 5218
        virBufferAsprintf(&buf, "%s,id=char%s,path=%s",
                          STRPREFIX(alias, "parallel") ? "parport" : "tty",
                          alias, dev->data.file.path);
5219 5220 5221
        break;

    case VIR_DOMAIN_CHR_TYPE_FILE:
5222
        virBufferAsprintf(&buf, "file,id=char%s,path=%s", alias,
5223
                          dev->data.file.path);
5224 5225 5226
        break;

    case VIR_DOMAIN_CHR_TYPE_PIPE:
5227
        virBufferAsprintf(&buf, "pipe,id=char%s,path=%s", alias,
5228
                          dev->data.file.path);
5229 5230 5231
        break;

    case VIR_DOMAIN_CHR_TYPE_STDIO:
5232
        virBufferAsprintf(&buf, "stdio,id=char%s", alias);
5233 5234
        break;

5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246
    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";

5247
        virBufferAsprintf(&buf,
5248 5249
                          "udp,id=char%s,host=%s,port=%s,localaddr=%s,"
                          "localport=%s",
5250
                          alias,
5251
                          connectHost,
5252
                          dev->data.udp.connectService,
5253
                          bindHost, bindService);
5254
        break;
5255
    }
5256 5257
    case VIR_DOMAIN_CHR_TYPE_TCP:
        telnet = dev->data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET;
5258
        virBufferAsprintf(&buf,
5259
                          "socket,id=char%s,host=%s,port=%s%s%s",
5260
                          alias,
5261 5262 5263 5264 5265 5266 5267
                          dev->data.tcp.host,
                          dev->data.tcp.service,
                          telnet ? ",telnet" : "",
                          dev->data.tcp.listen ? ",server,nowait" : "");
        break;

    case VIR_DOMAIN_CHR_TYPE_UNIX:
5268
        virBufferAsprintf(&buf,
5269
                          "socket,id=char%s,path=%s%s",
5270
                          alias,
5271 5272 5273
                          dev->data.nix.path,
                          dev->data.nix.listen ? ",server,nowait" : "");
        break;
5274 5275

    case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
5276
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEVMC)) {
5277
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
5278
                           _("spicevmc not supported in this QEMU binary"));
5279 5280
            goto error;
        }
5281
        virBufferAsprintf(&buf, "spicevmc,id=char%s,name=%s", alias,
E
Eric Blake 已提交
5282
                          virDomainChrSpicevmcTypeToString(dev->data.spicevmc));
5283 5284
        break;

5285 5286 5287 5288 5289 5290 5291 5292 5293 5294
    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;

5295
    default:
5296 5297 5298
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unsupported chardev '%s'"),
                       virDomainChrTypeToString(dev->type));
5299
        goto error;
5300 5301
    }

5302
    if (virBufferCheckError(&buf) < 0)
5303 5304 5305 5306
        goto error;

    return virBufferContentAndReset(&buf);

5307
 error:
5308 5309 5310 5311 5312
    virBufferFreeAndReset(&buf);
    return NULL;
}


5313 5314
static char *
qemuBuildChrArgStr(virDomainChrSourceDefPtr dev, const char *prefix)
5315 5316 5317 5318 5319 5320
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

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

5321
    switch ((virDomainChrType)dev->type) {
5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338
    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:
5339
        virBufferAsprintf(&buf, "file:%s", dev->data.file.path);
5340 5341 5342
        break;

    case VIR_DOMAIN_CHR_TYPE_PIPE:
5343
        virBufferAsprintf(&buf, "pipe:%s", dev->data.file.path);
5344 5345 5346 5347 5348 5349
        break;

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

5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361
    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";

5362
        virBufferAsprintf(&buf, "udp:%s:%s@%s:%s",
5363
                          connectHost,
5364
                          dev->data.udp.connectService,
5365 5366
                          bindHost,
                          bindService);
5367
        break;
5368
    }
5369 5370
    case VIR_DOMAIN_CHR_TYPE_TCP:
        if (dev->data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET) {
5371
            virBufferAsprintf(&buf, "telnet:%s:%s%s",
5372 5373 5374 5375
                              dev->data.tcp.host,
                              dev->data.tcp.service,
                              dev->data.tcp.listen ? ",server,nowait" : "");
        } else {
5376
            virBufferAsprintf(&buf, "tcp:%s:%s%s",
5377 5378 5379 5380 5381 5382 5383
                              dev->data.tcp.host,
                              dev->data.tcp.service,
                              dev->data.tcp.listen ? ",server,nowait" : "");
        }
        break;

    case VIR_DOMAIN_CHR_TYPE_UNIX:
5384
        virBufferAsprintf(&buf, "unix:%s%s",
5385 5386 5387
                          dev->data.nix.path,
                          dev->data.nix.listen ? ",server,nowait" : "");
        break;
5388

5389
    case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
5390
    case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
5391
    case VIR_DOMAIN_CHR_TYPE_NMDM:
5392
    case VIR_DOMAIN_CHR_TYPE_LAST:
5393
        break;
5394 5395
    }

5396
    if (virBufferCheckError(&buf) < 0)
5397 5398 5399 5400
        goto error;

    return virBufferContentAndReset(&buf);

5401
 error:
5402 5403 5404 5405 5406
    virBufferFreeAndReset(&buf);
    return NULL;
}


5407 5408
static char *
qemuBuildVirtioSerialPortDevStr(virDomainChrDefPtr dev,
5409
                                virQEMUCapsPtr qemuCaps)
5410 5411
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
5412 5413
    switch (dev->deviceType) {
    case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE:
5414
        virBufferAddLit(&buf, "virtconsole");
5415 5416 5417 5418
        break;
    case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL:
        /* Legacy syntax  '-device spicevmc' */
        if (dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC &&
5419
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC)) {
5420 5421 5422 5423 5424 5425
            virBufferAddLit(&buf, "spicevmc");
        } else {
            virBufferAddLit(&buf, "virtserialport");
        }
        break;
    default:
5426 5427
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Cannot use virtio serial for parallel/serial devices"));
5428 5429
        return NULL;
    }
5430

5431
    if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
5432
        dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW &&
5433
        dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
5434 5435 5436 5437
        /* Check it's a virtio-serial address */
        if (dev->info.type !=
            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL)
        {
5438 5439
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("virtio serial device has invalid address type"));
5440 5441 5442
            goto error;
        }

5443
        virBufferAsprintf(&buf,
5444 5445 5446
                          ",bus=" QEMU_VIRTIO_SERIAL_PREFIX "%d.%d",
                          dev->info.addr.vioserial.controller,
                          dev->info.addr.vioserial.bus);
5447
        virBufferAsprintf(&buf,
5448 5449 5450 5451
                          ",nr=%d",
                          dev->info.addr.vioserial.port);
    }

5452 5453
    if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
        dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC &&
5454 5455
        dev->target.name &&
        STRNEQ(dev->target.name, "com.redhat.spice.0")) {
5456 5457 5458
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Unsupported spicevmc target name '%s'"),
                       dev->target.name);
5459 5460
        goto error;
    }
5461 5462 5463

    if (!(dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
          dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC &&
5464
          virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC))) {
5465
        virBufferAsprintf(&buf, ",chardev=char%s,id=%s",
5466
                          dev->info.alias, dev->info.alias);
5467 5468 5469
        if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL) {
            virBufferAsprintf(&buf, ",name=%s", dev->target.name
                              ? dev->target.name : "com.redhat.spice.0");
5470
        }
5471 5472
    } else {
        virBufferAsprintf(&buf, ",id=%s", dev->info.alias);
5473
    }
5474
    if (virBufferCheckError(&buf) < 0)
5475 5476 5477 5478
        goto error;

    return virBufferContentAndReset(&buf);

5479
 error:
5480 5481 5482 5483
    virBufferFreeAndReset(&buf);
    return NULL;
}

5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503
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);
5504
    if (virBufferCheckError(&buf) < 0)
5505 5506 5507 5508
        goto error;

    return virBufferContentAndReset(&buf);

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

5514 5515 5516 5517 5518 5519 5520

static int
qemuBuildRNGBackendArgs(virCommandPtr cmd,
                        virDomainRNGDefPtr dev,
                        virQEMUCapsPtr qemuCaps)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
5521
    char *backend = NULL;
5522 5523
    int ret = -1;

5524
    switch ((virDomainRNGBackend) dev->backend) {
5525 5526 5527 5528
    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 "
5529
                             "backend"));
5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541
            goto cleanup;
        }

        virBufferAsprintf(&buf, "rng-random,id=%s", dev->info.alias);
        if (dev->source.file)
            virBufferAsprintf(&buf, ",filename=%s", dev->source.file);

        virCommandAddArg(cmd, "-object");
        virCommandAddArgBuffer(cmd, &buf);
        break;

    case VIR_DOMAIN_RNG_BACKEND_EGD:
5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558

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

        if (!(backend = qemuBuildChrChardevStr(dev->source.chardev,
                                               dev->info.alias, qemuCaps)))
            goto cleanup;

        virCommandAddArgList(cmd, "-chardev", backend, NULL);

        virCommandAddArg(cmd, "-object");
        virCommandAddArgFormat(cmd, "rng-egd,chardev=char%s,id=%s",
                               dev->info.alias, dev->info.alias);
5559 5560 5561 5562 5563 5564 5565 5566
        break;

    case VIR_DOMAIN_RNG_BACKEND_LAST:
        break;
    }

    ret = 0;

5567
 cleanup:
5568
    virBufferFreeAndReset(&buf);
5569
    VIR_FREE(backend);
5570 5571 5572 5573 5574 5575
    return ret;
}


static int
qemuBuildRNGDeviceArgs(virCommandPtr cmd,
5576
                       virDomainDefPtr def,
5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590
                       virDomainRNGDefPtr dev,
                       virQEMUCapsPtr qemuCaps)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    int ret = -1;

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

5591 5592 5593 5594
    if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
        virBufferAsprintf(&buf, "virtio-rng-ccw,rng=%s", dev->info.alias);
    else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
        virBufferAsprintf(&buf, "virtio-rng-s390,rng=%s", dev->info.alias);
5595 5596
    else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
        virBufferAsprintf(&buf, "virtio-rng-device,rng=%s", dev->info.alias);
5597 5598
    else
        virBufferAsprintf(&buf, "virtio-rng-pci,rng=%s", dev->info.alias);
5599

5600 5601 5602 5603 5604 5605 5606 5607
    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");
    }

5608
    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
5609 5610 5611 5612 5613 5614 5615
        goto cleanup;

    virCommandAddArg(cmd, "-device");
    virCommandAddArgBuffer(cmd, &buf);

    ret = 0;

5616
 cleanup:
5617 5618 5619 5620 5621
    virBufferFreeAndReset(&buf);
    return ret;
}


E
Eric Blake 已提交
5622
static char *qemuBuildTPMBackendStr(const virDomainDef *def,
5623 5624 5625
                                    virQEMUCapsPtr qemuCaps,
                                    const char *emulator)
{
E
Eric Blake 已提交
5626
    const virDomainTPMDef *tpm = def->tpm;
5627 5628
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    const char *type = virDomainTPMBackendTypeToString(tpm->type);
5629 5630
    char *cancel_path;
    const char *tpmdev;
5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654

    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;

        virBufferAddLit(&buf, ",path=");
        virBufferEscape(&buf, ',', ",", "%s", tpmdev);

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

        break;
    case VIR_DOMAIN_TPM_TYPE_LAST:
        goto error;
    }

5655
    if (virBufferCheckError(&buf) < 0)
5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671
        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:
    virBufferFreeAndReset(&buf);
    return NULL;
}


E
Eric Blake 已提交
5672
static char *qemuBuildTPMDevStr(const virDomainDef *def,
5673 5674 5675 5676
                                virQEMUCapsPtr qemuCaps,
                                const char *emulator)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
E
Eric Blake 已提交
5677
    const virDomainTPMDef *tpm = def->tpm;
5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690
    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);

5691
    if (virBufferCheckError(&buf) < 0)
5692 5693 5694 5695 5696 5697 5698 5699 5700 5701
        goto error;

    return virBufferContentAndReset(&buf);

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


5702 5703 5704 5705 5706 5707
static char *qemuBuildSmbiosBiosStr(virSysinfoDefPtr def)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if ((def->bios_vendor == NULL) && (def->bios_version == NULL) &&
        (def->bios_date == NULL) && (def->bios_release == NULL))
5708
        return NULL;
5709 5710 5711 5712 5713

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

    /* 0:Vendor */
    if (def->bios_vendor)
5714
        virBufferAsprintf(&buf, ",vendor=%s", def->bios_vendor);
5715 5716
    /* 0:BIOS Version */
    if (def->bios_version)
5717
        virBufferAsprintf(&buf, ",version=%s", def->bios_version);
5718 5719
    /* 0:BIOS Release Date */
    if (def->bios_date)
5720
        virBufferAsprintf(&buf, ",date=%s", def->bios_date);
5721 5722
    /* 0:System BIOS Major Release and 0:System BIOS Minor Release */
    if (def->bios_release)
5723
        virBufferAsprintf(&buf, ",release=%s", def->bios_release);
5724

5725
    if (virBufferCheckError(&buf) < 0)
5726 5727 5728 5729
        goto error;

    return virBufferContentAndReset(&buf);

5730
 error:
5731
    virBufferFreeAndReset(&buf);
5732
    return NULL;
5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748
}

static char *qemuBuildSmbiosSystemStr(virSysinfoDefPtr def, bool skip_uuid)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if ((def->system_manufacturer == NULL) && (def->system_sku == NULL) &&
        (def->system_product == NULL) && (def->system_version == NULL) &&
        (def->system_serial == NULL) && (def->system_family == NULL) &&
        (def->system_uuid == NULL || skip_uuid))
        return NULL;

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

    /* 1:Manufacturer */
    if (def->system_manufacturer)
5749
        virBufferAsprintf(&buf, ",manufacturer=%s",
5750 5751 5752
                          def->system_manufacturer);
     /* 1:Product Name */
    if (def->system_product)
5753
        virBufferAsprintf(&buf, ",product=%s", def->system_product);
5754 5755
    /* 1:Version */
    if (def->system_version)
5756
        virBufferAsprintf(&buf, ",version=%s", def->system_version);
5757 5758
    /* 1:Serial Number */
    if (def->system_serial)
5759
        virBufferAsprintf(&buf, ",serial=%s", def->system_serial);
5760 5761
    /* 1:UUID */
    if (def->system_uuid && !skip_uuid)
5762
        virBufferAsprintf(&buf, ",uuid=%s", def->system_uuid);
5763 5764
    /* 1:SKU Number */
    if (def->system_sku)
5765
        virBufferAsprintf(&buf, ",sku=%s", def->system_sku);
5766 5767
    /* 1:Family */
    if (def->system_family)
5768
        virBufferAsprintf(&buf, ",family=%s", def->system_family);
5769

5770
    if (virBufferCheckError(&buf) < 0)
5771 5772 5773 5774
        goto error;

    return virBufferContentAndReset(&buf);

5775
 error:
5776
    virBufferFreeAndReset(&buf);
5777
    return NULL;
5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798
}

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;

5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817
        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;
5818
        }
5819

5820 5821 5822
        now += def->data.variable.adjustment;
        gmtime_r(&now, &nowbits);

5823 5824 5825 5826 5827 5828 5829 5830
        /* 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;

5831
        virBufferAsprintf(&buf, "base=%d-%02d-%02dT%02d:%02d:%02d",
5832 5833 5834 5835 5836 5837 5838 5839 5840
                          nowbits.tm_year + 1900,
                          nowbits.tm_mon + 1,
                          nowbits.tm_mday,
                          nowbits.tm_hour,
                          nowbits.tm_min,
                          nowbits.tm_sec);
    }   break;

    default:
5841 5842 5843
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unsupported clock offset '%s'"),
                       virDomainClockOffsetTypeToString(def->offset));
5844 5845 5846 5847
        goto error;
    }

    /* Look for an 'rtc' timer element, and add in appropriate clock= and driftfix= */
5848
    size_t i;
5849 5850 5851 5852 5853 5854
    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:
5855 5856 5857
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("unsupported rtc timer track '%s'"),
                               virDomainTimerTrackTypeToString(def->timers[i]->track));
5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878
                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:
5879 5880 5881
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("unsupported rtc timer tickpolicy '%s'"),
                               virDomainTimerTickpolicyTypeToString(def->timers[i]->tickpolicy));
5882 5883 5884 5885 5886 5887
                goto error;
            }
            break; /* no need to check other timers - there is only one rtc */
        }
    }

5888
    if (virBufferCheckError(&buf) < 0)
5889 5890 5891 5892
        goto error;

    return virBufferContentAndReset(&buf);

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


static int
E
Eric Blake 已提交
5900 5901
qemuBuildCpuArgStr(virQEMUDriverPtr driver,
                   const virDomainDef *def,
5902
                   const char *emulator,
5903
                   virQEMUCapsPtr qemuCaps,
5904
                   virArch hostarch,
5905
                   char **opt,
5906 5907
                   bool *hasHwVirt,
                   bool migrating)
5908
{
5909
    virCPUDefPtr host = NULL;
5910
    virCPUDefPtr guest = NULL;
5911
    virCPUDefPtr cpu = NULL;
5912
    size_t ncpus = 0;
5913
    char **cpus = NULL;
5914
    const char *default_model;
5915
    virCPUDataPtr data = NULL;
5916
    bool have_cpu = false;
5917
    char *compare_msg = NULL;
5918 5919
    int ret = -1;
    virBuffer buf = VIR_BUFFER_INITIALIZER;
5920
    size_t i;
5921
    virCapsPtr caps = NULL;
5922 5923 5924

    *hasHwVirt = false;

5925 5926 5927 5928 5929
    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
        goto cleanup;

    host = caps->host.cpu;

5930
    if (def->os.arch == VIR_ARCH_I686)
5931 5932 5933 5934
        default_model = "qemu32";
    else
        default_model = "qemu64";

5935 5936
    if (def->cpu &&
        (def->cpu->mode != VIR_CPU_MODE_CUSTOM || def->cpu->model)) {
5937 5938 5939
        virCPUCompareResult cmp;
        const char *preferred;

5940
        if (!host ||
J
Jiri Denemark 已提交
5941
            !host->model ||
5942
            (ncpus = virQEMUCapsGetCPUDefinitions(qemuCaps, &cpus)) == 0) {
5943 5944
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("CPU specification not supported by hypervisor"));
5945 5946 5947
            goto cleanup;
        }

5948 5949 5950 5951 5952 5953 5954 5955
        if (!(cpu = virCPUDefCopy(def->cpu)))
            goto cleanup;

        if (cpu->mode != VIR_CPU_MODE_CUSTOM &&
            !migrating &&
            cpuUpdate(cpu, host) < 0)
            goto cleanup;

5956
        cmp = cpuGuestData(host, cpu, &data, &compare_msg);
5957 5958
        switch (cmp) {
        case VIR_CPU_COMPARE_INCOMPATIBLE:
5959
            if (compare_msg) {
5960 5961 5962
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("guest and host CPU are not compatible: %s"),
                               compare_msg);
5963
            } else {
5964 5965
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("guest CPU is not compatible with host CPU"));
5966
            }
5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977
            /* fall through */
        case VIR_CPU_COMPARE_ERROR:
            goto cleanup;

        default:
            break;
        }

        /* Only 'svm' requires --enable-nesting. The nested
         * 'vmx' patches now simply hook off the CPU features
         */
5978 5979 5980 5981 5982 5983 5984
        if (def->os.arch == VIR_ARCH_X86_64 ||
            def->os.arch == VIR_ARCH_I686) {
            int hasSVM = cpuHasFeature(data, "svm");
            if (hasSVM < 0)
                goto cleanup;
            *hasHwVirt = hasSVM > 0 ? true : false;
        }
5985

5986 5987
        if (cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) {
            const char *mode = virCPUModeTypeToString(cpu->mode);
5988
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_HOST)) {
5989 5990 5991
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("CPU mode '%s' is not supported by QEMU"
                                 " binary"), mode);
5992 5993 5994
                goto cleanup;
            }
            if (def->virtType != VIR_DOMAIN_VIRT_KVM) {
5995 5996 5997
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("CPU mode '%s' is only supported with kvm"),
                               mode);
5998 5999 6000 6001
                goto cleanup;
            }
            virBufferAddLit(&buf, "host");
        } else {
6002
            if (VIR_ALLOC(guest) < 0)
6003 6004 6005
                goto cleanup;
            if (VIR_STRDUP(guest->vendor_id, cpu->vendor_id) < 0)
                goto cleanup;
6006

6007
            guest->arch = host->arch;
6008 6009
            if (cpu->match == VIR_CPU_MATCH_MINIMUM)
                preferred = host->model;
6010
            else
6011
                preferred = cpu->model;
6012

6013 6014
            guest->type = VIR_CPU_TYPE_GUEST;
            guest->fallback = cpu->fallback;
6015
            if (cpuDecode(guest, data, (const char **)cpus, ncpus, preferred) < 0)
6016 6017 6018
                goto cleanup;

            virBufferAdd(&buf, guest->model, -1);
6019 6020
            if (guest->vendor_id)
                virBufferAsprintf(&buf, ",vendor=%s", guest->vendor_id);
6021 6022 6023 6024 6025 6026 6027 6028 6029
            for (i = 0; i < guest->nfeatures; i++) {
                char sign;
                if (guest->features[i].policy == VIR_CPU_FEATURE_DISABLE)
                    sign = '-';
                else
                    sign = '+';

                virBufferAsprintf(&buf, ",%c%s", sign, guest->features[i].name);
            }
6030
        }
6031
        have_cpu = true;
6032
    } else {
6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044
        /*
         * 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
         */
6045
        if (def->os.arch == VIR_ARCH_I686 &&
6046
            ((hostarch == VIR_ARCH_X86_64 &&
6047
              strstr(emulator, "kvm")) ||
6048 6049 6050 6051 6052 6053
             strstr(emulator, "x86_64"))) {
            virBufferAdd(&buf, default_model, -1);
            have_cpu = true;
        }
    }

6054
    /* Handle paravirtual timers  */
6055
    for (i = 0; i < def->clock.ntimers; i++) {
6056 6057 6058 6059 6060 6061
        virDomainTimerDefPtr timer = def->clock.timers[i];

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

        if (timer->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK) {
6062 6063
            virBufferAsprintf(&buf, "%s,%ckvmclock",
                              have_cpu ? "" : default_model,
6064 6065 6066 6067 6068 6069
                              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 已提交
6070
            have_cpu = true;
6071
        }
6072 6073
    }

6074 6075
    if (def->apic_eoi) {
        char sign;
6076
        if (def->apic_eoi == VIR_DOMAIN_FEATURE_STATE_ON)
6077 6078 6079 6080 6081 6082 6083
            sign = '+';
        else
            sign = '-';

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

6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099
    if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK]) {
        char sign;
        if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK] == VIR_DOMAIN_FEATURE_STATE_ON)
            sign = '+';
        else
            sign = '-';

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

6100
    if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_DOMAIN_FEATURE_STATE_ON) {
6101 6102 6103 6104 6105 6106
        if (!have_cpu) {
            virBufferAdd(&buf, default_model, -1);
            have_cpu = true;
        }

        for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
6107
            switch ((virDomainHyperv) i) {
6108
            case VIR_DOMAIN_HYPERV_RELAXED:
6109
            case VIR_DOMAIN_HYPERV_VAPIC:
6110 6111 6112 6113 6114
                if (def->hyperv_features[i] == VIR_DOMAIN_FEATURE_STATE_ON)
                    virBufferAsprintf(&buf, ",hv_%s",
                                      virDomainHypervTypeToString(i));
                break;

6115
            case VIR_DOMAIN_HYPERV_SPINLOCKS:
6116 6117 6118
                if (def->hyperv_features[i] == VIR_DOMAIN_FEATURE_STATE_ON)
                    virBufferAsprintf(&buf, ",hv_spinlocks=0x%x",
                                      def->hyperv_spinlocks);
6119 6120
                break;

6121 6122 6123 6124 6125 6126
            case VIR_DOMAIN_HYPERV_LAST:
                break;
            }
        }
    }

6127
    if (virBufferCheckError(&buf) < 0)
6128
        goto cleanup;
6129 6130 6131 6132 6133

    *opt = virBufferContentAndReset(&buf);

    ret = 0;

6134
 cleanup:
6135
    VIR_FREE(compare_msg);
J
Jiri Denemark 已提交
6136
    cpuDataFree(data);
6137
    virCPUDefFree(guest);
6138
    virCPUDefFree(cpu);
6139
    virObjectUnref(caps);
6140 6141 6142
    return ret;
}

6143 6144
static int
qemuBuildObsoleteAccelArg(virCommandPtr cmd,
E
Eric Blake 已提交
6145
                          const virDomainDef *def,
6146 6147
                          virQEMUCapsPtr qemuCaps)
{
6148 6149 6150 6151
    bool disableKQEMU = false;
    bool enableKQEMU = false;
    bool disableKVM = false;
    bool enableKVM = false;
6152 6153 6154 6155

    switch (def->virtType) {
    case VIR_DOMAIN_VIRT_QEMU:
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KQEMU))
6156
            disableKQEMU = true;
6157
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
6158
            disableKVM = true;
6159 6160 6161 6162
        break;

    case VIR_DOMAIN_VIRT_KQEMU:
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
6163
            disableKVM = true;
6164 6165

        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KQEMU)) {
6166
            enableKQEMU = true;
6167 6168 6169 6170 6171 6172 6173 6174 6175
        } else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_KQEMU)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("the QEMU binary does not support kqemu"));
            return -1;
        }
        break;

    case VIR_DOMAIN_VIRT_KVM:
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KQEMU))
6176
            disableKQEMU = true;
6177 6178

        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KVM)) {
6179
            enableKVM = true;
6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209
        } 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 (disableKQEMU)
        virCommandAddArg(cmd, "-no-kqemu");
    else if (enableKQEMU)
        virCommandAddArgList(cmd, "-enable-kqemu", "-kernel-kqemu", NULL);
    if (disableKVM)
        virCommandAddArg(cmd, "-no-kvm");
    if (enableKVM)
        virCommandAddArg(cmd, "-enable-kvm");

    return 0;
}

6210 6211
static int
qemuBuildMachineArgStr(virCommandPtr cmd,
E
Eric Blake 已提交
6212
                       const virDomainDef *def,
6213
                       virQEMUCapsPtr qemuCaps)
6214
{
6215 6216
    bool obsoleteAccel = false;

6217 6218 6219 6220 6221 6222 6223
    /* 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;

6224
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_OPT)) {
6225 6226 6227 6228
        /* 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);
6229 6230 6231 6232
        if (def->mem.dump_core) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("dump-guest-core is not available "
                             "with this QEMU binary"));
6233 6234
            return -1;
        }
6235 6236 6237 6238 6239 6240 6241 6242

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

6243
        obsoleteAccel = true;
6244 6245
    } else {
        virBuffer buf = VIR_BUFFER_INITIALIZER;
6246 6247

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

6250 6251 6252 6253 6254 6255 6256
        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 已提交
6257 6258 6259 6260
        /* 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))
6261
            virBufferAddLit(&buf, ",usb=off");
L
Li Zhang 已提交
6262

6263 6264 6265 6266 6267
        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"));
6268
                virBufferFreeAndReset(&buf);
6269 6270 6271 6272 6273 6274 6275
                return -1;
            }

            virBufferAsprintf(&buf, ",dump-guest-core=%s",
                              virDomainMemDumpTypeToString(def->mem.dump_core));
        }

6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287
        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;
            }
        }

6288
        virCommandAddArgBuffer(cmd, &buf);
6289 6290
    }

6291 6292 6293 6294
    if (obsoleteAccel &&
        qemuBuildObsoleteAccelArg(cmd, def, qemuCaps) < 0)
        return -1;

6295 6296 6297
    return 0;
}

6298
static char *
E
Eric Blake 已提交
6299
qemuBuildSmpArgStr(const virDomainDef *def,
6300
                   virQEMUCapsPtr qemuCaps)
6301 6302 6303
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

6304
    virBufferAsprintf(&buf, "%u", def->vcpus);
6305

6306
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SMP_TOPOLOGY)) {
6307
        if (def->vcpus != def->maxvcpus)
6308
            virBufferAsprintf(&buf, ",maxcpus=%u", def->maxvcpus);
6309 6310 6311
        /* 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) {
6312 6313 6314
            virBufferAsprintf(&buf, ",sockets=%u", def->cpu->sockets);
            virBufferAsprintf(&buf, ",cores=%u", def->cpu->cores);
            virBufferAsprintf(&buf, ",threads=%u", def->cpu->threads);
6315 6316
        }
        else {
6317 6318 6319
            virBufferAsprintf(&buf, ",sockets=%u", def->maxvcpus);
            virBufferAsprintf(&buf, ",cores=%u", 1);
            virBufferAsprintf(&buf, ",threads=%u", 1);
6320 6321 6322 6323
        }
    } else if (def->vcpus != def->maxvcpus) {
        virBufferFreeAndReset(&buf);
        /* FIXME - consider hot-unplugging cpus after boot for older qemu */
6324 6325 6326
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("setting current vcpu count less than maximum is "
                         "not supported with this QEMU binary"));
6327 6328 6329
        return NULL;
    }

6330
    if (virBufferCheckError(&buf) < 0)
6331 6332 6333 6334 6335
        return NULL;

    return virBufferContentAndReset(&buf);
}

B
Bharata B Rao 已提交
6336
static int
E
Eric Blake 已提交
6337
qemuBuildNumaArgStr(const virDomainDef *def, virCommandPtr cmd)
B
Bharata B Rao 已提交
6338
{
6339
    size_t i;
B
Bharata B Rao 已提交
6340
    virBuffer buf = VIR_BUFFER_INITIALIZER;
6341 6342
    char *cpumask = NULL;
    int ret = -1;
B
Bharata B Rao 已提交
6343 6344

    for (i = 0; i < def->cpu->ncells; i++) {
6345
        VIR_FREE(cpumask);
B
Bharata B Rao 已提交
6346 6347 6348
        virCommandAddArg(cmd, "-numa");
        virBufferAsprintf(&buf, "node,nodeid=%d", def->cpu->cells[i].cellid);
        virBufferAddLit(&buf, ",cpus=");
6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362
        if (!(cpumask = virBitmapFormat(def->cpu->cells[i].cpumask)))
            goto cleanup;

        /* Up through qemu 1.4, -numa does not accept a cpus
         * argument any more complex than start-stop.
         *
         * XXX For qemu 1.5, the syntax has not yet been decided;
         * but when it is, we need a capability bit and
         * translation of our cpumask into the qemu syntax.  */
        if (strchr(cpumask, ',')) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("disjoint NUMA cpu ranges are not supported "
                             "with this QEMU"));
            goto cleanup;
6363
        }
6364
        virBufferAdd(&buf, cpumask, -1);
6365 6366
        def->cpu->cells[i].mem = VIR_DIV_UP(def->cpu->cells[i].mem,
                                            1024) * 1024;
6367
        virBufferAsprintf(&buf, ",mem=%d", def->cpu->cells[i].mem / 1024);
B
Bharata B Rao 已提交
6368

6369
        if (virBufferCheckError(&buf) < 0)
6370
            goto cleanup;
B
Bharata B Rao 已提交
6371 6372 6373

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

6376
 cleanup:
6377
    VIR_FREE(cpumask);
B
Bharata B Rao 已提交
6378
    virBufferFreeAndReset(&buf);
6379
    return ret;
B
Bharata B Rao 已提交
6380
}
6381

6382

6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406
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,
                        "%s/%s.vnc", cfg->libDir, def->name) == -1)
6407
            goto error;
6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460

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

    } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VNC_COLON)) {
        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;
            }
            if (ret < 0) {
                virReportError(VIR_ERR_XML_ERROR,
                               _("listen network '%s' had no usable address"),
                               listenNetwork);
                goto error;
            }
            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->vncListen;

        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);
    } else {
        virBufferAsprintf(&opt, "%d",
                          graphics->data.vnc.port - 5900);
    }

    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VNC_COLON)) {
6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471
        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);
            }

6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484
        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;
            }

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

6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499
        if (graphics->data.vnc.auth.passwd || cfg->vncPassword)
            virBufferAddLit(&opt, ",password");

        if (cfg->vncTLS) {
            virBufferAddLit(&opt, ",tls");
            if (cfg->vncTLSx509verify)
                virBufferAsprintf(&opt, ",x509verify=%s", cfg->vncTLSx509certdir);
            else
                virBufferAsprintf(&opt, ",x509=%s", cfg->vncTLSx509certdir);
        }

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

            if (cfg->vncSASLdir)
6500
                virCommandAddEnvPair(cmd, "SASL_CONF_PATH", cfg->vncSASLdir);
6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515

            /* TODO: Support ACLs later */
        }
    }

    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)
6516
        virCommandAddEnvPassBlockSUID(cmd, "QEMU_AUDIO_DRV", NULL);
6517 6518 6519 6520 6521
    else
        virCommandAddEnvString(cmd, "QEMU_AUDIO_DRV=none");

    return 0;

6522
 error:
6523 6524 6525 6526 6527 6528
    VIR_FREE(netAddr);
    virBufferFreeAndReset(&opt);
    return -1;
}


6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542
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;
6543
    size_t i;
6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565

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

6566 6567 6568 6569 6570 6571 6572 6573 6574 6575
    if (cfg->spiceSASL) {
        virBufferAddLit(&opt, ",sasl");

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

        /* TODO: Support ACLs later */
    }

6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616
    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;
        }
        if (ret < 0) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("listen network '%s' had no usable address"),
                           listenNetwork);
            goto error;
        }
        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:
6617
            virBufferAddLit(&opt, ",agent-mouse=off");
6618 6619
            break;
        case VIR_DOMAIN_GRAPHICS_SPICE_MOUSE_MODE_CLIENT:
6620
            virBufferAddLit(&opt, ",agent-mouse=on");
6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633
            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");

6634 6635
    if (tlsPort > 0)
        virBufferAsprintf(&opt, ",x509-dir=%s", cfg->spiceTLSx509certdir);
6636 6637 6638

    switch (defaultMode) {
    case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE:
6639
        virBufferAddLit(&opt, ",tls-channel=default");
6640 6641
        break;
    case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_INSECURE:
6642
        virBufferAddLit(&opt, ",plaintext-channel=default");
6643 6644 6645 6646 6647 6648
        break;
    case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_ANY:
        /* nothing */
        break;
    }

6649
    for (i = 0; i < VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST; i++) {
6650
        switch (graphics->data.spice.channels[i]) {
6651
        case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE:
6652
            if (tlsPort <= 0) {
6653 6654
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("spice secure channels set in XML configuration, "
6655
                                 "but TLS port is not provided"));
6656 6657 6658 6659 6660
                goto error;
            }
            virBufferAsprintf(&opt, ",tls-channel=%s",
                              virDomainGraphicsSpiceChannelNameTypeToString(i));
            break;
6661

6662
        case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_INSECURE:
6663 6664 6665 6666 6667 6668
            if (port <= 0) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("spice insecure channels set in XML "
                                 "configuration, but plain port is not provided"));
                goto error;
            }
6669 6670 6671
            virBufferAsprintf(&opt, ",plaintext-channel=%s",
                              virDomainGraphicsSpiceChannelNameTypeToString(i));
            break;
6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696

        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;
            }
6697 6698
        }
    }
6699

6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716
    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",
                          virDomainGraphicsSpicePlaybackCompressionTypeToString(graphics->data.spice.playback));
    if (graphics->data.spice.streaming)
        virBufferAsprintf(&opt, ",streaming-video=%s",
                          virDomainGraphicsSpiceStreamingModeTypeToString(graphics->data.spice.streaming));
    if (graphics->data.spice.copypaste == VIR_DOMAIN_GRAPHICS_SPICE_CLIPBOARD_COPYPASTE_NO)
        virBufferAddLit(&opt, ",disable-copy-paste");
6717 6718 6719 6720 6721 6722 6723 6724 6725
    if (graphics->data.spice.filetransfer == VIR_DOMAIN_GRAPHICS_SPICE_AGENT_FILE_TRANSFER_NO) {
        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");
        }
    }
6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746

    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;

6747
 error:
6748 6749 6750 6751 6752
    VIR_FREE(netAddr);
    virBufferFreeAndReset(&opt);
    return -1;
}

6753
static int
6754
qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg,
6755 6756
                             virCommandPtr cmd,
                             virDomainDefPtr def,
6757
                             virQEMUCapsPtr qemuCaps,
6758
                             virDomainGraphicsDefPtr graphics)
6759
{
6760
    switch ((virDomainGraphicsType) graphics->type) {
6761
    case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
6762 6763
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_0_10) &&
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SDL)) {
6764
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
6765 6766
                           _("sdl not supported by '%s'"), def->emulator);
            return -1;
6767 6768
        }

6769
        if (graphics->data.sdl.xauth)
6770
            virCommandAddEnvPair(cmd, "XAUTHORITY", graphics->data.sdl.xauth);
6771
        if (graphics->data.sdl.display)
6772
            virCommandAddEnvPair(cmd, "DISPLAY", graphics->data.sdl.display);
6773 6774
        if (graphics->data.sdl.fullscreen)
            virCommandAddArg(cmd, "-full-screen");
6775

6776 6777 6778 6779
        /* 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
         */
6780 6781
        virCommandAddEnvPassBlockSUID(cmd, "QEMU_AUDIO_DRV", NULL);
        virCommandAddEnvPassBlockSUID(cmd, "SDL_AUDIODRIVER", NULL);
B
Bharata B Rao 已提交
6782

6783 6784 6785
        /* 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 :-( */
6786
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SDL))
6787
            virCommandAddArg(cmd, "-sdl");
6788

6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799
        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:
6800 6801 6802
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unsupported graphics type '%s'"),
                       virDomainGraphicsTypeToString(graphics->type));
6803
        return -1;
6804
    }
6805

6806 6807
    return 0;
}
6808

6809 6810 6811 6812 6813 6814 6815 6816 6817
static int
qemuBuildInterfaceCommandLine(virCommandPtr cmd,
                              virQEMUDriverPtr driver,
                              virConnectPtr conn,
                              virDomainDefPtr def,
                              virDomainNetDefPtr net,
                              virQEMUCapsPtr qemuCaps,
                              int vlan,
                              int bootindex,
6818
                              virNetDevVPortProfileOp vmop,
6819
                              bool standalone)
6820 6821 6822
{
    int ret = -1;
    char *nic = NULL, *host = NULL;
6823 6824 6825 6826 6827 6828
    int *tapfd = NULL;
    int tapfdSize = 0;
    int *vhostfd = NULL;
    int vhostfdSize = 0;
    char **tapfdName = NULL;
    char **vhostfdName = NULL;
6829
    int actualType = virDomainNetGetActualType(net);
6830
    size_t i;
6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841

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

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

6842 6843 6844 6845 6846 6847 6848 6849 6850 6851
    /* Currently nothing besides TAP devices supports multiqueue. */
    if (net->driver.virtio.queues > 0 &&
        !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
          actualType == VIR_DOMAIN_NET_TYPE_BRIDGE)) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Multiqueue network is not supported for: %s"),
                       virDomainNetTypeToString(actualType));
        return -1;
    }

6852 6853
    if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
        actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
6854 6855 6856 6857 6858
        tapfdSize = net->driver.virtio.queues;
        if (!tapfdSize)
            tapfdSize = 1;

        if (VIR_ALLOC_N(tapfd, tapfdSize) < 0 ||
6859
            VIR_ALLOC_N(tapfdName, tapfdSize) < 0)
6860 6861
            goto cleanup;

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

6864 6865
        if (qemuNetworkIfaceConnect(def, conn, driver, net,
                                    qemuCaps, tapfd, &tapfdSize) < 0)
6866 6867
            goto cleanup;
    } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
6868
        if (VIR_ALLOC(tapfd) < 0 || VIR_ALLOC(tapfdName) < 0)
6869 6870 6871 6872 6873
            goto cleanup;
        tapfdSize = 1;
        tapfd[0] = qemuPhysIfaceConnect(def, driver, net,
                                        qemuCaps, vmop);
        if (tapfd[0] < 0)
6874 6875 6876
            goto cleanup;
    }

6877 6878 6879 6880 6881
    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) {
6882 6883
        /* Attempt to use vhost-net mode for these types of
           network device */
6884 6885 6886 6887 6888
        vhostfdSize = net->driver.virtio.queues;
        if (!vhostfdSize)
            vhostfdSize = 1;

        if (VIR_ALLOC_N(vhostfd, vhostfdSize) < 0 ||
6889
            VIR_ALLOC_N(vhostfdName, vhostfdSize))
6890 6891
            goto cleanup;

6892 6893
        memset(vhostfd, -1, vhostfdSize * sizeof(vhostfd[0]));

6894
        if (qemuOpenVhostNet(def, net, qemuCaps, vhostfd, &vhostfdSize) < 0)
6895 6896 6897
            goto cleanup;
    }

6898
    for (i = 0; i < tapfdSize; i++) {
6899 6900
        virCommandPassFD(cmd, tapfd[i],
                         VIR_COMMAND_PASS_FD_CLOSE_PARENT);
6901
        if (virAsprintf(&tapfdName[i], "%d", tapfd[i]) < 0)
6902 6903 6904
            goto cleanup;
    }

6905
    for (i = 0; i < vhostfdSize; i++) {
6906 6907
        virCommandPassFD(cmd, vhostfd[i],
                         VIR_COMMAND_PASS_FD_CLOSE_PARENT);
6908
        if (virAsprintf(&vhostfdName[i], "%d", vhostfd[i]) < 0)
6909
            goto cleanup;
6910 6911 6912 6913 6914 6915 6916 6917 6918 6919
    }

    /* 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
     */
6920
    if (qemuDomainSupportsNetdev(def, qemuCaps, net)) {
6921
        if (!(host = qemuBuildHostNetStr(net, driver,
6922 6923 6924
                                         ',', vlan,
                                         tapfdName, tapfdSize,
                                         vhostfdName, vhostfdSize)))
6925 6926 6927
            goto cleanup;
        virCommandAddArgList(cmd, "-netdev", host, NULL);
    }
6928
    if (qemuDomainSupportsNicdev(def, qemuCaps, net)) {
6929
        if (!(nic = qemuBuildNicDevStr(def, net, vlan, bootindex,
6930
                                       vhostfdSize, qemuCaps)))
6931 6932 6933 6934 6935 6936 6937
            goto cleanup;
        virCommandAddArgList(cmd, "-device", nic, NULL);
    } else {
        if (!(nic = qemuBuildNicStr(net, "nic,", vlan)))
            goto cleanup;
        virCommandAddArgList(cmd, "-net", nic, NULL);
    }
6938
    if (!qemuDomainSupportsNetdev(def, qemuCaps, net)) {
6939
        if (!(host = qemuBuildHostNetStr(net, driver,
6940 6941 6942
                                         ',', vlan,
                                         tapfdName, tapfdSize,
                                         vhostfdName, vhostfdSize)))
6943 6944 6945 6946 6947
            goto cleanup;
        virCommandAddArgList(cmd, "-net", host, NULL);
    }

    ret = 0;
6948
 cleanup:
6949 6950
    if (ret < 0) {
        virErrorPtr saved_err = virSaveLastError();
6951
        virDomainConfNWFilterTeardown(net);
6952 6953 6954
        virSetError(saved_err);
        virFreeError(saved_err);
    }
6955
    for (i = 0; tapfd && i < tapfdSize && tapfd[i] >= 0; i++) {
6956 6957
        if (ret < 0)
            VIR_FORCE_CLOSE(tapfd[i]);
6958 6959
        if (tapfdName)
            VIR_FREE(tapfdName[i]);
6960
    }
6961
    for (i = 0; vhostfd && i < vhostfdSize && vhostfd[i] >= 0; i++) {
6962 6963
        if (ret < 0)
            VIR_FORCE_CLOSE(vhostfd[i]);
6964 6965
        if (vhostfdName)
            VIR_FREE(vhostfdName[i]);
6966 6967 6968
    }
    VIR_FREE(tapfd);
    VIR_FREE(vhostfd);
6969 6970 6971 6972 6973 6974 6975
    VIR_FREE(nic);
    VIR_FREE(host);
    VIR_FREE(tapfdName);
    VIR_FREE(vhostfdName);
    return ret;
}

6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987
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);
6988
    VIR_FREE(devstr);
6989 6990 6991
    return 0;
}

6992 6993 6994 6995
qemuBuildCommandLineCallbacks buildCommandLineCallbacks = {
    .qemuGetSCSIDeviceSgName = virSCSIDeviceGetSgName,
};

6996 6997 6998 6999 7000 7001 7002 7003 7004
/*
 * 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,
7005
                     virQEMUDriverPtr driver,
7006 7007 7008
                     virDomainDefPtr def,
                     virDomainChrSourceDefPtr monitor_chr,
                     bool monitor_json,
7009
                     virQEMUCapsPtr qemuCaps,
7010 7011 7012
                     const char *migrateFrom,
                     int migrateFd,
                     virDomainSnapshotObjPtr snapshot,
7013
                     virNetDevVPortProfileOp vmop,
C
Cole Robinson 已提交
7014 7015
                     qemuBuildCommandLineCallbacksPtr callbacks,
                     bool standalone)
7016
{
7017
    virErrorPtr originalError = NULL;
7018
    size_t i, j;
7019 7020 7021 7022 7023 7024 7025
    const char *emulator;
    char uuid[VIR_UUID_STRING_BUFLEN];
    char *cpu;
    char *smp;
    int last_good_net = -1;
    bool hasHwVirt = false;
    virCommandPtr cmd = NULL;
7026
    bool allowReboot = true;
7027
    bool emitBootindex = false;
7028 7029 7030
    int sdl = 0;
    int vnc = 0;
    int spice = 0;
7031
    int usbcontroller = 0;
M
Martin Kletzander 已提交
7032
    int actualSerials = 0;
7033
    bool usblegacy = false;
7034
    bool mlock = false;
7035 7036 7037
    int contOrder[] = {
        /* We don't add an explicit IDE or FD controller because the
         * provided PIIX4 device already includes one. It isn't possible to
7038 7039 7040 7041 7042
         * remove the PIIX4.
         *
         * We don't add PCI root controller either, because it's implicit,
         * but we do add PCI bridges. */
        VIR_DOMAIN_CONTROLLER_TYPE_PCI,
7043 7044 7045 7046 7047 7048
        VIR_DOMAIN_CONTROLLER_TYPE_USB,
        VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
        VIR_DOMAIN_CONTROLLER_TYPE_SATA,
        VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL,
        VIR_DOMAIN_CONTROLLER_TYPE_CCID,
    };
7049
    virArch hostarch = virArchFromHost();
7050
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
7051

7052
    VIR_DEBUG("conn=%p driver=%p def=%p mon=%p json=%d "
7053
              "qemuCaps=%p migrateFrom=%s migrateFD=%d "
7054 7055
              "snapshot=%p vmop=%d",
              conn, driver, def, monitor_chr, monitor_json,
7056
              qemuCaps, migrateFrom, migrateFd, snapshot, vmop);
7057

7058 7059 7060 7061
    virUUIDFormat(def->uuid, uuid);

    emulator = def->emulator;

7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078
    if (!cfg->privileged) {
        /* If we have no cgroups than we can have no tunings that
         * require them */

        if (def->mem.hard_limit || def->mem.soft_limit ||
            def->mem.min_guarantee || def->mem.swap_hard_limit) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Memory tuning is not available in session mode"));
            goto error;
        }

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

7079
        if (def->cputune.sharesSpecified || def->cputune.period ||
7080 7081 7082 7083 7084 7085 7086 7087
            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;
        }
    }

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

7102 7103 7104 7105
    /*
     * do not use boot=on for drives when not using KVM since this
     * is not supported at all in upstream QEmu.
     */
7106
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) &&
7107
        (def->virtType == VIR_DOMAIN_VIRT_QEMU))
7108
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_DRIVE_BOOT);
7109 7110

    cmd = virCommandNew(emulator);
7111

7112
    virCommandAddEnvPassCommon(cmd);
7113

7114
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NAME)) {
7115
        virCommandAddArg(cmd, "-name");
7116
        if (cfg->setProcessName &&
7117
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_NAME_PROCESS)) {
7118 7119 7120 7121
            virCommandAddArgFormat(cmd, "%s,process=qemu:%s",
                                   def->name, def->name);
        } else {
            virCommandAddArg(cmd, def->name);
7122 7123
        }
    }
C
Cole Robinson 已提交
7124 7125 7126 7127

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

7128 7129
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_FIPS))
        virCommandAddArg(cmd, "-enable-fips");
7130

7131
    if (qemuBuildMachineArgStr(cmd, def, qemuCaps) < 0)
7132
        goto error;
7133

7134
    if (qemuBuildCpuArgStr(driver, def, emulator, qemuCaps,
7135
                           hostarch, &cpu, &hasHwVirt, !!migrateFrom) < 0)
7136
        goto error;
7137

7138 7139 7140 7141
    if (cpu) {
        virCommandAddArgList(cmd, "-cpu", cpu, NULL);
        VIR_FREE(cpu);

7142
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NESTING) &&
7143 7144
            hasHwVirt)
            virCommandAddArg(cmd, "-enable-nesting");
7145
    }
7146

7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160
    if (def->os.loader) {
        virCommandAddArg(cmd, "-bios");
        virCommandAddArg(cmd, def->os.loader);
    }

    /* Set '-m MB' based on maxmem, because the lower 'memory' limit
     * is set post-startup using the balloon driver. If balloon driver
     * is not supported, then they're out of luck anyway.  Update the
     * XML to reflect our rounding.
     */
    virCommandAddArg(cmd, "-m");
    def->mem.max_balloon = VIR_DIV_UP(def->mem.max_balloon, 1024) * 1024;
    virCommandAddArgFormat(cmd, "%llu", def->mem.max_balloon / 1024);
    if (def->mem.hugepage_backed) {
7161
        if (!cfg->hugetlbfsMount) {
7162 7163 7164 7165
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("hugetlbfs filesystem is not mounted"));
            goto error;
        }
7166
        if (!cfg->hugepagePath) {
7167 7168 7169 7170
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("hugepages are disabled by administrator config"));
            goto error;
        }
7171
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MEM_PATH)) {
7172 7173 7174 7175 7176 7177
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("hugepage backing not supported by '%s'"),
                           def->emulator);
            goto error;
        }
        virCommandAddArgList(cmd, "-mem-prealloc", "-mem-path",
7178
                             cfg->hugepagePath, NULL);
7179 7180
    }

7181 7182 7183 7184 7185 7186 7187 7188 7189 7190
    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");
    }
7191
    mlock = def->mem.locked;
7192

7193
    virCommandAddArg(cmd, "-smp");
7194
    if (!(smp = qemuBuildSmpArgStr(def, qemuCaps)))
7195 7196 7197 7198 7199 7200 7201 7202
        goto error;
    virCommandAddArg(cmd, smp);
    VIR_FREE(smp);

    if (def->cpu && def->cpu->ncells)
        if (qemuBuildNumaArgStr(def, cmd) < 0)
            goto error;

7203
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_UUID))
7204 7205 7206 7207
        virCommandAddArgList(cmd, "-uuid", uuid, NULL);
    if (def->virtType == VIR_DOMAIN_VIRT_XEN ||
        STREQ(def->os.type, "xen") ||
        STREQ(def->os.type, "linux")) {
7208
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DOMID)) {
7209 7210
            virCommandAddArg(cmd, "-domid");
            virCommandAddArgFormat(cmd, "%d", def->id);
7211
        } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_XEN_DOMID)) {
7212 7213 7214 7215 7216 7217 7218
            virCommandAddArg(cmd, "-xen-attach");
            virCommandAddArg(cmd, "-xen-domid");
            virCommandAddArgFormat(cmd, "%d", def->id);
        } else {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("qemu emulator '%s' does not support xen"),
                           def->emulator);
7219 7220 7221 7222
            goto error;
        }
    }

7223 7224 7225 7226 7227
    if ((def->os.smbios_mode != VIR_DOMAIN_SMBIOS_NONE) &&
        (def->os.smbios_mode != VIR_DOMAIN_SMBIOS_EMULATE)) {
        virSysinfoDefPtr source = NULL;
        bool skip_uuid = false;

7228
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SMBIOS_TYPE)) {
7229 7230 7231
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("the QEMU binary %s does not support smbios settings"),
                           emulator);
7232 7233 7234
            goto error;
        }

7235 7236 7237
        /* should we really error out or just warn in those cases ? */
        if (def->os.smbios_mode == VIR_DOMAIN_SMBIOS_HOST) {
            if (driver->hostsysinfo == NULL) {
7238
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
7239
                               _("Host SMBIOS information is not available"));
7240
                goto error;
7241
            }
7242 7243 7244 7245 7246 7247 7248 7249 7250
            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;
7251
            }
7252 7253
            source = def->sysinfo;
            /* domain_conf guaranteed that system_uuid matches guest uuid. */
7254
        }
7255 7256
        if (source != NULL) {
            char *smbioscmd;
7257

7258 7259 7260 7261
            smbioscmd = qemuBuildSmbiosBiosStr(source);
            if (smbioscmd != NULL) {
                virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
                VIR_FREE(smbioscmd);
7262
            }
7263 7264 7265 7266
            smbioscmd = qemuBuildSmbiosSystemStr(source, skip_uuid);
            if (smbioscmd != NULL) {
                virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
                VIR_FREE(smbioscmd);
7267
            }
7268
        }
7269
    }
7270

7271 7272 7273 7274 7275 7276 7277
    /*
     * 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...
     */
7278
    if (!def->graphics) {
7279
        virCommandAddArg(cmd, "-nographic");
7280

7281
        if (cfg->nogfxAllowHostAudio)
7282
            virCommandAddEnvPassBlockSUID(cmd, "QEMU_AUDIO_DRV", NULL);
7283 7284 7285 7286
        else
            virCommandAddEnvString(cmd, "QEMU_AUDIO_DRV=none");
    }

7287
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
7288
        /* Disable global config files and default devices */
7289
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_USER_CONFIG))
7290
            virCommandAddArg(cmd, "-no-user-config");
7291
        else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NODEFCONFIG))
7292 7293
            virCommandAddArg(cmd, "-nodefconfig");
        virCommandAddArg(cmd, "-nodefaults");
7294 7295
    }

7296 7297
    /* Serial graphics adapter */
    if (def->os.bios.useserial == VIR_DOMAIN_BIOS_USESERIAL_YES) {
7298
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
7299 7300 7301 7302
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("qemu does not support -device"));
            goto error;
        }
7303
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGA)) {
7304 7305 7306 7307 7308 7309 7310
            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"));
7311 7312
            goto error;
        }
7313
        virCommandAddArgList(cmd, "-device", "sga", NULL);
7314 7315
    }

7316 7317 7318
    if (monitor_chr) {
        char *chrdev;
        /* Use -chardev if it's available */
7319
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV)) {
J
Jim Fehlig 已提交
7320

7321 7322
            virCommandAddArg(cmd, "-chardev");
            if (!(chrdev = qemuBuildChrChardevStr(monitor_chr, "monitor",
7323
                                                  qemuCaps)))
7324 7325 7326
                goto error;
            virCommandAddArg(cmd, chrdev);
            VIR_FREE(chrdev);
7327

7328 7329 7330 7331 7332 7333 7334 7335
            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,";
7336

7337 7338 7339 7340 7341
            virCommandAddArg(cmd, "-monitor");
            if (!(chrdev = qemuBuildChrArgStr(monitor_chr, prefix)))
                goto error;
            virCommandAddArg(cmd, chrdev);
            VIR_FREE(chrdev);
7342 7343 7344
        }
    }

7345
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_RTC)) {
7346
        char *rtcopt;
7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357
        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;
7358

7359 7360 7361
        case VIR_DOMAIN_CLOCK_OFFSET_UTC:
            /* Nothing, its the default */
            break;
7362

7363 7364 7365 7366
        default:
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("unsupported clock offset '%s'"),
                           virDomainClockOffsetTypeToString(def->clock.offset));
7367
            goto error;
7368 7369 7370 7371 7372
        }
    }
    if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE &&
        def->clock.data.timezone) {
        virCommandAddEnvPair(cmd, "TZ", def->clock.data.timezone);
7373 7374
    }

7375
    for (i = 0; i < def->clock.ntimers; i++) {
7376
        switch ((virDomainTimerNameType) def->clock.timers[i]->name) {
7377 7378 7379 7380 7381 7382
        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;
7383

7384
        case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
7385 7386 7387
        case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK:
            /* Timers above are handled when building -cpu.  */
        case VIR_DOMAIN_TIMER_NAME_LAST:
7388 7389 7390 7391 7392 7393
            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) */
7394
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_RTC_TD_HACK)) {
7395 7396 7397 7398
                switch (def->clock.timers[i]->tickpolicy) {
                case -1:
                case VIR_DOMAIN_TIMER_TICKPOLICY_DELAY:
                    /* the default - do nothing */
7399
                    break;
7400 7401
                case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP:
                    virCommandAddArg(cmd, "-rtc-td-hack");
7402
                    break;
7403 7404 7405 7406 7407
                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 已提交
7408
                    goto error;
7409
                }
7410
            } else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_RTC)
7411 7412 7413 7414 7415 7416 7417 7418 7419
                       && (def->clock.timers[i]->tickpolicy
                           != VIR_DOMAIN_TIMER_TICKPOLICY_DELAY)
                       && (def->clock.timers[i]->tickpolicy != -1)) {
                /* 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;
7420
            }
7421
            break;
7422

7423 7424 7425 7426 7427 7428
        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. */
7429 7430 7431 7432
                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))
7433 7434 7435
                    virCommandAddArg(cmd, "-no-kvm-pit-reinjection");
                break;
            case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP:
7436 7437
                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_KVM_PIT) ||
                    virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM_PIT_TICK_POLICY)) {
7438
                    /* do nothing - this is default for kvm-pit */
7439
                } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_TDF)) {
7440 7441
                    /* -tdf switches to 'catchup' with userspace pit. */
                    virCommandAddArg(cmd, "-tdf");
7442
                } else {
7443 7444 7445 7446
                    /* can't catchup if we have neither pit mode */
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("unsupported pit tickpolicy '%s'"),
                                   virDomainTimerTickpolicyTypeToString(def->clock.timers[i]->tickpolicy));
7447 7448 7449
                    goto error;
                }
                break;
7450 7451 7452 7453 7454 7455 7456
            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;
7457
            }
7458
            break;
7459

7460 7461 7462 7463 7464 7465 7466
        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"! */
7467

7468
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_HPET)) {
7469 7470 7471 7472 7473 7474 7475
                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,
7476 7477
                                   "%s", _("hpet timer is not supported"));
                    goto error;
7478 7479
                }
            }
7480 7481 7482
            break;
        }
    }
7483

7484 7485 7486 7487 7488 7489 7490 7491 7492
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_REBOOT)) {
        /* 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_DESTROY) {
            allowReboot = false;
            virCommandAddArg(cmd, "-no-reboot");
        }
    }
7493

7494 7495 7496 7497
    /* 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.
     */
7498 7499
    if (monitor_json && allowReboot &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) {
7500
        virCommandAddArg(cmd, "-no-shutdown");
7501
    }
7502

7503
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_ACPI)) {
7504
        if (def->features[VIR_DOMAIN_FEATURE_ACPI] != VIR_DOMAIN_FEATURE_STATE_ON)
7505 7506
            virCommandAddArg(cmd, "-no-acpi");
    }
7507

7508
    if (def->pm.s3) {
7509
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DISABLE_S3)) {
7510 7511 7512
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("setting ACPI S3 not supported"));
            goto error;
7513
        }
7514 7515 7516 7517 7518 7519
        virCommandAddArg(cmd, "-global");
        virCommandAddArgFormat(cmd, "PIIX4_PM.disable_s3=%d",
                               def->pm.s3 == VIR_DOMAIN_PM_STATE_DISABLED);
    }

    if (def->pm.s4) {
7520
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DISABLE_S4)) {
7521
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
7522 7523 7524 7525 7526 7527 7528
                           "%s", _("setting ACPI S4 not supported"));
            goto error;
        }
        virCommandAddArg(cmd, "-global");
        virCommandAddArgFormat(cmd, "PIIX4_PM.disable_s4=%d",
                               def->pm.s4 == VIR_DOMAIN_PM_STATE_DISABLED);
    }
7529

7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541
    if (!def->os.bootloader) {
        int boot_nparams = 0;
        virBuffer boot_buf = VIR_BUFFER_INITIALIZER;
        /*
         * 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
             */
7542
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX)) {
7543
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
7544
                               _("hypervisor lacks deviceboot feature"));
7545 7546
                goto error;
            }
7547
            emitBootindex = true;
7548
        } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX) &&
7549
                   (def->os.bootmenu != VIR_DOMAIN_BOOT_MENU_ENABLED ||
7550
                    !virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_MENU))) {
7551 7552
            emitBootindex = true;
        }
7553

7554 7555
        if (!emitBootindex) {
            char boot[VIR_DOMAIN_BOOT_LAST+1];
7556

7557
            for (i = 0; i < def->os.nBootDevs; i++) {
7558 7559 7560
                switch (def->os.bootDevs[i]) {
                case VIR_DOMAIN_BOOT_CDROM:
                    boot[i] = 'd';
7561
                    break;
7562 7563
                case VIR_DOMAIN_BOOT_FLOPPY:
                    boot[i] = 'a';
7564
                    break;
7565 7566 7567 7568 7569 7570 7571 7572
                case VIR_DOMAIN_BOOT_DISK:
                    boot[i] = 'c';
                    break;
                case VIR_DOMAIN_BOOT_NET:
                    boot[i] = 'n';
                    break;
                default:
                    boot[i] = 'c';
7573
                    break;
7574
                }
7575
            }
7576
            boot[def->os.nBootDevs] = '\0';
7577

7578 7579
            virBufferAsprintf(&boot_buf, "%s", boot);
            boot_nparams++;
7580 7581
        }

7582
        if (def->os.bootmenu) {
7583
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_MENU)) {
7584 7585
                if (boot_nparams++)
                    virBufferAddChar(&boot_buf, ',');
7586

7587
                if (def->os.bootmenu == VIR_DOMAIN_BOOT_MENU_ENABLED)
7588
                    virBufferAddLit(&boot_buf, "menu=on");
7589
                else
7590
                    virBufferAddLit(&boot_buf, "menu=off");
7591 7592 7593 7594 7595 7596 7597
            } 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");
            }
        }
7598

7599
        if (def->os.bios.rt_set) {
7600
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_REBOOT_TIMEOUT)) {
7601 7602 7603
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("reboot timeout is not supported "
                                 "by this QEMU binary"));
7604
                virBufferFreeAndReset(&boot_buf);
7605
                goto error;
7606 7607 7608 7609 7610 7611 7612 7613
            }

            if (boot_nparams++)
                virBufferAddChar(&boot_buf, ',');

            virBufferAsprintf(&boot_buf,
                              "reboot-timeout=%d",
                              def->os.bios.rt_delay);
7614 7615
        }

7616 7617 7618 7619 7620 7621
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_STRICT)) {
            if (boot_nparams++)
                virBufferAddChar(&boot_buf, ',');
            virBufferAddLit(&boot_buf, "strict=on");
        }

7622 7623
        if (boot_nparams > 0) {
            virCommandAddArg(cmd, "-boot");
7624

7625
            if (virBufferCheckError(&boot_buf) < 0)
7626 7627
                goto error;

7628 7629
            if (boot_nparams < 2 || emitBootindex) {
                virCommandAddArgBuffer(cmd, &boot_buf);
7630
                virBufferFreeAndReset(&boot_buf);
7631
            } else {
7632
                char *str = virBufferContentAndReset(&boot_buf);
7633 7634
                virCommandAddArgFormat(cmd,
                                       "order=%s",
7635 7636
                                       str);
                VIR_FREE(str);
7637 7638 7639
            }
        }

7640 7641 7642 7643 7644 7645
        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);
O
Olivia Yin 已提交
7646 7647 7648 7649 7650 7651 7652 7653 7654
        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;
            }
        }
7655 7656 7657
    } else {
        virCommandAddArgList(cmd, "-bootloader", def->os.bootloader, NULL);
    }
7658

7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669 7670 7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705
    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);
        }
    }

7706
    for (i = 0; i < def->ndisks; i++) {
7707
        virDomainDiskDefPtr disk = def->disks[i];
7708

7709 7710
        if (disk->src->driverName != NULL &&
            !STREQ(disk->src->driverName, "qemu")) {
7711 7712
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("unsupported driver name '%s' for disk '%s'"),
7713
                           disk->src->driverName, disk->src->path);
7714 7715 7716 7717
            goto error;
        }
    }

7718
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
7719 7720 7721
        for (j = 0; j < ARRAY_CARDINALITY(contOrder); j++) {
            for (i = 0; i < def->ncontrollers; i++) {
                virDomainControllerDefPtr cont = def->controllers[i];
7722

7723 7724
                if (cont->type != contOrder[j])
                    continue;
7725

7726 7727 7728 7729 7730 7731 7732
                /* Also, skip USB controllers with type none.*/
                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;
                }

L
Laine Stump 已提交
7733
                /* Skip pci-root/pcie-root */
7734
                if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI &&
L
Laine Stump 已提交
7735 7736
                    (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT ||
                     cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT)) {
7737 7738 7739
                    continue;
                }

7740 7741
                /* Only recent QEMU implements a SATA (AHCI) controller */
                if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_SATA) {
7742
                    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_AHCI)) {
7743 7744 7745
                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                       _("SATA is not supported with this "
                                         "QEMU binary"));
7746
                        goto error;
7747 7748 7749
                    } else if (cont->idx == 0 && qemuDomainMachineIsQ35(def)) {
                        /* first SATA controller on Q35 machines is implicit */
                        continue;
7750 7751
                    } else {
                        char *devstr;
7752

7753 7754
                        virCommandAddArg(cmd, "-device");
                        if (!(devstr = qemuBuildControllerDevStr(def, cont,
7755
                                                                 qemuCaps, NULL)))
7756
                            goto error;
7757 7758 7759

                        virCommandAddArg(cmd, devstr);
                        VIR_FREE(devstr);
7760
                    }
7761 7762
                } else if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
                           cont->model == -1 &&
7763
                           !qemuDomainMachineIsQ35(def) &&
7764
                           (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI) ||
7765 7766
                            (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_OHCI) &&
                             def->os.arch == VIR_ARCH_PPC64))) {
7767 7768 7769 7770
                    if (usblegacy) {
                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                       _("Multiple legacy USB controllers are "
                                         "not supported"));
7771 7772
                        goto error;
                    }
7773 7774 7775 7776 7777
                    usblegacy = true;
                } else {
                    virCommandAddArg(cmd, "-device");

                    char *devstr;
7778
                    if (!(devstr = qemuBuildControllerDevStr(def, cont, qemuCaps,
7779 7780 7781 7782 7783
                                                             &usbcontroller)))
                        goto error;

                    virCommandAddArg(cmd, devstr);
                    VIR_FREE(devstr);
7784
                }
7785
            }
7786 7787
        }
    }
7788

7789
    if (usbcontroller == 0 && !qemuDomainMachineIsQ35(def))
7790
        virCommandAddArg(cmd, "-usb");
7791

7792
    for (i = 0; i < def->nhubs; i++) {
7793 7794
        virDomainHubDefPtr hub = def->hubs[i];
        char *optstr;
7795

7796
        virCommandAddArg(cmd, "-device");
7797
        if (!(optstr = qemuBuildHubDevStr(def, hub, qemuCaps)))
7798 7799 7800 7801
            goto error;
        virCommandAddArg(cmd, optstr);
        VIR_FREE(optstr);
    }
7802

7803
    /* If QEMU supports -drive param instead of old -hda, -hdb, -cdrom .. */
7804
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) {
7805
        int bootCD = 0, bootFloppy = 0, bootDisk = 0;
7806

7807
        if ((virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_BOOT) || emitBootindex)) {
7808 7809
            /* bootDevs will get translated into either bootindex=N or boot=on
             * depending on what qemu supports */
7810
            for (i = 0; i < def->os.nBootDevs; i++) {
7811 7812 7813 7814 7815 7816 7817 7818 7819 7820 7821
                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;
                }
7822
            }
7823
        }
7824

7825
        for (i = 0; i < def->ndisks; i++) {
7826 7827 7828
            char *optstr;
            int bootindex = 0;
            virDomainDiskDefPtr disk = def->disks[i];
7829
            bool withDeviceArg = false;
7830
            bool deviceFlagMasked = false;
7831

7832 7833 7834
            /* Unless we have -device, then USB disks need special
               handling */
            if ((disk->bus == VIR_DOMAIN_DISK_BUS_USB) &&
7835
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
7836 7837
                if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
                    virCommandAddArg(cmd, "-usbdevice");
7838
                    virCommandAddArgFormat(cmd, "disk:%s", disk->src->path);
7839 7840 7841
                } else {
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("unsupported usb disk type for '%s'"),
7842
                                   disk->src->path);
7843
                    goto error;
7844
                }
7845
                continue;
7846
            }
7847 7848 7849 7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861

            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;
7862
            }
7863 7864 7865 7866

            virCommandAddArg(cmd, "-drive");

            /* Unfortunately it is not possible to use
7867
               -device for floppies, xen PV, or SD
7868 7869 7870
               devices. Fortunately, those don't need
               static PCI addresses, so we don't really
               care that we can't use -device */
7871
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
7872 7873
                if (disk->bus != VIR_DOMAIN_DISK_BUS_XEN &&
                    disk->bus != VIR_DOMAIN_DISK_BUS_SD) {
7874
                    withDeviceArg = true;
7875
                } else {
7876
                    virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE);
7877 7878
                    deviceFlagMasked = true;
                }
7879
            }
7880 7881
            optstr = qemuBuildDriveStr(conn, disk,
                                       emitBootindex ? false : !!bootindex,
7882
                                       qemuCaps);
7883
            if (deviceFlagMasked)
7884
                virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE);
7885 7886 7887 7888 7889 7890 7891 7892 7893
            if (!optstr)
                goto error;
            virCommandAddArg(cmd, optstr);
            VIR_FREE(optstr);

            if (!emitBootindex)
                bootindex = 0;
            else if (disk->info.bootIndex)
                bootindex = disk->info.bootIndex;
7894

7895 7896 7897 7898 7899 7900 7901
            if (withDeviceArg) {
                if (disk->bus == VIR_DOMAIN_DISK_BUS_FDC) {
                    virCommandAddArg(cmd, "-global");
                    virCommandAddArgFormat(cmd, "isa-fdc.drive%c=drive-%s",
                                           disk->info.addr.drive.unit
                                           ? 'B' : 'A',
                                           disk->info.alias);
E
Eric Blake 已提交
7902

7903 7904 7905 7906 7907 7908 7909 7910 7911
                    if (bootindex) {
                        virCommandAddArg(cmd, "-global");
                        virCommandAddArgFormat(cmd, "isa-fdc.bootindex%c=%d",
                                               disk->info.addr.drive.unit
                                               ? 'B' : 'A',
                                               bootindex);
                    }
                } else {
                    virCommandAddArg(cmd, "-device");
E
Eric Blake 已提交
7912

7913
                    if (!(optstr = qemuBuildDriveDevStr(def, disk, bootindex,
7914
                                                        qemuCaps)))
7915 7916 7917 7918
                        goto error;
                    virCommandAddArg(cmd, optstr);
                    VIR_FREE(optstr);
                }
E
Eric Blake 已提交
7919
            }
7920 7921
        }
    } else {
7922
        for (i = 0; i < def->ndisks; i++) {
7923 7924 7925 7926
            char dev[NAME_MAX];
            char *file;
            const char *fmt;
            virDomainDiskDefPtr disk = def->disks[i];
E
Eric Blake 已提交
7927

7928
            if ((disk->src->type == VIR_STORAGE_TYPE_BLOCK) &&
7929
                (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
7930
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
7931 7932
                               _("tray status 'open' is invalid for "
                                 "block type disk"));
E
Eric Blake 已提交
7933 7934 7935
                goto error;
            }

7936 7937 7938
            if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
                if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
                    virCommandAddArg(cmd, "-usbdevice");
7939
                    virCommandAddArgFormat(cmd, "disk:%s", disk->src->path);
7940 7941 7942
                } else {
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("unsupported usb disk type for '%s'"),
7943
                                   disk->src->path);
E
Eric Blake 已提交
7944 7945
                    goto error;
                }
7946
                continue;
E
Eric Blake 已提交
7947
            }
7948 7949 7950

            if (STREQ(disk->dst, "hdc") &&
                disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
7951
                if (disk->src->path) {
7952 7953 7954
                    snprintf(dev, NAME_MAX, "-%s", "cdrom");
                } else {
                    continue;
E
Eric Blake 已提交
7955 7956
                }
            } else {
7957 7958 7959 7960 7961 7962 7963 7964
                if (STRPREFIX(disk->dst, "hd") ||
                    STRPREFIX(disk->dst, "fd")) {
                    snprintf(dev, NAME_MAX, "-%s", disk->dst);
                } else {
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("unsupported disk type '%s'"), disk->dst);
                    goto error;
                }
E
Eric Blake 已提交
7965 7966
            }

7967
            if (disk->src->type == VIR_STORAGE_TYPE_DIR) {
7968
                /* QEMU only supports magic FAT format for now */
7969 7970
                if (disk->src->format > 0 &&
                    disk->src->format != VIR_STORAGE_FILE_FAT) {
7971 7972
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("unsupported disk driver type for '%s'"),
7973
                                   virStorageFileFormatTypeToString(disk->src->format));
7974 7975 7976 7977 7978 7979 7980 7981 7982 7983 7984
                    goto error;
                }
                if (!disk->readonly) {
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("cannot create virtual FAT disks in read-write mode"));
                    goto error;
                }
                if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
                    fmt = "fat:floppy:%s";
                else
                    fmt = "fat:%s";
E
Eric Blake 已提交
7985

7986
                if (virAsprintf(&file, fmt, disk->src) < 0)
7987
                    goto error;
7988
            } else if (disk->src->type == VIR_STORAGE_TYPE_NETWORK) {
7989 7990
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("network disks are only supported with -drive"));
7991
                goto error;
7992
            } else {
7993
                if (VIR_STRDUP(file, disk->src->path) < 0) {
7994
                    goto error;
7995
                }
E
Eric Blake 已提交
7996 7997
            }

7998 7999 8000 8001 8002 8003 8004 8005
            /* Don't start with source if the tray is open for
             * CDROM and Floppy device.
             */
            if (!((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY ||
                   disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
                  disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN))
                virCommandAddArgList(cmd, dev, file, NULL);
            VIR_FREE(file);
E
Eric Blake 已提交
8006 8007 8008
        }
    }

8009
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_FSDEV)) {
8010
        for (i = 0; i < def->nfss; i++) {
8011 8012
            char *optstr;
            virDomainFSDefPtr fs = def->fss[i];
8013

8014
            virCommandAddArg(cmd, "-fsdev");
8015
            if (!(optstr = qemuBuildFSStr(fs, qemuCaps)))
8016 8017 8018
                goto error;
            virCommandAddArg(cmd, optstr);
            VIR_FREE(optstr);
8019

8020
            virCommandAddArg(cmd, "-device");
8021
            if (!(optstr = qemuBuildFSDevStr(def, fs, qemuCaps)))
8022 8023 8024 8025 8026 8027 8028 8029 8030
                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;
8031 8032 8033
        }
    }

8034
    if (!def->nnets) {
8035
        /* If we have -device, then we set -nodefault already */
8036
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
8037
            virCommandAddArgList(cmd, "-net", "none", NULL);
8038
    } else {
8039
        int bootNet = 0;
8040

8041 8042 8043 8044
        if (emitBootindex) {
            /* convert <boot dev='network'/> to bootindex since we didn't emit
             * -boot n
             */
8045
            for (i = 0; i < def->os.nBootDevs; i++) {
8046 8047 8048 8049
                if (def->os.bootDevs[i] == VIR_DOMAIN_BOOT_NET) {
                    bootNet = i + 1;
                    break;
                }
8050 8051 8052
            }
        }

8053
        for (i = 0; i < def->nnets; i++) {
8054
            virDomainNetDefPtr net = def->nets[i];
8055
            int vlan;
8056

8057
            /* VLANs are not used with -netdev, so don't record them */
8058
            if (qemuDomainSupportsNetdev(def, qemuCaps, net))
8059
                vlan = -1;
8060 8061
            else
                vlan = i;
8062

8063
            if (qemuBuildInterfaceCommandLine(cmd, driver, conn, def, net,
8064 8065
                                              qemuCaps, vlan, bootNet, vmop,
                                              standalone) < 0)
8066 8067 8068
                goto error;
            last_good_net = i;
            bootNet = 0;
8069 8070 8071
        }
    }

8072 8073 8074 8075 8076
    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;
8077
        virBuffer opt = VIR_BUFFER_INITIALIZER;
8078
        const char *database;
8079

8080 8081 8082 8083
        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) {
8084
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
8085 8086 8087
                           _("this QEMU binary lacks multiple smartcard "
                             "support"));
            virBufferFreeAndReset(&opt);
8088 8089 8090
            goto error;
        }

8091 8092
        switch (smartcard->type) {
        case VIR_DOMAIN_SMARTCARD_TYPE_HOST:
8093 8094
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) {
8095 8096 8097 8098
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("this QEMU binary lacks smartcard host "
                                 "mode support"));
                goto error;
8099 8100
            }

8101 8102
            virBufferAddLit(&opt, "ccid-card-emulated,backend=nss-emulated");
            break;
8103

8104
        case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES:
8105 8106
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) {
8107 8108 8109 8110 8111
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("this QEMU binary lacks smartcard host "
                                 "mode support"));
                goto error;
            }
8112

8113 8114 8115 8116
            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);
8117
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
8118 8119
                                   _("invalid certificate name: %s"),
                                   smartcard->data.cert.file[j]);
8120 8121
                    goto error;
                }
8122
                virBufferAsprintf(&opt, ",cert%zu=%s", j + 1,
8123 8124 8125 8126 8127 8128 8129 8130
                                  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);
8131 8132
                    goto error;
                }
8133 8134 8135
                database = smartcard->data.cert.database;
            } else {
                database = VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE;
8136
            }
8137
            virBufferAsprintf(&opt, ",db=%s", database);
8138
            break;
8139

8140
        case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
8141 8142
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_PASSTHRU)) {
8143 8144 8145 8146
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("this QEMU binary lacks smartcard "
                                 "passthrough mode support"));
                goto error;
8147 8148
            }

8149 8150 8151
            virCommandAddArg(cmd, "-chardev");
            if (!(devstr = qemuBuildChrChardevStr(&smartcard->data.passthru,
                                                  smartcard->info.alias,
8152
                                                  qemuCaps))) {
8153 8154
                virBufferFreeAndReset(&opt);
                goto error;
8155
            }
8156 8157
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);
8158

8159 8160 8161
            virBufferAsprintf(&opt, "ccid-card-passthru,chardev=char%s",
                              smartcard->info.alias);
            break;
8162

8163 8164 8165 8166 8167
        default:
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("unexpected smartcard type %d"),
                           smartcard->type);
            virBufferFreeAndReset(&opt);
8168 8169
            goto error;
        }
8170 8171 8172 8173
        virCommandAddArg(cmd, "-device");
        virBufferAsprintf(&opt, ",id=%s,bus=ccid0.0", smartcard->info.alias);
        virCommandAddArgBuffer(cmd, &opt);
    }
8174

8175 8176 8177
    for (i = 0; i < def->nserials; i++) {
        virDomainChrDefPtr serial = def->serials[i];
        char *devstr;
8178

8179 8180 8181
        if (serial->source.type == VIR_DOMAIN_CHR_TYPE_SPICEPORT && !spice)
            continue;

8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199
        /* 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);
8200
        }
8201
        actualSerials++;
8202
    }
8203

M
Martin Kletzander 已提交
8204 8205 8206 8207
    /* If we have -device, then we set -nodefault already */
    if (!actualSerials && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
            virCommandAddArgList(cmd, "-serial", "none", NULL);

8208 8209
    if (!def->nparallels) {
        /* If we have -device, then we set -nodefault already */
8210
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
8211 8212
            virCommandAddArgList(cmd, "-parallel", "none", NULL);
    } else {
8213
        for (i = 0; i < def->nparallels; i++) {
8214 8215
            virDomainChrDefPtr parallel = def->parallels[i];
            char *devstr;
8216

8217
            /* Use -chardev with -device if they are available */
8218 8219
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) &&
                virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8220 8221 8222
                virCommandAddArg(cmd, "-chardev");
                if (!(devstr = qemuBuildChrChardevStr(&parallel->source,
                                                      parallel->info.alias,
8223
                                                      qemuCaps)))
8224 8225 8226
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
8227

8228 8229
                if (qemuBuildChrDeviceCommandLine(cmd, def, parallel, qemuCaps) < 0)
                    goto error;
8230 8231 8232 8233 8234 8235 8236
            } else {
                virCommandAddArg(cmd, "-parallel");
                if (!(devstr = qemuBuildChrArgStr(&parallel->source, NULL)))
                      goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
            }
8237
        }
8238
    }
8239

8240
    for (i = 0; i < def->nchannels; i++) {
8241 8242
        virDomainChrDefPtr channel = def->channels[i];
        char *devstr;
8243

8244 8245
        switch (channel->targetType) {
        case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD:
8246 8247
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8248 8249
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("guestfwd requires QEMU to support -chardev & -device"));
8250 8251
                goto error;
            }
8252

8253 8254 8255
            virCommandAddArg(cmd, "-chardev");
            if (!(devstr = qemuBuildChrChardevStr(&channel->source,
                                                  channel->info.alias,
8256
                                                  qemuCaps)))
8257 8258 8259 8260
                goto error;
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);

8261
            if (qemuBuildChrDeviceStr(&devstr, def, channel, qemuCaps) < 0)
8262
                goto error;
8263 8264
            virCommandAddArgList(cmd, "-netdev", devstr, NULL);
            VIR_FREE(devstr);
8265 8266
            break;

8267
        case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO:
8268
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8269 8270
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("virtio channel requires QEMU to support -device"));
8271 8272
                goto error;
            }
8273

8274
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC) &&
8275 8276 8277 8278 8279 8280 8281 8282 8283
                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,
8284
                                                      qemuCaps)))
8285 8286 8287
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
8288
            }
8289

8290
            if (qemuBuildChrDeviceCommandLine(cmd, def, channel, qemuCaps) < 0)
8291
                goto error;
8292 8293
            break;
        }
8294
    }
8295

8296
    /* Explicit console devices */
8297
    for (i = 0; i < def->nconsoles; i++) {
8298 8299
        virDomainChrDefPtr console = def->consoles[i];
        char *devstr;
8300

8301
        switch (console->targetType) {
8302 8303
        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLP:
        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLPLM:
8304
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8305 8306 8307 8308
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("sclp console requires QEMU to support -device"));
                goto error;
            }
8309
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCLP_S390)) {
8310 8311 8312 8313 8314 8315 8316 8317
                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,
8318
                                                  qemuCaps)))
8319 8320 8321 8322
                goto error;
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);

8323
            if (qemuBuildChrDeviceCommandLine(cmd, def, console, qemuCaps) < 0)
8324 8325 8326
                goto error;
            break;

8327
        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO:
8328
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8329 8330 8331
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("virtio channel requires QEMU to support -device"));
                goto error;
P
Peng Zhou 已提交
8332 8333
            }

8334 8335 8336
            virCommandAddArg(cmd, "-chardev");
            if (!(devstr = qemuBuildChrChardevStr(&console->source,
                                                  console->info.alias,
8337
                                                  qemuCaps)))
8338 8339 8340
                goto error;
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);
8341

8342
            if (qemuBuildChrDeviceCommandLine(cmd, def, console, qemuCaps) < 0)
8343
                goto error;
8344
            break;
8345 8346

        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL:
8347
            break;
8348 8349 8350 8351 8352 8353

        default:
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("unsupported console target type %s"),
                           NULLSTR(virDomainChrConsoleTargetTypeToString(console->targetType)));
            goto error;
8354
        }
8355
    }
8356

8357 8358 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 8372
    if (def->tpm) {
        char *optstr;

        if (!(optstr = qemuBuildTPMBackendStr(def, qemuCaps, emulator)))
            goto error;

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

        if (!(optstr = qemuBuildTPMDevStr(def, qemuCaps, emulator)))
            goto error;

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

8373
    for (i = 0; i < def->ninputs; i++) {
8374 8375 8376
        virDomainInputDefPtr input = def->inputs[i];

        if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) {
8377
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8378 8379
                char *optstr;
                virCommandAddArg(cmd, "-device");
8380
                if (!(optstr = qemuBuildUSBInputDevStr(def, input, qemuCaps)))
8381
                    goto error;
8382 8383 8384
                virCommandAddArg(cmd, optstr);
                VIR_FREE(optstr);
            } else {
8385 8386 8387 8388 8389 8390 8391 8392 8393 8394 8395
                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;
                }
8396 8397
            }
        }
8398
    }
8399

8400
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_0_10) && sdl + vnc + spice > 1) {
8401 8402 8403 8404 8405 8406 8407 8408
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("only 1 graphics device is supported"));
        goto error;
    }
    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"));
8409 8410 8411
        goto error;
    }

8412
    for (i = 0; i < def->ngraphics; ++i) {
8413
        if (qemuBuildGraphicsCommandLine(cfg, cmd, def, qemuCaps,
8414 8415 8416
                                         def->graphics[i]) < 0)
            goto error;
    }
8417

8418
    if (def->nvideos > 0) {
8419
        int primaryVideoType = def->videos[0]->type;
8420
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY) &&
8421
             ((primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_VGA &&
8422
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VGA)) ||
8423
             (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_CIRRUS &&
8424
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_CIRRUS_VGA)) ||
8425
             (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_VMVGA &&
8426
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMWARE_SVGA)) ||
8427
             (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_QXL &&
8428
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL_VGA)))
8429
           ) {
8430
            for (i = 0; i < def->nvideos; i++) {
8431 8432
                char *str;
                virCommandAddArg(cmd, "-device");
8433
                if (!(str = qemuBuildDeviceVideoStr(def, def->videos[i], qemuCaps, !i)))
8434 8435 8436 8437 8438
                    goto error;

                virCommandAddArg(cmd, str);
                VIR_FREE(str);
            }
8439
        } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA)) {
8440
            if (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_XEN) {
8441 8442
                /* nothing - vga has no effect on Xen pvfb */
            } else {
8443
                if ((primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_QXL) &&
8444
                    !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA_QXL)) {
8445 8446
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("This QEMU does not support QXL graphics adapters"));
8447 8448 8449
                    goto error;
                }

8450
                const char *vgastr = qemuVideoTypeToString(primaryVideoType);
8451
                if (!vgastr || STREQ(vgastr, "")) {
8452 8453
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("video type %s is not supported with QEMU"),
8454
                                   virDomainVideoTypeToString(primaryVideoType));
8455 8456 8457 8458
                    goto error;
                }

                virCommandAddArgList(cmd, "-vga", vgastr, NULL);
8459

8460 8461
                if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_QXL &&
                    (def->videos[0]->vram || def->videos[0]->ram) &&
8462 8463
                    virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
                    const char *dev = (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL_VGA)
8464 8465 8466 8467 8468 8469 8470 8471 8472 8473 8474 8475 8476 8477 8478 8479
                                       ? "qxl-vga" : "qxl");
                    int ram = def->videos[0]->ram;
                    int vram = def->videos[0]->vram;

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

8481
                    if (ram) {
E
Eric Blake 已提交
8482
                        virCommandAddArg(cmd, "-global");
8483 8484 8485 8486 8487 8488 8489
                        virCommandAddArgFormat(cmd, "%s.ram_size=%u",
                                               dev, ram * 1024);
                    }
                    if (vram) {
                        virCommandAddArg(cmd, "-global");
                        virCommandAddArgFormat(cmd, "%s.vram_size=%u",
                                               dev, vram * 1024);
8490 8491
                    }
                }
8492
            }
8493 8494

            if (def->nvideos > 1) {
8495
                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8496
                    for (i = 1; i < def->nvideos; i++) {
8497 8498 8499 8500 8501 8502 8503 8504 8505 8506
                        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");

8507
                        if (!(str = qemuBuildDeviceVideoStr(def, def->videos[i], qemuCaps, false)))
8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518
                            goto error;

                        virCommandAddArg(cmd, str);
                        VIR_FREE(str);
                    }
                } else {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   "%s", _("only one video card is currently supported"));
                    goto error;
                }
            }
8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 8532 8533 8534 8535
        } else {

            switch (def->videos[0]->type) {
            case VIR_DOMAIN_VIDEO_TYPE_VGA:
                virCommandAddArg(cmd, "-std-vga");
                break;

            case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
                virCommandAddArg(cmd, "-vmwarevga");
                break;

            case VIR_DOMAIN_VIDEO_TYPE_XEN:
            case VIR_DOMAIN_VIDEO_TYPE_CIRRUS:
                /* No special args - this is the default */
                break;

            default:
8536 8537 8538
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("video type %s is not supported with this QEMU"),
                               virDomainVideoTypeToString(def->videos[0]->type));
8539 8540 8541
                goto error;
            }

8542
            if (def->nvideos > 1) {
8543 8544
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("only one video card is currently supported"));
8545 8546 8547 8548 8549 8550
                goto error;
            }
        }

    } else {
        /* If we have -device, then we set -nodefault already */
8551 8552 8553
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) &&
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA) &&
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA_NONE))
8554 8555 8556 8557 8558
            virCommandAddArgList(cmd, "-vga", "none", NULL);
    }

    /* Add sound hardware */
    if (def->nsounds) {
8559
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8560
            for (i = 0; i < def->nsounds; i++) {
8561 8562 8563 8564 8565 8566 8567 8568 8569 8570
                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");
8571
                    if (!(str = qemuBuildSoundDevStr(def, sound, qemuCaps)))
8572 8573 8574
                        goto error;

                    virCommandAddArg(cmd, str);
8575
                    VIR_FREE(str);
8576 8577
                    if (sound->model == VIR_DOMAIN_SOUND_MODEL_ICH6 ||
                        sound->model == VIR_DOMAIN_SOUND_MODEL_ICH9) {
8578 8579
                        char *codecstr = NULL;

8580
                        for (j = 0; j < sound->ncodecs; j++) {
8581
                            virCommandAddArg(cmd, "-device");
8582
                            if (!(codecstr = qemuBuildSoundCodecStr(sound, sound->codecs[j], qemuCaps))) {
8583
                                goto error;
8584

8585 8586 8587 8588
                            }
                            virCommandAddArg(cmd, codecstr);
                            VIR_FREE(codecstr);
                        }
8589
                        if (j == 0) {
8590 8591 8592 8593 8594
                            virDomainSoundCodecDef codec = {
                                VIR_DOMAIN_SOUND_CODEC_TYPE_DUPLEX,
                                0
                            };
                            virCommandAddArg(cmd, "-device");
8595
                            if (!(codecstr = qemuBuildSoundCodecStr(sound, &codec, qemuCaps))) {
8596 8597 8598 8599 8600 8601
                                goto error;

                            }
                            virCommandAddArg(cmd, codecstr);
                            VIR_FREE(codecstr);
                        }
8602
                    }
8603 8604 8605 8606 8607
                }
            }
        } else {
            int size = 100;
            char *modstr;
8608
            if (VIR_ALLOC_N(modstr, size+1) < 0)
8609
                goto error;
8610

8611
            for (i = 0; i < def->nsounds && size > 0; i++) {
8612 8613 8614 8615
                virDomainSoundDefPtr sound = def->sounds[i];
                const char *model = virDomainSoundModelTypeToString(sound->model);
                if (!model) {
                    VIR_FREE(modstr);
8616 8617
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   "%s", _("invalid sound model"));
8618 8619
                    goto error;
                }
8620

8621 8622
                if (sound->model == VIR_DOMAIN_SOUND_MODEL_ICH6 ||
                    sound->model == VIR_DOMAIN_SOUND_MODEL_ICH9) {
A
Alex Jia 已提交
8623
                    VIR_FREE(modstr);
8624 8625
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("this QEMU binary lacks hda support"));
8626 8627 8628
                    goto error;
                }

8629 8630 8631 8632 8633 8634 8635 8636 8637 8638 8639 8640 8641 8642 8643
                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;

8644
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8645 8646
            virCommandAddArg(cmd, "-device");

8647
            optstr = qemuBuildWatchdogDevStr(def, watchdog, qemuCaps);
8648 8649 8650 8651 8652 8653 8654
            if (!optstr)
                goto error;
        } else {
            virCommandAddArg(cmd, "-watchdog");

            const char *model = virDomainWatchdogModelTypeToString(watchdog->model);
            if (!model) {
8655 8656
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               "%s", _("missing watchdog model"));
8657 8658 8659
                goto error;
            }

8660 8661
            if (VIR_STRDUP(optstr, model) < 0)
                goto error;
8662 8663 8664 8665 8666 8667 8668 8669 8670
        }
        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) {
8671 8672
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("invalid watchdog action"));
8673 8674 8675 8676 8677
            goto error;
        }
        virCommandAddArgList(cmd, "-watchdog-action", action, NULL);
    }

8678
    /* Add redirected devices */
8679
    for (i = 0; i < def->nredirdevs; i++) {
8680 8681 8682 8683 8684 8685
        virDomainRedirdevDefPtr redirdev = def->redirdevs[i];
        char *devstr;

        virCommandAddArg(cmd, "-chardev");
        if (!(devstr = qemuBuildChrChardevStr(&redirdev->source.chr,
                                              redirdev->info.alias,
8686
                                              qemuCaps))) {
8687 8688 8689 8690 8691 8692
            goto error;
        }

        virCommandAddArg(cmd, devstr);
        VIR_FREE(devstr);

8693
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
8694 8695 8696
            goto error;

        virCommandAddArg(cmd, "-device");
8697
        if (!(devstr = qemuBuildRedirdevDevStr(def, redirdev, qemuCaps)))
8698 8699 8700 8701 8702
            goto error;
        virCommandAddArg(cmd, devstr);
        VIR_FREE(devstr);
    }

8703
    /* Add host passthrough hardware */
8704
    for (i = 0; i < def->nhostdevs; i++) {
8705 8706 8707
        virDomainHostdevDefPtr hostdev = def->hostdevs[i];
        char *devstr;

8708
        if (hostdev->info->bootIndex) {
8709
            if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
8710
                (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
8711 8712
                 hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
                 hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)) {
8713
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
8714
                               _("booting from assigned devices is only "
8715
                                 "supported for PCI, USB and SCSI devices"));
8716
                goto error;
8717
            } else {
8718 8719
                if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
                    if (hostdev->source.subsys.u.pci.backend
8720
                        == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733 8734
                        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;
                        }
                    }
8735 8736
                }
                if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
8737
                    !virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_HOST_BOOTINDEX)) {
8738
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
8739 8740
                                   _("booting from assigned USB devices is not "
                                     "supported with this version of qemu"));
8741 8742
                    goto error;
                }
8743 8744 8745 8746 8747 8748 8749
                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;
                }
8750 8751 8752
            }
        }

8753 8754 8755 8756
        /* USB */
        if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
            hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {

8757
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8758
                virCommandAddArg(cmd, "-device");
8759
                if (!(devstr = qemuBuildUSBHostdevDevStr(def, hostdev, qemuCaps)))
8760 8761 8762 8763 8764
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
            } else {
                virCommandAddArg(cmd, "-usbdevice");
8765
                if (!(devstr = qemuBuildUSBHostdevUSBDevStr(hostdev)))
8766 8767 8768 8769 8770 8771 8772 8773 8774
                    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) {
8775
            int backend = hostdev->source.subsys.u.pci.backend;
8776

8777
            if (backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
8778 8779 8780 8781 8782 8783
                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;
                }
8784 8785 8786
                /* VFIO requires all of the guest's memory to be locked
                 * resident */
                mlock = true;
8787 8788
            }

8789
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8790
                char *configfd_name = NULL;
8791
                if ((backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) &&
8792
                    virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
8793 8794 8795 8796 8797
                    int configfd = qemuOpenPCIConfig(hostdev);

                    if (configfd >= 0) {
                        if (virAsprintf(&configfd_name, "%d", configfd) < 0) {
                            VIR_FORCE_CLOSE(configfd);
8798
                            goto error;
8799 8800
                        }

8801 8802
                        virCommandPassFD(cmd, configfd,
                                         VIR_COMMAND_PASS_FD_CLOSE_PARENT);
8803 8804 8805
                    }
                }
                virCommandAddArg(cmd, "-device");
8806
                devstr = qemuBuildPCIHostdevDevStr(def, hostdev, configfd_name, qemuCaps);
8807 8808 8809 8810 8811
                VIR_FREE(configfd_name);
                if (!devstr)
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
8812
            } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCIDEVICE)) {
8813
                virCommandAddArg(cmd, "-pcidevice");
8814
                if (!(devstr = qemuBuildPCIHostdevPCIDevStr(hostdev, qemuCaps)))
8815 8816 8817 8818
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
            } else {
8819 8820
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("PCI device assignment is not supported by this version of qemu"));
8821 8822 8823
                goto error;
            }
        }
8824 8825 8826 8827 8828 8829 8830 8831 8832 8833

        /* SCSI */
        if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
            hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE) &&
                virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) &&
                virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SCSI_GENERIC)) {
                char *drvstr;

                virCommandAddArg(cmd, "-drive");
8834
                if (!(drvstr = qemuBuildSCSIHostdevDrvStr(hostdev, qemuCaps, callbacks)))
8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 8847 8848 8849
                    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;
            }
        }
8850 8851
    }

8852 8853 8854 8855 8856 8857
    /* Migration is very annoying due to wildly varying syntax &
     * capabilities over time of KVM / QEMU codebases.
     */
    if (migrateFrom) {
        virCommandAddArg(cmd, "-incoming");
        if (STRPREFIX(migrateFrom, "tcp")) {
8858
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_TCP)) {
8859 8860 8861
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("TCP migration is not supported with "
                                       "this QEMU binary"));
8862 8863 8864 8865
                goto error;
            }
            virCommandAddArg(cmd, migrateFrom);
        } else if (STREQ(migrateFrom, "stdio")) {
8866
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) {
8867
                virCommandAddArgFormat(cmd, "fd:%d", migrateFd);
8868
                virCommandPassFD(cmd, migrateFd, 0);
8869
            } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) {
8870 8871
                virCommandAddArg(cmd, "exec:cat");
                virCommandSetInputFD(cmd, migrateFd);
8872
            } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_KVM_STDIO)) {
8873 8874 8875
                virCommandAddArg(cmd, migrateFrom);
                virCommandSetInputFD(cmd, migrateFd);
            } else {
8876 8877 8878
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("STDIO migration is not supported "
                                       "with this QEMU binary"));
8879 8880 8881
                goto error;
            }
        } else if (STRPREFIX(migrateFrom, "exec")) {
8882
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) {
8883 8884 8885
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("EXEC migration is not supported "
                                       "with this QEMU binary"));
8886 8887 8888 8889
                goto error;
            }
            virCommandAddArg(cmd, migrateFrom);
        } else if (STRPREFIX(migrateFrom, "fd")) {
8890
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) {
8891 8892 8893
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("FD migration is not supported "
                                       "with this QEMU binary"));
8894 8895 8896
                goto error;
            }
            virCommandAddArg(cmd, migrateFrom);
8897
            virCommandPassFD(cmd, migrateFd, 0);
8898
        } else if (STRPREFIX(migrateFrom, "unix")) {
8899
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_UNIX)) {
8900 8901 8902
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("UNIX migration is not supported "
                                       "with this QEMU binary"));
8903 8904 8905
                goto error;
            }
            virCommandAddArg(cmd, migrateFrom);
8906
        } else {
8907 8908
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("unknown migration protocol"));
8909 8910 8911
            goto error;
        }
    }
8912 8913 8914 8915 8916 8917 8918

    /* 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
     */
8919 8920
    if (STREQLEN(def->os.machine, "s390-virtio", 10) &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390) && def->memballoon)
8921 8922 8923 8924
        def->memballoon->model = VIR_DOMAIN_MEMBALLOON_MODEL_NONE;

    if (def->memballoon &&
        def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_NONE) {
8925
        if (def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO) {
8926 8927 8928
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("Memory balloon device type '%s' is not supported by this version of qemu"),
                           virDomainMemballoonModelTypeToString(def->memballoon->model));
8929 8930
            goto error;
        }
8931
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8932 8933 8934
            char *optstr;
            virCommandAddArg(cmd, "-device");

8935
            optstr = qemuBuildMemballoonDevStr(def, def->memballoon, qemuCaps);
8936 8937 8938 8939
            if (!optstr)
                goto error;
            virCommandAddArg(cmd, optstr);
            VIR_FREE(optstr);
8940
        } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BALLOON)) {
8941 8942 8943 8944
            virCommandAddArgList(cmd, "-balloon", "virtio", NULL);
        }
    }

8945 8946 8947 8948 8949 8950
    if (def->rng) {
        /* add the RNG source backend */
        if (qemuBuildRNGBackendArgs(cmd, def->rng, qemuCaps) < 0)
            goto error;

        /* add the device */
8951
        if (qemuBuildRNGDeviceArgs(cmd, def, def->rng, qemuCaps) < 0)
8952 8953 8954
            goto error;
    }

8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 8970 8971 8972 8973 8974 8975 8976 8977 8978
    if (def->nvram) {
        if (def->os.arch == VIR_ARCH_PPC64 &&
            STREQ(def->os.machine, "pseries")) {
            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;
        }
    }
8979 8980
    if (snapshot)
        virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL);
8981 8982 8983 8984 8985 8986 8987 8988 8989 8990 8991 8992 8993

    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] : "");
    }

8994
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SECCOMP_SANDBOX)) {
8995
        if (cfg->seccompSandbox == 0)
8996
            virCommandAddArgList(cmd, "-sandbox", "off", NULL);
8997
        else if (cfg->seccompSandbox > 0)
8998
            virCommandAddArgList(cmd, "-sandbox", "on", NULL);
8999
    } else if (cfg->seccompSandbox > 0) {
9000 9001 9002 9003 9004
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("QEMU does not support seccomp sandboxes"));
        goto error;
    }

H
Hu Tao 已提交
9005 9006 9007 9008 9009 9010 9011 9012 9013 9014 9015 9016 9017 9018 9019 9020
    if (def->panic) {
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PANIC)) {
            if (def->panic->info.addr.isa.iobase > 0) {
                virCommandAddArg(cmd, "-device");
                virCommandAddArgFormat(cmd, "pvpanic,ioport=%d",
                                       def->panic->info.addr.isa.iobase);
            } else {
                virCommandAddArgList(cmd, "-device", "pvpanic", NULL);
            }
        } else {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("your QEMU is too old to support pvpanic"));
            goto error;
        }
    }

9021 9022 9023 9024 9025 9026 9027 9028 9029 9030 9031 9032 9033
    if (mlock) {
        unsigned long long memKB;

        /* VFIO requires all of the guest's memory to be
         * locked resident, plus some amount for IO
         * space. Alex Williamson suggested adding 1GiB for IO
         * space just to be safe (some finer tuning might be
         * nice, though).
         */
        memKB = def->mem.hard_limit ?
            def->mem.hard_limit : def->mem.max_balloon + 1024 * 1024;
        virCommandSetMaxMemLock(cmd, memKB * 1024);
    }
9034

9035 9036 9037 9038
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSG_TIMESTAMP) &&
        cfg->logTimestamp)
        virCommandAddArgList(cmd, "-msg", "timestamp=on", NULL);

9039
    virObjectUnref(cfg);
9040 9041
    return cmd;

9042
 error:
9043
    virObjectUnref(cfg);
9044 9045 9046
    /* free up any resources in the network driver
     * but don't overwrite the original error */
    originalError = virSaveLastError();
9047
    for (i = 0; last_good_net != -1 && i <= last_good_net; i++)
9048
        virDomainConfNWFilterTeardown(def->nets[i]);
9049
    virSetError(originalError);
J
John Ferlan 已提交
9050
    virFreeError(originalError);
9051 9052 9053 9054
    virCommandFree(cmd);
    return NULL;
}

9055 9056 9057
/* This function generates the correct '-device' string for character
 * devices of each architecture.
 */
9058 9059
static int
qemuBuildSerialChrDeviceStr(char **deviceStr,
9060
                            virDomainDefPtr def,
9061 9062 9063 9064
                            virDomainChrDefPtr serial,
                            virQEMUCapsPtr qemuCaps,
                            virArch arch,
                            char *machine)
9065 9066 9067
{
    virBuffer cmd = VIR_BUFFER_INITIALIZER;

9068
    if ((arch == VIR_ARCH_PPC64) && STREQ(machine, "pseries")) {
9069 9070 9071 9072
        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);
9073
            if (qemuBuildDeviceAddressStr(&cmd, def, &serial->info, qemuCaps) < 0)
9074 9075
                goto error;
        }
G
Guannan Ren 已提交
9076 9077 9078
    } else {
        virBufferAsprintf(&cmd, "%s,chardev=char%s,id=%s",
                          virDomainChrSerialTargetTypeToString(serial->targetType),
9079 9080
                          serial->info.alias, serial->info.alias);

G
Guannan Ren 已提交
9081
        if (serial->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB) {
9082
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_SERIAL)) {
G
Guannan Ren 已提交
9083 9084 9085 9086 9087 9088 9089 9090 9091 9092 9093 9094
                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;
            }

9095
            if (qemuBuildDeviceAddressStr(&cmd, def, &serial->info, qemuCaps) < 0)
9096
                goto error;
G
Guannan Ren 已提交
9097 9098 9099
        }
    }

9100
    if (virBufferCheckError(&cmd) < 0)
9101 9102
        goto error;

9103 9104
    *deviceStr = virBufferContentAndReset(&cmd);
    return 0;
9105

9106
 error:
9107
    virBufferFreeAndReset(&cmd);
9108 9109 9110 9111 9112 9113 9114 9115
    return -1;
}

static int
qemuBuildParallelChrDeviceStr(char **deviceStr,
                              virDomainChrDefPtr chr)
{
    if (virAsprintf(deviceStr, "isa-parallel,chardev=char%s,id=%s",
J
Ján Tomko 已提交
9116
                    chr->info.alias, chr->info.alias) < 0)
9117 9118
        return -1;
    return 0;
9119
}
9120

9121 9122 9123 9124 9125 9126 9127 9128 9129
static int
qemuBuildChannelChrDeviceStr(char **deviceStr,
                             virDomainChrDefPtr chr,
                             virQEMUCapsPtr qemuCaps)
{
    int ret = -1;
    char *addr = NULL;
    int port;

9130
    switch ((virDomainChrChannelTargetType) chr->targetType) {
9131 9132 9133 9134 9135 9136 9137 9138
    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,
9139
                        "user,guestfwd=tcp:%s:%i-chardev:char%s,id=user-%s",
J
Ján Tomko 已提交
9140
                        addr, port, chr->info.alias, chr->info.alias) < 0)
9141 9142 9143 9144 9145 9146 9147 9148 9149 9150 9151 9152 9153 9154
            goto cleanup;
        break;

    case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO:
        if (!(*deviceStr = qemuBuildVirtioSerialPortDevStr(chr, qemuCaps)))
                goto cleanup;
        break;

    case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_NONE:
    case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST:
        return ret;
    }

    ret = 0;
9155
 cleanup:
9156 9157 9158 9159 9160 9161 9162 9163 9164 9165 9166
    VIR_FREE(addr);
    return ret;
}

static int
qemuBuildConsoleChrDeviceStr(char **deviceStr,
                             virDomainChrDefPtr chr,
                             virQEMUCapsPtr qemuCaps)
{
    int ret = -1;

9167
    switch ((virDomainChrConsoleTargetType) chr->targetType) {
9168 9169 9170 9171 9172 9173 9174 9175 9176 9177 9178 9179 9180 9181 9182 9183 9184 9185 9186 9187 9188 9189
    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:
        if (!(*deviceStr = qemuBuildVirtioSerialPortDevStr(chr, qemuCaps)))
            goto cleanup;
        break;

    case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL:
    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:
        break;
    }

    ret = 0;
9190
 cleanup:
9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201
    return ret;
}

int
qemuBuildChrDeviceStr(char **deviceStr,
                      virDomainDefPtr vmdef,
                      virDomainChrDefPtr chr,
                      virQEMUCapsPtr qemuCaps)
{
    int ret = -1;

9202
    switch ((virDomainChrDeviceType) chr->deviceType) {
9203
    case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL:
9204
        ret = qemuBuildSerialChrDeviceStr(deviceStr, vmdef, chr, qemuCaps,
9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221 9222 9223 9224 9225 9226 9227 9228
                                          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:
        ret = qemuBuildChannelChrDeviceStr(deviceStr, chr, qemuCaps);
        break;

    case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE:
        ret = qemuBuildConsoleChrDeviceStr(deviceStr, chr, qemuCaps);
        break;

    case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST:
        return ret;
    }

    return ret;
}


9229 9230 9231 9232 9233 9234 9235
/*
 * 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 已提交
9236 9237
                               char ***retenv,
                               char ***retargv)
9238 9239
{
    char **arglist = NULL;
9240 9241 9242
    size_t argcount = 0;
    size_t argalloc = 0;
    size_t envend;
9243
    size_t i;
9244 9245
    const char *curr = args;
    const char *start;
E
Eric Blake 已提交
9246 9247
    char **progenv = NULL;
    char **progargv = NULL;
9248 9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 9270 9271 9272

    /* Iterate over string, splitting on sequences of ' ' */
    while (curr && *curr != '\0') {
        char *arg;
        const char *next;

        start = curr;
        /* accept a space in CEPH_ARGS */
        if (STRPREFIX(curr, "CEPH_ARGS=-m ")) {
            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');

9273
        if (VIR_STRNDUP(arg, curr, next ? next - curr : -1) < 0)
9274
            goto error;
9275

9276 9277
        if (next && (*next == '\'' || *next == '"'))
            next++;
9278

9279 9280 9281
        if (VIR_RESIZE_N(arglist, argalloc, argcount, 2) < 0) {
            VIR_FREE(arg);
            goto error;
9282 9283 9284
        }

        arglist[argcount++] = arg;
9285
        arglist[argcount] = NULL;
9286 9287 9288 9289 9290 9291 9292 9293 9294

        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) */
9295
    for (envend = 0; ((envend < argcount) &&
9296 9297 9298 9299 9300 9301 9302
                       (strchr(arglist[envend], '=') != NULL));
         envend++)
        ; /* nada */

    /* Copy the list of env vars */
    if (envend > 0) {
        if (VIR_REALLOC_N(progenv, envend+1) < 0)
9303
            goto error;
9304
        for (i = 0; i < envend; i++)
9305 9306 9307 9308 9309 9310
            progenv[i] = arglist[i];
        progenv[i] = NULL;
    }

    /* Copy the list of argv */
    if (VIR_REALLOC_N(progargv, argcount-envend + 1) < 0)
9311
        goto error;
9312
    for (i = envend; i < argcount; i++)
9313 9314 9315 9316 9317 9318 9319 9320 9321 9322
        progargv[i-envend] = arglist[i];
    progargv[i-envend] = NULL;

    VIR_FREE(arglist);

    *retenv = progenv;
    *retargv = progargv;

    return 0;

9323
 error:
9324 9325
    VIR_FREE(progenv);
    VIR_FREE(progargv);
E
Eric Blake 已提交
9326
    virStringFreeList(arglist);
9327 9328 9329 9330 9331 9332 9333
    return -1;
}


/*
 * Search for a named env variable, and return the value part
 */
E
Eric Blake 已提交
9334
static const char *qemuFindEnv(char **progenv,
9335 9336
                               const char *name)
{
9337
    size_t i;
9338 9339
    int len = strlen(name);

9340
    for (i = 0; progenv && progenv[i]; i++) {
9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 9358
        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,
9359
                  int *retnkeywords,
9360 9361 9362 9363 9364 9365 9366 9367
                  int allowEmptyValue)
{
    int keywordCount = 0;
    int keywordAlloc = 0;
    char **keywords = NULL;
    char **values = NULL;
    const char *start = str;
    const char *end;
9368
    size_t i;
9369 9370 9371

    *retkeywords = NULL;
    *retvalues = NULL;
9372
    *retnkeywords = 0;
9373 9374 9375 9376 9377 9378 9379 9380
    end = start + strlen(str);

    while (start) {
        const char *separator;
        const char *endmark;
        char *keyword;
        char *value = NULL;

9381 9382 9383 9384 9385 9386 9387 9388
        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)
9389 9390 9391 9392 9393 9394
            endmark = end;
        if (!(separator = strchr(start, '=')))
            separator = end;

        if (separator >= endmark) {
            if (!allowEmptyValue) {
9395 9396
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("malformed keyword arguments in '%s'"), str);
9397 9398 9399 9400 9401
                goto error;
            }
            separator = endmark;
        }

9402 9403
        if (VIR_STRNDUP(keyword, start, separator - start) < 0)
            goto error;
9404 9405 9406

        if (separator < endmark) {
            separator++;
9407
            if (VIR_STRNDUP(value, separator, endmark - separator) < 0) {
9408
                VIR_FREE(keyword);
9409
                goto error;
9410
            }
9411 9412 9413 9414 9415 9416 9417 9418 9419 9420
            if (strchr(value, ',')) {
                char *p = strchr(value, ',') + 1;
                char *q = p + 1;
                while (*q) {
                    if (*q == ',')
                        q++;
                    *p++ = *q++;
                }
                *p = '\0';
            }
9421 9422 9423 9424 9425 9426 9427
        }

        if (keywordAlloc == keywordCount) {
            if (VIR_REALLOC_N(keywords, keywordAlloc + 10) < 0 ||
                VIR_REALLOC_N(values, keywordAlloc + 10) < 0) {
                VIR_FREE(keyword);
                VIR_FREE(value);
9428
                goto error;
9429 9430 9431 9432 9433 9434 9435 9436 9437 9438 9439 9440 9441
            }
            keywordAlloc += 10;
        }

        keywords[keywordCount] = keyword;
        values[keywordCount] = value;
        keywordCount++;

        start = endmark < end ? endmark + 1 : NULL;
    }

    *retkeywords = keywords;
    *retvalues = values;
9442 9443
    *retnkeywords = keywordCount;
    return 0;
9444

9445
 error:
9446
    for (i = 0; i < keywordCount; i++) {
9447 9448 9449 9450 9451 9452 9453 9454 9455 9456 9457 9458 9459 9460 9461 9462
        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
9463
qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt,
9464
                         const char *val,
9465
                         virDomainDefPtr dom,
9466 9467
                         int nvirtiodisk,
                         bool old_style_ceph_args)
9468 9469 9470 9471 9472
{
    virDomainDiskDefPtr def = NULL;
    char **keywords;
    char **values;
    int nkeywords;
9473
    size_t i;
9474 9475 9476
    int idx = -1;
    int busid = -1;
    int unitid = -1;
9477
    int trans = VIR_DOMAIN_DISK_TRANS_DEFAULT;
9478

9479 9480 9481 9482 9483
    if (qemuParseKeywords(val,
                          &keywords,
                          &values,
                          &nkeywords,
                          0) < 0)
9484 9485
        return NULL;

9486
    if (VIR_ALLOC(def) < 0)
9487
        goto cleanup;
9488 9489
    if (VIR_ALLOC(def->src) < 0)
        goto error;
9490

9491 9492 9493 9494 9495
    if (((dom->os.arch == VIR_ARCH_PPC64) &&
        dom->os.machine && STREQ(dom->os.machine, "pseries")))
        def->bus = VIR_DOMAIN_DISK_BUS_SCSI;
    else
       def->bus = VIR_DOMAIN_DISK_BUS_IDE;
9496
    def->device = VIR_DOMAIN_DISK_DEVICE_DISK;
9497
    def->src->type = VIR_STORAGE_TYPE_FILE;
9498

9499
    for (i = 0; i < nkeywords; i++) {
9500 9501
        if (STREQ(keywords[i], "file")) {
            if (values[i] && STRNEQ(values[i], "")) {
9502
                def->src->path = values[i];
9503
                values[i] = NULL;
9504 9505 9506 9507 9508 9509
                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;
9510

9511 9512
                    if (qemuParseNBDString(def) < 0)
                        goto error;
9513 9514
                } else if (STRPREFIX(def->src->path, "rbd:")) {
                    char *p = def->src->path;
9515

9516 9517 9518
                    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)
9519
                        goto error;
9520
                    /* old-style CEPH_ARGS env variable is parsed later */
9521 9522 9523 9524
                    if (!old_style_ceph_args && qemuParseRBDString(def) < 0) {
                        VIR_FREE(p);
                        goto error;
                    }
9525 9526

                    VIR_FREE(p);
9527 9528 9529 9530
                } 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;
9531 9532

                    if (qemuParseGlusterString(def) < 0)
9533
                        goto error;
9534 9535 9536
                } 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 已提交
9537 9538 9539

                    if (qemuParseISCSIString(def) < 0)
                        goto error;
9540 9541
                } else if (STRPREFIX(def->src->path, "sheepdog:")) {
                    char *p = def->src->path;
9542 9543
                    char *port, *vdi;

9544 9545 9546
                    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)
9547
                        goto error;
9548
                    VIR_FREE(p);
9549

9550 9551
                    /* def->src->path must be [vdiname] or [host]:[port]:[vdiname] */
                    port = strchr(def->src->path, ':');
9552
                    if (port) {
9553 9554
                        *port = '\0';
                        vdi = strchr(port + 1, ':');
9555
                        if (!vdi) {
9556
                            *port = ':';
9557
                            virReportError(VIR_ERR_INTERNAL_ERROR,
9558
                                           _("cannot parse sheepdog filename '%s'"),
9559
                                           def->src->path);
9560
                            goto error;
9561
                        }
9562
                        port++;
9563
                        *vdi++ = '\0';
9564
                        if (VIR_ALLOC(def->src->hosts) < 0)
9565
                            goto error;
9566 9567 9568
                        def->src->nhosts = 1;
                        def->src->hosts->name = def->src->path;
                        if (VIR_STRDUP(def->src->hosts->port, port) < 0)
9569
                            goto error;
9570 9571 9572
                        def->src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
                        def->src->hosts->socket = NULL;
                        if (VIR_STRDUP(def->src->path, vdi) < 0)
9573
                            goto error;
9574 9575
                    }
                } else
9576
                    def->src->type = VIR_STORAGE_TYPE_FILE;
9577
            } else {
9578
                def->src->type = VIR_STORAGE_TYPE_FILE;
9579 9580
            }
        } else if (STREQ(keywords[i], "if")) {
9581
            if (STREQ(values[i], "ide")) {
9582
                def->bus = VIR_DOMAIN_DISK_BUS_IDE;
9583 9584 9585 9586 9587 9588 9589
                if (((dom->os.arch == VIR_ARCH_PPC64) &&
                     dom->os.machine && STREQ(dom->os.machine, "pseries"))) {
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("pseries systems do not support ide devices '%s'"), val);
                    goto error;
                }
            } else if (STREQ(values[i], "scsi"))
9590 9591 9592 9593 9594
                def->bus = VIR_DOMAIN_DISK_BUS_SCSI;
            else if (STREQ(values[i], "virtio"))
                def->bus = VIR_DOMAIN_DISK_BUS_VIRTIO;
            else if (STREQ(values[i], "xen"))
                def->bus = VIR_DOMAIN_DISK_BUS_XEN;
9595 9596
            else if (STREQ(values[i], "sd"))
                def->bus = VIR_DOMAIN_DISK_BUS_SD;
9597 9598 9599
        } else if (STREQ(keywords[i], "media")) {
            if (STREQ(values[i], "cdrom")) {
                def->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
9600
                def->readonly = true;
9601 9602 9603
            } else if (STREQ(values[i], "floppy"))
                def->device = VIR_DOMAIN_DISK_DEVICE_FLOPPY;
        } else if (STREQ(keywords[i], "format")) {
9604
            if (VIR_STRDUP(def->src->driverName, "qemu") < 0)
9605
                goto error;
9606
            def->src->format = virStorageFileFormatTypeFromString(values[i]);
9607 9608 9609 9610 9611 9612 9613 9614 9615
        } 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;
9616 9617
            else if (STREQ(values[i], "directsync"))
                def->cachemode = VIR_DOMAIN_DISK_CACHE_DIRECTSYNC;
9618 9619
            else if (STREQ(values[i], "unsafe"))
                def->cachemode = VIR_DOMAIN_DISK_CACHE_UNSAFE;
9620
        } else if (STREQ(keywords[i], "werror")) {
9621 9622
            if (STREQ(values[i], "stop"))
                def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_STOP;
9623 9624
            else if (STREQ(values[i], "report"))
                def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_REPORT;
9625 9626
            else if (STREQ(values[i], "ignore"))
                def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_IGNORE;
9627
            else if (STREQ(values[i], "enospc"))
9628
                def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_ENOSPACE;
9629 9630 9631 9632 9633 9634 9635
        } 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;
9636 9637
        } else if (STREQ(keywords[i], "index")) {
            if (virStrToLong_i(values[i], NULL, 10, &idx) < 0) {
9638 9639
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse drive index '%s'"), val);
9640
                goto error;
9641 9642 9643
            }
        } else if (STREQ(keywords[i], "bus")) {
            if (virStrToLong_i(values[i], NULL, 10, &busid) < 0) {
9644 9645
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse drive bus '%s'"), val);
9646
                goto error;
9647 9648 9649
            }
        } else if (STREQ(keywords[i], "unit")) {
            if (virStrToLong_i(values[i], NULL, 10, &unitid) < 0) {
9650 9651
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse drive unit '%s'"), val);
9652
                goto error;
9653 9654 9655
            }
        } else if (STREQ(keywords[i], "readonly")) {
            if ((values[i] == NULL) || STREQ(values[i], "on"))
9656
                def->readonly = true;
E
Eric Blake 已提交
9657 9658
        } else if (STREQ(keywords[i], "aio")) {
            if ((def->iomode = virDomainDiskIoTypeFromString(values[i])) < 0) {
9659 9660
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse io mode '%s'"), values[i]);
9661
                goto error;
E
Eric Blake 已提交
9662
            }
9663 9664 9665 9666 9667 9668 9669 9670
        } 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]);
9671
                goto error;
9672 9673 9674 9675 9676 9677 9678 9679 9680
            }
        } 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]);
9681
                goto error;
9682 9683 9684 9685 9686 9687 9688 9689 9690
            }
        } 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]);
9691
                goto error;
9692 9693 9694 9695 9696 9697 9698 9699 9700 9701 9702
            }
        } else if (STREQ(keywords[i], "trans")) {
            def->geometry.trans =
                virDomainDiskGeometryTransTypeFromString(values[i]);
            if ((trans < VIR_DOMAIN_DISK_TRANS_DEFAULT) ||
                (trans >= VIR_DOMAIN_DISK_TRANS_LAST)) {
                virDomainDiskDefFree(def);
                def = NULL;
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse translation value'%s'"),
                               values[i]);
9703
                goto error;
9704
            }
9705 9706 9707
        }
    }

9708 9709 9710
    if (def->rerror_policy == def->error_policy)
        def->rerror_policy = 0;

9711
    if (!def->src->path &&
9712
        def->device == VIR_DOMAIN_DISK_DEVICE_DISK &&
9713
        def->src->type != VIR_STORAGE_TYPE_NETWORK) {
9714 9715
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("missing file parameter in drive '%s'"), val);
9716
        goto error;
9717 9718 9719 9720 9721 9722 9723 9724
    }
    if (idx == -1 &&
        def->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
        idx = nvirtiodisk;

    if (idx == -1 &&
        unitid == -1 &&
        busid == -1) {
9725
        virReportError(VIR_ERR_INTERNAL_ERROR,
9726 9727 9728
                       _("missing index/unit/bus parameter in drive '%s'"),
                       val);
        goto error;
9729 9730 9731 9732 9733 9734 9735 9736 9737 9738 9739 9740 9741 9742 9743 9744 9745 9746 9747 9748 9749
    }

    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) {
9750
        ignore_value(VIR_STRDUP(def->dst, "hda"));
9751 9752
    } else if (def->bus == VIR_DOMAIN_DISK_BUS_SCSI ||
               def->bus == VIR_DOMAIN_DISK_BUS_SD) {
9753
        ignore_value(VIR_STRDUP(def->dst, "sda"));
9754
    } else if (def->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
9755
        ignore_value(VIR_STRDUP(def->dst, "vda"));
9756
    } else if (def->bus == VIR_DOMAIN_DISK_BUS_XEN) {
9757
        ignore_value(VIR_STRDUP(def->dst, "xvda"));
9758
    } else {
9759
        ignore_value(VIR_STRDUP(def->dst, "hda"));
9760 9761
    }

9762
    if (!def->dst)
9763
        goto error;
9764 9765 9766 9767 9768
    if (STREQ(def->dst, "xvda"))
        def->dst[3] = 'a' + idx;
    else
        def->dst[2] = 'a' + idx;

9769
    if (virDomainDiskDefAssignAddress(xmlopt, def) < 0) {
9770 9771
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("invalid device name '%s'"), def->dst);
9772 9773
        virDomainDiskDefFree(def);
        def = NULL;
9774
        goto cleanup;
9775 9776
    }

9777
 cleanup:
9778
    for (i = 0; i < nkeywords; i++) {
9779 9780 9781 9782 9783 9784
        VIR_FREE(keywords[i]);
        VIR_FREE(values[i]);
    }
    VIR_FREE(keywords);
    VIR_FREE(values);
    return def;
9785

9786
 error:
9787 9788 9789
    virDomainDiskDefFree(def);
    def = NULL;
    goto cleanup;
9790 9791 9792 9793 9794 9795 9796 9797 9798 9799
}

/*
 * Tries to find a NIC definition matching a vlan we want
 */
static const char *
qemuFindNICForVLAN(int nnics,
                   const char **nics,
                   int wantvlan)
{
9800
    size_t i;
9801
    for (i = 0; i < nnics; i++) {
9802 9803 9804 9805 9806 9807 9808 9809 9810
        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) {
9811 9812
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot parse NIC vlan in '%s'"), nics[i]);
9813 9814 9815 9816 9817 9818 9819 9820 9821 9822
            return NULL;
        }

        if (gotvlan == wantvlan)
            return nics[i];
    }

    if (wantvlan == 0 && nnics > 0)
        return nics[0];

9823 9824
    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("cannot find NIC definition for vlan %d"), wantvlan);
9825 9826 9827 9828 9829 9830 9831 9832 9833 9834
    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
9835
qemuParseCommandLineNet(virDomainXMLOptionPtr xmlopt,
9836 9837 9838 9839 9840 9841 9842 9843 9844 9845 9846
                        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;
9847
    bool genmac = true;
9848
    size_t i;
9849 9850 9851 9852

    tmp = strchr(val, ',');

    if (tmp) {
9853 9854 9855 9856 9857
        if (qemuParseKeywords(tmp+1,
                              &keywords,
                              &values,
                              &nkeywords,
                              0) < 0)
9858 9859 9860 9861 9862
            return NULL;
    } else {
        nkeywords = 0;
    }

9863
    if (VIR_ALLOC(def) < 0)
9864 9865 9866 9867 9868 9869 9870 9871 9872 9873 9874 9875 9876
        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;

9877
    for (i = 0; i < nkeywords; i++) {
9878 9879
        if (STREQ(keywords[i], "vlan")) {
            if (virStrToLong_i(values[i], NULL, 10, &wantvlan) < 0) {
9880 9881
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse vlan in '%s'"), val);
9882 9883 9884 9885 9886 9887
                virDomainNetDefFree(def);
                def = NULL;
                goto cleanup;
            }
        } else if (def->type == VIR_DOMAIN_NET_TYPE_ETHERNET &&
                   STREQ(keywords[i], "script") && STRNEQ(values[i], "")) {
9888
            def->script = values[i];
9889 9890 9891 9892 9893 9894 9895 9896 9897 9898 9899 9900 9901 9902 9903 9904 9905 9906 9907 9908 9909
            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")) {
9910 9911
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot parse NIC definition '%s'"), nic);
9912 9913 9914 9915 9916
        virDomainNetDefFree(def);
        def = NULL;
        goto cleanup;
    }

9917
    for (i = 0; i < nkeywords; i++) {
9918 9919 9920 9921 9922 9923 9924
        VIR_FREE(keywords[i]);
        VIR_FREE(values[i]);
    }
    VIR_FREE(keywords);
    VIR_FREE(values);

    if (STRPREFIX(nic, "nic,")) {
9925 9926 9927 9928 9929
        if (qemuParseKeywords(nic + strlen("nic,"),
                              &keywords,
                              &values,
                              &nkeywords,
                              0) < 0) {
9930 9931 9932 9933 9934 9935 9936 9937
            virDomainNetDefFree(def);
            def = NULL;
            goto cleanup;
        }
    } else {
        nkeywords = 0;
    }

9938
    for (i = 0; i < nkeywords; i++) {
9939
        if (STREQ(keywords[i], "macaddr")) {
9940
            genmac = false;
9941
            if (virMacAddrParse(values[i], &def->mac) < 0) {
9942 9943 9944
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("unable to parse mac address '%s'"),
                               values[i]);
9945 9946 9947 9948 9949 9950 9951
                virDomainNetDefFree(def);
                def = NULL;
                goto cleanup;
            }
        } else if (STREQ(keywords[i], "model")) {
            def->model = values[i];
            values[i] = NULL;
9952 9953
        } else if (STREQ(keywords[i], "vhost")) {
            if ((values[i] == NULL) || STREQ(values[i], "on")) {
9954
                def->driver.virtio.name = VIR_DOMAIN_NET_BACKEND_TYPE_VHOST;
9955
            } else if (STREQ(keywords[i], "off")) {
9956
                def->driver.virtio.name = VIR_DOMAIN_NET_BACKEND_TYPE_QEMU;
9957
            }
9958 9959
        } else if (STREQ(keywords[i], "sndbuf") && values[i]) {
            if (virStrToLong_ul(values[i], NULL, 10, &def->tune.sndbuf) < 0) {
9960 9961
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse sndbuf size in '%s'"), val);
9962 9963 9964 9965 9966
                virDomainNetDefFree(def);
                def = NULL;
                goto cleanup;
            }
            def->tune.sndbuf_specified = true;
9967 9968 9969 9970
        }
    }

    if (genmac)
9971
        virDomainNetGenerateMAC(xmlopt, &def->mac);
9972

9973
 cleanup:
9974
    for (i = 0; i < nkeywords; i++) {
9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990 9991 9992
        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;
9993 9994 9995 9996
    virDomainHostdevDefPtr def = virDomainHostdevDefAlloc();

    if (!def)
       goto error;
9997 9998

    if (!STRPREFIX(val, "host=")) {
9999 10000
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown PCI device syntax '%s'"), val);
10001
        goto error;
10002 10003 10004 10005
    }

    start = val + strlen("host=");
    if (virStrToLong_i(start, &end, 16, &bus) < 0 || *end != ':') {
10006 10007
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot extract PCI device bus '%s'"), val);
10008
        goto error;
10009 10010 10011
    }
    start = end + 1;
    if (virStrToLong_i(start, &end, 16, &slot) < 0 || *end != '.') {
10012 10013
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot extract PCI device slot '%s'"), val);
10014
        goto error;
10015 10016 10017
    }
    start = end + 1;
    if (virStrToLong_i(start, NULL, 16, &func) < 0) {
10018 10019
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot extract PCI device function '%s'"), val);
10020
        goto error;
10021 10022 10023
    }

    def->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
10024
    def->managed = true;
10025
    def->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
10026 10027 10028
    def->source.subsys.u.pci.addr.bus = bus;
    def->source.subsys.u.pci.addr.slot = slot;
    def->source.subsys.u.pci.addr.function = func;
10029
    return def;
10030 10031 10032 10033

 error:
    virDomainHostdevDefFree(def);
    return NULL;
10034 10035 10036 10037 10038 10039 10040 10041 10042
}


/*
 * Tries to parse a QEMU USB device
 */
static virDomainHostdevDefPtr
qemuParseCommandLineUSB(const char *val)
{
10043
    virDomainHostdevDefPtr def = virDomainHostdevDefAlloc();
10044 10045 10046 10047
    int first = 0, second = 0;
    const char *start;
    char *end;

10048 10049 10050
    if (!def)
       goto error;

10051
    if (!STRPREFIX(val, "host:")) {
10052 10053
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown USB device syntax '%s'"), val);
10054
        goto error;
10055 10056 10057 10058 10059
    }

    start = val + strlen("host:");
    if (strchr(start, ':')) {
        if (virStrToLong_i(start, &end, 16, &first) < 0 || *end != ':') {
10060 10061
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot extract USB device vendor '%s'"), val);
10062
            goto error;
10063 10064 10065
        }
        start = end + 1;
        if (virStrToLong_i(start, NULL, 16, &second) < 0) {
10066 10067
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot extract USB device product '%s'"), val);
10068
            goto error;
10069 10070 10071
        }
    } else {
        if (virStrToLong_i(start, &end, 10, &first) < 0 || *end != '.') {
10072 10073
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot extract USB device bus '%s'"), val);
10074
            goto error;
10075 10076 10077
        }
        start = end + 1;
        if (virStrToLong_i(start, NULL, 10, &second) < 0) {
10078 10079
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot extract USB device address '%s'"), val);
10080
            goto error;
10081 10082 10083 10084
        }
    }

    def->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
10085
    def->managed = false;
10086 10087 10088 10089 10090 10091 10092 10093 10094
    def->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB;
    if (*end == '.') {
        def->source.subsys.u.usb.bus = first;
        def->source.subsys.u.usb.device = second;
    } else {
        def->source.subsys.u.usb.vendor = first;
        def->source.subsys.u.usb.product = second;
    }
    return def;
10095 10096 10097 10098

 error:
    virDomainHostdevDefFree(def);
    return NULL;
10099 10100 10101 10102 10103 10104
}


/*
 * Tries to parse a QEMU serial/parallel device
 */
10105 10106 10107
static int
qemuParseCommandLineChr(virDomainChrSourceDefPtr source,
                        const char *val)
10108 10109
{
    if (STREQ(val, "null")) {
10110
        source->type = VIR_DOMAIN_CHR_TYPE_NULL;
10111
    } else if (STREQ(val, "vc")) {
10112
        source->type = VIR_DOMAIN_CHR_TYPE_VC;
10113
    } else if (STREQ(val, "pty")) {
10114
        source->type = VIR_DOMAIN_CHR_TYPE_PTY;
10115
    } else if (STRPREFIX(val, "file:")) {
10116
        source->type = VIR_DOMAIN_CHR_TYPE_FILE;
10117 10118
        if (VIR_STRDUP(source->data.file.path, val + strlen("file:")) < 0)
            goto error;
10119
    } else if (STRPREFIX(val, "pipe:")) {
10120
        source->type = VIR_DOMAIN_CHR_TYPE_PIPE;
10121 10122
        if (VIR_STRDUP(source->data.file.path, val + strlen("pipe:")) < 0)
            goto error;
10123
    } else if (STREQ(val, "stdio")) {
10124
        source->type = VIR_DOMAIN_CHR_TYPE_STDIO;
10125 10126
    } else if (STRPREFIX(val, "udp:")) {
        const char *svc1, *host2, *svc2;
10127
        source->type = VIR_DOMAIN_CHR_TYPE_UDP;
10128 10129 10130 10131 10132
        val += strlen("udp:");
        svc1 = strchr(val, ':');
        host2 = svc1 ? strchr(svc1, '@') : NULL;
        svc2 = host2 ? strchr(host2, ':') : NULL;

10133 10134 10135
        if (svc1 && svc1 != val &&
            VIR_STRNDUP(source->data.udp.connectHost, val, svc1 - val) < 0)
            goto error;
10136 10137 10138

        if (svc1) {
            svc1++;
10139 10140 10141
            if (VIR_STRNDUP(source->data.udp.connectService, svc1,
                            host2 ? host2 - svc1 : strlen(svc1)) < 0)
                goto error;
10142 10143 10144 10145
        }

        if (host2) {
            host2++;
10146 10147
            if (svc2 && svc2 != host2 &&
                VIR_STRNDUP(source->data.udp.bindHost, host2, svc2 - host2) < 0)
10148
                goto error;
10149
        }
10150

10151 10152
        if (svc2) {
            svc2++;
10153
            if (STRNEQ(svc2, "0")) {
10154 10155
                if (VIR_STRDUP(source->data.udp.bindService, svc2) < 0)
                    goto error;
10156
            }
10157 10158 10159 10160
        }
    } else if (STRPREFIX(val, "tcp:") ||
               STRPREFIX(val, "telnet:")) {
        const char *opt, *svc;
10161
        source->type = VIR_DOMAIN_CHR_TYPE_TCP;
10162 10163 10164 10165
        if (STRPREFIX(val, "tcp:")) {
            val += strlen("tcp:");
        } else {
            val += strlen("telnet:");
10166
            source->data.tcp.protocol = VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET;
10167 10168 10169
        }
        svc = strchr(val, ':');
        if (!svc) {
10170 10171
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot find port number in character device %s"), val);
10172 10173 10174 10175
            goto error;
        }
        opt = strchr(svc, ',');
        if (opt && strstr(opt, "server"))
10176
            source->data.tcp.listen = true;
10177

10178 10179
        if (VIR_STRNDUP(source->data.tcp.host, val, svc - val) < 0)
            goto error;
10180
        svc++;
10181
        if (VIR_STRNDUP(source->data.tcp.service, svc, opt ? opt - svc : -1) < 0)
10182
            goto error;
10183 10184 10185 10186
    } else if (STRPREFIX(val, "unix:")) {
        const char *opt;
        val += strlen("unix:");
        opt = strchr(val, ',');
10187
        source->type = VIR_DOMAIN_CHR_TYPE_UNIX;
10188
        if (VIR_STRNDUP(source->data.nix.path, val, opt ? opt - val : -1) < 0)
10189
            goto error;
10190 10191

    } else if (STRPREFIX(val, "/dev")) {
10192
        source->type = VIR_DOMAIN_CHR_TYPE_DEV;
10193 10194
        if (VIR_STRDUP(source->data.file.path, val) < 0)
            goto error;
10195
    } else {
10196 10197
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown character device syntax %s"), val);
10198 10199 10200
        goto error;
    }

10201
    return 0;
10202

10203
 error:
10204
    return -1;
10205 10206 10207 10208 10209 10210 10211 10212 10213
}


static virCPUDefPtr
qemuInitGuestCPU(virDomainDefPtr dom)
{
    if (!dom->cpu) {
        virCPUDefPtr cpu;

10214
        if (VIR_ALLOC(cpu) < 0)
10215 10216 10217 10218 10219 10220 10221 10222 10223 10224 10225 10226 10227 10228 10229
            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)
{
10230
    virCPUDefPtr cpu = NULL;
10231
    char **tokens;
10232
    char **hv_tokens = NULL;
10233
    char *model = NULL;
10234
    int ret = -1;
10235
    size_t i;
10236

10237 10238
    if (!(tokens = virStringSplit(val, ",", 0)))
        goto cleanup;
10239

10240 10241
    if (tokens[0] == NULL)
        goto syntax;
10242

10243 10244 10245 10246 10247 10248 10249
    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;
10250 10251 10252

            if (!STREQ(model, "qemu32") && !STREQ(model, "qemu64")) {
                if (!(cpu = qemuInitGuestCPU(dom)))
10253
                    goto cleanup;
10254 10255 10256 10257

                cpu->model = model;
                model = NULL;
            }
10258 10259
        } else if (*tokens[i] == '+' || *tokens[i] == '-') {
            const char *feature = tokens[i] + 1; /* '+' or '-' */
10260 10261
            int policy;

10262
            if (*tokens[i] == '+')
10263 10264 10265 10266
                policy = VIR_CPU_FEATURE_REQUIRE;
            else
                policy = VIR_CPU_FEATURE_DISABLE;

10267
            if (*feature == '\0')
10268 10269
                goto syntax;

10270 10271 10272 10273 10274 10275 10276 10277
            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;
             }

10278 10279
            if (STREQ(feature, "kvmclock")) {
                bool present = (policy == VIR_CPU_FEATURE_REQUIRE);
10280
                size_t j;
10281

10282 10283
                for (j = 0; j < dom->clock.ntimers; j++) {
                    if (dom->clock.timers[j]->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK)
10284 10285 10286
                        break;
                }

10287
                if (j == dom->clock.ntimers) {
10288 10289 10290 10291 10292
                    virDomainTimerDefPtr timer;
                    if (VIR_ALLOC(timer) < 0 ||
                        VIR_APPEND_ELEMENT_COPY(dom->clock.timers,
                                                dom->clock.ntimers, timer) < 0) {
                        VIR_FREE(timer);
10293
                        goto cleanup;
10294 10295 10296 10297 10298 10299
                    }
                    timer->name = VIR_DOMAIN_TIMER_NAME_KVMCLOCK;
                    timer->present = present;
                    timer->tickpolicy = -1;
                    timer->track = -1;
                    timer->mode = -1;
10300 10301
                } else if (dom->clock.timers[j]->present != -1 &&
                    dom->clock.timers[j]->present != present) {
10302 10303
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("conflicting occurrences of kvmclock feature"));
10304
                    goto cleanup;
10305
                }
10306 10307
            } else if (STREQ(feature, "kvm_pv_eoi")) {
                if (policy == VIR_CPU_FEATURE_REQUIRE)
10308
                    dom->apic_eoi = VIR_DOMAIN_FEATURE_STATE_ON;
10309
                else
10310
                    dom->apic_eoi = VIR_DOMAIN_FEATURE_STATE_OFF;
10311 10312 10313
            } else {
                if (!cpu) {
                    if (!(cpu = qemuInitGuestCPU(dom)))
10314
                        goto cleanup;
10315

10316 10317 10318 10319
                    cpu->model = model;
                    model = NULL;
                }

10320 10321
                if (virCPUDefAddFeature(cpu, feature, policy) < 0)
                    goto cleanup;
10322
            }
10323
        } else if (STRPREFIX(tokens[i], "hv_")) {
10324 10325
            const char *token = tokens[i] + 3; /* "hv_" */
            const char *feature, *value;
10326 10327
            int f;

10328 10329 10330 10331 10332 10333 10334 10335 10336
            if (*token == '\0')
                goto syntax;

            if (!(hv_tokens = virStringSplit(token, "=", 2)))
                goto cleanup;

            feature = hv_tokens[0];
            value = hv_tokens[1];

10337
            if (*feature == '\0')
10338 10339
                goto syntax;

10340
            dom->features[VIR_DOMAIN_FEATURE_HYPERV] = VIR_DOMAIN_FEATURE_STATE_ON;
10341 10342 10343 10344 10345

            if ((f = virDomainHypervTypeFromString(feature)) < 0) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("unsupported HyperV Enlightenment feature "
                                 "'%s'"), feature);
10346
                goto cleanup;
10347 10348
            }

10349
            switch ((virDomainHyperv) f) {
10350
            case VIR_DOMAIN_HYPERV_RELAXED:
10351 10352 10353 10354 10355 10356 10357
            case VIR_DOMAIN_HYPERV_VAPIC:
                if (value) {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("HyperV feature '%s' should not "
                                     "have a value"), feature);
                    goto cleanup;
                }
10358 10359 10360
                dom->hyperv_features[f] = VIR_DOMAIN_FEATURE_STATE_ON;
                break;

10361
            case VIR_DOMAIN_HYPERV_SPINLOCKS:
10362 10363 10364 10365 10366 10367 10368 10369 10370 10371 10372 10373 10374 10375 10376
                dom->hyperv_features[f] = VIR_DOMAIN_FEATURE_STATE_ON;
                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;
10377 10378
                break;

10379 10380 10381
            case VIR_DOMAIN_HYPERV_LAST:
                break;
            }
10382 10383
            virStringFreeList(hv_tokens);
            hv_tokens = NULL;
10384
        }
10385
    }
10386

10387
    if (dom->os.arch == VIR_ARCH_X86_64) {
10388
        bool is_32bit = false;
10389
        if (cpu) {
10390
            virCPUDataPtr cpuData = NULL;
10391

10392 10393 10394
            if (cpuEncode(VIR_ARCH_X86_64, cpu, NULL, &cpuData,
                          NULL, NULL, NULL, NULL) < 0)
                goto cleanup;
10395

J
Jiri Denemark 已提交
10396 10397
            is_32bit = (cpuHasFeature(cpuData, "lm") != 1);
            cpuDataFree(cpuData);
10398 10399 10400
        } else if (model) {
            is_32bit = STREQ(model, "qemu32");
        }
10401

10402
        if (is_32bit)
10403
            dom->os.arch = VIR_ARCH_I686;
10404
    }
10405 10406 10407

    ret = 0;

10408
 cleanup:
10409
    VIR_FREE(model);
10410
    virStringFreeList(tokens);
10411
    virStringFreeList(hv_tokens);
10412
    return ret;
10413

10414
 syntax:
10415 10416
    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("unknown CPU syntax '%s'"), val);
10417
    goto cleanup;
10418 10419 10420 10421 10422 10423 10424 10425 10426 10427 10428
}


static int
qemuParseCommandLineSmp(virDomainDefPtr dom,
                        const char *val)
{
    unsigned int sockets = 0;
    unsigned int cores = 0;
    unsigned int threads = 0;
    unsigned int maxcpus = 0;
10429
    size_t i;
10430 10431 10432 10433 10434 10435 10436
    int nkws;
    char **kws;
    char **vals;
    int n;
    char *end;
    int ret;

10437
    if (qemuParseKeywords(val, &kws, &vals, &nkws, 1) < 0)
10438 10439 10440 10441 10442 10443 10444 10445 10446 10447 10448 10449 10450 10451 10452 10453 10454 10455 10456 10457 10458 10459 10460 10461 10462 10463 10464 10465 10466 10467 10468 10469 10470 10471 10472 10473 10474 10475 10476
        return -1;

    for (i = 0; i < nkws; i++) {
        if (vals[i] == NULL) {
            if (i > 0 ||
                virStrToLong_i(kws[i], &end, 10, &n) < 0 || *end != '\0')
                goto syntax;
            dom->vcpus = n;
        } 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;
        }
    }

    dom->maxvcpus = maxcpus ? maxcpus : dom->vcpus;

    if (sockets && cores && threads) {
        virCPUDefPtr cpu;

        if (!(cpu = qemuInitGuestCPU(dom)))
            goto error;
        cpu->sockets = sockets;
        cpu->cores = cores;
        cpu->threads = threads;
    } else if (sockets || cores || threads)
        goto syntax;

    ret = 0;

10477
 cleanup:
10478 10479 10480 10481 10482 10483 10484 10485 10486
    for (i = 0; i < nkws; i++) {
        VIR_FREE(kws[i]);
        VIR_FREE(vals[i]);
    }
    VIR_FREE(kws);
    VIR_FREE(vals);

    return ret;

10487
 syntax:
10488 10489
    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("cannot parse CPU topology '%s'"), val);
10490
 error:
10491 10492 10493 10494 10495
    ret = -1;
    goto cleanup;
}


10496
static void
10497 10498
qemuParseCommandLineBootDevs(virDomainDefPtr def, const char *str)
{
10499 10500
    int n, b = 0;

10501
    for (n = 0; str[n] && b < VIR_DOMAIN_BOOT_LAST; n++) {
10502 10503 10504 10505 10506 10507 10508 10509 10510 10511 10512 10513 10514 10515 10516
        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;
}


10517 10518 10519 10520 10521
/*
 * 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 已提交
10522 10523 10524 10525 10526 10527 10528 10529
static virDomainDefPtr
qemuParseCommandLine(virCapsPtr qemuCaps,
                     virDomainXMLOptionPtr xmlopt,
                     char **progenv,
                     char **progargv,
                     char **pidfile,
                     virDomainChrSourceDefPtr *monConfig,
                     bool *monJSON)
10530 10531
{
    virDomainDefPtr def;
10532
    size_t i;
10533
    bool nographics = false;
10534
    bool fullscreen = false;
10535
    char *path;
10536
    size_t nnics = 0;
10537 10538 10539
    const char **nics = NULL;
    int video = VIR_DOMAIN_VIDEO_TYPE_CIRRUS;
    int nvirtiodisk = 0;
W
Wen Congyang 已提交
10540
    qemuDomainCmdlineDefPtr cmd = NULL;
E
Eric Blake 已提交
10541
    virDomainDiskDefPtr disk = NULL;
10542
    const char *ceph_args = qemuFindEnv(progenv, "CEPH_ARGS");
10543

10544 10545 10546 10547 10548 10549 10550
    if (pidfile)
        *pidfile = NULL;
    if (monConfig)
        *monConfig = NULL;
    if (monJSON)
        *monJSON = false;

10551
    if (!progargv[0]) {
10552 10553
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("no emulator path found"));
10554 10555 10556 10557
        return NULL;
    }

    if (VIR_ALLOC(def) < 0)
10558
        goto error;
10559 10560 10561

    /* allocate the cmdlinedef up-front; if it's unused, we'll free it later */
    if (VIR_ALLOC(cmd) < 0)
10562
        goto error;
10563

E
Eric Blake 已提交
10564
    if (virUUIDGenerate(def->uuid) < 0) {
10565 10566
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to generate uuid"));
E
Eric Blake 已提交
10567 10568
        goto error;
    }
10569 10570 10571 10572 10573 10574

    def->id = -1;
    def->mem.cur_balloon = def->mem.max_balloon = 64 * 1024;
    def->maxvcpus = 1;
    def->vcpus = 1;
    def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC;
10575

10576 10577 10578 10579
    def->onReboot = VIR_DOMAIN_LIFECYCLE_RESTART;
    def->onCrash = VIR_DOMAIN_LIFECYCLE_DESTROY;
    def->onPoweroff = VIR_DOMAIN_LIFECYCLE_DESTROY;
    def->virtType = VIR_DOMAIN_VIRT_QEMU;
10580 10581
    if (VIR_STRDUP(def->emulator, progargv[0]) < 0)
        goto error;
10582

10583 10584
    if (!(path = last_component(def->emulator)))
        goto error;
10585

10586
    if (strstr(path, "xenner")) {
10587
        def->virtType = VIR_DOMAIN_VIRT_KVM;
10588 10589
        if (VIR_STRDUP(def->os.type, "xen") < 0)
            goto error;
10590
    } else {
10591 10592
        if (VIR_STRDUP(def->os.type, "hvm") < 0)
            goto error;
10593 10594
        if (strstr(path, "kvm")) {
            def->virtType = VIR_DOMAIN_VIRT_KVM;
10595
            def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_DOMAIN_FEATURE_STATE_ON;
10596
        }
10597 10598
    }

10599
    if (def->virtType == VIR_DOMAIN_VIRT_KVM)
10600
        def->os.arch = qemuCaps->host.arch;
10601
    else if (STRPREFIX(path, "qemu-system-"))
10602
        def->os.arch = virArchFromString(path + strlen("qemu-system-"));
10603
    else
10604
        def->os.arch = VIR_ARCH_I686;
10605

10606 10607
    if ((def->os.arch == VIR_ARCH_I686) ||
        (def->os.arch == VIR_ARCH_X86_64))
10608
        def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_DOMAIN_FEATURE_STATE_ON;
10609

10610 10611 10612
#define WANT_VALUE()                                                   \
    const char *val = progargv[++i];                                   \
    if (!val) {                                                        \
10613
        virReportError(VIR_ERR_INTERNAL_ERROR,                         \
10614
                       _("missing value for %s argument"), arg);       \
10615 10616 10617 10618 10619
        goto error;                                                    \
    }

    /* One initial loop to get list of NICs, so we
     * can correlate them later */
10620
    for (i = 1; progargv[i]; i++) {
10621 10622 10623 10624 10625 10626 10627 10628
        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();
10629 10630 10631
            if (STRPREFIX(val, "nic") &&
                VIR_APPEND_ELEMENT(nics, nnics, val) < 0)
                goto error;
10632 10633 10634 10635
        }
    }

    /* Now the real processing loop */
10636
    for (i = 1; progargv[i]; i++) {
10637
        const char *arg = progargv[i];
L
Laine Stump 已提交
10638 10639
        bool argRecognized = true;

10640 10641 10642 10643 10644 10645 10646 10647 10648 10649
        /* 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)
10650
                goto error;
10651 10652
            vnc->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;

10653
            if (STRPREFIX(val, "unix:")) {
10654
                /* -vnc unix:/some/big/path */
10655
                if (VIR_STRDUP(vnc->data.vnc.socket, val + 5) < 0) {
10656
                    virDomainGraphicsDefFree(vnc);
10657
                    goto error;
10658 10659
                }
            } else {
10660 10661 10662 10663 10664 10665
                /*
                 * -vnc 127.0.0.1:4
                 * -vnc [2001:1:2:3:4:5:1234:1234]:4
                 * -vnc some.host.name:4
                 */
                char *opts;
10666
                char *port;
10667 10668 10669 10670 10671
                const char *sep = ":";
                if (val[0] == '[')
                    sep = "]:";
                tmp = strstr(val, sep);
                if (!tmp) {
10672
                    virDomainGraphicsDefFree(vnc);
10673 10674
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("missing VNC port number in '%s'"), val);
10675 10676
                    goto error;
                }
10677 10678
                port = tmp + strlen(sep);
                if (virStrToLong_i(port, &opts, 10,
10679
                                   &vnc->data.vnc.port) < 0) {
10680
                    virDomainGraphicsDefFree(vnc);
10681
                    virReportError(VIR_ERR_INTERNAL_ERROR,
10682
                                   _("cannot parse VNC port '%s'"), port);
10683 10684 10685
                    goto error;
                }
                if (val[0] == '[')
10686 10687
                    virDomainGraphicsListenSetAddress(vnc, 0,
                                                      val+1, tmp-(val+1), true);
10688
                else
10689 10690 10691 10692
                    virDomainGraphicsListenSetAddress(vnc, 0,
                                                      val, tmp-val, true);
                if (!virDomainGraphicsListenGetAddress(vnc, 0)) {
                    virDomainGraphicsDefFree(vnc);
10693
                    goto error;
10694
                }
10695 10696

                if (*opts == ',') {
10697 10698 10699
                    char *orig_opts;

                    if (VIR_STRDUP(orig_opts, opts + 1) < 0) {
10700
                        virDomainGraphicsDefFree(vnc);
10701
                        goto error;
10702 10703 10704 10705 10706 10707 10708 10709 10710 10711 10712 10713 10714 10715 10716 10717 10718 10719 10720 10721 10722 10723 10724 10725 10726 10727 10728 10729 10730 10731 10732 10733
                    }
                    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;
                            }
10734 10735 10736 10737 10738 10739 10740 10741 10742 10743 10744 10745 10746 10747 10748 10749 10750 10751 10752 10753 10754 10755 10756
                        } 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;
                            }
10757 10758 10759 10760 10761 10762
                        }

                        opts = nextopt;
                    }
                    VIR_FREE(orig_opts);
                }
10763
                vnc->data.vnc.port += 5900;
10764
                vnc->data.vnc.autoport = false;
10765 10766
            }

10767
            if (VIR_APPEND_ELEMENT(def->graphics, def->ngraphics, vnc) < 0) {
10768
                virDomainGraphicsDefFree(vnc);
10769
                goto error;
10770 10771 10772 10773 10774
            }
        } else if (STREQ(arg, "-m")) {
            int mem;
            WANT_VALUE();
            if (virStrToLong_i(val, NULL, 10, &mem) < 0) {
10775 10776
                virReportError(VIR_ERR_INTERNAL_ERROR, \
                               _("cannot parse memory level '%s'"), val);
10777 10778 10779 10780 10781 10782 10783 10784 10785 10786
                goto error;
            }
            def->mem.cur_balloon = def->mem.max_balloon = mem * 1024;
        } 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) {
10787 10788
                virReportError(VIR_ERR_INTERNAL_ERROR, \
                               _("cannot parse UUID '%s'"), val);
10789 10790 10791 10792 10793 10794 10795
                goto error;
            }
        } else if (STRPREFIX(arg, "-hd") ||
                   STRPREFIX(arg, "-sd") ||
                   STRPREFIX(arg, "-fd") ||
                   STREQ(arg, "-cdrom")) {
            WANT_VALUE();
10796
            if (!(disk = virDomainDiskDefNew()))
10797
                goto error;
10798 10799

            if (STRPREFIX(val, "/dev/"))
10800
                disk->src->type = VIR_STORAGE_TYPE_BLOCK;
10801
            else if (STRPREFIX(val, "nbd:")) {
10802 10803
                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_NBD;
10804
            } else if (STRPREFIX(val, "rbd:")) {
10805 10806
                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_RBD;
10807
                val += strlen("rbd:");
10808
            } else if (STRPREFIX(val, "gluster")) {
10809 10810
                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_GLUSTER;
10811
            } else if (STRPREFIX(val, "sheepdog:")) {
10812 10813
                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_SHEEPDOG;
10814 10815
                val += strlen("sheepdog:");
            } else
10816
                disk->src->type = VIR_STORAGE_TYPE_FILE;
10817 10818
            if (STREQ(arg, "-cdrom")) {
                disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
10819 10820 10821
                if (((def->os.arch == VIR_ARCH_PPC64) &&
                    def->os.machine && STREQ(def->os.machine, "pseries")))
                    disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
10822 10823
                if (VIR_STRDUP(disk->dst, "hdc") < 0)
                    goto error;
10824
                disk->readonly = true;
10825 10826 10827 10828 10829 10830 10831 10832 10833 10834
            } 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;
10835 10836 10837
                   if (((def->os.arch == VIR_ARCH_PPC64) &&
                       def->os.machine && STREQ(def->os.machine, "pseries")))
                       disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
10838
                }
10839 10840
                if (VIR_STRDUP(disk->dst, arg + 1) < 0)
                    goto error;
10841
            }
10842
            if (VIR_STRDUP(disk->src->path, val) < 0)
10843
                goto error;
10844

10845
            if (disk->src->type == VIR_STORAGE_TYPE_NETWORK) {
10846
                char *port;
10847

10848
                switch ((virStorageNetProtocol) disk->src->protocol) {
10849
                case VIR_STORAGE_NET_PROTOCOL_NBD:
10850
                    if (qemuParseNBDString(disk) < 0)
10851 10852
                        goto error;
                    break;
10853
                case VIR_STORAGE_NET_PROTOCOL_RBD:
10854 10855 10856
                    /* old-style CEPH_ARGS env variable is parsed later */
                    if (!ceph_args && qemuParseRBDString(disk) < 0)
                        goto error;
10857
                    break;
10858
                case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
10859
                    /* disk->src must be [vdiname] or [host]:[port]:[vdiname] */
10860
                    port = strchr(disk->src->path, ':');
10861 10862 10863 10864 10865 10866
                    if (port) {
                        char *vdi;

                        *port++ = '\0';
                        vdi = strchr(port, ':');
                        if (!vdi) {
10867 10868
                            virReportError(VIR_ERR_INTERNAL_ERROR,
                                           _("cannot parse sheepdog filename '%s'"), val);
10869 10870 10871
                            goto error;
                        }
                        *vdi++ = '\0';
10872
                        if (VIR_ALLOC(disk->src->hosts) < 0)
10873
                            goto error;
10874 10875 10876
                        disk->src->nhosts = 1;
                        disk->src->hosts->name = disk->src->path;
                        if (VIR_STRDUP(disk->src->hosts->port, port) < 0)
10877
                            goto error;
10878
                        if (VIR_STRDUP(disk->src->path, vdi) < 0)
10879
                            goto error;
10880 10881
                    }
                    break;
10882
                case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
10883 10884 10885
                    if (qemuParseGlusterString(disk) < 0)
                        goto error;

P
Paolo Bonzini 已提交
10886
                    break;
10887
                case VIR_STORAGE_NET_PROTOCOL_ISCSI:
P
Paolo Bonzini 已提交
10888 10889 10890
                    if (qemuParseISCSIString(disk) < 0)
                        goto error;

10891
                    break;
10892 10893 10894 10895 10896 10897
                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:
10898
                case VIR_STORAGE_NET_PROTOCOL_NONE:
10899 10900
                    /* ignored for now */
                    break;
10901 10902 10903
                }
            }

10904
            if (virDomainDiskDefAssignAddress(xmlopt, disk) < 0) {
10905 10906 10907
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("Cannot assign address for device name '%s'"),
                               disk->dst);
10908
                goto error;
10909
            }
10910

10911
            if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
10912
                goto error;
10913
        } else if (STREQ(arg, "-no-acpi")) {
10914
            def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_DOMAIN_FEATURE_STATE_DEFAULT;
10915 10916 10917 10918
        } 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 已提交
10919 10920
        } else if (STREQ(arg, "-enable-kvm")) {
            def->virtType = VIR_DOMAIN_VIRT_KVM;
10921
        } else if (STREQ(arg, "-nographic")) {
10922
            nographics = true;
10923
        } else if (STREQ(arg, "-full-screen")) {
10924
            fullscreen = true;
10925 10926 10927 10928
        } else if (STREQ(arg, "-localtime")) {
            def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME;
        } else if (STREQ(arg, "-kernel")) {
            WANT_VALUE();
10929 10930
            if (VIR_STRDUP(def->os.kernel, val) < 0)
                goto error;
10931 10932
        } else if (STREQ(arg, "-bios")) {
            WANT_VALUE();
10933 10934
            if (VIR_STRDUP(def->os.loader, val) < 0)
                goto error;
10935 10936
        } else if (STREQ(arg, "-initrd")) {
            WANT_VALUE();
10937 10938
            if (VIR_STRDUP(def->os.initrd, val) < 0)
                goto error;
10939 10940
        } else if (STREQ(arg, "-append")) {
            WANT_VALUE();
10941 10942
            if (VIR_STRDUP(def->os.cmdline, val) < 0)
                goto error;
O
Olivia Yin 已提交
10943 10944
        } else if (STREQ(arg, "-dtb")) {
            WANT_VALUE();
10945 10946
            if (VIR_STRDUP(def->os.dtb, val) < 0)
                goto error;
10947
        } else if (STREQ(arg, "-boot")) {
10948
            const char *token = NULL;
10949 10950
            WANT_VALUE();

10951 10952 10953 10954 10955 10956 10957 10958 10959 10960
            if (!strchr(val, ','))
                qemuParseCommandLineBootDevs(def, val);
            else {
                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;
10961 10962 10963 10964 10965 10966 10967 10968 10969 10970 10971 10972 10973 10974 10975 10976
                    } 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;
10977 10978 10979 10980 10981 10982 10983 10984
                    }
                    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++;
                }
            }
10985 10986 10987 10988 10989
        } else if (STREQ(arg, "-name")) {
            char *process;
            WANT_VALUE();
            process = strstr(val, ",process=");
            if (process == NULL) {
10990 10991
                if (VIR_STRDUP(def->name, val) < 0)
                    goto error;
10992
            } else {
10993 10994
                if (VIR_STRNDUP(def->name, val, process - val) < 0)
                    goto error;
10995
            }
10996 10997
            if (STREQ(def->name, ""))
                VIR_FREE(def->name);
10998 10999
        } else if (STREQ(arg, "-M") ||
                   STREQ(arg, "-machine")) {
11000 11001 11002 11003 11004 11005 11006
            char **list;
            char *param;
            size_t j = 0;

            /* -machine [type=]name[,prop[=value][,...]]
             * Set os.machine only if first parameter lacks '=' or
             * contains explicit type='...' */
11007
            WANT_VALUE();
11008 11009
            if (!(list = virStringSplit(val, ",", 0)))
                goto error;
11010 11011 11012 11013 11014 11015 11016
            param = list[0];

            if (STRPREFIX(param, "type="))
                param += strlen("type=");
            if (!strchr(param, '=')) {
                if (VIR_STRDUP(def->os.machine, param) < 0) {
                    virStringFreeList(list);
11017
                    goto error;
11018 11019 11020 11021 11022 11023 11024 11025 11026 11027 11028 11029 11030 11031 11032
                }
                j++;
            }

            /* handle all remaining "-machine" parameters */
            while ((param = list[j++])) {
                if (STRPREFIX(param, "dump-guest-core=")) {
                    param += strlen("dump-guest-core=");
                    def->mem.dump_core = virDomainMemDumpTypeFromString(param);
                    if (def->mem.dump_core <= 0)
                        def->mem.dump_core = VIR_DOMAIN_MEM_DUMP_DEFAULT;
                } else if (STRPREFIX(param, "mem-merge=off")) {
                    def->mem.nosharepages = true;
                } else if (STRPREFIX(param, "accel=kvm")) {
                    def->virtType = VIR_DOMAIN_VIRT_KVM;
11033
                    def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_DOMAIN_FEATURE_STATE_ON;
11034 11035
                }
            }
11036
            virStringFreeList(list);
11037 11038 11039 11040
        } else if (STREQ(arg, "-serial")) {
            WANT_VALUE();
            if (STRNEQ(val, "none")) {
                virDomainChrDefPtr chr;
11041 11042 11043 11044

                if (!(chr = virDomainChrDefNew()))
                    goto error;

E
Eric Blake 已提交
11045 11046
                if (qemuParseCommandLineChr(&chr->source, val) < 0) {
                    virDomainChrDefFree(chr);
11047
                    goto error;
E
Eric Blake 已提交
11048
                }
11049 11050 11051
                chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
                chr->target.port = def->nserials;
                if (VIR_APPEND_ELEMENT(def->serials, def->nserials, chr) < 0) {
11052
                    virDomainChrDefFree(chr);
11053
                    goto error;
11054 11055 11056 11057 11058 11059
                }
            }
        } else if (STREQ(arg, "-parallel")) {
            WANT_VALUE();
            if (STRNEQ(val, "none")) {
                virDomainChrDefPtr chr;
11060 11061 11062 11063

                if (!(chr = virDomainChrDefNew()))
                    goto error;

E
Eric Blake 已提交
11064 11065
                if (qemuParseCommandLineChr(&chr->source, val) < 0) {
                    virDomainChrDefFree(chr);
11066
                    goto error;
E
Eric Blake 已提交
11067
                }
11068 11069 11070
                chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL;
                chr->target.port = def->nparallels;
                if (VIR_APPEND_ELEMENT(def->parallels, def->nparallels, chr) < 0) {
11071
                    virDomainChrDefFree(chr);
11072
                    goto error;
11073 11074 11075 11076 11077
                }
            }
        } else if (STREQ(arg, "-usbdevice")) {
            WANT_VALUE();
            if (STREQ(val, "tablet") ||
11078 11079
                STREQ(val, "mouse") ||
                STREQ(val, "keyboard")) {
11080 11081
                virDomainInputDefPtr input;
                if (VIR_ALLOC(input) < 0)
11082
                    goto error;
11083 11084 11085
                input->bus = VIR_DOMAIN_INPUT_BUS_USB;
                if (STREQ(val, "tablet"))
                    input->type = VIR_DOMAIN_INPUT_TYPE_TABLET;
11086
                else if (STREQ(val, "mouse"))
11087
                    input->type = VIR_DOMAIN_INPUT_TYPE_MOUSE;
11088 11089 11090 11091
                else
                    input->type = VIR_DOMAIN_INPUT_TYPE_KBD;

                if (VIR_APPEND_ELEMENT(def->inputs, def->ninputs, input) < 0) {
11092
                    virDomainInputDefFree(input);
11093
                    goto error;
11094 11095
                }
            } else if (STRPREFIX(val, "disk:")) {
11096
                if (!(disk = virDomainDiskDefNew()))
11097
                    goto error;
11098
                if (VIR_STRDUP(disk->src->path, val + strlen("disk:")) < 0)
11099
                    goto error;
11100 11101
                if (STRPREFIX(disk->src->path, "/dev/"))
                    disk->src->type = VIR_STORAGE_TYPE_BLOCK;
11102
                else
11103
                    disk->src->type = VIR_STORAGE_TYPE_FILE;
11104 11105
                disk->device = VIR_DOMAIN_DISK_DEVICE_DISK;
                disk->bus = VIR_DOMAIN_DISK_BUS_USB;
11106
                disk->removable = VIR_DOMAIN_FEATURE_STATE_DEFAULT;
11107 11108
                if (VIR_STRDUP(disk->dst, "sda") < 0)
                    goto error;
11109
                if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
11110
                    goto error;
11111 11112 11113 11114
            } else {
                virDomainHostdevDefPtr hostdev;
                if (!(hostdev = qemuParseCommandLineUSB(val)))
                    goto error;
11115
                if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev) < 0) {
11116
                    virDomainHostdevDefFree(hostdev);
11117
                    goto error;
11118 11119 11120 11121 11122 11123
                }
            }
        } else if (STREQ(arg, "-net")) {
            WANT_VALUE();
            if (!STRPREFIX(val, "nic") && STRNEQ(val, "none")) {
                virDomainNetDefPtr net;
11124
                if (!(net = qemuParseCommandLineNet(xmlopt, val, nnics, nics)))
11125
                    goto error;
11126
                if (VIR_APPEND_ELEMENT(def->nets, def->nnets, net) < 0) {
11127
                    virDomainNetDefFree(net);
11128
                    goto error;
11129 11130 11131 11132
                }
            }
        } else if (STREQ(arg, "-drive")) {
            WANT_VALUE();
11133
            if (!(disk = qemuParseCommandLineDisk(xmlopt, val, def,
11134
                                                  nvirtiodisk,
11135
                                                  ceph_args != NULL)))
11136 11137 11138
                goto error;
            if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
                nvirtiodisk++;
11139 11140
            if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
                goto error;
11141 11142 11143 11144 11145
        } else if (STREQ(arg, "-pcidevice")) {
            virDomainHostdevDefPtr hostdev;
            WANT_VALUE();
            if (!(hostdev = qemuParseCommandLinePCI(val)))
                goto error;
11146
            if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev) < 0) {
11147
                virDomainHostdevDefFree(hostdev);
11148
                goto error;
11149 11150 11151 11152 11153 11154 11155 11156 11157 11158 11159 11160 11161 11162 11163 11164
            }
        } 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;
11165 11166
                } else if (STRPREFIX(start, "hda")) {
                    type = VIR_DOMAIN_SOUND_MODEL_ICH6;
11167 11168 11169 11170 11171
                }

                if (type != -1) {
                    virDomainSoundDefPtr snd;
                    if (VIR_ALLOC(snd) < 0)
11172
                        goto error;
11173
                    snd->model = type;
11174
                    if (VIR_APPEND_ELEMENT(def->sounds, def->nsounds, snd) < 0) {
11175
                        VIR_FREE(snd);
11176
                        goto error;
11177 11178 11179 11180 11181 11182 11183
                    }
                }

                start = tmp ? tmp + 1 : NULL;
            }
        } else if (STREQ(arg, "-watchdog")) {
            WANT_VALUE();
11184
            int model = virDomainWatchdogModelTypeFromString(val);
11185 11186 11187 11188

            if (model != -1) {
                virDomainWatchdogDefPtr wd;
                if (VIR_ALLOC(wd) < 0)
11189
                    goto error;
11190 11191 11192 11193 11194 11195
                wd->model = model;
                wd->action = VIR_DOMAIN_WATCHDOG_ACTION_RESET;
                def->watchdog = wd;
            }
        } else if (STREQ(arg, "-watchdog-action") && def->watchdog) {
            WANT_VALUE();
11196
            int action = virDomainWatchdogActionTypeFromString(val);
11197 11198 11199 11200 11201

            if (action != -1)
                def->watchdog->action = action;
        } else if (STREQ(arg, "-bootloader")) {
            WANT_VALUE();
11202 11203
            if (VIR_STRDUP(def->os.bootloader, val) < 0)
                goto error;
11204 11205 11206 11207 11208 11209 11210 11211 11212
        } 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) {
11213 11214
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("unknown video adapter type '%s'"), val);
11215 11216 11217 11218 11219 11220 11221 11222 11223 11224 11225
                    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")) {
11226 11227
            virDomainControllerDefPtr ctldef;
            if (VIR_ALLOC(ctldef) < 0)
11228
                goto error;
11229 11230 11231
            ctldef->type = VIR_DOMAIN_CONTROLLER_TYPE_USB;
            ctldef->idx = 0;
            ctldef->model = -1;
11232 11233
            if (virDomainControllerInsert(def, ctldef) < 0) {
                VIR_FREE(ctldef);
11234
                goto error;
11235
            }
11236 11237
        } else if (STREQ(arg, "-pidfile")) {
            WANT_VALUE();
11238
            if (pidfile)
11239 11240
                if (VIR_STRDUP(*pidfile, val) < 0)
                    goto error;
11241 11242 11243 11244 11245
        } else if (STREQ(arg, "-incoming")) {
            WANT_VALUE();
            /* ignore, used via restore/migrate APIs */
        } else if (STREQ(arg, "-monitor")) {
            WANT_VALUE();
11246 11247 11248 11249
            if (monConfig) {
                virDomainChrSourceDefPtr chr;

                if (VIR_ALLOC(chr) < 0)
11250
                    goto error;
11251

E
Eric Blake 已提交
11252 11253
                if (qemuParseCommandLineChr(chr, val) < 0) {
                    virDomainChrSourceDefFree(chr);
11254
                    goto error;
E
Eric Blake 已提交
11255
                }
11256 11257 11258

                *monConfig = chr;
            }
11259 11260 11261 11262 11263 11264 11265 11266 11267 11268 11269 11270 11271 11272 11273 11274 11275 11276 11277 11278 11279 11280 11281 11282 11283 11284 11285 11286 11287 11288 11289 11290 11291 11292 11293 11294
        } 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=");
            if (STREQ(val, "0"))
                def->pm.s3 = VIR_DOMAIN_PM_STATE_ENABLED;
            else if (STREQ(val, "1"))
                def->pm.s3 = VIR_DOMAIN_PM_STATE_DISABLED;
            else {
                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=");
            if (STREQ(val, "0"))
                def->pm.s4 = VIR_DOMAIN_PM_STATE_ENABLED;
            else if (STREQ(val, "1"))
                def->pm.s4 = VIR_DOMAIN_PM_STATE_DISABLED;
            else {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("invalid value for disable_s4 parameter: "
                                 "'%s'"), val);
                goto error;
            }

11295 11296 11297 11298 11299
        } else if (STREQ(arg, "-global") &&
                   STRPREFIX(progargv[i + 1], "spapr-nvram.reg=")) {
            WANT_VALUE();

            if (VIR_ALLOC(def->nvram) < 0)
11300
                goto error;
11301 11302 11303 11304 11305 11306 11307 11308 11309 11310 11311

            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;
            }
11312 11313 11314
        } else if (STREQ(arg, "-S") ||
                   STREQ(arg, "-nodefaults") ||
                   STREQ(arg, "-nodefconfig")) {
11315
            /* ignore, always added by libvirt */
L
Laine Stump 已提交
11316 11317 11318 11319 11320 11321 11322 11323 11324 11325 11326 11327 11328 11329 11330 11331 11332 11333
        } 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;
            }
11334
        } else {
L
Laine Stump 已提交
11335 11336 11337 11338
            argRecognized = false;
        }

        if (!argRecognized) {
11339
            char *tmp = NULL;
11340 11341 11342 11343 11344
            /* 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);
11345 11346 11347
            if (VIR_STRDUP(tmp, arg) < 0 ||
                VIR_APPEND_ELEMENT(cmd->args, cmd->num_args, tmp) < 0) {
                VIR_FREE(tmp);
11348
                goto error;
11349
            }
11350 11351 11352 11353
        }
    }

#undef WANT_VALUE
11354 11355 11356
    if (def->ndisks > 0 && ceph_args) {
        char *hosts, *port, *saveptr = NULL, *token;
        virDomainDiskDefPtr first_rbd_disk = NULL;
11357
        for (i = 0; i < def->ndisks; i++) {
11358 11359
            if (def->disks[i]->src->type == VIR_STORAGE_TYPE_NETWORK &&
                def->disks[i]->src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) {
11360 11361
                first_rbd_disk = def->disks[i];
                break;
11362
            }
11363
        }
11364

11365
        if (!first_rbd_disk) {
11366 11367
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("CEPH_ARGS was set without an rbd disk"));
11368 11369
            goto error;
        }
11370

11371 11372
        /* CEPH_ARGS should be: -m host1[:port1][,host2[:port2]]... */
        if (!STRPREFIX(ceph_args, "-m ")) {
11373 11374
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("could not parse CEPH_ARGS '%s'"), ceph_args);
11375 11376
            goto error;
        }
11377 11378
        if (VIR_STRDUP(hosts, strchr(ceph_args, ' ') + 1) < 0)
            goto error;
11379
        first_rbd_disk->src->nhosts = 0;
11380 11381
        token = strtok_r(hosts, ",", &saveptr);
        while (token != NULL) {
11382 11383
            if (VIR_REALLOC_N(first_rbd_disk->src->hosts,
                              first_rbd_disk->src->nhosts + 1) < 0) {
11384
                VIR_FREE(hosts);
11385
                goto error;
11386 11387 11388 11389
            }
            port = strchr(token, ':');
            if (port) {
                *port++ = '\0';
11390
                if (VIR_STRDUP(port, port) < 0) {
11391
                    VIR_FREE(hosts);
11392
                    goto error;
11393 11394
                }
            }
11395 11396
            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,
11397
                           token) < 0) {
11398
                VIR_FREE(hosts);
11399
                goto error;
11400
            }
11401 11402
            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;
11403

11404
            first_rbd_disk->src->nhosts++;
11405 11406 11407 11408
            token = strtok_r(NULL, ",", &saveptr);
        }
        VIR_FREE(hosts);

11409
        if (first_rbd_disk->src->nhosts == 0) {
11410 11411
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("found no rbd hosts in CEPH_ARGS '%s'"), ceph_args);
11412
            goto error;
11413 11414 11415
        }
    }

11416 11417
    if (!def->os.machine) {
        const char *defaultMachine =
11418
                        virCapabilitiesDefaultGuestMachine(qemuCaps,
11419 11420 11421 11422
                                                           def->os.type,
                                                           def->os.arch,
                                                           virDomainVirtTypeToString(def->virtType));
        if (defaultMachine != NULL)
11423 11424
            if (VIR_STRDUP(def->os.machine, defaultMachine) < 0)
                goto error;
11425 11426
    }

11427 11428 11429 11430 11431
    if (!nographics && def->ngraphics == 0) {
        virDomainGraphicsDefPtr sdl;
        const char *display = qemuFindEnv(progenv, "DISPLAY");
        const char *xauth = qemuFindEnv(progenv, "XAUTHORITY");
        if (VIR_ALLOC(sdl) < 0)
11432
            goto error;
11433 11434
        sdl->type = VIR_DOMAIN_GRAPHICS_TYPE_SDL;
        sdl->data.sdl.fullscreen = fullscreen;
11435
        if (VIR_STRDUP(sdl->data.sdl.display, display) < 0) {
11436
            VIR_FREE(sdl);
11437
            goto error;
11438
        }
11439
        if (VIR_STRDUP(sdl->data.sdl.xauth, xauth) < 0) {
11440
            VIR_FREE(sdl);
11441
            goto error;
11442 11443
        }

11444
        if (VIR_APPEND_ELEMENT(def->graphics, def->ngraphics, sdl) < 0) {
11445
            virDomainGraphicsDefFree(sdl);
11446
            goto error;
11447 11448 11449 11450 11451 11452
        }
    }

    if (def->ngraphics) {
        virDomainVideoDefPtr vid;
        if (VIR_ALLOC(vid) < 0)
11453
            goto error;
11454 11455 11456 11457 11458
        if (def->virtType == VIR_DOMAIN_VIRT_XEN)
            vid->type = VIR_DOMAIN_VIDEO_TYPE_XEN;
        else
            vid->type = video;
        vid->vram = virDomainVideoDefaultRAM(def, vid->type);
11459 11460
        vid->ram = vid->type == VIR_DOMAIN_VIDEO_TYPE_QXL ?
                       virDomainVideoDefaultRAM(def, vid->type) : 0;
11461 11462
        vid->heads = 1;

11463
        if (VIR_APPEND_ELEMENT(def->videos, def->nvideos, vid) < 0) {
11464
            virDomainVideoDefFree(vid);
11465
            goto error;
11466 11467 11468 11469 11470 11471 11472 11473 11474
        }
    }

    /*
     * having a balloon is the default, define one with type="none" to avoid it
     */
    if (!def->memballoon) {
        virDomainMemballoonDefPtr memballoon;
        if (VIR_ALLOC(memballoon) < 0)
11475
            goto error;
L
Laine Stump 已提交
11476
        memballoon->model = VIR_DOMAIN_MEMBALLOON_MODEL_NONE;
11477 11478 11479 11480 11481 11482 11483 11484 11485

        def->memballoon = memballoon;
    }

    VIR_FREE(nics);

    if (virDomainDefAddImplicitControllers(def) < 0)
        goto error;

11486 11487 11488
    if (virDomainDefPostParse(def, qemuCaps, xmlopt) < 0)
        goto error;

11489
    if (cmd->num_args || cmd->num_env) {
11490
        def->ns = *virDomainXMLOptionGetNamespace(xmlopt);
11491 11492 11493
        def->namespaceData = cmd;
    }
    else
11494
        qemuDomainCmdlineDefFree(cmd);
11495 11496 11497

    return def;

11498
 error:
E
Eric Blake 已提交
11499
    virDomainDiskDefFree(disk);
11500
    qemuDomainCmdlineDefFree(cmd);
11501 11502
    virDomainDefFree(def);
    VIR_FREE(nics);
11503 11504 11505 11506 11507 11508
    if (monConfig) {
        virDomainChrSourceDefFree(*monConfig);
        *monConfig = NULL;
    }
    if (pidfile)
        VIR_FREE(*pidfile);
11509 11510 11511 11512
    return NULL;
}


11513
virDomainDefPtr qemuParseCommandLineString(virCapsPtr qemuCaps,
11514
                                           virDomainXMLOptionPtr xmlopt,
11515 11516 11517 11518
                                           const char *args,
                                           char **pidfile,
                                           virDomainChrSourceDefPtr *monConfig,
                                           bool *monJSON)
11519
{
E
Eric Blake 已提交
11520 11521
    char **progenv = NULL;
    char **progargv = NULL;
11522 11523 11524 11525 11526
    virDomainDefPtr def = NULL;

    if (qemuStringToArgvEnv(args, &progenv, &progargv) < 0)
        goto cleanup;

11527
    def = qemuParseCommandLine(qemuCaps, xmlopt, progenv, progargv,
11528
                               pidfile, monConfig, monJSON);
11529

11530
 cleanup:
E
Eric Blake 已提交
11531 11532
    virStringFreeList(progargv);
    virStringFreeList(progenv);
11533 11534 11535

    return def;
}
11536 11537


11538
static int qemuParseProcFileStrings(int pid_value,
11539
                                    const char *name,
E
Eric Blake 已提交
11540
                                    char ***list)
11541 11542 11543 11544 11545 11546 11547
{
    char *path = NULL;
    int ret = -1;
    char *data = NULL;
    ssize_t len;
    char *tmp;
    size_t nstr = 0;
11548
    char **str = NULL;
11549

11550
    if (virAsprintf(&path, "/proc/%d/%s", pid_value, name) < 0)
11551 11552 11553 11554 11555 11556 11557
        goto cleanup;

    if ((len = virFileReadAll(path, 1024*128, &data)) < 0)
        goto cleanup;

    tmp = data;
    while (tmp < (data + len)) {
11558
        if (VIR_EXPAND_N(str, nstr, 1) < 0)
11559 11560
            goto cleanup;

11561
        if (VIR_STRDUP(str[nstr-1], tmp) < 0)
11562 11563 11564 11565 11566 11567 11568
            goto cleanup;
        /* Skip arg */
        tmp += strlen(tmp);
        /* Skip \0 separator */
        tmp++;
    }

11569
    if (VIR_EXPAND_N(str, nstr, 1) < 0)
11570 11571 11572 11573 11574
        goto cleanup;

    str[nstr-1] = NULL;

    ret = nstr-1;
E
Eric Blake 已提交
11575
    *list = str;
11576

11577
 cleanup:
E
Eric Blake 已提交
11578 11579
    if (ret < 0)
        virStringFreeList(str);
11580 11581 11582 11583 11584
    VIR_FREE(data);
    VIR_FREE(path);
    return ret;
}

11585
virDomainDefPtr qemuParseCommandLinePid(virCapsPtr qemuCaps,
11586
                                        virDomainXMLOptionPtr xmlopt,
11587
                                        pid_t pid,
11588 11589 11590 11591 11592
                                        char **pidfile,
                                        virDomainChrSourceDefPtr *monConfig,
                                        bool *monJSON)
{
    virDomainDefPtr def = NULL;
E
Eric Blake 已提交
11593 11594
    char **progargv = NULL;
    char **progenv = NULL;
11595 11596 11597
    char *exepath = NULL;
    char *emulator;

11598 11599 11600 11601
    /* 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 ||
11602 11603 11604
        qemuParseProcFileStrings(pid, "environ", &progenv) < 0)
        goto cleanup;

11605
    if (!(def = qemuParseCommandLine(qemuCaps, xmlopt, progenv, progargv,
11606 11607 11608
                                     pidfile, monConfig, monJSON)))
        goto cleanup;

11609
    if (virAsprintf(&exepath, "/proc/%d/exe", (int) pid) < 0)
11610 11611 11612 11613 11614
        goto cleanup;

    if (virFileResolveLink(exepath, &emulator) < 0) {
        virReportSystemError(errno,
                             _("Unable to resolve %s for pid %u"),
11615
                             exepath, (int) pid);
11616 11617 11618 11619 11620
        goto cleanup;
    }
    VIR_FREE(def->emulator);
    def->emulator = emulator;

11621
 cleanup:
11622
    VIR_FREE(exepath);
E
Eric Blake 已提交
11623 11624
    virStringFreeList(progargv);
    virStringFreeList(progenv);
11625 11626
    return def;
}