qemu_command.c 405.6 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 "secret_conf.h"
49
#include "network/bridge_driver.h"
50
#include "virnetdevtap.h"
51
#include "base64.h"
52
#include "device_conf.h"
53
#include "virstoragefile.h"
54
#include "virtpm.h"
55
#include "virscsi.h"
56 57 58
#if defined(__linux__)
# include <linux/capability.h>
#endif
59 60 61 62 63 64

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

#define VIR_FROM_THIS VIR_FROM_QEMU

65 66
VIR_LOG_INIT("qemu.qemu_command");

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

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


VIR_ENUM_DECL(qemuDiskCacheV1)
VIR_ENUM_DECL(qemuDiskCacheV2)

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

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

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

114 115 116 117 118 119 120 121 122 123
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");

124 125 126 127 128 129
VIR_ENUM_DECL(qemuSoundCodec)

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

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

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

153

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

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

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

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

199
    virObjectUnref(cfg);
200
    return rc;
201

202
 error:
203 204 205 206 207
    ignore_value(virNetDevMacVLanDeleteWithVPortProfile(
                     res_ifname, &net->mac,
                     virDomainNetGetActualDirectDev(net),
                     virDomainNetGetActualDirectMode(net),
                     virDomainNetGetActualVirtPortProfile(net),
208
                     cfg->stateDir));
209
    VIR_FREE(res_ifname);
210
    virObjectUnref(cfg);
211
    return -1;
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 253
/**
 * 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]);
254 255
    virCommandPassFD(cmd, pair[1],
                     VIR_COMMAND_PASS_FD_CLOSE_PARENT);
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
    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 ||
275
        virCommandWait(cmd, NULL) < 0) {
276 277 278 279
        VIR_FORCE_CLOSE(*tapfd);
        *tapfd = -1;
    }

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

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

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

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

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

        if (fail)
320
            return ret;
321

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

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

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

347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367
    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;
        }
368 369
    }

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

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

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

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

392 393
    ret = 0;

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

405
    return ret;
406 407
}

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

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

    return true;
}

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

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

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

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

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

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

497 498 499 500 501 502 503 504 505 506 507
        /* 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;
            }
508
            VIR_WARN("Unable to open vhost-net. Opened so far %zu, requested %d",
509 510 511
                     i, *vhostfdSize);
            *vhostfdSize = i;
            break;
512
        }
513
    }
514
    virDomainAuditNetDevice(def, net, "/dev/vhost-net", *vhostfdSize);
515
    return 0;
516

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

    return -1;
522 523
}

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

530 531
    for (i = 0; i < def->nnets; i++) {
        virDomainNetDefPtr net = def->nets[i];
532 533 534 535 536 537
        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.
         */
538
        if (networkAllocateActualDevice(def, net) < 0)
539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
            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;
            }
566
            if (virDomainHostdevInsert(def, hostdev) < 0)
567 568 569 570
                goto cleanup;
        }
    }
    ret = 0;
571
 cleanup:
572 573
    return ret;
}
574

575
static int qemuDomainDeviceAliasIndex(const virDomainDeviceInfo *info,
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600
                                      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)
{
601
    char *dev_name;
602

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


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

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


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

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

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

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

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

    return 0;
}

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

    return 0;
737
}
738 739

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

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

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

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

    return 0;
}


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


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

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

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


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

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

    return 0;
}


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

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


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

883 884 885 886 887 888 889 890 891 892 893 894
    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);
895 896
}

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

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

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

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

    return idx;
}


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

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

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

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

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

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

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

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

    return 0;
}

1062

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

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

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

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

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

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

1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118

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

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

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

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

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

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

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

    return ret;
1163
}
1164

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

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

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

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

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

    return 0;
}

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

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

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

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

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

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

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

1287
    ret = 0;
1288

1289
 cleanup:
1290
    return ret;
1291
}
1292 1293


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

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

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

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

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

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

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

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

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

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

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

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

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

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

    return false;
}
1459

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

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

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

        nbuses = max_idx + 1;

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

1489 1490 1491 1492 1493 1494
            /* 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 */
1495
            if (virDomainPCIAddressReserveNextSlot(addrs, &info, flags) < 0)
1496 1497 1498
                goto cleanup;

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

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

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

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

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

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

1543 1544
    ret = 0;

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

    return ret;
}

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

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

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

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

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

1572

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

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

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

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

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

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

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

    return addrs;

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

1630

1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643
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 已提交
1644
        virDomainCCWAddressReleaseAddr(priv->ccwaddrs, info) < 0)
1645 1646 1647 1648
        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) &&
1649 1650
             virDomainPCIAddressReleaseSlot(priv->pciaddrs,
                                            &info->addr.pci) < 0)
1651 1652 1653 1654 1655
        VIR_WARN("Unable to release PCI address on %s",
                 NULLSTR(devstr));
}


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

1663 1664 1665 1666

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

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

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

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

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

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

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


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


1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816
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"));
}


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

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

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

    /* 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;
1890 1891
        if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,
                                           false, false) < 0)
1892
           goto cleanup;
1893 1894
        tmp_addr.function = 3;
        tmp_addr.multi = 0;
1895 1896
        if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,
                                           false, false) < 0)
1897
           goto cleanup;
1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908
    }

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

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

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

1952
        if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
1953 1954 1955 1956
            VIR_DEBUG("PCI address 0:0:1.0 in use, future addition of a video"
                      " device will not be possible without manual"
                      " intervention");
            virResetLastError();
1957
        } else if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0) {
1958
            goto cleanup;
1959 1960
        }
    }
1961
    ret = 0;
1962
 cleanup:
1963 1964
    VIR_FREE(addrStr);
    return ret;
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 2002
/*
 * 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,
2003
                         virDomainPCIAddressSetPtr addrs)
2004 2005
{
    size_t i, j;
2006
    virDomainPCIConnectFlags flags;
2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
    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;
    }
2017

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

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

2057
    flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI;
2058

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

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

    /* Sound cards */
2086
    for (i = 0; i < def->nsounds; i++) {
2087 2088 2089 2090 2091 2092 2093
        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;

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

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

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

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

        /* USB2 needs special handling to put all companions in the same slot */
        if (IS_USB2_CONTROLLER(def->controllers[i])) {
2128
            virDevicePCIAddress addr = { 0, 0, 0, 0, false };
2129
            memset(&tmp_addr, 0, sizeof(tmp_addr));
2130
            for (j = 0; j < i; j++) {
2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143
                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;
2144
                addr.multi = VIR_DEVICE_ADDRESS_PCI_MULTI_ON;
2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156
                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 */
2157
                if (virDomainPCIAddressGetNextSlot(addrs, &tmp_addr, flags) < 0)
2158 2159
                    goto error;

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

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

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

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

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

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

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

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

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

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

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

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

    return 0;

2288
 error:
2289 2290 2291
    return -1;
}

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

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

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

2314
        if (!(devStr = virDomainPCIAddressAsString(&info->addr.pci)))
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 2341
            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;
        }

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

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

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

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

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

#define QEMU_SERIAL_PARAM_ACCEPTED_CHARS \
  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"

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

    return 0;
}

2469 2470 2471 2472
static char *
qemuGetSecretString(virConnectPtr conn,
                    const char *scheme,
                    bool encoded,
2473
                    virStorageAuthDefPtr authdef,
2474 2475 2476 2477 2478
                    virSecretUsageType secretUsageType)
{
    size_t secret_size;
    virSecretPtr sec = NULL;
    char *secret = NULL;
2479
    char uuidStr[VIR_UUID_STRING_BUFLEN];
2480 2481

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

    if (!sec) {
2494
        if (authdef->secretType == VIR_STORAGE_SECRET_TYPE_UUID) {
2495 2496
            virReportError(VIR_ERR_NO_SECRET,
                           _("%s no secret matches uuid '%s'"),
2497
                           scheme, uuidStr);
2498 2499 2500
        } else {
            virReportError(VIR_ERR_NO_SECRET,
                           _("%s no secret matches usage value '%s'"),
2501
                           scheme, authdef->secret.usage);
2502
        }
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 (authdef->secretType == 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
                           authdef->username, uuidStr);
2514 2515 2516 2517
        } else {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("could not get value of the secret for "
                             "username '%s' using usage value '%s'"),
2518
                           authdef->username, authdef->secret.usage);
2519
        }
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
    return -1;
}

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

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

2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640
        if (STRPREFIX(p, "id=")) {
            const char *secrettype;
            /* formulate authdef for disk->src->auth */
            if (VIR_ALLOC(authdef) < 0)
                goto error;

            if (VIR_STRDUP(authdef->username, p + strlen("id=")) < 0)
                goto error;
            secrettype = virSecretUsageTypeToString(VIR_SECRET_USAGE_TYPE_CEPH);
            if (VIR_STRDUP(authdef->secrettype, secrettype) < 0)
                goto error;
            disk->src->auth = authdef;
            authdef = NULL;

            /* Cannot formulate a secretType (eg, usage or uuid) given
             * what is provided.
             */
        }
2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654
        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;
                    }
                }
2655 2656 2657
                if (qemuAddRBDHost(disk, h) < 0)
                    goto error;

2658 2659 2660 2661 2662 2663
                h = sep;
            }
        }

        p = next;
    }
2664
    VIR_FREE(options);
2665 2666
    return 0;

2667
 error:
2668
    VIR_FREE(options);
2669
    virStorageAuthDefFree(authdef);
2670 2671
    return -1;
}
2672

2673
static int
P
Paolo Bonzini 已提交
2674 2675
qemuParseDriveURIString(virDomainDiskDefPtr def, virURIPtr uri,
                        const char *scheme)
2676 2677 2678 2679 2680
{
    int ret = -1;
    char *transp = NULL;
    char *sock = NULL;
    char *volimg = NULL;
2681
    char *secret = NULL;
2682
    virStorageAuthDefPtr authdef = NULL;
2683

2684
    if (VIR_ALLOC(def->src->hosts) < 0)
2685
        goto error;
2686

P
Paolo Bonzini 已提交
2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697
    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) {
2698
        def->src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
P
Paolo Bonzini 已提交
2699
    } else {
2700 2701
        def->src->hosts->transport = virStorageNetHostTransportTypeFromString(transp);
        if (def->src->hosts->transport < 0) {
2702
            virReportError(VIR_ERR_INTERNAL_ERROR,
P
Paolo Bonzini 已提交
2703
                           _("Invalid %s transport type '%s'"), scheme, transp);
2704 2705 2706
            goto error;
        }
    }
2707
    def->src->nhosts = 0; /* set to 1 once everything succeeds */
2708

2709 2710
    if (def->src->hosts->transport != VIR_STORAGE_NET_HOST_TRANS_UNIX) {
        if (VIR_STRDUP(def->src->hosts->name, uri->server) < 0)
2711
            goto error;
2712

2713
        if (virAsprintf(&def->src->hosts->port, "%d", uri->port) < 0)
2714
            goto error;
2715
    } else {
2716 2717
        def->src->hosts->name = NULL;
        def->src->hosts->port = 0;
2718 2719 2720
        if (uri->query) {
            if (STRPREFIX(uri->query, "socket=")) {
                sock = strchr(uri->query, '=') + 1;
2721
                if (VIR_STRDUP(def->src->hosts->socket, sock) < 0)
2722
                    goto error;
2723 2724 2725 2726 2727 2728 2729
            } else {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("Invalid query parameter '%s'"), uri->query);
                goto error;
            }
        }
    }
P
Paolo Bonzini 已提交
2730 2731
    if (uri->path) {
        volimg = uri->path + 1; /* skip the prefix slash */
2732 2733
        VIR_FREE(def->src->path);
        if (VIR_STRDUP(def->src->path, volimg) < 0)
2734
            goto error;
P
Paolo Bonzini 已提交
2735
    } else {
2736
        VIR_FREE(def->src->path);
P
Paolo Bonzini 已提交
2737
    }
2738

2739
    if (uri->user) {
2740 2741 2742 2743 2744
        const char *secrettype;
        /* formulate authdef for disk->src->auth */
        if (VIR_ALLOC(authdef) < 0)
            goto error;

2745 2746 2747 2748
        secret = strchr(uri->user, ':');
        if (secret)
            *secret = '\0';

2749
        if (VIR_STRDUP(authdef->username, uri->user) < 0)
2750
            goto error;
2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762
        if (STREQ(scheme, "iscsi")) {
            secrettype =
                virSecretUsageTypeToString(VIR_SECRET_USAGE_TYPE_ISCSI);
            if (VIR_STRDUP(authdef->secrettype, secrettype) < 0)
                goto error;
        }
        def->src->auth = authdef;
        authdef = NULL;

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

2765
    def->src->nhosts = 1;
2766 2767
    ret = 0;

2768
 cleanup:
2769 2770 2771 2772
    virURIFree(uri);

    return ret;

2773
 error:
2774 2775
    virStorageNetHostDefClear(def->src->hosts);
    VIR_FREE(def->src->hosts);
2776
    virStorageAuthDefFree(authdef);
2777 2778 2779
    goto cleanup;
}

P
Paolo Bonzini 已提交
2780 2781 2782 2783 2784
static int
qemuParseGlusterString(virDomainDiskDefPtr def)
{
    virURIPtr uri = NULL;

2785
    if (!(uri = virURIParse(def->src->path)))
P
Paolo Bonzini 已提交
2786 2787 2788 2789 2790
        return -1;

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

P
Paolo Bonzini 已提交
2791 2792 2793 2794 2795 2796 2797
static int
qemuParseISCSIString(virDomainDiskDefPtr def)
{
    virURIPtr uri = NULL;
    char *slash;
    unsigned lun;

2798
    if (!(uri = virURIParse(def->src->path)))
P
Paolo Bonzini 已提交
2799 2800 2801 2802 2803 2804 2805 2806 2807
        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,
2808
                           _("invalid name '%s' for iSCSI disk"),
2809
                           def->src->path);
P
Paolo Bonzini 已提交
2810 2811 2812 2813 2814 2815 2816
            return -1;
        }
    }

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

2817 2818 2819
static int
qemuParseNBDString(virDomainDiskDefPtr disk)
{
2820
    virStorageNetHostDefPtr h = NULL;
2821
    char *host, *port;
P
Paolo Bonzini 已提交
2822
    char *src;
2823

P
Paolo Bonzini 已提交
2824 2825
    virURIPtr uri = NULL;

2826 2827
    if (strstr(disk->src->path, "://")) {
        if (!(uri = virURIParse(disk->src->path)))
2828 2829
            return -1;
        return qemuParseDriveURIString(disk, uri, "nbd");
P
Paolo Bonzini 已提交
2830 2831
    }

2832
    if (VIR_ALLOC(h) < 0)
2833
        goto error;
2834

2835
    host = disk->src->path + strlen("nbd:");
2836 2837 2838 2839
    if (STRPREFIX(host, "unix:/")) {
        src = strchr(host + strlen("unix:"), ':');
        if (src)
            *src++ = '\0';
2840

2841
        h->transport = VIR_STORAGE_NET_HOST_TRANS_UNIX;
2842 2843
        if (VIR_STRDUP(h->socket, host + strlen("unix:")) < 0)
            goto error;
2844 2845 2846 2847
    } else {
        port = strchr(host, ':');
        if (!port) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
2848
                           _("cannot parse nbd filename '%s'"), disk->src->path);
2849 2850
            goto error;
        }
2851

2852
        *port++ = '\0';
2853 2854
        if (VIR_STRDUP(h->name, host) < 0)
            goto error;
P
Paolo Bonzini 已提交
2855

2856 2857 2858 2859
        src = strchr(port, ':');
        if (src)
            *src++ = '\0';

2860 2861
        if (VIR_STRDUP(h->port, port) < 0)
            goto error;
2862
    }
2863

P
Paolo Bonzini 已提交
2864
    if (src && STRPREFIX(src, "exportname=")) {
2865 2866
        if (VIR_STRDUP(src, strchr(src, '=') + 1) < 0)
            goto error;
P
Paolo Bonzini 已提交
2867 2868 2869 2870
    } else {
        src = NULL;
    }

2871 2872 2873 2874
    VIR_FREE(disk->src->path);
    disk->src->path = src;
    disk->src->nhosts = 1;
    disk->src->hosts = h;
2875 2876
    return 0;

2877
 error:
2878
    virStorageNetHostDefClear(h);
2879 2880 2881 2882
    VIR_FREE(h);
    return -1;
}

2883

2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900
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;
    }

2901
    switch ((virStorageNetProtocol) protocol) {
2902
        case VIR_STORAGE_NET_PROTOCOL_HTTP:
2903 2904
            return 80;

2905
        case VIR_STORAGE_NET_PROTOCOL_HTTPS:
2906 2907
            return 443;

2908
        case VIR_STORAGE_NET_PROTOCOL_FTP:
2909 2910
            return 21;

2911
        case VIR_STORAGE_NET_PROTOCOL_FTPS:
2912 2913
            return 990;

2914
        case VIR_STORAGE_NET_PROTOCOL_TFTP:
2915 2916
            return 69;

2917
        case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
2918 2919
            return 7000;

2920
        case VIR_STORAGE_NET_PROTOCOL_NBD:
2921 2922
            return 10809;

2923 2924
        case VIR_STORAGE_NET_PROTOCOL_ISCSI:
        case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
2925 2926 2927
            /* no default port specified */
            return 0;

2928 2929
        case VIR_STORAGE_NET_PROTOCOL_RBD:
        case VIR_STORAGE_NET_PROTOCOL_LAST:
2930 2931
        case VIR_STORAGE_NET_PROTOCOL_NONE:
            /* not applicable */
2932 2933 2934 2935 2936 2937
            return -1;
    }

    return -1;
}

2938
#define QEMU_DEFAULT_NBD_PORT "10809"
2939

2940
static char *
2941 2942
qemuBuildNetworkDriveURI(int protocol,
                         const char *src,
2943
                         const char *volume,
2944
                         size_t nhosts,
2945
                         virStorageNetHostDefPtr hosts,
2946 2947 2948 2949
                         const char *username,
                         const char *secret)
{
    char *ret = NULL;
2950
    virBuffer buf = VIR_BUFFER_INITIALIZER;
2951
    virURIPtr uri = NULL;
2952
    size_t i;
2953

2954
    switch ((virStorageNetProtocol) protocol) {
2955
        case VIR_STORAGE_NET_PROTOCOL_NBD:
2956 2957 2958
            if (nhosts != 1) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("protocol '%s' accepts only one host"),
2959
                               virStorageNetProtocolTypeToString(protocol));
2960 2961 2962 2963
                goto cleanup;
            }

            if (!((hosts->name && strchr(hosts->name, ':')) ||
2964
                  (hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP &&
2965
                   !hosts->name) ||
2966
                  (hosts->transport == VIR_STORAGE_NET_HOST_TRANS_UNIX &&
2967 2968 2969 2970 2971 2972
                   hosts->socket &&
                   hosts->socket[0] != '/'))) {

                virBufferAddLit(&buf, "nbd:");

                switch (hosts->transport) {
2973
                case VIR_STORAGE_NET_HOST_TRANS_TCP:
2974 2975 2976 2977 2978 2979
                    virBufferStrcat(&buf, hosts->name, NULL);
                    virBufferAsprintf(&buf, ":%s",
                                      hosts->port ? hosts->port :
                                      QEMU_DEFAULT_NBD_PORT);
                    break;

2980
                case VIR_STORAGE_NET_HOST_TRANS_UNIX:
2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993
                    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'"),
2994
                                   virStorageNetHostTransportTypeToString(hosts->transport));
2995 2996 2997 2998 2999 3000
                    goto cleanup;
                }

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

3001
                if (virBufferCheckError(&buf) < 0)
3002 3003 3004 3005 3006 3007 3008 3009
                    goto cleanup;

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

3010 3011 3012 3013 3014 3015 3016
        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:
3017 3018 3019
            if (nhosts != 1) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("protocol '%s' accepts only one host"),
3020
                               virStorageNetProtocolTypeToString(protocol));
3021 3022
                goto cleanup;
            }
3023

3024 3025
            if (VIR_ALLOC(uri) < 0)
                goto cleanup;
3026

3027
            if (hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP) {
3028
                if (VIR_STRDUP(uri->scheme,
3029
                               virStorageNetProtocolTypeToString(protocol)) < 0)
3030 3031 3032
                    goto cleanup;
            } else {
                if (virAsprintf(&uri->scheme, "%s+%s",
3033
                                virStorageNetProtocolTypeToString(protocol),
3034
                                virStorageNetHostTransportTypeToString(hosts->transport)) < 0)
3035 3036
                    goto cleanup;
            }
3037

3038 3039
            if ((uri->port = qemuNetworkDriveGetPort(protocol, hosts->port)) < 0)
                goto cleanup;
3040

3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052
            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;
                }
            }
3053

3054 3055
            if (hosts->socket &&
                virAsprintf(&uri->query, "socket=%s", hosts->socket) < 0)
3056
                goto cleanup;
3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068

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

3071
            ret = virURIFormat(uri);
3072

3073 3074
            break;

3075
        case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098
            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;

3099
        case VIR_STORAGE_NET_PROTOCOL_RBD:
3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134
            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);
                }
            }

3135
            if (virBufferCheckError(&buf) < 0)
3136 3137 3138 3139 3140 3141
                goto cleanup;

            ret = virBufferContentAndReset(&buf);
            break;


3142
        case VIR_STORAGE_NET_PROTOCOL_LAST:
3143
        case VIR_STORAGE_NET_PROTOCOL_NONE:
3144 3145
            goto cleanup;
    }
3146

3147
 cleanup:
3148
    virBufferFreeAndReset(&buf);
3149 3150 3151 3152 3153 3154
    virURIFree(uri);

    return ret;
}


3155
int
3156 3157 3158
qemuGetDriveSourceString(virStorageSourcePtr src,
                         virConnectPtr conn,
                         char **source)
3159
{
3160 3161 3162 3163 3164 3165 3166 3167 3168
    int actualType = virStorageSourceGetActualType(src);
    char *secret = NULL;
    char *username = NULL;
    int ret = -1;

    *source = NULL;

    if (conn) {
        if (actualType == VIR_STORAGE_TYPE_NETWORK &&
3169
            src->auth &&
3170 3171 3172 3173 3174
            (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);
3175
            username = src->auth->username;
3176 3177 3178 3179 3180 3181

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

3183 3184 3185
            if (!(secret = qemuGetSecretString(conn,
                                               protocol,
                                               encode,
3186
                                               src->auth,
3187 3188 3189 3190 3191
                                               secretType)))
                goto cleanup;
        }
    }

3192
    switch ((virStorageType) actualType) {
E
Eric Blake 已提交
3193 3194 3195
    case VIR_STORAGE_TYPE_BLOCK:
    case VIR_STORAGE_TYPE_FILE:
    case VIR_STORAGE_TYPE_DIR:
3196 3197 3198 3199
        if (!src->path) {
            ret = 1;
            goto cleanup;
        }
3200

3201 3202
        if (VIR_STRDUP(*source, src->path) < 0)
            goto cleanup;
3203 3204 3205

        break;

E
Eric Blake 已提交
3206
    case VIR_STORAGE_TYPE_NETWORK:
3207 3208
        if (!(*source = qemuBuildNetworkDriveURI(src->protocol,
                                                 src->path,
3209
                                                 src->volume,
3210 3211 3212 3213 3214
                                                 src->nhosts,
                                                 src->hosts,
                                                 username,
                                                 secret)))
            goto cleanup;
3215 3216
        break;

E
Eric Blake 已提交
3217
    case VIR_STORAGE_TYPE_VOLUME:
3218
    case VIR_STORAGE_TYPE_NONE:
E
Eric Blake 已提交
3219
    case VIR_STORAGE_TYPE_LAST:
3220 3221 3222
        break;
    }

3223
    ret = 0;
3224

3225
 cleanup:
J
John Ferlan 已提交
3226
    VIR_FREE(secret);
3227 3228 3229
    return ret;
}

P
Paolo Bonzini 已提交
3230

3231
char *
3232
qemuBuildDriveStr(virConnectPtr conn,
3233
                  virDomainDiskDefPtr disk,
3234
                  bool bootable,
3235
                  virQEMUCapsPtr qemuCaps)
3236 3237 3238
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;
    const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
3239 3240
    const char *trans =
        virDomainDiskGeometryTransTypeToString(disk->geometry.trans);
3241 3242
    int idx = virDiskNameToIndex(disk->dst);
    int busid = -1, unitid = -1;
3243
    char *source = NULL;
3244
    int actualType = virStorageSourceGetActualType(disk->src);
3245 3246

    if (idx < 0) {
3247 3248
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unsupported disk type '%s'"), disk->dst);
3249 3250 3251 3252 3253 3254
        goto error;
    }

    switch (disk->bus) {
    case VIR_DOMAIN_DISK_BUS_SCSI:
        if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
3255 3256
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("unexpected address type for scsi disk"));
3257 3258 3259 3260 3261 3262 3263
            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) {
3264 3265
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("SCSI controller only supports 1 bus"));
3266 3267 3268 3269 3270 3271 3272 3273
            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) {
3274 3275
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("unexpected address type for ide disk"));
3276 3277 3278 3279
            goto error;
        }
        /* We can only have 1 IDE controller (currently) */
        if (disk->info.addr.drive.controller != 0) {
3280 3281
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Only 1 %s controller is supported"), bus);
3282 3283 3284 3285 3286 3287 3288 3289
            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) {
3290 3291
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("unexpected address type for fdc disk"));
3292 3293 3294 3295
            goto error;
        }
        /* We can only have 1 FDC controller (currently) */
        if (disk->info.addr.drive.controller != 0) {
3296 3297
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Only 1 %s controller is supported"), bus);
3298 3299 3300 3301
            goto error;
        }
        /* We can only have 1 FDC bus (currently) */
        if (disk->info.addr.drive.bus != 0) {
3302 3303
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Only 1 %s bus is supported"), bus);
3304 3305
            goto error;
        }
3306
        if (disk->info.addr.drive.target != 0) {
3307 3308
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("target must be 0 for controller fdc"));
3309 3310
            goto error;
        }
3311 3312 3313 3314 3315 3316 3317 3318 3319
        unitid = disk->info.addr.drive.unit;

        break;

    case VIR_DOMAIN_DISK_BUS_VIRTIO:
        idx = -1;
        break;

    case VIR_DOMAIN_DISK_BUS_XEN:
3320 3321 3322
    case VIR_DOMAIN_DISK_BUS_SD:
        /* Xen and SD have no address type currently, so assign
         * based on index */
3323 3324 3325
        break;
    }

3326
    if (qemuGetDriveSourceString(disk->src, conn, &source) < 0)
3327 3328 3329
        goto error;

    if (source &&
3330 3331 3332
        !((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY ||
           disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
          disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
3333

3334 3335 3336
        virBufferAddLit(&opt, "file=");

        switch (actualType) {
E
Eric Blake 已提交
3337
        case VIR_STORAGE_TYPE_DIR:
3338
            /* QEMU only supports magic FAT format for now */
3339 3340
            if (disk->src->format > 0 &&
                disk->src->format != VIR_STORAGE_FILE_FAT) {
3341 3342
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("unsupported disk driver type for '%s'"),
3343
                               virStorageFileFormatTypeToString(disk->src->format));
3344 3345
                goto error;
            }
3346

3347
            if (!disk->readonly) {
3348 3349
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("cannot create virtual FAT disks in read-write mode"));
3350 3351
                goto error;
            }
3352 3353 3354

            virBufferAddLit(&opt, "fat:");

3355
            if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
3356
                virBufferAddLit(&opt, "floppy:");
3357

3358 3359
            break;

E
Eric Blake 已提交
3360
        case VIR_STORAGE_TYPE_BLOCK:
3361
            if (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN) {
3362
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
3363
                               disk->src->type == VIR_STORAGE_TYPE_VOLUME ?
3364 3365
                               _("tray status 'open' is invalid for block type volume") :
                               _("tray status 'open' is invalid for block type disk"));
3366 3367
                goto error;
            }
3368 3369 3370 3371 3372

            break;

        default:
            break;
3373
        }
3374 3375

        virBufferEscape(&opt, ',', ",", "%s,", source);
3376
    }
3377
    VIR_FREE(source);
3378

3379
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
3380 3381
        virBufferAddLit(&opt, "if=none");
    else
3382
        virBufferAsprintf(&opt, "if=%s", bus);
3383

3384
    if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
3385
        if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
3386
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD))
3387
                virBufferAddLit(&opt, ",media=cdrom");
3388
        } else if (disk->bus == VIR_DOMAIN_DISK_BUS_IDE) {
3389
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_IDE_CD))
3390
                virBufferAddLit(&opt, ",media=cdrom");
3391 3392 3393 3394
        } else {
            virBufferAddLit(&opt, ",media=cdrom");
        }
    }
3395

3396
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
3397
        virBufferAsprintf(&opt, ",id=%s%s", QEMU_DRIVE_HOST_PREFIX, disk->info.alias);
3398 3399 3400
    } else {
        if (busid == -1 && unitid == -1) {
            if (idx != -1)
3401
                virBufferAsprintf(&opt, ",index=%d", idx);
3402 3403
        } else {
            if (busid != -1)
3404
                virBufferAsprintf(&opt, ",bus=%d", busid);
3405
            if (unitid != -1)
3406
                virBufferAsprintf(&opt, ",unit=%d", unitid);
3407 3408 3409
        }
    }
    if (bootable &&
3410
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_BOOT) &&
3411 3412
        (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK ||
         disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) &&
3413 3414 3415
        disk->bus != VIR_DOMAIN_DISK_BUS_IDE)
        virBufferAddLit(&opt, ",boot=on");
    if (disk->readonly &&
3416 3417 3418 3419 3420 3421 3422
        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;
        }
3423
        virBufferAddLit(&opt, ",readonly=on");
3424
    }
3425
    if (disk->transient) {
3426 3427
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("transient disks not supported yet"));
3428 3429
        goto error;
    }
3430 3431
    if (disk->src->format > 0 &&
        disk->src->type != VIR_STORAGE_TYPE_DIR &&
3432
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_FORMAT))
3433
        virBufferAsprintf(&opt, ",format=%s",
3434
                          virStorageFileFormatTypeToString(disk->src->format));
3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449

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

3450
    if (disk->serial &&
3451
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_SERIAL)) {
3452 3453
        if (qemuSafeSerialParamValue(disk->serial) < 0)
            goto error;
3454
        virBufferAsprintf(&opt, ",serial=%s", disk->serial);
3455 3456 3457
    }

    if (disk->cachemode) {
3458 3459
        const char *mode = NULL;

3460
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_V2)) {
3461 3462 3463
            mode = qemuDiskCacheV2TypeToString(disk->cachemode);

            if (disk->cachemode == VIR_DOMAIN_DISK_CACHE_DIRECTSYNC &&
3464
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC)) {
3465 3466 3467
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("disk cache mode 'directsync' is not "
                                 "supported by this QEMU"));
3468
                goto error;
3469
            } else if (disk->cachemode == VIR_DOMAIN_DISK_CACHE_UNSAFE &&
3470
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_UNSAFE)) {
3471 3472 3473
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("disk cache mode 'unsafe' is not "
                                 "supported by this QEMU"));
3474
                goto error;
3475 3476 3477 3478
            }
        } else {
            mode = qemuDiskCacheV1TypeToString(disk->cachemode);
        }
3479

3480
        virBufferAsprintf(&opt, ",cache=%s", mode);
3481 3482 3483 3484
    } else if (disk->shared && !disk->readonly) {
        virBufferAddLit(&opt, ",cache=off");
    }

O
Osier Yang 已提交
3485
    if (disk->copy_on_read) {
3486
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_COPY_ON_READ)) {
O
Osier Yang 已提交
3487 3488 3489
            virBufferAsprintf(&opt, ",copy-on-read=%s",
                              virDomainDiskCopyOnReadTypeToString(disk->copy_on_read));
        } else {
3490 3491
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("copy_on_read is not supported by this QEMU binary"));
O
Osier Yang 已提交
3492 3493 3494 3495
            goto error;
        }
    }

O
Osier Yang 已提交
3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506
    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;
        }
    }

3507
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MONITOR_JSON)) {
3508 3509 3510 3511
        const char *wpolicy = NULL, *rpolicy = NULL;

        if (disk->error_policy)
            wpolicy = virDomainDiskErrorPolicyTypeToString(disk->error_policy);
3512 3513
        if (disk->rerror_policy)
            rpolicy = virDomainDiskErrorPolicyTypeToString(disk->rerror_policy);
3514 3515

        if (disk->error_policy == VIR_DOMAIN_DISK_ERROR_POLICY_ENOSPACE) {
3516 3517 3518
            /* 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.
3519
             */
3520 3521 3522 3523
            wpolicy = "enospc";
        } else if (!rpolicy) {
            /* for other policies, rpolicy can match wpolicy */
            rpolicy = wpolicy;
3524
        }
3525 3526 3527 3528 3529

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

E
Eric Blake 已提交
3532
    if (disk->iomode) {
3533
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_AIO)) {
3534
            virBufferAsprintf(&opt, ",aio=%s",
E
Eric Blake 已提交
3535 3536
                              virDomainDiskIoTypeToString(disk->iomode));
        } else {
3537 3538 3539
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("disk aio mode not supported with this "
                             "QEMU binary"));
E
Eric Blake 已提交
3540 3541 3542 3543
            goto error;
        }
    }

3544
    /* block I/O throttling */
3545 3546 3547 3548 3549 3550
    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) &&
3551
        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE)) {
3552 3553 3554
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("block I/O throttling not supported with this "
                         "QEMU binary"));
3555 3556 3557
        goto error;
    }

3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587
    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);
    }

3588
    if (virBufferCheckError(&opt) < 0)
3589 3590 3591 3592
        goto error;

    return virBufferContentAndReset(&opt);

3593
 error:
3594
    VIR_FREE(source);
3595 3596 3597 3598 3599
    virBufferFreeAndReset(&opt);
    return NULL;
}

char *
3600 3601
qemuBuildDriveDevStr(virDomainDefPtr def,
                     virDomainDiskDefPtr disk,
3602
                     int bootindex,
3603
                     virQEMUCapsPtr qemuCaps)
3604 3605 3606 3607
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;
    const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
    int idx = virDiskNameToIndex(disk->dst);
3608
    int controllerModel;
3609 3610

    if (idx < 0) {
3611 3612
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unsupported disk type '%s'"), disk->dst);
3613 3614 3615
        goto error;
    }

3616 3617 3618 3619 3620 3621 3622 3623 3624
    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;
        }
    }

3625 3626 3627 3628 3629 3630 3631
    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;
    }

3632 3633 3634 3635
    if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
        /* make sure that both the bus and the qemu binary support
         *  type='lun' (SG_IO).
         */
3636 3637
        if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO &&
            disk->bus != VIR_DOMAIN_DISK_BUS_SCSI) {
3638 3639 3640
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("disk device='lun' is not supported for bus='%s'"),
                           bus);
3641 3642
            goto error;
        }
3643 3644
        if (disk->src->type == VIR_STORAGE_TYPE_NETWORK) {
            if (disk->src->protocol != VIR_STORAGE_NET_PROTOCOL_ISCSI) {
3645 3646
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("disk device='lun' is not supported for protocol='%s'"),
3647
                               virStorageNetProtocolTypeToString(disk->src->protocol));
3648 3649
                goto error;
            }
3650
        } else if (!virDomainDiskSourceIsBlockType(disk)) {
3651 3652
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("disk device='lun' is only valid for block type disk source"));
3653 3654
            goto error;
        }
3655
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SG_IO)) {
3656 3657
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("disk device='lun' is not supported by this QEMU"));
3658 3659
            goto error;
        }
3660 3661 3662 3663 3664
        if (disk->wwn) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting wwn is not supported for lun device"));
            goto error;
        }
3665 3666 3667 3668 3669 3670
        if (disk->vendor || disk->product) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting vendor or product is not supported "
                             "for lun device"));
            goto error;
        }
3671 3672
    }

3673 3674
    switch (disk->bus) {
    case VIR_DOMAIN_DISK_BUS_IDE:
3675
        if (disk->info.addr.drive.target != 0) {
3676 3677
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("target must be 0 for ide controller"));
3678 3679
            goto error;
        }
3680

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

3689
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_IDE_CD)) {
3690 3691 3692 3693 3694 3695 3696 3697
            if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
                virBufferAddLit(&opt, "ide-cd");
            else
                virBufferAddLit(&opt, "ide-hd");
        } else {
            virBufferAddLit(&opt, "ide-drive");
        }

3698
        virBufferAsprintf(&opt, ",bus=ide.%d,unit=%d",
3699 3700 3701 3702
                          disk->info.addr.drive.bus,
                          disk->info.addr.drive.unit);
        break;
    case VIR_DOMAIN_DISK_BUS_SCSI:
3703
        if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
3704
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_BLOCK)) {
3705 3706 3707
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("This QEMU doesn't support scsi-block for "
                                 "lun passthrough"));
3708 3709 3710 3711
                goto error;
            }
        }

3712
        if (disk->wwn &&
3713
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_WWN)) {
3714 3715 3716 3717 3718 3719
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting wwn for scsi disk is not supported "
                             "by this QEMU"));
            goto error;
        }

3720 3721 3722 3723
        /* Properties wwn, vendor and product were introduced in the
         * same QEMU release (1.2.0).
         */
        if ((disk->vendor || disk->product) &&
3724
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_WWN)) {
3725 3726 3727 3728 3729 3730
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Setting vendor or product for scsi disk is not "
                             "supported by this QEMU"));
            goto error;
        }

3731
        controllerModel =
H
Han Cheng 已提交
3732 3733
            virDomainDeviceFindControllerModel(def, &disk->info,
                                               VIR_DOMAIN_CONTROLLER_TYPE_SCSI);
3734
        if ((qemuSetSCSIControllerModel(def, qemuCaps, &controllerModel)) < 0)
3735
            goto error;
3736 3737 3738

        if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) {
            if (disk->info.addr.drive.target != 0) {
3739 3740 3741
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("target must be 0 for controller "
                                 "model 'lsilogic'"));
3742 3743 3744
                goto error;
            }

3745
            if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
3746
                virBufferAddLit(&opt, "scsi-block");
3747
            } else {
3748
                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) {
3749 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");
                }
            }

3758 3759 3760 3761 3762
            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 {
3763
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_CHANNEL)) {
3764
                if (disk->info.addr.drive.target > 7) {
3765 3766 3767
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("This QEMU doesn't support target "
                                     "greater than 7"));
3768 3769 3770 3771 3772
                    goto error;
                }

                if ((disk->info.addr.drive.bus != disk->info.addr.drive.unit) &&
                    (disk->info.addr.drive.bus != 0)) {
3773 3774 3775
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("This QEMU only supports both bus and "
                                     "unit equal to 0"));
3776 3777 3778 3779
                    goto error;
                }
            }

3780
            if (disk->device != VIR_DOMAIN_DISK_DEVICE_LUN) {
3781
                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) {
3782 3783 3784 3785 3786 3787 3788 3789
                    if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
                        virBufferAddLit(&opt, "scsi-cd");
                    else
                        virBufferAddLit(&opt, "scsi-hd");
                } else {
                    virBufferAddLit(&opt, "scsi-disk");
                }
            } else {
3790
                virBufferAddLit(&opt, "scsi-block");
3791
            }
3792

3793 3794 3795 3796 3797 3798
            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);
        }
3799
        break;
J
Jim Fehlig 已提交
3800
    case VIR_DOMAIN_DISK_BUS_SATA:
3801
        if (disk->info.addr.drive.bus != 0) {
3802 3803
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("bus must be 0 for ide controller"));
3804 3805 3806
            goto error;
        }
        if (disk->info.addr.drive.target != 0) {
3807 3808
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("target must be 0 for ide controller"));
3809 3810
            goto error;
        }
3811

3812
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_IDE_CD)) {
3813 3814 3815 3816 3817 3818 3819 3820
            if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
                virBufferAddLit(&opt, "ide-cd");
            else
                virBufferAddLit(&opt, "ide-hd");
        } else {
            virBufferAddLit(&opt, "ide-drive");
        }

3821 3822 3823
        if (qemuDomainMachineIsQ35(def) &&
            disk->info.addr.drive.controller == 0) {
            /* Q35 machines have an implicit ahci (sata) controller at
3824 3825 3826
             * 00:1F.2 which for some reason is hardcoded with the id
             * "ide" instead of the seemingly more reasonable "ahci0"
             * or "sata0".
3827
             */
3828
            virBufferAsprintf(&opt, ",bus=ide.%d", disk->info.addr.drive.unit);
3829 3830
        } else {
            /* All other ahci controllers have been created by
3831 3832
             * libvirt, and we gave them the id "ahci${n}" where ${n}
             * is the controller number. So we identify them that way.
3833 3834 3835 3836 3837
             */
            virBufferAsprintf(&opt, ",bus=ahci%d.%d",
                              disk->info.addr.drive.controller,
                              disk->info.addr.drive.unit);
        }
J
Jim Fehlig 已提交
3838
        break;
3839
    case VIR_DOMAIN_DISK_BUS_VIRTIO:
3840 3841 3842 3843
        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) {
3844
            virBufferAddLit(&opt, "virtio-blk-s390");
3845 3846 3847
        } else if (disk->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) {
            virBufferAddLit(&opt, "virtio-blk-device");
3848 3849 3850
        } else {
            virBufferAddLit(&opt, "virtio-blk-pci");
        }
3851
        qemuBuildIoEventFdStr(&opt, disk->ioeventfd, qemuCaps);
3852
        if (disk->event_idx &&
3853
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_EVENT_IDX)) {
3854 3855 3856
            virBufferAsprintf(&opt, ",event_idx=%s",
                              virDomainVirtioEventIdxTypeToString(disk->event_idx));
        }
3857
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SCSI)) {
3858 3859 3860 3861 3862 3863 3864
            /* 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");
        }
3865
        if (qemuBuildDeviceAddressStr(&opt, def, &disk->info, qemuCaps) < 0)
A
Alex Jia 已提交
3866
            goto error;
3867 3868
        break;
    case VIR_DOMAIN_DISK_BUS_USB:
3869 3870 3871 3872 3873 3874 3875
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_STORAGE)) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("This QEMU doesn't support '-device "
                             "usb-storage'"));
            goto error;

        }
3876
        virBufferAddLit(&opt, "usb-storage");
3877

3878
        if (qemuBuildDeviceAddressStr(&opt, def, &disk->info, qemuCaps) < 0)
3879
            goto error;
3880 3881
        break;
    default:
3882 3883
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unsupported disk bus '%s' with device setup"), bus);
3884 3885
        goto error;
    }
3886 3887
    virBufferAsprintf(&opt, ",drive=%s%s", QEMU_DRIVE_HOST_PREFIX, disk->info.alias);
    virBufferAsprintf(&opt, ",id=%s", disk->info.alias);
3888
    if (bootindex && virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX))
3889
        virBufferAsprintf(&opt, ",bootindex=%d", bootindex);
3890
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKIO)) {
V
Viktor Mihajlovski 已提交
3891
        if (disk->blockio.logical_block_size > 0)
3892
            virBufferAsprintf(&opt, ",logical_block_size=%u",
V
Viktor Mihajlovski 已提交
3893 3894
                              disk->blockio.logical_block_size);
        if (disk->blockio.physical_block_size > 0)
3895
            virBufferAsprintf(&opt, ",physical_block_size=%u",
V
Viktor Mihajlovski 已提交
3896
                              disk->blockio.physical_block_size);
3897
    }
3898

3899 3900 3901 3902 3903 3904
    if (disk->wwn) {
        if (STRPREFIX(disk->wwn, "0x"))
            virBufferAsprintf(&opt, ",wwn=%s", disk->wwn);
        else
            virBufferAsprintf(&opt, ",wwn=0x%s", disk->wwn);
    }
3905

3906 3907 3908 3909 3910 3911
    if (disk->vendor)
        virBufferAsprintf(&opt, ",vendor=%s", disk->vendor);

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

3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927
    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;
            }
        }
    }

3928
    if (virBufferCheckError(&opt) < 0)
3929 3930 3931 3932
        goto error;

    return virBufferContentAndReset(&opt);

3933
 error:
3934 3935 3936 3937 3938 3939
    virBufferFreeAndReset(&opt);
    return NULL;
}


char *qemuBuildFSStr(virDomainFSDefPtr fs,
3940
                     virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED)
3941 3942
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;
3943
    const char *driver = qemuDomainFSDriverTypeToString(fs->fsdriver);
3944
    const char *wrpolicy = virDomainFSWrpolicyTypeToString(fs->wrpolicy);
3945 3946

    if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
3947 3948
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("only supports mount filesystem type"));
3949 3950 3951
        goto error;
    }

3952
    if (!driver) {
3953 3954
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Filesystem driver type not supported"));
3955 3956 3957 3958
        goto error;
    }
    virBufferAdd(&opt, driver, -1);

3959 3960 3961 3962
    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");
3963
        } else if (fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH) {
3964
            virBufferAddLit(&opt, ",security_model=passthrough");
3965
        } else if (fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_SQUASH) {
3966 3967 3968 3969 3970 3971
            virBufferAddLit(&opt, ",security_model=none");
        }
    } else {
        /* For other fs drivers, default(passthru) should always
         * be supported */
        if (fs->accessmode != VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH) {
3972 3973
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("only supports passthrough accessmode"));
3974 3975
            goto error;
        }
3976
    }
3977 3978

    if (fs->wrpolicy) {
3979
       if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_FSDEV_WRITEOUT)) {
3980 3981
           virBufferAsprintf(&opt, ",writeout=%s", wrpolicy);
       } else {
3982
           virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
3983 3984 3985 3986 3987
                          _("filesystem writeout not supported"));
           goto error;
       }
    }

3988 3989
    virBufferAsprintf(&opt, ",id=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
    virBufferAsprintf(&opt, ",path=%s", fs->src);
3990

3991
    if (fs->readonly) {
3992
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_FSDEV_READONLY)) {
3993 3994
            virBufferAddLit(&opt, ",readonly");
        } else {
3995 3996 3997
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("readonly filesystem is not supported by this "
                             "QEMU binary"));
3998 3999 4000 4001
            goto error;
        }
    }

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

    return virBufferContentAndReset(&opt);

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


char *
4014 4015
qemuBuildFSDevStr(virDomainDefPtr def,
                  virDomainFSDefPtr fs,
4016
                  virQEMUCapsPtr qemuCaps)
4017 4018 4019 4020
{
    virBuffer opt = VIR_BUFFER_INITIALIZER;

    if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
4021 4022
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("can only passthrough directories"));
4023 4024 4025 4026
        goto error;
    }

    virBufferAddLit(&opt, "virtio-9p-pci");
4027 4028 4029
    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 已提交
4030

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

4034
    if (virBufferCheckError(&opt) < 0)
4035 4036 4037 4038
        goto error;

    return virBufferContentAndReset(&opt);

4039
 error:
4040 4041 4042 4043 4044
    virBufferFreeAndReset(&opt);
    return NULL;
}


4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063
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 已提交
4064 4065
    case VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI:
        return QEMU_CAPS_NEC_USB_XHCI;
4066 4067 4068 4069 4070 4071 4072
    default:
        return -1;
    }
}


static int
4073 4074
qemuBuildUSBControllerDevStr(virDomainDefPtr domainDef,
                             virDomainControllerDefPtr def,
4075
                             virQEMUCapsPtr qemuCaps,
4076 4077 4078
                             virBuffer *buf)
{
    const char *smodel;
4079
    int model, flags;
4080 4081

    model = def->model;
4082

4083
    if (model == -1) {
4084
        if (domainDef->os.arch == VIR_ARCH_PPC64)
4085 4086 4087 4088
            model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI;
        else
            model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI;
    }
4089 4090

    smodel = qemuControllerModelUSBTypeToString(model);
4091
    flags = qemuControllerModelUSBToCaps(model);
4092

4093
    if (flags == -1 || !virQEMUCapsGet(qemuCaps, flags)) {
4094 4095
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("%s not supported in this QEMU binary"), smodel);
4096 4097 4098
        return -1;
    }

4099 4100 4101
    virBufferAsprintf(buf, "%s", smodel);

    if (def->info.mastertype == VIR_DOMAIN_CONTROLLER_MASTER_USB) {
4102
        virBufferAddLit(buf, ",masterbus=");
4103
        qemuUSBId(buf, def->idx);
4104
        virBufferAsprintf(buf, ".0,firstport=%d", def->info.master.usb.startport);
4105
    } else {
4106
        virBufferAddLit(buf, ",id=");
4107
        qemuUSBId(buf, def->idx);
4108 4109
    }

4110 4111 4112
    return 0;
}

4113
char *
4114 4115
qemuBuildControllerDevStr(virDomainDefPtr domainDef,
                          virDomainControllerDefPtr def,
4116
                          virQEMUCapsPtr qemuCaps,
4117
                          int *nusbcontroller)
4118 4119
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4120
    int model;
4121

4122
    if (!(def->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI &&
4123
          def->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI)) {
4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138
        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;
        }
4139 4140
    }

4141 4142
    switch (def->type) {
    case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
4143
        model = def->model;
4144
        if ((qemuSetSCSIControllerModel(domainDef, qemuCaps, &model)) < 0)
4145 4146
            return NULL;

4147
        switch (model) {
4148
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI:
4149 4150 4151 4152 4153
            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");
4154 4155 4156
            else if (def->info.type ==
                     VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
                virBufferAddLit(&buf, "virtio-scsi-device");
4157 4158
            else
                virBufferAddLit(&buf, "virtio-scsi-pci");
4159
            break;
4160
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC:
4161
            virBufferAddLit(&buf, "lsi");
4162 4163 4164 4165
            break;
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI:
            virBufferAddLit(&buf, "spapr-vscsi");
            break;
4166 4167 4168
        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1078:
            virBufferAddLit(&buf, "megasas");
            break;
4169
        default:
4170 4171 4172
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("Unsupported controller model: %s"),
                           virDomainControllerModelSCSITypeToString(def->model));
4173
        }
4174
        virBufferAsprintf(&buf, ",id=scsi%d", def->idx);
4175 4176 4177 4178 4179
        break;

    case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
        if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
            virBufferAddLit(&buf, "virtio-serial-pci");
4180 4181 4182
        } else if (def->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
            virBufferAddLit(&buf, "virtio-serial-ccw");
4183 4184 4185
        } else if (def->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
            virBufferAddLit(&buf, "virtio-serial-s390");
4186 4187 4188
        } else if (def->info.type ==
                   VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) {
            virBufferAddLit(&buf, "virtio-serial-device");
4189 4190 4191
        } else {
            virBufferAddLit(&buf, "virtio-serial");
        }
4192
        virBufferAsprintf(&buf, ",id=" QEMU_VIRTIO_SERIAL_PREFIX "%d",
4193 4194
                          def->idx);
        if (def->opts.vioserial.ports != -1) {
4195
            virBufferAsprintf(&buf, ",max_ports=%d",
4196 4197 4198
                              def->opts.vioserial.ports);
        }
        if (def->opts.vioserial.vectors != -1) {
4199
            virBufferAsprintf(&buf, ",vectors=%d",
4200 4201 4202 4203
                              def->opts.vioserial.vectors);
        }
        break;

E
Eric Blake 已提交
4204
    case VIR_DOMAIN_CONTROLLER_TYPE_CCID:
4205
        virBufferAsprintf(&buf, "usb-ccid,id=ccid%d", def->idx);
E
Eric Blake 已提交
4206 4207
        break;

J
Jim Fehlig 已提交
4208 4209 4210 4211
    case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
        virBufferAsprintf(&buf, "ahci,id=ahci%d", def->idx);
        break;

4212
    case VIR_DOMAIN_CONTROLLER_TYPE_USB:
4213
        if (qemuBuildUSBControllerDevStr(domainDef, def, qemuCaps, &buf) == -1)
4214 4215 4216 4217 4218 4219 4220
            goto error;

        if (nusbcontroller)
            *nusbcontroller += 1;

        break;

4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231
    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;
4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245
        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;
4246
        case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
L
Laine Stump 已提交
4247
        case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
4248
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
L
Laine Stump 已提交
4249
                           _("wrong function called for pci-root/pcie-root"));
4250 4251 4252 4253
            return NULL;
        }
        break;

4254 4255 4256
    /* We always get an IDE controller, whether we want it or not. */
    case VIR_DOMAIN_CONTROLLER_TYPE_IDE:
    default:
4257 4258 4259
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Unknown controller type: %s"),
                       virDomainControllerTypeToString(def->type));
4260 4261 4262
        goto error;
    }

4263 4264
    if (def->queues)
        virBufferAsprintf(&buf, ",num_queues=%u", def->queues);
4265

4266 4267 4268 4269 4270 4271
    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);

4272
    if (qemuBuildDeviceAddressStr(&buf, domainDef, &def->info, qemuCaps) < 0)
4273 4274
        goto error;

4275
    if (virBufferCheckError(&buf) < 0)
4276 4277 4278 4279
        goto error;

    return virBufferContentAndReset(&buf);

4280
 error:
4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291
    virBufferFreeAndReset(&buf);
    return NULL;
}


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

4294 4295 4296 4297 4298 4299 4300 4301 4302
    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 : "")));
4303 4304 4305 4306 4307
    return str;
}


char *
4308 4309
qemuBuildNicDevStr(virDomainDefPtr def,
                   virDomainNetDefPtr net,
4310
                   int vlan,
4311
                   int bootindex,
4312
                   int vhostfdSize,
4313
                   virQEMUCapsPtr qemuCaps)
4314 4315
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4316
    const char *nic = net->model;
4317
    bool usingVirtio = false;
4318
    char macaddr[VIR_MAC_STRING_BUFLEN];
4319

4320 4321
    if (STREQ(net->model, "virtio")) {
        if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)
4322
            nic = "virtio-net-ccw";
4323
        else if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390)
4324
            nic = "virtio-net-s390";
4325 4326
        else if (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
            nic = "virtio-net-device";
4327
        else
4328
            nic = "virtio-net-pci";
4329

4330
        usingVirtio = true;
4331 4332
    }

4333
    virBufferAdd(&buf, nic, -1);
4334
    if (usingVirtio && net->driver.virtio.txmode) {
4335
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_TX_ALG)) {
4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348
            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.
                     */
4349 4350
                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                   _("unrecognized virtio-net-pci 'tx' option"));
4351 4352 4353
                    goto error;
            }
        } else {
4354 4355
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("virtio-net-pci 'tx' option not supported in this QEMU binary"));
4356 4357 4358
            goto error;
        }
    }
4359
    if (usingVirtio) {
4360
        qemuBuildIoEventFdStr(&buf, net->driver.virtio.ioeventfd, qemuCaps);
4361
        if (net->driver.virtio.event_idx &&
4362
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_EVENT_IDX)) {
4363 4364 4365 4366
            virBufferAsprintf(&buf, ",event_idx=%s",
                              virDomainVirtioEventIdxTypeToString(net->driver.virtio.event_idx));
        }
    }
4367 4368
    if (usingVirtio && vhostfdSize > 1) {
        /* As advised at http://www.linux-kvm.org/page/Multiqueue
4369 4370
         * we should add vectors=2*N+2 where N is the vhostfdSize */
        virBufferAsprintf(&buf, ",mq=on,vectors=%d", 2 * vhostfdSize + 2);
4371
    }
4372
    if (vlan == -1)
4373
        virBufferAsprintf(&buf, ",netdev=host%s", net->info.alias);
4374
    else
4375 4376
        virBufferAsprintf(&buf, ",vlan=%d", vlan);
    virBufferAsprintf(&buf, ",id=%s", net->info.alias);
4377 4378
    virBufferAsprintf(&buf, ",mac=%s",
                      virMacAddrFormat(&net->mac, macaddr));
4379
    if (qemuBuildDeviceAddressStr(&buf, def, &net->info, qemuCaps) < 0)
4380
        goto error;
4381
    if (qemuBuildRomStr(&buf, &net->info, qemuCaps) < 0)
4382
       goto error;
4383
    if (bootindex && virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX))
4384
        virBufferAsprintf(&buf, ",bootindex=%d", bootindex);
4385

4386
    if (virBufferCheckError(&buf) < 0)
4387 4388 4389 4390
        goto error;

    return virBufferContentAndReset(&buf);

4391
 error:
4392 4393 4394 4395 4396 4397 4398
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
qemuBuildHostNetStr(virDomainNetDefPtr net,
4399
                    virQEMUDriverPtr driver,
4400 4401
                    char type_sep,
                    int vlan,
4402 4403 4404 4405
                    char **tapfd,
                    int tapfdSize,
                    char **vhostfd,
                    int vhostfdSize)
4406
{
4407
    bool is_tap = false;
4408
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4409
    virDomainNetType netType = virDomainNetGetActualType(net);
4410
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
4411
    size_t i;
4412

4413
    if (net->script && netType != VIR_DOMAIN_NET_TYPE_ETHERNET) {
4414 4415 4416
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("scripts are not supported on interfaces of type %s"),
                       virDomainNetTypeToString(netType));
4417
        virObjectUnref(cfg);
4418 4419 4420 4421
        return NULL;
    }

    switch (netType) {
R
Richa Marwaha 已提交
4422 4423 4424 4425 4426
    /*
     * If type='bridge', and we're running as privileged user
     * or -netdev bridge is not supported then it will fall
     * through, -net tap,fd
     */
4427
    case VIR_DOMAIN_NET_TYPE_BRIDGE:
R
Richa Marwaha 已提交
4428
    case VIR_DOMAIN_NET_TYPE_NETWORK:
4429
    case VIR_DOMAIN_NET_TYPE_DIRECT:
4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442
        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);
            }
        }
4443
        type_sep = ',';
4444
        is_tap = true;
4445 4446 4447 4448 4449
        break;

    case VIR_DOMAIN_NET_TYPE_ETHERNET:
        virBufferAddLit(&buf, "tap");
        if (net->ifname) {
4450
            virBufferAsprintf(&buf, "%cifname=%s", type_sep, net->ifname);
4451 4452
            type_sep = ',';
        }
4453
        if (net->script) {
4454
            virBufferAsprintf(&buf, "%cscript=%s", type_sep,
4455
                              net->script);
4456 4457
            type_sep = ',';
        }
4458
        is_tap = true;
4459 4460 4461
        break;

    case VIR_DOMAIN_NET_TYPE_CLIENT:
4462 4463 4464 4465 4466 4467 4468
       virBufferAsprintf(&buf, "socket%cconnect=%s:%d",
                         type_sep,
                         net->data.socket.address,
                         net->data.socket.port);
       type_sep = ',';
       break;

4469
    case VIR_DOMAIN_NET_TYPE_SERVER:
4470 4471 4472 4473 4474 4475 4476
       virBufferAsprintf(&buf, "socket%clisten=%s:%d",
                         type_sep,
                         net->data.socket.address,
                         net->data.socket.port);
       type_sep = ',';
       break;

4477
    case VIR_DOMAIN_NET_TYPE_MCAST:
4478 4479 4480 4481 4482 4483
       virBufferAsprintf(&buf, "socket%cmcast=%s:%d",
                         type_sep,
                         net->data.socket.address,
                         net->data.socket.port);
       type_sep = ',';
       break;
4484 4485 4486 4487 4488 4489 4490 4491

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

    if (vlan >= 0) {
4492
        virBufferAsprintf(&buf, "%cvlan=%d", type_sep, vlan);
4493
        if (net->info.alias)
4494
            virBufferAsprintf(&buf, ",name=host%s",
4495 4496
                              net->info.alias);
    } else {
4497
        virBufferAsprintf(&buf, "%cid=host%s",
4498 4499 4500
                          type_sep, net->info.alias);
    }

4501
    if (is_tap) {
4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514
        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);
                }
            }
        }
4515
        if (net->tune.sndbuf_specified)
4516
            virBufferAsprintf(&buf, ",sndbuf=%lu", net->tune.sndbuf);
4517 4518
    }

4519 4520
    virObjectUnref(cfg);

4521
    if (virBufferCheckError(&buf) < 0)
4522 4523 4524 4525 4526 4527 4528
        return NULL;

    return virBufferContentAndReset(&buf);
}


char *
4529 4530
qemuBuildWatchdogDevStr(virDomainDefPtr def,
                        virDomainWatchdogDefPtr dev,
4531
                        virQEMUCapsPtr qemuCaps)
4532 4533 4534 4535 4536
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    const char *model = virDomainWatchdogModelTypeToString(dev->model);
    if (!model) {
4537 4538
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("missing watchdog model"));
4539 4540 4541
        goto error;
    }

4542
    virBufferAsprintf(&buf, "%s,id=%s", model, dev->info.alias);
4543
    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
4544 4545
        goto error;

4546
    if (virBufferCheckError(&buf) < 0)
4547 4548 4549 4550
        goto error;

    return virBufferContentAndReset(&buf);

4551
 error:
4552 4553 4554 4555 4556 4557
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
4558 4559
qemuBuildMemballoonDevStr(virDomainDefPtr def,
                          virDomainMemballoonDefPtr dev,
4560
                          virQEMUCapsPtr qemuCaps)
4561 4562 4563
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

4564 4565 4566 4567 4568 4569 4570
    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;
4571 4572 4573
        case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
            virBufferAddLit(&buf, "virtio-balloon-device");
            break;
4574
        default:
4575 4576 4577
            virReportError(VIR_ERR_XML_ERROR,
                           _("memballoon unsupported with address type '%s'"),
                           virDomainDeviceAddressTypeToString(dev->info.type));
4578 4579 4580
            goto error;
    }

4581
    virBufferAsprintf(&buf, ",id=%s", dev->info.alias);
4582
    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
4583 4584
        goto error;

4585
    if (virBufferCheckError(&buf) < 0)
4586 4587 4588 4589
        goto error;

    return virBufferContentAndReset(&buf);

4590
 error:
4591 4592 4593 4594
    virBufferFreeAndReset(&buf);
    return NULL;
}

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

4610
    if (virBufferCheckError(&buf) < 0)
4611 4612 4613 4614
        goto error;

    return virBufferContentAndReset(&buf);

4615
 error:
4616 4617 4618
    virBufferFreeAndReset(&buf);
    return NULL;
}
4619 4620

char *
4621 4622
qemuBuildUSBInputDevStr(virDomainDefPtr def,
                        virDomainInputDefPtr dev,
4623
                        virQEMUCapsPtr qemuCaps)
4624 4625 4626
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639
    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;
    }
4640

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

4644
    if (virBufferCheckError(&buf) < 0)
4645 4646 4647 4648
        goto error;

    return virBufferContentAndReset(&buf);

4649
 error:
4650 4651 4652 4653 4654 4655
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
4656 4657
qemuBuildSoundDevStr(virDomainDefPtr def,
                     virDomainSoundDefPtr sound,
4658
                     virQEMUCapsPtr qemuCaps)
4659 4660 4661 4662 4663
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    const char *model = virDomainSoundModelTypeToString(sound->model);

    if (!model) {
4664 4665
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("invalid sound model"));
4666 4667 4668
        goto error;
    }

4669 4670 4671
    /* Hack for devices with different names in QEMU and libvirt */
    switch (sound->model) {
    case VIR_DOMAIN_SOUND_MODEL_ES1370:
4672
        model = "ES1370";
4673 4674
        break;
    case VIR_DOMAIN_SOUND_MODEL_AC97:
4675
        model = "AC97";
4676 4677
        break;
    case VIR_DOMAIN_SOUND_MODEL_ICH6:
4678
        model = "intel-hda";
4679
        break;
4680 4681 4682 4683 4684 4685 4686 4687 4688
    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;
4689
    }
4690

4691
    virBufferAsprintf(&buf, "%s,id=%s", model, sound->info.alias);
4692
    if (qemuBuildDeviceAddressStr(&buf, def, &sound->info, qemuCaps) < 0)
4693 4694
        goto error;

4695
    if (virBufferCheckError(&buf) < 0)
4696 4697 4698 4699
        goto error;

    return virBufferContentAndReset(&buf);

4700
 error:
4701 4702 4703 4704
    virBufferFreeAndReset(&buf);
    return NULL;
}

4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719

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


4720 4721
static char *
qemuBuildSoundCodecStr(virDomainSoundDefPtr sound,
4722
                       virDomainSoundCodecDefPtr codec,
4723
                       virQEMUCapsPtr qemuCaps)
4724 4725
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4726
    const char *stype;
4727
    int type, flags;
4728

4729 4730
    type = codec->type;
    stype = qemuSoundCodecTypeToString(type);
4731
    flags = qemuSoundCodecTypeToCaps(type);
4732

4733
    if (flags == -1 || !virQEMUCapsGet(qemuCaps, flags)) {
4734 4735
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("%s not supported in this QEMU binary"), stype);
4736 4737 4738
        goto error;
    }

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

4742 4743
    return virBufferContentAndReset(&buf);

4744
 error:
4745 4746 4747
    virBufferFreeAndReset(&buf);
    return NULL;
}
4748 4749

static char *
4750 4751
qemuBuildDeviceVideoStr(virDomainDefPtr def,
                        virDomainVideoDefPtr video,
4752
                        virQEMUCapsPtr qemuCaps,
4753
                        bool primary)
4754 4755
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4756
    const char *model;
4757

4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772
    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;
        }

4773
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL)) {
4774 4775 4776 4777 4778 4779
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("only one video card is currently supported"));
            goto error;
        }

        model = "qxl";
4780 4781
    }

4782
    virBufferAsprintf(&buf, "%s,id=%s", model, video->info.alias);
4783 4784

    if (video->type == VIR_DOMAIN_VIDEO_TYPE_QXL) {
4785
        if (video->vram > (UINT_MAX / 1024)) {
4786
            virReportError(VIR_ERR_OVERFLOW,
4787 4788
                           _("value for 'vram' must be less than '%u'"),
                           UINT_MAX / 1024);
4789 4790
            goto error;
        }
4791 4792 4793 4794 4795 4796 4797 4798 4799
        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);
4800

4801
        /* QEMU accepts bytes for vram_size. */
4802
        virBufferAsprintf(&buf, ",vram_size=%u", video->vram * 1024);
4803 4804
    }

4805
    if (qemuBuildDeviceAddressStr(&buf, def, &video->info, qemuCaps) < 0)
4806 4807
        goto error;

4808
    if (virBufferCheckError(&buf) < 0)
4809 4810 4811 4812
        goto error;

    return virBufferContentAndReset(&buf);

4813
 error:
4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825
    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",
4826 4827 4828
                    dev->source.subsys.u.pci.addr.domain,
                    dev->source.subsys.u.pci.addr.bus,
                    dev->source.subsys.u.pci.addr.slot,
4829
                    dev->source.subsys.u.pci.addr.function) < 0)
4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842
        return -1;

    configfd = open(path, O_RDWR, 0);

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

    VIR_FREE(path);

    return configfd;
}

char *
4843 4844 4845
qemuBuildPCIHostdevDevStr(virDomainDefPtr def,
                          virDomainHostdevDefPtr dev,
                          const char *configfd,
4846
                          virQEMUCapsPtr qemuCaps)
4847 4848
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4849
    int backend = dev->source.subsys.u.pci.backend;
4850

4851
    /* caller has to assign proper passthrough backend type */
4852
    switch ((virDomainHostdevSubsysPCIBackendType) backend) {
4853
    case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
4854 4855 4856
        virBufferAddLit(&buf, "pci-assign");
        if (configfd && *configfd)
            virBufferAsprintf(&buf, ",configfd=%s", configfd);
4857 4858 4859 4860 4861 4862
        break;

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

4863
    default:
4864 4865
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("invalid PCI passthrough type '%s'"),
4866
                       virDomainHostdevSubsysPCIBackendTypeToString(backend));
4867
        break;
4868
    }
4869

4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881
    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",
4882 4883 4884
                      dev->source.subsys.u.pci.addr.bus,
                      dev->source.subsys.u.pci.addr.slot,
                      dev->source.subsys.u.pci.addr.function);
4885 4886 4887
    virBufferAsprintf(&buf, ",id=%s", dev->info->alias);
    if (dev->info->bootIndex)
        virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);
4888
    if (qemuBuildDeviceAddressStr(&buf, def, dev->info, qemuCaps) < 0)
4889
        goto error;
4890
    if (qemuBuildRomStr(&buf, dev->info, qemuCaps) < 0)
4891
       goto error;
4892

4893
    if (virBufferCheckError(&buf) < 0)
4894 4895 4896 4897
        goto error;

    return virBufferContentAndReset(&buf);

4898
 error:
4899 4900 4901 4902 4903 4904
    virBufferFreeAndReset(&buf);
    return NULL;
}


char *
4905 4906
qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev,
                             virQEMUCapsPtr qemuCaps)
4907 4908 4909
{
    char *ret = NULL;

4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929
    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:
4930 4931 4932 4933
    return ret;
}


4934
char *
4935 4936
qemuBuildRedirdevDevStr(virDomainDefPtr def,
                        virDomainRedirdevDefPtr dev,
4937
                        virQEMUCapsPtr qemuCaps)
4938
{
4939
    size_t i;
4940
    virBuffer buf = VIR_BUFFER_INITIALIZER;
4941
    virDomainRedirFilterDefPtr redirfilter = def->redirfilter;
4942 4943

    if (dev->bus != VIR_DOMAIN_REDIRDEV_BUS_USB) {
4944 4945 4946
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Redirection bus %s is not supported by QEMU"),
                       virDomainRedirdevBusTypeToString(dev->bus));
4947 4948 4949
        goto error;
    }

4950
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_REDIR)) {
4951 4952 4953
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("USB redirection is not supported "
                         "by this version of QEMU"));
4954 4955 4956 4957 4958 4959 4960
        goto error;
    }

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

4961
    if (redirfilter && redirfilter->nusbdevs) {
4962
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_REDIR_FILTER)) {
4963 4964 4965 4966 4967 4968
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("USB redirection filter is not "
                             "supported by this version of QEMU"));
            goto error;
        }

4969
        virBufferAddLit(&buf, ",filter=");
4970 4971

        for (i = 0; i < redirfilter->nusbdevs; i++) {
4972
            virDomainRedirFilterUSBDevDefPtr usbdev = redirfilter->usbdevs[i];
4973 4974 4975
            if (usbdev->usbClass >= 0)
                virBufferAsprintf(&buf, "0x%02X:", usbdev->usbClass);
            else
4976
                virBufferAddLit(&buf, "-1:");
4977 4978 4979 4980

            if (usbdev->vendor >= 0)
                virBufferAsprintf(&buf, "0x%04X:", usbdev->vendor);
            else
4981
                virBufferAddLit(&buf, "-1:");
4982 4983 4984 4985

            if (usbdev->product >= 0)
                virBufferAsprintf(&buf, "0x%04X:", usbdev->product);
            else
4986
                virBufferAddLit(&buf, "-1:");
4987 4988 4989 4990

            if (usbdev->version >= 0)
                virBufferAsprintf(&buf, "0x%04X:", usbdev->version);
            else
4991
                virBufferAddLit(&buf, "-1:");
4992 4993 4994

            virBufferAsprintf(&buf, "%u", usbdev->allow);
            if (i < redirfilter->nusbdevs -1)
4995
                virBufferAddLit(&buf, "|");
4996 4997 4998
        }
    }

4999
    if (dev->info.bootIndex) {
5000
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_REDIR_BOOTINDEX)) {
5001 5002 5003 5004 5005 5006 5007 5008
            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);
    }

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

5012
    if (virBufferCheckError(&buf) < 0)
5013 5014 5015 5016
        goto error;

    return virBufferContentAndReset(&buf);

5017
 error:
5018 5019 5020 5021
    virBufferFreeAndReset(&buf);
    return NULL;
}

5022
char *
5023 5024
qemuBuildUSBHostdevDevStr(virDomainDefPtr def,
                          virDomainHostdevDefPtr dev,
5025
                          virQEMUCapsPtr qemuCaps)
5026
{
5027
    virBuffer buf = VIR_BUFFER_INITIALIZER;
5028

5029 5030
    if (!dev->missing &&
        !dev->source.subsys.u.usb.bus &&
5031
        !dev->source.subsys.u.usb.device) {
5032 5033
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("USB host device is missing bus/device information"));
5034 5035 5036
        return NULL;
    }

5037 5038 5039 5040 5041 5042 5043
    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);
5044 5045
    if (dev->info->bootIndex)
        virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);
5046

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

5050
    if (virBufferCheckError(&buf) < 0)
5051
        goto error;
5052

5053 5054
    return virBufferContentAndReset(&buf);

5055
 error:
5056 5057
    virBufferFreeAndReset(&buf);
    return NULL;
5058 5059 5060
}


M
Marc-André Lureau 已提交
5061
char *
5062 5063
qemuBuildHubDevStr(virDomainDefPtr def,
                   virDomainHubDefPtr dev,
5064
                   virQEMUCapsPtr qemuCaps)
M
Marc-André Lureau 已提交
5065 5066 5067 5068
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

    if (dev->type != VIR_DOMAIN_HUB_TYPE_USB) {
5069 5070 5071
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("hub type %s not supported"),
                       virDomainHubTypeToString(dev->type));
M
Marc-André Lureau 已提交
5072 5073 5074
        goto error;
    }

5075
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_HUB)) {
5076
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
5077
                       _("usb-hub not supported by QEMU binary"));
M
Marc-André Lureau 已提交
5078 5079 5080 5081 5082
        goto error;
    }

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

5086
    if (virBufferCheckError(&buf) < 0)
M
Marc-André Lureau 已提交
5087 5088 5089 5090
        goto error;

    return virBufferContentAndReset(&buf);

5091
 error:
M
Marc-André Lureau 已提交
5092 5093 5094 5095 5096
    virBufferFreeAndReset(&buf);
    return NULL;
}


5097
char *
5098
qemuBuildUSBHostdevUSBDevStr(virDomainHostdevDefPtr dev)
5099 5100 5101
{
    char *ret = NULL;

5102 5103 5104 5105 5106 5107
    if (dev->missing) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("This QEMU doesn't not support missing USB devices"));
        return NULL;
    }

5108 5109
    if (!dev->source.subsys.u.usb.bus &&
        !dev->source.subsys.u.usb.device) {
5110 5111
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("USB host device is missing bus/device information"));
5112 5113 5114
        return NULL;
    }

5115 5116 5117
    ignore_value(virAsprintf(&ret, "host:%d.%d",
                             dev->source.subsys.u.usb.bus,
                             dev->source.subsys.u.usb.device));
5118 5119 5120
    return ret;
}

5121 5122
char *
qemuBuildSCSIHostdevDrvStr(virDomainHostdevDefPtr dev,
5123 5124
                           virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED,
                           qemuBuildCommandLineCallbacksPtr callbacks)
5125 5126 5127 5128
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    char *sg = NULL;

5129 5130
    sg = (callbacks->qemuGetSCSIDeviceSgName)(NULL,
                                              dev->source.subsys.u.scsi.adapter,
5131 5132 5133 5134
                                              dev->source.subsys.u.scsi.bus,
                                              dev->source.subsys.u.scsi.target,
                                              dev->source.subsys.u.scsi.unit);
    if (!sg)
5135 5136 5137 5138 5139 5140 5141
        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 已提交
5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152
    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;
        }
    }

5153
    if (virBufferCheckError(&buf) < 0)
5154 5155 5156 5157
        goto error;

    VIR_FREE(sg);
    return virBufferContentAndReset(&buf);
5158
 error:
5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174
    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);

5175
    if (qemuSetSCSIControllerModel(def, qemuCaps, &model) < 0)
5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207
        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);
    }
5208

5209 5210 5211 5212
    virBufferAsprintf(&buf, ",drive=%s-%s,id=%s",
                      virDomainDeviceAddressTypeToString(dev->info->type),
                      dev->info->alias, dev->info->alias);

5213 5214 5215
    if (dev->info->bootIndex)
        virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);

5216
    if (virBufferCheckError(&buf) < 0)
5217 5218 5219
        goto error;

    return virBufferContentAndReset(&buf);
5220
 error:
5221 5222 5223
    virBufferFreeAndReset(&buf);
    return NULL;
}
5224 5225 5226

/* This function outputs a -chardev command line option which describes only the
 * host side of the character device */
5227
static char *
5228
qemuBuildChrChardevStr(virDomainChrSourceDefPtr dev, const char *alias,
5229
                       virQEMUCapsPtr qemuCaps)
5230 5231 5232 5233
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    bool telnet;

5234
    switch (dev->type) {
5235
    case VIR_DOMAIN_CHR_TYPE_NULL:
5236
        virBufferAsprintf(&buf, "null,id=char%s", alias);
5237 5238 5239
        break;

    case VIR_DOMAIN_CHR_TYPE_VC:
5240
        virBufferAsprintf(&buf, "vc,id=char%s", alias);
5241 5242 5243
        break;

    case VIR_DOMAIN_CHR_TYPE_PTY:
5244
        virBufferAsprintf(&buf, "pty,id=char%s", alias);
5245 5246 5247
        break;

    case VIR_DOMAIN_CHR_TYPE_DEV:
5248 5249 5250
        virBufferAsprintf(&buf, "%s,id=char%s,path=%s",
                          STRPREFIX(alias, "parallel") ? "parport" : "tty",
                          alias, dev->data.file.path);
5251 5252 5253
        break;

    case VIR_DOMAIN_CHR_TYPE_FILE:
5254
        virBufferAsprintf(&buf, "file,id=char%s,path=%s", alias,
5255
                          dev->data.file.path);
5256 5257 5258
        break;

    case VIR_DOMAIN_CHR_TYPE_PIPE:
5259
        virBufferAsprintf(&buf, "pipe,id=char%s,path=%s", alias,
5260
                          dev->data.file.path);
5261 5262 5263
        break;

    case VIR_DOMAIN_CHR_TYPE_STDIO:
5264
        virBufferAsprintf(&buf, "stdio,id=char%s", alias);
5265 5266
        break;

5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278
    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";

5279
        virBufferAsprintf(&buf,
5280 5281
                          "udp,id=char%s,host=%s,port=%s,localaddr=%s,"
                          "localport=%s",
5282
                          alias,
5283
                          connectHost,
5284
                          dev->data.udp.connectService,
5285
                          bindHost, bindService);
5286
        break;
5287
    }
5288 5289
    case VIR_DOMAIN_CHR_TYPE_TCP:
        telnet = dev->data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET;
5290
        virBufferAsprintf(&buf,
5291
                          "socket,id=char%s,host=%s,port=%s%s%s",
5292
                          alias,
5293 5294 5295 5296 5297 5298 5299
                          dev->data.tcp.host,
                          dev->data.tcp.service,
                          telnet ? ",telnet" : "",
                          dev->data.tcp.listen ? ",server,nowait" : "");
        break;

    case VIR_DOMAIN_CHR_TYPE_UNIX:
5300
        virBufferAsprintf(&buf,
5301
                          "socket,id=char%s,path=%s%s",
5302
                          alias,
5303 5304 5305
                          dev->data.nix.path,
                          dev->data.nix.listen ? ",server,nowait" : "");
        break;
5306 5307

    case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
5308
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_SPICEVMC)) {
5309
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
5310
                           _("spicevmc not supported in this QEMU binary"));
5311 5312
            goto error;
        }
5313
        virBufferAsprintf(&buf, "spicevmc,id=char%s,name=%s", alias,
E
Eric Blake 已提交
5314
                          virDomainChrSpicevmcTypeToString(dev->data.spicevmc));
5315 5316
        break;

5317 5318 5319 5320 5321 5322 5323 5324 5325 5326
    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;

5327
    default:
5328 5329 5330
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unsupported chardev '%s'"),
                       virDomainChrTypeToString(dev->type));
5331
        goto error;
5332 5333
    }

5334
    if (virBufferCheckError(&buf) < 0)
5335 5336 5337 5338
        goto error;

    return virBufferContentAndReset(&buf);

5339
 error:
5340 5341 5342 5343 5344
    virBufferFreeAndReset(&buf);
    return NULL;
}


5345 5346
static char *
qemuBuildChrArgStr(virDomainChrSourceDefPtr dev, const char *prefix)
5347 5348 5349 5350 5351 5352
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

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

5353
    switch ((virDomainChrType)dev->type) {
5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370
    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:
5371
        virBufferAsprintf(&buf, "file:%s", dev->data.file.path);
5372 5373 5374
        break;

    case VIR_DOMAIN_CHR_TYPE_PIPE:
5375
        virBufferAsprintf(&buf, "pipe:%s", dev->data.file.path);
5376 5377 5378 5379 5380 5381
        break;

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

5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393
    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";

5394
        virBufferAsprintf(&buf, "udp:%s:%s@%s:%s",
5395
                          connectHost,
5396
                          dev->data.udp.connectService,
5397 5398
                          bindHost,
                          bindService);
5399
        break;
5400
    }
5401 5402
    case VIR_DOMAIN_CHR_TYPE_TCP:
        if (dev->data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET) {
5403
            virBufferAsprintf(&buf, "telnet:%s:%s%s",
5404 5405 5406 5407
                              dev->data.tcp.host,
                              dev->data.tcp.service,
                              dev->data.tcp.listen ? ",server,nowait" : "");
        } else {
5408
            virBufferAsprintf(&buf, "tcp:%s:%s%s",
5409 5410 5411 5412 5413 5414 5415
                              dev->data.tcp.host,
                              dev->data.tcp.service,
                              dev->data.tcp.listen ? ",server,nowait" : "");
        }
        break;

    case VIR_DOMAIN_CHR_TYPE_UNIX:
5416
        virBufferAsprintf(&buf, "unix:%s%s",
5417 5418 5419
                          dev->data.nix.path,
                          dev->data.nix.listen ? ",server,nowait" : "");
        break;
5420

5421
    case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
5422
    case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
5423
    case VIR_DOMAIN_CHR_TYPE_NMDM:
5424
    case VIR_DOMAIN_CHR_TYPE_LAST:
5425
        break;
5426 5427
    }

5428
    if (virBufferCheckError(&buf) < 0)
5429 5430 5431 5432
        goto error;

    return virBufferContentAndReset(&buf);

5433
 error:
5434 5435 5436 5437 5438
    virBufferFreeAndReset(&buf);
    return NULL;
}


5439 5440
static char *
qemuBuildVirtioSerialPortDevStr(virDomainChrDefPtr dev,
5441
                                virQEMUCapsPtr qemuCaps)
5442 5443
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
5444 5445
    switch (dev->deviceType) {
    case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE:
5446
        virBufferAddLit(&buf, "virtconsole");
5447 5448 5449 5450
        break;
    case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL:
        /* Legacy syntax  '-device spicevmc' */
        if (dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC &&
5451
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC)) {
5452 5453 5454 5455 5456 5457
            virBufferAddLit(&buf, "spicevmc");
        } else {
            virBufferAddLit(&buf, "virtserialport");
        }
        break;
    default:
5458 5459
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Cannot use virtio serial for parallel/serial devices"));
5460 5461
        return NULL;
    }
5462

5463
    if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
5464
        dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW &&
5465
        dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
5466 5467 5468 5469
        /* Check it's a virtio-serial address */
        if (dev->info.type !=
            VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL)
        {
5470 5471
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("virtio serial device has invalid address type"));
5472 5473 5474
            goto error;
        }

5475
        virBufferAsprintf(&buf,
5476 5477 5478
                          ",bus=" QEMU_VIRTIO_SERIAL_PREFIX "%d.%d",
                          dev->info.addr.vioserial.controller,
                          dev->info.addr.vioserial.bus);
5479
        virBufferAsprintf(&buf,
5480 5481 5482 5483
                          ",nr=%d",
                          dev->info.addr.vioserial.port);
    }

5484 5485
    if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
        dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC &&
5486 5487
        dev->target.name &&
        STRNEQ(dev->target.name, "com.redhat.spice.0")) {
5488 5489 5490
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("Unsupported spicevmc target name '%s'"),
                       dev->target.name);
5491 5492
        goto error;
    }
5493 5494 5495

    if (!(dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
          dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC &&
5496
          virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC))) {
5497
        virBufferAsprintf(&buf, ",chardev=char%s,id=%s",
5498
                          dev->info.alias, dev->info.alias);
5499 5500 5501
        if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL) {
            virBufferAsprintf(&buf, ",name=%s", dev->target.name
                              ? dev->target.name : "com.redhat.spice.0");
5502
        }
5503 5504
    } else {
        virBufferAsprintf(&buf, ",id=%s", dev->info.alias);
5505
    }
5506
    if (virBufferCheckError(&buf) < 0)
5507 5508 5509 5510
        goto error;

    return virBufferContentAndReset(&buf);

5511
 error:
5512 5513 5514 5515
    virBufferFreeAndReset(&buf);
    return NULL;
}

5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535
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);
5536
    if (virBufferCheckError(&buf) < 0)
5537 5538 5539 5540
        goto error;

    return virBufferContentAndReset(&buf);

5541
 error:
5542 5543 5544 5545
    virBufferFreeAndReset(&buf);
    return NULL;
}

5546 5547 5548 5549 5550 5551 5552

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

5556
    switch ((virDomainRNGBackend) dev->backend) {
5557 5558 5559 5560
    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 "
5561
                             "backend"));
5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573
            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:
5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590

        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);
5591 5592 5593 5594 5595 5596 5597 5598
        break;

    case VIR_DOMAIN_RNG_BACKEND_LAST:
        break;
    }

    ret = 0;

5599
 cleanup:
5600
    virBufferFreeAndReset(&buf);
5601
    VIR_FREE(backend);
5602 5603 5604 5605 5606 5607
    return ret;
}


static int
qemuBuildRNGDeviceArgs(virCommandPtr cmd,
5608
                       virDomainDefPtr def,
5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622
                       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;
    }

5623 5624 5625 5626
    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);
5627 5628
    else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO)
        virBufferAsprintf(&buf, "virtio-rng-device,rng=%s", dev->info.alias);
5629 5630
    else
        virBufferAsprintf(&buf, "virtio-rng-pci,rng=%s", dev->info.alias);
5631

5632 5633 5634 5635 5636 5637 5638 5639
    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");
    }

5640
    if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
5641 5642 5643 5644 5645 5646 5647
        goto cleanup;

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

    ret = 0;

5648
 cleanup:
5649 5650 5651 5652 5653
    virBufferFreeAndReset(&buf);
    return ret;
}


E
Eric Blake 已提交
5654
static char *qemuBuildTPMBackendStr(const virDomainDef *def,
5655 5656 5657
                                    virQEMUCapsPtr qemuCaps,
                                    const char *emulator)
{
E
Eric Blake 已提交
5658
    const virDomainTPMDef *tpm = def->tpm;
5659 5660
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    const char *type = virDomainTPMBackendTypeToString(tpm->type);
5661 5662
    char *cancel_path;
    const char *tpmdev;
5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686

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

5687
    if (virBufferCheckError(&buf) < 0)
5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703
        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 已提交
5704
static char *qemuBuildTPMDevStr(const virDomainDef *def,
5705 5706 5707 5708
                                virQEMUCapsPtr qemuCaps,
                                const char *emulator)
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;
E
Eric Blake 已提交
5709
    const virDomainTPMDef *tpm = def->tpm;
5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722
    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);

5723
    if (virBufferCheckError(&buf) < 0)
5724 5725 5726 5727 5728 5729 5730 5731 5732 5733
        goto error;

    return virBufferContentAndReset(&buf);

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


5734 5735 5736 5737 5738 5739
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))
5740
        return NULL;
5741 5742 5743 5744 5745

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

    /* 0:Vendor */
    if (def->bios_vendor)
5746
        virBufferAsprintf(&buf, ",vendor=%s", def->bios_vendor);
5747 5748
    /* 0:BIOS Version */
    if (def->bios_version)
5749
        virBufferAsprintf(&buf, ",version=%s", def->bios_version);
5750 5751
    /* 0:BIOS Release Date */
    if (def->bios_date)
5752
        virBufferAsprintf(&buf, ",date=%s", def->bios_date);
5753 5754
    /* 0:System BIOS Major Release and 0:System BIOS Minor Release */
    if (def->bios_release)
5755
        virBufferAsprintf(&buf, ",release=%s", def->bios_release);
5756

5757
    if (virBufferCheckError(&buf) < 0)
5758 5759 5760 5761
        goto error;

    return virBufferContentAndReset(&buf);

5762
 error:
5763
    virBufferFreeAndReset(&buf);
5764
    return NULL;
5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780
}

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)
5781
        virBufferAsprintf(&buf, ",manufacturer=%s",
5782 5783 5784
                          def->system_manufacturer);
     /* 1:Product Name */
    if (def->system_product)
5785
        virBufferAsprintf(&buf, ",product=%s", def->system_product);
5786 5787
    /* 1:Version */
    if (def->system_version)
5788
        virBufferAsprintf(&buf, ",version=%s", def->system_version);
5789 5790
    /* 1:Serial Number */
    if (def->system_serial)
5791
        virBufferAsprintf(&buf, ",serial=%s", def->system_serial);
5792 5793
    /* 1:UUID */
    if (def->system_uuid && !skip_uuid)
5794
        virBufferAsprintf(&buf, ",uuid=%s", def->system_uuid);
5795 5796
    /* 1:SKU Number */
    if (def->system_sku)
5797
        virBufferAsprintf(&buf, ",sku=%s", def->system_sku);
5798 5799
    /* 1:Family */
    if (def->system_family)
5800
        virBufferAsprintf(&buf, ",family=%s", def->system_family);
5801

5802
    if (virBufferCheckError(&buf) < 0)
5803 5804 5805 5806
        goto error;

    return virBufferContentAndReset(&buf);

5807
 error:
5808
    virBufferFreeAndReset(&buf);
5809
    return NULL;
5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830
}

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;

5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849
        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;
5850
        }
5851

5852 5853 5854
        now += def->data.variable.adjustment;
        gmtime_r(&now, &nowbits);

5855 5856 5857 5858 5859 5860 5861 5862
        /* 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;

5863
        virBufferAsprintf(&buf, "base=%d-%02d-%02dT%02d:%02d:%02d",
5864 5865 5866 5867 5868 5869 5870 5871 5872
                          nowbits.tm_year + 1900,
                          nowbits.tm_mon + 1,
                          nowbits.tm_mday,
                          nowbits.tm_hour,
                          nowbits.tm_min,
                          nowbits.tm_sec);
    }   break;

    default:
5873 5874 5875
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unsupported clock offset '%s'"),
                       virDomainClockOffsetTypeToString(def->offset));
5876 5877 5878 5879
        goto error;
    }

    /* Look for an 'rtc' timer element, and add in appropriate clock= and driftfix= */
5880
    size_t i;
5881 5882 5883 5884 5885 5886
    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:
5887 5888 5889
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("unsupported rtc timer track '%s'"),
                               virDomainTimerTrackTypeToString(def->timers[i]->track));
5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910
                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:
5911 5912 5913
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("unsupported rtc timer tickpolicy '%s'"),
                               virDomainTimerTickpolicyTypeToString(def->timers[i]->tickpolicy));
5914 5915 5916 5917 5918 5919
                goto error;
            }
            break; /* no need to check other timers - there is only one rtc */
        }
    }

5920
    if (virBufferCheckError(&buf) < 0)
5921 5922 5923 5924
        goto error;

    return virBufferContentAndReset(&buf);

5925
 error:
5926 5927 5928 5929 5930 5931
    virBufferFreeAndReset(&buf);
    return NULL;
}


static int
E
Eric Blake 已提交
5932 5933
qemuBuildCpuArgStr(virQEMUDriverPtr driver,
                   const virDomainDef *def,
5934
                   const char *emulator,
5935
                   virQEMUCapsPtr qemuCaps,
5936
                   virArch hostarch,
5937
                   char **opt,
5938 5939
                   bool *hasHwVirt,
                   bool migrating)
5940
{
5941
    virCPUDefPtr host = NULL;
5942
    virCPUDefPtr guest = NULL;
5943
    virCPUDefPtr cpu = NULL;
5944
    size_t ncpus = 0;
5945
    char **cpus = NULL;
5946
    const char *default_model;
5947
    virCPUDataPtr data = NULL;
5948
    bool have_cpu = false;
5949
    char *compare_msg = NULL;
5950 5951
    int ret = -1;
    virBuffer buf = VIR_BUFFER_INITIALIZER;
5952
    size_t i;
5953
    virCapsPtr caps = NULL;
5954 5955 5956

    *hasHwVirt = false;

5957 5958 5959 5960 5961
    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
        goto cleanup;

    host = caps->host.cpu;

5962
    if (def->os.arch == VIR_ARCH_I686)
5963 5964 5965 5966
        default_model = "qemu32";
    else
        default_model = "qemu64";

5967 5968
    if (def->cpu &&
        (def->cpu->mode != VIR_CPU_MODE_CUSTOM || def->cpu->model)) {
5969 5970 5971
        virCPUCompareResult cmp;
        const char *preferred;

5972
        if (!host ||
J
Jiri Denemark 已提交
5973
            !host->model ||
5974
            (ncpus = virQEMUCapsGetCPUDefinitions(qemuCaps, &cpus)) == 0) {
5975 5976
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("CPU specification not supported by hypervisor"));
5977 5978 5979
            goto cleanup;
        }

5980 5981 5982 5983 5984 5985 5986 5987
        if (!(cpu = virCPUDefCopy(def->cpu)))
            goto cleanup;

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

5988
        cmp = cpuGuestData(host, cpu, &data, &compare_msg);
5989 5990
        switch (cmp) {
        case VIR_CPU_COMPARE_INCOMPATIBLE:
5991
            if (compare_msg) {
5992 5993 5994
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("guest and host CPU are not compatible: %s"),
                               compare_msg);
5995
            } else {
5996 5997
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("guest CPU is not compatible with host CPU"));
5998
            }
5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009
            /* 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
         */
6010 6011 6012 6013 6014 6015 6016
        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;
        }
6017

6018 6019
        if (cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) {
            const char *mode = virCPUModeTypeToString(cpu->mode);
6020
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_HOST)) {
6021 6022 6023
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("CPU mode '%s' is not supported by QEMU"
                                 " binary"), mode);
6024 6025 6026
                goto cleanup;
            }
            if (def->virtType != VIR_DOMAIN_VIRT_KVM) {
6027 6028 6029
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("CPU mode '%s' is only supported with kvm"),
                               mode);
6030 6031 6032 6033
                goto cleanup;
            }
            virBufferAddLit(&buf, "host");
        } else {
6034
            if (VIR_ALLOC(guest) < 0)
6035 6036 6037
                goto cleanup;
            if (VIR_STRDUP(guest->vendor_id, cpu->vendor_id) < 0)
                goto cleanup;
6038

6039
            guest->arch = host->arch;
6040 6041
            if (cpu->match == VIR_CPU_MATCH_MINIMUM)
                preferred = host->model;
6042
            else
6043
                preferred = cpu->model;
6044

6045 6046
            guest->type = VIR_CPU_TYPE_GUEST;
            guest->fallback = cpu->fallback;
6047
            if (cpuDecode(guest, data, (const char **)cpus, ncpus, preferred) < 0)
6048 6049 6050
                goto cleanup;

            virBufferAdd(&buf, guest->model, -1);
6051 6052
            if (guest->vendor_id)
                virBufferAsprintf(&buf, ",vendor=%s", guest->vendor_id);
6053 6054 6055 6056 6057 6058 6059 6060 6061
            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);
            }
6062
        }
6063
        have_cpu = true;
6064
    } else {
6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076
        /*
         * 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
         */
6077
        if (def->os.arch == VIR_ARCH_I686 &&
6078
            ((hostarch == VIR_ARCH_X86_64 &&
6079
              strstr(emulator, "kvm")) ||
6080 6081 6082 6083 6084 6085
             strstr(emulator, "x86_64"))) {
            virBufferAdd(&buf, default_model, -1);
            have_cpu = true;
        }
    }

6086
    /* Handle paravirtual timers  */
6087
    for (i = 0; i < def->clock.ntimers; i++) {
6088 6089 6090 6091 6092 6093
        virDomainTimerDefPtr timer = def->clock.timers[i];

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

        if (timer->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK) {
6094 6095
            virBufferAsprintf(&buf, "%s,%ckvmclock",
                              have_cpu ? "" : default_model,
6096 6097 6098 6099 6100 6101
                              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 已提交
6102
            have_cpu = true;
6103
        }
6104 6105
    }

6106 6107
    if (def->apic_eoi) {
        char sign;
6108
        if (def->apic_eoi == VIR_DOMAIN_FEATURE_STATE_ON)
6109 6110 6111 6112 6113 6114 6115
            sign = '+';
        else
            sign = '-';

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

6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131
    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;
    }

6132
    if (def->features[VIR_DOMAIN_FEATURE_HYPERV] == VIR_DOMAIN_FEATURE_STATE_ON) {
6133 6134 6135 6136 6137 6138
        if (!have_cpu) {
            virBufferAdd(&buf, default_model, -1);
            have_cpu = true;
        }

        for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
6139
            switch ((virDomainHyperv) i) {
6140
            case VIR_DOMAIN_HYPERV_RELAXED:
6141
            case VIR_DOMAIN_HYPERV_VAPIC:
6142 6143 6144 6145 6146
                if (def->hyperv_features[i] == VIR_DOMAIN_FEATURE_STATE_ON)
                    virBufferAsprintf(&buf, ",hv_%s",
                                      virDomainHypervTypeToString(i));
                break;

6147
            case VIR_DOMAIN_HYPERV_SPINLOCKS:
6148 6149 6150
                if (def->hyperv_features[i] == VIR_DOMAIN_FEATURE_STATE_ON)
                    virBufferAsprintf(&buf, ",hv_spinlocks=0x%x",
                                      def->hyperv_spinlocks);
6151 6152
                break;

6153 6154 6155 6156 6157 6158
            case VIR_DOMAIN_HYPERV_LAST:
                break;
            }
        }
    }

6159
    if (virBufferCheckError(&buf) < 0)
6160
        goto cleanup;
6161 6162 6163 6164 6165

    *opt = virBufferContentAndReset(&buf);

    ret = 0;

6166
 cleanup:
6167
    VIR_FREE(compare_msg);
J
Jiri Denemark 已提交
6168
    cpuDataFree(data);
6169
    virCPUDefFree(guest);
6170
    virCPUDefFree(cpu);
6171
    virObjectUnref(caps);
6172 6173 6174
    return ret;
}

6175 6176
static int
qemuBuildObsoleteAccelArg(virCommandPtr cmd,
E
Eric Blake 已提交
6177
                          const virDomainDef *def,
6178 6179
                          virQEMUCapsPtr qemuCaps)
{
6180 6181 6182 6183
    bool disableKQEMU = false;
    bool enableKQEMU = false;
    bool disableKVM = false;
    bool enableKVM = false;
6184 6185 6186 6187

    switch (def->virtType) {
    case VIR_DOMAIN_VIRT_QEMU:
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KQEMU))
6188
            disableKQEMU = true;
6189
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
6190
            disableKVM = true;
6191 6192 6193 6194
        break;

    case VIR_DOMAIN_VIRT_KQEMU:
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
6195
            disableKVM = true;
6196 6197

        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KQEMU)) {
6198
            enableKQEMU = true;
6199 6200 6201 6202 6203 6204 6205 6206 6207
        } 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))
6208
            disableKQEMU = true;
6209 6210

        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KVM)) {
6211
            enableKVM = true;
6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241
        } 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;
}

6242 6243
static int
qemuBuildMachineArgStr(virCommandPtr cmd,
E
Eric Blake 已提交
6244
                       const virDomainDef *def,
6245
                       virQEMUCapsPtr qemuCaps)
6246
{
6247 6248
    bool obsoleteAccel = false;

6249 6250 6251 6252 6253 6254 6255
    /* 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;

6256
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_OPT)) {
6257 6258 6259 6260
        /* 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);
6261 6262 6263 6264
        if (def->mem.dump_core) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("dump-guest-core is not available "
                             "with this QEMU binary"));
6265 6266
            return -1;
        }
6267 6268 6269 6270 6271 6272 6273 6274

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

6275
        obsoleteAccel = true;
6276 6277
    } else {
        virBuffer buf = VIR_BUFFER_INITIALIZER;
6278 6279

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

6282 6283 6284 6285 6286 6287 6288
        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 已提交
6289 6290 6291 6292
        /* 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))
6293
            virBufferAddLit(&buf, ",usb=off");
L
Li Zhang 已提交
6294

6295 6296 6297 6298 6299
        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"));
6300
                virBufferFreeAndReset(&buf);
6301 6302 6303 6304 6305 6306 6307
                return -1;
            }

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

6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319
        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;
            }
        }

6320
        virCommandAddArgBuffer(cmd, &buf);
6321 6322
    }

6323 6324 6325 6326
    if (obsoleteAccel &&
        qemuBuildObsoleteAccelArg(cmd, def, qemuCaps) < 0)
        return -1;

6327 6328 6329
    return 0;
}

6330
static char *
E
Eric Blake 已提交
6331
qemuBuildSmpArgStr(const virDomainDef *def,
6332
                   virQEMUCapsPtr qemuCaps)
6333 6334 6335
{
    virBuffer buf = VIR_BUFFER_INITIALIZER;

6336
    virBufferAsprintf(&buf, "%u", def->vcpus);
6337

6338
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SMP_TOPOLOGY)) {
6339
        if (def->vcpus != def->maxvcpus)
6340
            virBufferAsprintf(&buf, ",maxcpus=%u", def->maxvcpus);
6341 6342 6343
        /* 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) {
6344 6345 6346
            virBufferAsprintf(&buf, ",sockets=%u", def->cpu->sockets);
            virBufferAsprintf(&buf, ",cores=%u", def->cpu->cores);
            virBufferAsprintf(&buf, ",threads=%u", def->cpu->threads);
6347 6348
        }
        else {
6349 6350 6351
            virBufferAsprintf(&buf, ",sockets=%u", def->maxvcpus);
            virBufferAsprintf(&buf, ",cores=%u", 1);
            virBufferAsprintf(&buf, ",threads=%u", 1);
6352 6353 6354 6355
        }
    } else if (def->vcpus != def->maxvcpus) {
        virBufferFreeAndReset(&buf);
        /* FIXME - consider hot-unplugging cpus after boot for older qemu */
6356 6357 6358
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("setting current vcpu count less than maximum is "
                         "not supported with this QEMU binary"));
6359 6360 6361
        return NULL;
    }

6362
    if (virBufferCheckError(&buf) < 0)
6363 6364 6365 6366 6367
        return NULL;

    return virBufferContentAndReset(&buf);
}

B
Bharata B Rao 已提交
6368
static int
E
Eric Blake 已提交
6369
qemuBuildNumaArgStr(const virDomainDef *def, virCommandPtr cmd)
B
Bharata B Rao 已提交
6370
{
6371
    size_t i;
B
Bharata B Rao 已提交
6372
    virBuffer buf = VIR_BUFFER_INITIALIZER;
6373 6374
    char *cpumask = NULL;
    int ret = -1;
B
Bharata B Rao 已提交
6375 6376

    for (i = 0; i < def->cpu->ncells; i++) {
6377
        VIR_FREE(cpumask);
B
Bharata B Rao 已提交
6378 6379 6380
        virCommandAddArg(cmd, "-numa");
        virBufferAsprintf(&buf, "node,nodeid=%d", def->cpu->cells[i].cellid);
        virBufferAddLit(&buf, ",cpus=");
6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394
        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;
6395
        }
6396
        virBufferAdd(&buf, cpumask, -1);
6397 6398
        def->cpu->cells[i].mem = VIR_DIV_UP(def->cpu->cells[i].mem,
                                            1024) * 1024;
6399
        virBufferAsprintf(&buf, ",mem=%d", def->cpu->cells[i].mem / 1024);
B
Bharata B Rao 已提交
6400

6401
        if (virBufferCheckError(&buf) < 0)
6402
            goto cleanup;
B
Bharata B Rao 已提交
6403 6404 6405

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

6408
 cleanup:
6409
    VIR_FREE(cpumask);
B
Bharata B Rao 已提交
6410
    virBufferFreeAndReset(&buf);
6411
    return ret;
B
Bharata B Rao 已提交
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
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)
6439
            goto error;
6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492

        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)) {
6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503
        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);
            }

6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516
        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));
        }

6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531
        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)
6532
                virCommandAddEnvPair(cmd, "SASL_CONF_PATH", cfg->vncSASLdir);
6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547

            /* 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)
6548
        virCommandAddEnvPassBlockSUID(cmd, "QEMU_AUDIO_DRV", NULL);
6549 6550 6551 6552 6553
    else
        virCommandAddEnvString(cmd, "QEMU_AUDIO_DRV=none");

    return 0;

6554
 error:
6555 6556 6557 6558 6559 6560
    VIR_FREE(netAddr);
    virBufferFreeAndReset(&opt);
    return -1;
}


6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574
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;
6575
    size_t i;
6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597

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

6598 6599 6600 6601 6602 6603 6604 6605 6606 6607
    if (cfg->spiceSASL) {
        virBufferAddLit(&opt, ",sasl");

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

        /* TODO: Support ACLs later */
    }

6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648
    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:
6649
            virBufferAddLit(&opt, ",agent-mouse=off");
6650 6651
            break;
        case VIR_DOMAIN_GRAPHICS_SPICE_MOUSE_MODE_CLIENT:
6652
            virBufferAddLit(&opt, ",agent-mouse=on");
6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665
            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");

6666 6667
    if (tlsPort > 0)
        virBufferAsprintf(&opt, ",x509-dir=%s", cfg->spiceTLSx509certdir);
6668 6669 6670

    switch (defaultMode) {
    case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE:
6671
        virBufferAddLit(&opt, ",tls-channel=default");
6672 6673
        break;
    case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_INSECURE:
6674
        virBufferAddLit(&opt, ",plaintext-channel=default");
6675 6676 6677 6678 6679 6680
        break;
    case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_ANY:
        /* nothing */
        break;
    }

6681
    for (i = 0; i < VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_LAST; i++) {
6682
        switch (graphics->data.spice.channels[i]) {
6683
        case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE:
6684
            if (tlsPort <= 0) {
6685 6686
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("spice secure channels set in XML configuration, "
6687
                                 "but TLS port is not provided"));
6688 6689 6690 6691 6692
                goto error;
            }
            virBufferAsprintf(&opt, ",tls-channel=%s",
                              virDomainGraphicsSpiceChannelNameTypeToString(i));
            break;
6693

6694
        case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_INSECURE:
6695 6696 6697 6698 6699 6700
            if (port <= 0) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("spice insecure channels set in XML "
                                 "configuration, but plain port is not provided"));
                goto error;
            }
6701 6702 6703
            virBufferAsprintf(&opt, ",plaintext-channel=%s",
                              virDomainGraphicsSpiceChannelNameTypeToString(i));
            break;
6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728

        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;
            }
6729 6730
        }
    }
6731

6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748
    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");
6749 6750 6751 6752 6753 6754 6755 6756 6757
    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");
        }
    }
6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778

    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;

6779
 error:
6780 6781 6782 6783 6784
    VIR_FREE(netAddr);
    virBufferFreeAndReset(&opt);
    return -1;
}

6785
static int
6786
qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg,
6787 6788
                             virCommandPtr cmd,
                             virDomainDefPtr def,
6789
                             virQEMUCapsPtr qemuCaps,
6790
                             virDomainGraphicsDefPtr graphics)
6791
{
6792
    switch ((virDomainGraphicsType) graphics->type) {
6793
    case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
6794 6795
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_0_10) &&
            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SDL)) {
6796
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
6797 6798
                           _("sdl not supported by '%s'"), def->emulator);
            return -1;
6799 6800
        }

6801
        if (graphics->data.sdl.xauth)
6802
            virCommandAddEnvPair(cmd, "XAUTHORITY", graphics->data.sdl.xauth);
6803
        if (graphics->data.sdl.display)
6804
            virCommandAddEnvPair(cmd, "DISPLAY", graphics->data.sdl.display);
6805 6806
        if (graphics->data.sdl.fullscreen)
            virCommandAddArg(cmd, "-full-screen");
6807

6808 6809 6810 6811
        /* 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
         */
6812 6813
        virCommandAddEnvPassBlockSUID(cmd, "QEMU_AUDIO_DRV", NULL);
        virCommandAddEnvPassBlockSUID(cmd, "SDL_AUDIODRIVER", NULL);
B
Bharata B Rao 已提交
6814

6815 6816 6817
        /* 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 :-( */
6818
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SDL))
6819
            virCommandAddArg(cmd, "-sdl");
6820

6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831
        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:
6832 6833 6834
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("unsupported graphics type '%s'"),
                       virDomainGraphicsTypeToString(graphics->type));
6835
        return -1;
6836
    }
6837

6838 6839
    return 0;
}
6840

6841 6842 6843 6844 6845 6846 6847 6848 6849
static int
qemuBuildInterfaceCommandLine(virCommandPtr cmd,
                              virQEMUDriverPtr driver,
                              virConnectPtr conn,
                              virDomainDefPtr def,
                              virDomainNetDefPtr net,
                              virQEMUCapsPtr qemuCaps,
                              int vlan,
                              int bootindex,
6850
                              virNetDevVPortProfileOp vmop,
6851
                              bool standalone)
6852 6853 6854
{
    int ret = -1;
    char *nic = NULL, *host = NULL;
6855 6856 6857 6858 6859 6860
    int *tapfd = NULL;
    int tapfdSize = 0;
    int *vhostfd = NULL;
    int vhostfdSize = 0;
    char **tapfdName = NULL;
    char **vhostfdName = NULL;
6861
    int actualType = virDomainNetGetActualType(net);
6862
    size_t i;
6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873

    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;

6874 6875 6876 6877 6878 6879 6880 6881 6882 6883
    /* 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;
    }

6884 6885
    if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
        actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
6886 6887 6888 6889 6890
        tapfdSize = net->driver.virtio.queues;
        if (!tapfdSize)
            tapfdSize = 1;

        if (VIR_ALLOC_N(tapfd, tapfdSize) < 0 ||
6891
            VIR_ALLOC_N(tapfdName, tapfdSize) < 0)
6892 6893
            goto cleanup;

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

6896 6897
        if (qemuNetworkIfaceConnect(def, conn, driver, net,
                                    qemuCaps, tapfd, &tapfdSize) < 0)
6898 6899
            goto cleanup;
    } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
6900
        if (VIR_ALLOC(tapfd) < 0 || VIR_ALLOC(tapfdName) < 0)
6901 6902 6903 6904 6905
            goto cleanup;
        tapfdSize = 1;
        tapfd[0] = qemuPhysIfaceConnect(def, driver, net,
                                        qemuCaps, vmop);
        if (tapfd[0] < 0)
6906 6907 6908
            goto cleanup;
    }

6909 6910 6911 6912 6913
    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) {
6914 6915
        /* Attempt to use vhost-net mode for these types of
           network device */
6916 6917 6918 6919 6920
        vhostfdSize = net->driver.virtio.queues;
        if (!vhostfdSize)
            vhostfdSize = 1;

        if (VIR_ALLOC_N(vhostfd, vhostfdSize) < 0 ||
6921
            VIR_ALLOC_N(vhostfdName, vhostfdSize))
6922 6923
            goto cleanup;

6924 6925
        memset(vhostfd, -1, vhostfdSize * sizeof(vhostfd[0]));

6926
        if (qemuOpenVhostNet(def, net, qemuCaps, vhostfd, &vhostfdSize) < 0)
6927 6928 6929
            goto cleanup;
    }

6930
    for (i = 0; i < tapfdSize; i++) {
6931 6932
        virCommandPassFD(cmd, tapfd[i],
                         VIR_COMMAND_PASS_FD_CLOSE_PARENT);
6933
        if (virAsprintf(&tapfdName[i], "%d", tapfd[i]) < 0)
6934 6935 6936
            goto cleanup;
    }

6937
    for (i = 0; i < vhostfdSize; i++) {
6938 6939
        virCommandPassFD(cmd, vhostfd[i],
                         VIR_COMMAND_PASS_FD_CLOSE_PARENT);
6940
        if (virAsprintf(&vhostfdName[i], "%d", vhostfd[i]) < 0)
6941
            goto cleanup;
6942 6943 6944 6945 6946 6947 6948 6949 6950 6951
    }

    /* 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
     */
6952
    if (qemuDomainSupportsNetdev(def, qemuCaps, net)) {
6953
        if (!(host = qemuBuildHostNetStr(net, driver,
6954 6955 6956
                                         ',', vlan,
                                         tapfdName, tapfdSize,
                                         vhostfdName, vhostfdSize)))
6957 6958 6959
            goto cleanup;
        virCommandAddArgList(cmd, "-netdev", host, NULL);
    }
6960
    if (qemuDomainSupportsNicdev(def, qemuCaps, net)) {
6961
        if (!(nic = qemuBuildNicDevStr(def, net, vlan, bootindex,
6962
                                       vhostfdSize, qemuCaps)))
6963 6964 6965 6966 6967 6968 6969
            goto cleanup;
        virCommandAddArgList(cmd, "-device", nic, NULL);
    } else {
        if (!(nic = qemuBuildNicStr(net, "nic,", vlan)))
            goto cleanup;
        virCommandAddArgList(cmd, "-net", nic, NULL);
    }
6970
    if (!qemuDomainSupportsNetdev(def, qemuCaps, net)) {
6971
        if (!(host = qemuBuildHostNetStr(net, driver,
6972 6973 6974
                                         ',', vlan,
                                         tapfdName, tapfdSize,
                                         vhostfdName, vhostfdSize)))
6975 6976 6977 6978 6979
            goto cleanup;
        virCommandAddArgList(cmd, "-net", host, NULL);
    }

    ret = 0;
6980
 cleanup:
6981 6982
    if (ret < 0) {
        virErrorPtr saved_err = virSaveLastError();
6983
        virDomainConfNWFilterTeardown(net);
6984 6985 6986
        virSetError(saved_err);
        virFreeError(saved_err);
    }
6987
    for (i = 0; tapfd && i < tapfdSize && tapfd[i] >= 0; i++) {
6988 6989
        if (ret < 0)
            VIR_FORCE_CLOSE(tapfd[i]);
6990 6991
        if (tapfdName)
            VIR_FREE(tapfdName[i]);
6992
    }
6993
    for (i = 0; vhostfd && i < vhostfdSize && vhostfd[i] >= 0; i++) {
6994 6995
        if (ret < 0)
            VIR_FORCE_CLOSE(vhostfd[i]);
6996 6997
        if (vhostfdName)
            VIR_FREE(vhostfdName[i]);
6998 6999 7000
    }
    VIR_FREE(tapfd);
    VIR_FREE(vhostfd);
7001 7002 7003 7004 7005 7006 7007
    VIR_FREE(nic);
    VIR_FREE(host);
    VIR_FREE(tapfdName);
    VIR_FREE(vhostfdName);
    return ret;
}

7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019
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);
7020
    VIR_FREE(devstr);
7021 7022 7023
    return 0;
}

7024 7025 7026 7027
qemuBuildCommandLineCallbacks buildCommandLineCallbacks = {
    .qemuGetSCSIDeviceSgName = virSCSIDeviceGetSgName,
};

7028 7029 7030 7031 7032 7033 7034 7035 7036
/*
 * 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,
7037
                     virQEMUDriverPtr driver,
7038 7039 7040
                     virDomainDefPtr def,
                     virDomainChrSourceDefPtr monitor_chr,
                     bool monitor_json,
7041
                     virQEMUCapsPtr qemuCaps,
7042 7043 7044
                     const char *migrateFrom,
                     int migrateFd,
                     virDomainSnapshotObjPtr snapshot,
7045
                     virNetDevVPortProfileOp vmop,
C
Cole Robinson 已提交
7046 7047
                     qemuBuildCommandLineCallbacksPtr callbacks,
                     bool standalone)
7048
{
7049
    virErrorPtr originalError = NULL;
7050
    size_t i, j;
7051 7052 7053 7054 7055 7056 7057
    const char *emulator;
    char uuid[VIR_UUID_STRING_BUFLEN];
    char *cpu;
    char *smp;
    int last_good_net = -1;
    bool hasHwVirt = false;
    virCommandPtr cmd = NULL;
7058
    bool allowReboot = true;
7059
    bool emitBootindex = false;
7060 7061 7062
    int sdl = 0;
    int vnc = 0;
    int spice = 0;
7063
    int usbcontroller = 0;
M
Martin Kletzander 已提交
7064
    int actualSerials = 0;
7065
    bool usblegacy = false;
7066
    bool mlock = false;
7067 7068 7069
    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
7070 7071 7072 7073 7074
         * 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,
7075 7076 7077 7078 7079 7080
        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,
    };
7081
    virArch hostarch = virArchFromHost();
7082
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
7083

7084
    VIR_DEBUG("conn=%p driver=%p def=%p mon=%p json=%d "
7085
              "qemuCaps=%p migrateFrom=%s migrateFD=%d "
7086 7087
              "snapshot=%p vmop=%d",
              conn, driver, def, monitor_chr, monitor_json,
7088
              qemuCaps, migrateFrom, migrateFd, snapshot, vmop);
7089

7090 7091 7092 7093
    virUUIDFormat(def->uuid, uuid);

    emulator = def->emulator;

7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110
    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;
        }

7111
        if (def->cputune.sharesSpecified || def->cputune.period ||
7112 7113 7114 7115 7116 7117 7118 7119
            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;
        }
    }

7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133
    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;
        }
    }

7134 7135 7136 7137
    /*
     * do not use boot=on for drives when not using KVM since this
     * is not supported at all in upstream QEmu.
     */
7138
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) &&
7139
        (def->virtType == VIR_DOMAIN_VIRT_QEMU))
7140
        virQEMUCapsClear(qemuCaps, QEMU_CAPS_DRIVE_BOOT);
7141 7142

    cmd = virCommandNew(emulator);
7143

7144
    virCommandAddEnvPassCommon(cmd);
7145

7146
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NAME)) {
7147
        virCommandAddArg(cmd, "-name");
7148
        if (cfg->setProcessName &&
7149
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_NAME_PROCESS)) {
7150 7151 7152 7153
            virCommandAddArgFormat(cmd, "%s,process=qemu:%s",
                                   def->name, def->name);
        } else {
            virCommandAddArg(cmd, def->name);
7154 7155
        }
    }
C
Cole Robinson 已提交
7156 7157 7158 7159

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

7160 7161
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_FIPS))
        virCommandAddArg(cmd, "-enable-fips");
7162

7163
    if (qemuBuildMachineArgStr(cmd, def, qemuCaps) < 0)
7164
        goto error;
7165

7166
    if (qemuBuildCpuArgStr(driver, def, emulator, qemuCaps,
7167
                           hostarch, &cpu, &hasHwVirt, !!migrateFrom) < 0)
7168
        goto error;
7169

7170 7171 7172 7173
    if (cpu) {
        virCommandAddArgList(cmd, "-cpu", cpu, NULL);
        VIR_FREE(cpu);

7174
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NESTING) &&
7175 7176
            hasHwVirt)
            virCommandAddArg(cmd, "-enable-nesting");
7177
    }
7178

7179 7180 7181 7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192
    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) {
7193
        if (!cfg->hugetlbfsMount) {
7194 7195 7196 7197
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("hugetlbfs filesystem is not mounted"));
            goto error;
        }
7198
        if (!cfg->hugepagePath) {
7199 7200 7201 7202
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("hugepages are disabled by administrator config"));
            goto error;
        }
7203
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MEM_PATH)) {
7204 7205 7206 7207 7208 7209
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("hugepage backing not supported by '%s'"),
                           def->emulator);
            goto error;
        }
        virCommandAddArgList(cmd, "-mem-prealloc", "-mem-path",
7210
                             cfg->hugepagePath, NULL);
7211 7212
    }

7213 7214 7215 7216 7217 7218 7219 7220 7221 7222
    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");
    }
7223
    mlock = def->mem.locked;
7224

7225
    virCommandAddArg(cmd, "-smp");
7226
    if (!(smp = qemuBuildSmpArgStr(def, qemuCaps)))
7227 7228 7229 7230 7231 7232 7233 7234
        goto error;
    virCommandAddArg(cmd, smp);
    VIR_FREE(smp);

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

7235
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_UUID))
7236 7237 7238 7239
        virCommandAddArgList(cmd, "-uuid", uuid, NULL);
    if (def->virtType == VIR_DOMAIN_VIRT_XEN ||
        STREQ(def->os.type, "xen") ||
        STREQ(def->os.type, "linux")) {
7240
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DOMID)) {
7241 7242
            virCommandAddArg(cmd, "-domid");
            virCommandAddArgFormat(cmd, "%d", def->id);
7243
        } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_XEN_DOMID)) {
7244 7245 7246 7247 7248 7249 7250
            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);
7251 7252 7253 7254
            goto error;
        }
    }

7255 7256 7257 7258 7259
    if ((def->os.smbios_mode != VIR_DOMAIN_SMBIOS_NONE) &&
        (def->os.smbios_mode != VIR_DOMAIN_SMBIOS_EMULATE)) {
        virSysinfoDefPtr source = NULL;
        bool skip_uuid = false;

7260
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SMBIOS_TYPE)) {
7261 7262 7263
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("the QEMU binary %s does not support smbios settings"),
                           emulator);
7264 7265 7266
            goto error;
        }

7267 7268 7269
        /* should we really error out or just warn in those cases ? */
        if (def->os.smbios_mode == VIR_DOMAIN_SMBIOS_HOST) {
            if (driver->hostsysinfo == NULL) {
7270
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
7271
                               _("Host SMBIOS information is not available"));
7272
                goto error;
7273
            }
7274 7275 7276 7277 7278 7279 7280 7281 7282
            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;
7283
            }
7284 7285
            source = def->sysinfo;
            /* domain_conf guaranteed that system_uuid matches guest uuid. */
7286
        }
7287 7288
        if (source != NULL) {
            char *smbioscmd;
7289

7290 7291 7292 7293
            smbioscmd = qemuBuildSmbiosBiosStr(source);
            if (smbioscmd != NULL) {
                virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
                VIR_FREE(smbioscmd);
7294
            }
7295 7296 7297 7298
            smbioscmd = qemuBuildSmbiosSystemStr(source, skip_uuid);
            if (smbioscmd != NULL) {
                virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
                VIR_FREE(smbioscmd);
7299
            }
7300
        }
7301
    }
7302

7303 7304 7305 7306 7307 7308 7309
    /*
     * 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...
     */
7310
    if (!def->graphics) {
7311
        virCommandAddArg(cmd, "-nographic");
7312

7313
        if (cfg->nogfxAllowHostAudio)
7314
            virCommandAddEnvPassBlockSUID(cmd, "QEMU_AUDIO_DRV", NULL);
7315 7316 7317 7318
        else
            virCommandAddEnvString(cmd, "QEMU_AUDIO_DRV=none");
    }

7319
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
7320
        /* Disable global config files and default devices */
7321
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_USER_CONFIG))
7322
            virCommandAddArg(cmd, "-no-user-config");
7323
        else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NODEFCONFIG))
7324 7325
            virCommandAddArg(cmd, "-nodefconfig");
        virCommandAddArg(cmd, "-nodefaults");
7326 7327
    }

7328 7329
    /* Serial graphics adapter */
    if (def->os.bios.useserial == VIR_DOMAIN_BIOS_USESERIAL_YES) {
7330
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
7331 7332 7333 7334
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("qemu does not support -device"));
            goto error;
        }
7335
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGA)) {
7336 7337 7338 7339 7340 7341 7342
            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"));
7343 7344
            goto error;
        }
7345
        virCommandAddArgList(cmd, "-device", "sga", NULL);
7346 7347
    }

7348 7349 7350
    if (monitor_chr) {
        char *chrdev;
        /* Use -chardev if it's available */
7351
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV)) {
J
Jim Fehlig 已提交
7352

7353 7354
            virCommandAddArg(cmd, "-chardev");
            if (!(chrdev = qemuBuildChrChardevStr(monitor_chr, "monitor",
7355
                                                  qemuCaps)))
7356 7357 7358
                goto error;
            virCommandAddArg(cmd, chrdev);
            VIR_FREE(chrdev);
7359

7360 7361 7362 7363 7364 7365 7366 7367
            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,";
7368

7369 7370 7371 7372 7373
            virCommandAddArg(cmd, "-monitor");
            if (!(chrdev = qemuBuildChrArgStr(monitor_chr, prefix)))
                goto error;
            virCommandAddArg(cmd, chrdev);
            VIR_FREE(chrdev);
7374 7375 7376
        }
    }

7377
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_RTC)) {
7378
        char *rtcopt;
7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389
        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;
7390

7391 7392 7393
        case VIR_DOMAIN_CLOCK_OFFSET_UTC:
            /* Nothing, its the default */
            break;
7394

7395 7396 7397 7398
        default:
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("unsupported clock offset '%s'"),
                           virDomainClockOffsetTypeToString(def->clock.offset));
7399
            goto error;
7400 7401 7402 7403 7404
        }
    }
    if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE &&
        def->clock.data.timezone) {
        virCommandAddEnvPair(cmd, "TZ", def->clock.data.timezone);
7405 7406
    }

7407
    for (i = 0; i < def->clock.ntimers; i++) {
7408
        switch ((virDomainTimerNameType) def->clock.timers[i]->name) {
7409 7410 7411 7412 7413 7414
        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;
7415

7416
        case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
7417 7418 7419
        case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK:
            /* Timers above are handled when building -cpu.  */
        case VIR_DOMAIN_TIMER_NAME_LAST:
7420 7421 7422 7423 7424 7425
            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) */
7426
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_RTC_TD_HACK)) {
7427 7428 7429 7430
                switch (def->clock.timers[i]->tickpolicy) {
                case -1:
                case VIR_DOMAIN_TIMER_TICKPOLICY_DELAY:
                    /* the default - do nothing */
7431
                    break;
7432 7433
                case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP:
                    virCommandAddArg(cmd, "-rtc-td-hack");
7434
                    break;
7435 7436 7437 7438 7439
                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 已提交
7440
                    goto error;
7441
                }
7442
            } else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_RTC)
7443 7444 7445 7446 7447 7448 7449 7450 7451
                       && (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;
7452
            }
7453
            break;
7454

7455 7456 7457 7458 7459 7460
        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. */
7461 7462 7463 7464
                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))
7465 7466 7467
                    virCommandAddArg(cmd, "-no-kvm-pit-reinjection");
                break;
            case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP:
7468 7469
                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_KVM_PIT) ||
                    virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM_PIT_TICK_POLICY)) {
7470
                    /* do nothing - this is default for kvm-pit */
7471
                } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_TDF)) {
7472 7473
                    /* -tdf switches to 'catchup' with userspace pit. */
                    virCommandAddArg(cmd, "-tdf");
7474
                } else {
7475 7476 7477 7478
                    /* can't catchup if we have neither pit mode */
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("unsupported pit tickpolicy '%s'"),
                                   virDomainTimerTickpolicyTypeToString(def->clock.timers[i]->tickpolicy));
7479 7480 7481
                    goto error;
                }
                break;
7482 7483 7484 7485 7486 7487 7488
            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;
7489
            }
7490
            break;
7491

7492 7493 7494 7495 7496 7497 7498
        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"! */
7499

7500
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_HPET)) {
7501 7502 7503 7504 7505 7506 7507
                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,
7508 7509
                                   "%s", _("hpet timer is not supported"));
                    goto error;
7510 7511
                }
            }
7512 7513 7514
            break;
        }
    }
7515

7516 7517 7518 7519 7520 7521 7522 7523 7524
    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");
        }
    }
7525

7526 7527 7528 7529
    /* 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.
     */
7530 7531
    if (monitor_json && allowReboot &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_SHUTDOWN)) {
7532
        virCommandAddArg(cmd, "-no-shutdown");
7533
    }
7534

7535
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_ACPI)) {
7536
        if (def->features[VIR_DOMAIN_FEATURE_ACPI] != VIR_DOMAIN_FEATURE_STATE_ON)
7537 7538
            virCommandAddArg(cmd, "-no-acpi");
    }
7539

7540
    if (def->pm.s3) {
7541
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DISABLE_S3)) {
7542 7543 7544
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           "%s", _("setting ACPI S3 not supported"));
            goto error;
7545
        }
7546 7547 7548 7549 7550 7551
        virCommandAddArg(cmd, "-global");
        virCommandAddArgFormat(cmd, "PIIX4_PM.disable_s3=%d",
                               def->pm.s3 == VIR_DOMAIN_PM_STATE_DISABLED);
    }

    if (def->pm.s4) {
7552
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DISABLE_S4)) {
7553
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
7554 7555 7556 7557 7558 7559 7560
                           "%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);
    }
7561

7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573
    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
             */
7574
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX)) {
7575
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
7576
                               _("hypervisor lacks deviceboot feature"));
7577 7578
                goto error;
            }
7579
            emitBootindex = true;
7580
        } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX) &&
7581
                   (def->os.bootmenu != VIR_DOMAIN_BOOT_MENU_ENABLED ||
7582
                    !virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_MENU))) {
7583 7584
            emitBootindex = true;
        }
7585

7586 7587
        if (!emitBootindex) {
            char boot[VIR_DOMAIN_BOOT_LAST+1];
7588

7589
            for (i = 0; i < def->os.nBootDevs; i++) {
7590 7591 7592
                switch (def->os.bootDevs[i]) {
                case VIR_DOMAIN_BOOT_CDROM:
                    boot[i] = 'd';
7593
                    break;
7594 7595
                case VIR_DOMAIN_BOOT_FLOPPY:
                    boot[i] = 'a';
7596
                    break;
7597 7598 7599 7600 7601 7602 7603 7604
                case VIR_DOMAIN_BOOT_DISK:
                    boot[i] = 'c';
                    break;
                case VIR_DOMAIN_BOOT_NET:
                    boot[i] = 'n';
                    break;
                default:
                    boot[i] = 'c';
7605
                    break;
7606
                }
7607
            }
7608
            boot[def->os.nBootDevs] = '\0';
7609

7610 7611
            virBufferAsprintf(&boot_buf, "%s", boot);
            boot_nparams++;
7612 7613
        }

7614
        if (def->os.bootmenu) {
7615
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_MENU)) {
7616 7617
                if (boot_nparams++)
                    virBufferAddChar(&boot_buf, ',');
7618

7619
                if (def->os.bootmenu == VIR_DOMAIN_BOOT_MENU_ENABLED)
7620
                    virBufferAddLit(&boot_buf, "menu=on");
7621
                else
7622
                    virBufferAddLit(&boot_buf, "menu=off");
7623 7624 7625 7626 7627 7628 7629
            } 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");
            }
        }
7630

7631
        if (def->os.bios.rt_set) {
7632
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_REBOOT_TIMEOUT)) {
7633 7634 7635
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("reboot timeout is not supported "
                                 "by this QEMU binary"));
7636
                virBufferFreeAndReset(&boot_buf);
7637
                goto error;
7638 7639 7640 7641 7642 7643 7644 7645
            }

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

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

7648 7649 7650 7651 7652 7653
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOT_STRICT)) {
            if (boot_nparams++)
                virBufferAddChar(&boot_buf, ',');
            virBufferAddLit(&boot_buf, "strict=on");
        }

7654 7655
        if (boot_nparams > 0) {
            virCommandAddArg(cmd, "-boot");
7656

7657
            if (virBufferCheckError(&boot_buf) < 0)
7658 7659
                goto error;

7660 7661
            if (boot_nparams < 2 || emitBootindex) {
                virCommandAddArgBuffer(cmd, &boot_buf);
7662
                virBufferFreeAndReset(&boot_buf);
7663
            } else {
7664
                char *str = virBufferContentAndReset(&boot_buf);
7665 7666
                virCommandAddArgFormat(cmd,
                                       "order=%s",
7667 7668
                                       str);
                VIR_FREE(str);
7669 7670 7671
            }
        }

7672 7673 7674 7675 7676 7677
        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 已提交
7678 7679 7680 7681 7682 7683 7684 7685 7686
        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;
            }
        }
7687 7688 7689
    } else {
        virCommandAddArgList(cmd, "-bootloader", def->os.bootloader, NULL);
    }
7690

7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737
    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);
        }
    }

7738
    for (i = 0; i < def->ndisks; i++) {
7739
        virDomainDiskDefPtr disk = def->disks[i];
7740

7741 7742
        if (disk->src->driverName != NULL &&
            !STREQ(disk->src->driverName, "qemu")) {
7743 7744
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("unsupported driver name '%s' for disk '%s'"),
7745
                           disk->src->driverName, disk->src->path);
7746 7747 7748 7749
            goto error;
        }
    }

7750
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
7751 7752 7753
        for (j = 0; j < ARRAY_CARDINALITY(contOrder); j++) {
            for (i = 0; i < def->ncontrollers; i++) {
                virDomainControllerDefPtr cont = def->controllers[i];
7754

7755 7756
                if (cont->type != contOrder[j])
                    continue;
7757

7758 7759 7760 7761 7762 7763 7764
                /* 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 已提交
7765
                /* Skip pci-root/pcie-root */
7766
                if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI &&
L
Laine Stump 已提交
7767 7768
                    (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT ||
                     cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT)) {
7769 7770 7771
                    continue;
                }

7772 7773
                /* Only recent QEMU implements a SATA (AHCI) controller */
                if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_SATA) {
7774
                    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_AHCI)) {
7775 7776 7777
                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                       _("SATA is not supported with this "
                                         "QEMU binary"));
7778
                        goto error;
7779 7780 7781
                    } else if (cont->idx == 0 && qemuDomainMachineIsQ35(def)) {
                        /* first SATA controller on Q35 machines is implicit */
                        continue;
7782 7783
                    } else {
                        char *devstr;
7784

7785 7786
                        virCommandAddArg(cmd, "-device");
                        if (!(devstr = qemuBuildControllerDevStr(def, cont,
7787
                                                                 qemuCaps, NULL)))
7788
                            goto error;
7789 7790 7791

                        virCommandAddArg(cmd, devstr);
                        VIR_FREE(devstr);
7792
                    }
7793 7794
                } else if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
                           cont->model == -1 &&
7795
                           !qemuDomainMachineIsQ35(def) &&
7796
                           (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI) ||
7797 7798
                            (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_OHCI) &&
                             def->os.arch == VIR_ARCH_PPC64))) {
7799 7800 7801 7802
                    if (usblegacy) {
                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                       _("Multiple legacy USB controllers are "
                                         "not supported"));
7803 7804
                        goto error;
                    }
7805 7806 7807 7808 7809
                    usblegacy = true;
                } else {
                    virCommandAddArg(cmd, "-device");

                    char *devstr;
7810
                    if (!(devstr = qemuBuildControllerDevStr(def, cont, qemuCaps,
7811 7812 7813 7814 7815
                                                             &usbcontroller)))
                        goto error;

                    virCommandAddArg(cmd, devstr);
                    VIR_FREE(devstr);
7816
                }
7817
            }
7818 7819
        }
    }
7820

7821
    if (usbcontroller == 0 && !qemuDomainMachineIsQ35(def))
7822
        virCommandAddArg(cmd, "-usb");
7823

7824
    for (i = 0; i < def->nhubs; i++) {
7825 7826
        virDomainHubDefPtr hub = def->hubs[i];
        char *optstr;
7827

7828
        virCommandAddArg(cmd, "-device");
7829
        if (!(optstr = qemuBuildHubDevStr(def, hub, qemuCaps)))
7830 7831 7832 7833
            goto error;
        virCommandAddArg(cmd, optstr);
        VIR_FREE(optstr);
    }
7834

7835
    /* If QEMU supports -drive param instead of old -hda, -hdb, -cdrom .. */
7836
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) {
7837
        int bootCD = 0, bootFloppy = 0, bootDisk = 0;
7838

7839
        if ((virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_BOOT) || emitBootindex)) {
7840 7841
            /* bootDevs will get translated into either bootindex=N or boot=on
             * depending on what qemu supports */
7842
            for (i = 0; i < def->os.nBootDevs; i++) {
7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853
                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;
                }
7854
            }
7855
        }
7856

7857
        for (i = 0; i < def->ndisks; i++) {
7858 7859 7860
            char *optstr;
            int bootindex = 0;
            virDomainDiskDefPtr disk = def->disks[i];
7861
            bool withDeviceArg = false;
7862
            bool deviceFlagMasked = false;
7863

7864 7865 7866
            /* Unless we have -device, then USB disks need special
               handling */
            if ((disk->bus == VIR_DOMAIN_DISK_BUS_USB) &&
7867
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
7868 7869
                if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
                    virCommandAddArg(cmd, "-usbdevice");
7870
                    virCommandAddArgFormat(cmd, "disk:%s", disk->src->path);
7871 7872 7873
                } else {
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("unsupported usb disk type for '%s'"),
7874
                                   disk->src->path);
7875
                    goto error;
7876
                }
7877
                continue;
7878
            }
7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893

            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;
7894
            }
7895 7896 7897 7898

            virCommandAddArg(cmd, "-drive");

            /* Unfortunately it is not possible to use
7899
               -device for floppies, xen PV, or SD
7900 7901 7902
               devices. Fortunately, those don't need
               static PCI addresses, so we don't really
               care that we can't use -device */
7903
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
7904 7905
                if (disk->bus != VIR_DOMAIN_DISK_BUS_XEN &&
                    disk->bus != VIR_DOMAIN_DISK_BUS_SD) {
7906
                    withDeviceArg = true;
7907
                } else {
7908
                    virQEMUCapsClear(qemuCaps, QEMU_CAPS_DEVICE);
7909 7910
                    deviceFlagMasked = true;
                }
7911
            }
7912 7913
            optstr = qemuBuildDriveStr(conn, disk,
                                       emitBootindex ? false : !!bootindex,
7914
                                       qemuCaps);
7915
            if (deviceFlagMasked)
7916
                virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE);
7917 7918 7919 7920 7921 7922 7923 7924 7925
            if (!optstr)
                goto error;
            virCommandAddArg(cmd, optstr);
            VIR_FREE(optstr);

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

7927 7928 7929 7930 7931 7932 7933
            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 已提交
7934

7935 7936 7937 7938 7939 7940 7941 7942 7943
                    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 已提交
7944

7945
                    if (!(optstr = qemuBuildDriveDevStr(def, disk, bootindex,
7946
                                                        qemuCaps)))
7947 7948 7949 7950
                        goto error;
                    virCommandAddArg(cmd, optstr);
                    VIR_FREE(optstr);
                }
E
Eric Blake 已提交
7951
            }
7952 7953
        }
    } else {
7954
        for (i = 0; i < def->ndisks; i++) {
7955 7956 7957 7958
            char dev[NAME_MAX];
            char *file;
            const char *fmt;
            virDomainDiskDefPtr disk = def->disks[i];
E
Eric Blake 已提交
7959

7960
            if ((disk->src->type == VIR_STORAGE_TYPE_BLOCK) &&
7961
                (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
7962
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
7963 7964
                               _("tray status 'open' is invalid for "
                                 "block type disk"));
E
Eric Blake 已提交
7965 7966 7967
                goto error;
            }

7968 7969 7970
            if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
                if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
                    virCommandAddArg(cmd, "-usbdevice");
7971
                    virCommandAddArgFormat(cmd, "disk:%s", disk->src->path);
7972 7973 7974
                } else {
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("unsupported usb disk type for '%s'"),
7975
                                   disk->src->path);
E
Eric Blake 已提交
7976 7977
                    goto error;
                }
7978
                continue;
E
Eric Blake 已提交
7979
            }
7980 7981 7982

            if (STREQ(disk->dst, "hdc") &&
                disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
7983
                if (disk->src->path) {
7984 7985 7986
                    snprintf(dev, NAME_MAX, "-%s", "cdrom");
                } else {
                    continue;
E
Eric Blake 已提交
7987 7988
                }
            } else {
7989 7990 7991 7992 7993 7994 7995 7996
                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 已提交
7997 7998
            }

7999
            if (disk->src->type == VIR_STORAGE_TYPE_DIR) {
8000
                /* QEMU only supports magic FAT format for now */
8001 8002
                if (disk->src->format > 0 &&
                    disk->src->format != VIR_STORAGE_FILE_FAT) {
8003 8004
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("unsupported disk driver type for '%s'"),
8005
                                   virStorageFileFormatTypeToString(disk->src->format));
8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016
                    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 已提交
8017

8018
                if (virAsprintf(&file, fmt, disk->src) < 0)
8019
                    goto error;
8020
            } else if (disk->src->type == VIR_STORAGE_TYPE_NETWORK) {
8021 8022
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                               _("network disks are only supported with -drive"));
8023
                goto error;
8024
            } else {
8025
                if (VIR_STRDUP(file, disk->src->path) < 0) {
8026
                    goto error;
8027
                }
E
Eric Blake 已提交
8028 8029
            }

8030 8031 8032 8033 8034 8035 8036 8037
            /* 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 已提交
8038 8039 8040
        }
    }

8041
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_FSDEV)) {
8042
        for (i = 0; i < def->nfss; i++) {
8043 8044
            char *optstr;
            virDomainFSDefPtr fs = def->fss[i];
8045

8046
            virCommandAddArg(cmd, "-fsdev");
8047
            if (!(optstr = qemuBuildFSStr(fs, qemuCaps)))
8048 8049 8050
                goto error;
            virCommandAddArg(cmd, optstr);
            VIR_FREE(optstr);
8051

8052
            virCommandAddArg(cmd, "-device");
8053
            if (!(optstr = qemuBuildFSDevStr(def, fs, qemuCaps)))
8054 8055 8056 8057 8058 8059 8060 8061 8062
                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;
8063 8064 8065
        }
    }

8066
    if (!def->nnets) {
8067
        /* If we have -device, then we set -nodefault already */
8068
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
8069
            virCommandAddArgList(cmd, "-net", "none", NULL);
8070
    } else {
8071
        int bootNet = 0;
8072

8073 8074 8075 8076
        if (emitBootindex) {
            /* convert <boot dev='network'/> to bootindex since we didn't emit
             * -boot n
             */
8077
            for (i = 0; i < def->os.nBootDevs; i++) {
8078 8079 8080 8081
                if (def->os.bootDevs[i] == VIR_DOMAIN_BOOT_NET) {
                    bootNet = i + 1;
                    break;
                }
8082 8083 8084
            }
        }

8085
        for (i = 0; i < def->nnets; i++) {
8086
            virDomainNetDefPtr net = def->nets[i];
8087
            int vlan;
8088

8089
            /* VLANs are not used with -netdev, so don't record them */
8090
            if (qemuDomainSupportsNetdev(def, qemuCaps, net))
8091
                vlan = -1;
8092 8093
            else
                vlan = i;
8094

8095
            if (qemuBuildInterfaceCommandLine(cmd, driver, conn, def, net,
8096 8097
                                              qemuCaps, vlan, bootNet, vmop,
                                              standalone) < 0)
8098 8099 8100
                goto error;
            last_good_net = i;
            bootNet = 0;
8101 8102 8103
        }
    }

8104 8105 8106 8107 8108
    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;
8109
        virBuffer opt = VIR_BUFFER_INITIALIZER;
8110
        const char *database;
8111

8112 8113 8114 8115
        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) {
8116
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
8117 8118 8119
                           _("this QEMU binary lacks multiple smartcard "
                             "support"));
            virBufferFreeAndReset(&opt);
8120 8121 8122
            goto error;
        }

8123 8124
        switch (smartcard->type) {
        case VIR_DOMAIN_SMARTCARD_TYPE_HOST:
8125 8126
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) {
8127 8128 8129 8130
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("this QEMU binary lacks smartcard host "
                                 "mode support"));
                goto error;
8131 8132
            }

8133 8134
            virBufferAddLit(&opt, "ccid-card-emulated,backend=nss-emulated");
            break;
8135

8136
        case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES:
8137 8138
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) {
8139 8140 8141 8142 8143
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("this QEMU binary lacks smartcard host "
                                 "mode support"));
                goto error;
            }
8144

8145 8146 8147 8148
            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);
8149
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
8150 8151
                                   _("invalid certificate name: %s"),
                                   smartcard->data.cert.file[j]);
8152 8153
                    goto error;
                }
8154
                virBufferAsprintf(&opt, ",cert%zu=%s", j + 1,
8155 8156 8157 8158 8159 8160 8161 8162
                                  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);
8163 8164
                    goto error;
                }
8165 8166 8167
                database = smartcard->data.cert.database;
            } else {
                database = VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE;
8168
            }
8169
            virBufferAsprintf(&opt, ",db=%s", database);
8170
            break;
8171

8172
        case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
8173 8174
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_PASSTHRU)) {
8175 8176 8177 8178
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("this QEMU binary lacks smartcard "
                                 "passthrough mode support"));
                goto error;
8179 8180
            }

8181 8182 8183
            virCommandAddArg(cmd, "-chardev");
            if (!(devstr = qemuBuildChrChardevStr(&smartcard->data.passthru,
                                                  smartcard->info.alias,
8184
                                                  qemuCaps))) {
8185 8186
                virBufferFreeAndReset(&opt);
                goto error;
8187
            }
8188 8189
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);
8190

8191 8192 8193
            virBufferAsprintf(&opt, "ccid-card-passthru,chardev=char%s",
                              smartcard->info.alias);
            break;
8194

8195 8196 8197 8198 8199
        default:
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("unexpected smartcard type %d"),
                           smartcard->type);
            virBufferFreeAndReset(&opt);
8200 8201
            goto error;
        }
8202 8203 8204 8205
        virCommandAddArg(cmd, "-device");
        virBufferAsprintf(&opt, ",id=%s,bus=ccid0.0", smartcard->info.alias);
        virCommandAddArgBuffer(cmd, &opt);
    }
8206

8207 8208 8209
    for (i = 0; i < def->nserials; i++) {
        virDomainChrDefPtr serial = def->serials[i];
        char *devstr;
8210

8211 8212 8213
        if (serial->source.type == VIR_DOMAIN_CHR_TYPE_SPICEPORT && !spice)
            continue;

8214 8215 8216 8217 8218 8219 8220 8221 8222 8223 8224 8225 8226 8227 8228 8229 8230 8231
        /* 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);
8232
        }
8233
        actualSerials++;
8234
    }
8235

M
Martin Kletzander 已提交
8236 8237 8238 8239
    /* If we have -device, then we set -nodefault already */
    if (!actualSerials && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
            virCommandAddArgList(cmd, "-serial", "none", NULL);

8240 8241
    if (!def->nparallels) {
        /* If we have -device, then we set -nodefault already */
8242
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
8243 8244
            virCommandAddArgList(cmd, "-parallel", "none", NULL);
    } else {
8245
        for (i = 0; i < def->nparallels; i++) {
8246 8247
            virDomainChrDefPtr parallel = def->parallels[i];
            char *devstr;
8248

8249
            /* Use -chardev with -device if they are available */
8250 8251
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) &&
                virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8252 8253 8254
                virCommandAddArg(cmd, "-chardev");
                if (!(devstr = qemuBuildChrChardevStr(&parallel->source,
                                                      parallel->info.alias,
8255
                                                      qemuCaps)))
8256 8257 8258
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
8259

8260 8261
                if (qemuBuildChrDeviceCommandLine(cmd, def, parallel, qemuCaps) < 0)
                    goto error;
8262 8263 8264 8265 8266 8267 8268
            } else {
                virCommandAddArg(cmd, "-parallel");
                if (!(devstr = qemuBuildChrArgStr(&parallel->source, NULL)))
                      goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
            }
8269
        }
8270
    }
8271

8272
    for (i = 0; i < def->nchannels; i++) {
8273 8274
        virDomainChrDefPtr channel = def->channels[i];
        char *devstr;
8275

8276 8277
        switch (channel->targetType) {
        case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD:
8278 8279
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV) ||
                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8280 8281
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("guestfwd requires QEMU to support -chardev & -device"));
8282 8283
                goto error;
            }
8284

8285 8286 8287
            virCommandAddArg(cmd, "-chardev");
            if (!(devstr = qemuBuildChrChardevStr(&channel->source,
                                                  channel->info.alias,
8288
                                                  qemuCaps)))
8289 8290 8291 8292
                goto error;
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);

8293
            if (qemuBuildChrDeviceStr(&devstr, def, channel, qemuCaps) < 0)
8294
                goto error;
8295 8296
            virCommandAddArgList(cmd, "-netdev", devstr, NULL);
            VIR_FREE(devstr);
8297 8298
            break;

8299
        case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO:
8300
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8301 8302
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("virtio channel requires QEMU to support -device"));
8303 8304
                goto error;
            }
8305

8306
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC) &&
8307 8308 8309 8310 8311 8312 8313 8314 8315
                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,
8316
                                                      qemuCaps)))
8317 8318 8319
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
8320
            }
8321

8322
            if (qemuBuildChrDeviceCommandLine(cmd, def, channel, qemuCaps) < 0)
8323
                goto error;
8324 8325
            break;
        }
8326
    }
8327

8328
    /* Explicit console devices */
8329
    for (i = 0; i < def->nconsoles; i++) {
8330 8331
        virDomainChrDefPtr console = def->consoles[i];
        char *devstr;
8332

8333
        switch (console->targetType) {
8334 8335
        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLP:
        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SCLPLM:
8336
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8337 8338 8339 8340
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("sclp console requires QEMU to support -device"));
                goto error;
            }
8341
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCLP_S390)) {
8342 8343 8344 8345 8346 8347 8348 8349
                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,
8350
                                                  qemuCaps)))
8351 8352 8353 8354
                goto error;
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);

8355
            if (qemuBuildChrDeviceCommandLine(cmd, def, console, qemuCaps) < 0)
8356 8357 8358
                goto error;
            break;

8359
        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO:
8360
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8361 8362 8363
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("virtio channel requires QEMU to support -device"));
                goto error;
P
Peng Zhou 已提交
8364 8365
            }

8366 8367 8368
            virCommandAddArg(cmd, "-chardev");
            if (!(devstr = qemuBuildChrChardevStr(&console->source,
                                                  console->info.alias,
8369
                                                  qemuCaps)))
8370 8371 8372
                goto error;
            virCommandAddArg(cmd, devstr);
            VIR_FREE(devstr);
8373

8374
            if (qemuBuildChrDeviceCommandLine(cmd, def, console, qemuCaps) < 0)
8375
                goto error;
8376
            break;
8377 8378

        case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL:
8379
            break;
8380 8381 8382 8383 8384 8385

        default:
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("unsupported console target type %s"),
                           NULLSTR(virDomainChrConsoleTargetTypeToString(console->targetType)));
            goto error;
8386
        }
8387
    }
8388

8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400 8401 8402 8403 8404
    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);
    }

8405
    for (i = 0; i < def->ninputs; i++) {
8406 8407 8408
        virDomainInputDefPtr input = def->inputs[i];

        if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) {
8409
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8410 8411
                char *optstr;
                virCommandAddArg(cmd, "-device");
8412
                if (!(optstr = qemuBuildUSBInputDevStr(def, input, qemuCaps)))
8413
                    goto error;
8414 8415 8416
                virCommandAddArg(cmd, optstr);
                VIR_FREE(optstr);
            } else {
8417 8418 8419 8420 8421 8422 8423 8424 8425 8426 8427
                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;
                }
8428 8429
            }
        }
8430
    }
8431

8432
    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_0_10) && sdl + vnc + spice > 1) {
8433 8434 8435 8436 8437 8438 8439 8440
        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"));
8441 8442 8443
        goto error;
    }

8444
    for (i = 0; i < def->ngraphics; ++i) {
8445
        if (qemuBuildGraphicsCommandLine(cfg, cmd, def, qemuCaps,
8446 8447 8448
                                         def->graphics[i]) < 0)
            goto error;
    }
8449

8450
    if (def->nvideos > 0) {
8451
        int primaryVideoType = def->videos[0]->type;
8452
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY) &&
8453
             ((primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_VGA &&
8454
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VGA)) ||
8455
             (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_CIRRUS &&
8456
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_CIRRUS_VGA)) ||
8457
             (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_VMVGA &&
8458
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMWARE_SVGA)) ||
8459
             (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_QXL &&
8460
                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL_VGA)))
8461
           ) {
8462
            for (i = 0; i < def->nvideos; i++) {
8463 8464
                char *str;
                virCommandAddArg(cmd, "-device");
8465
                if (!(str = qemuBuildDeviceVideoStr(def, def->videos[i], qemuCaps, !i)))
8466 8467 8468 8469 8470
                    goto error;

                virCommandAddArg(cmd, str);
                VIR_FREE(str);
            }
8471
        } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA)) {
8472
            if (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_XEN) {
8473 8474
                /* nothing - vga has no effect on Xen pvfb */
            } else {
8475
                if ((primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_QXL) &&
8476
                    !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA_QXL)) {
8477 8478
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("This QEMU does not support QXL graphics adapters"));
8479 8480 8481
                    goto error;
                }

8482
                const char *vgastr = qemuVideoTypeToString(primaryVideoType);
8483
                if (!vgastr || STREQ(vgastr, "")) {
8484 8485
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("video type %s is not supported with QEMU"),
8486
                                   virDomainVideoTypeToString(primaryVideoType));
8487 8488 8489 8490
                    goto error;
                }

                virCommandAddArgList(cmd, "-vga", vgastr, NULL);
8491

8492 8493
                if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_QXL &&
                    (def->videos[0]->vram || def->videos[0]->ram) &&
8494 8495
                    virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
                    const char *dev = (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL_VGA)
8496 8497 8498 8499 8500 8501 8502 8503 8504 8505 8506 8507 8508 8509 8510 8511
                                       ? "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;
                    }
8512

8513
                    if (ram) {
E
Eric Blake 已提交
8514
                        virCommandAddArg(cmd, "-global");
8515 8516 8517 8518 8519 8520 8521
                        virCommandAddArgFormat(cmd, "%s.ram_size=%u",
                                               dev, ram * 1024);
                    }
                    if (vram) {
                        virCommandAddArg(cmd, "-global");
                        virCommandAddArgFormat(cmd, "%s.vram_size=%u",
                                               dev, vram * 1024);
8522 8523
                    }
                }
8524
            }
8525 8526

            if (def->nvideos > 1) {
8527
                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8528
                    for (i = 1; i < def->nvideos; i++) {
8529 8530 8531 8532 8533 8534 8535 8536 8537 8538
                        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");

8539
                        if (!(str = qemuBuildDeviceVideoStr(def, def->videos[i], qemuCaps, false)))
8540 8541 8542 8543 8544 8545 8546 8547 8548 8549 8550
                            goto error;

                        virCommandAddArg(cmd, str);
                        VIR_FREE(str);
                    }
                } else {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   "%s", _("only one video card is currently supported"));
                    goto error;
                }
            }
8551 8552 8553 8554 8555 8556 8557 8558 8559 8560 8561 8562 8563 8564 8565 8566 8567
        } 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:
8568 8569 8570
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("video type %s is not supported with this QEMU"),
                               virDomainVideoTypeToString(def->videos[0]->type));
8571 8572 8573
                goto error;
            }

8574
            if (def->nvideos > 1) {
8575 8576
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("only one video card is currently supported"));
8577 8578 8579 8580 8581 8582
                goto error;
            }
        }

    } else {
        /* If we have -device, then we set -nodefault already */
8583 8584 8585
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) &&
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA) &&
            virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA_NONE))
8586 8587 8588 8589 8590
            virCommandAddArgList(cmd, "-vga", "none", NULL);
    }

    /* Add sound hardware */
    if (def->nsounds) {
8591
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8592
            for (i = 0; i < def->nsounds; i++) {
8593 8594 8595 8596 8597 8598 8599 8600 8601 8602
                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");
8603
                    if (!(str = qemuBuildSoundDevStr(def, sound, qemuCaps)))
8604 8605 8606
                        goto error;

                    virCommandAddArg(cmd, str);
8607
                    VIR_FREE(str);
8608 8609
                    if (sound->model == VIR_DOMAIN_SOUND_MODEL_ICH6 ||
                        sound->model == VIR_DOMAIN_SOUND_MODEL_ICH9) {
8610 8611
                        char *codecstr = NULL;

8612
                        for (j = 0; j < sound->ncodecs; j++) {
8613
                            virCommandAddArg(cmd, "-device");
8614
                            if (!(codecstr = qemuBuildSoundCodecStr(sound, sound->codecs[j], qemuCaps))) {
8615
                                goto error;
8616

8617 8618 8619 8620
                            }
                            virCommandAddArg(cmd, codecstr);
                            VIR_FREE(codecstr);
                        }
8621
                        if (j == 0) {
8622 8623 8624 8625 8626
                            virDomainSoundCodecDef codec = {
                                VIR_DOMAIN_SOUND_CODEC_TYPE_DUPLEX,
                                0
                            };
                            virCommandAddArg(cmd, "-device");
8627
                            if (!(codecstr = qemuBuildSoundCodecStr(sound, &codec, qemuCaps))) {
8628 8629 8630 8631 8632 8633
                                goto error;

                            }
                            virCommandAddArg(cmd, codecstr);
                            VIR_FREE(codecstr);
                        }
8634
                    }
8635 8636 8637 8638 8639
                }
            }
        } else {
            int size = 100;
            char *modstr;
8640
            if (VIR_ALLOC_N(modstr, size+1) < 0)
8641
                goto error;
8642

8643
            for (i = 0; i < def->nsounds && size > 0; i++) {
8644 8645 8646 8647
                virDomainSoundDefPtr sound = def->sounds[i];
                const char *model = virDomainSoundModelTypeToString(sound->model);
                if (!model) {
                    VIR_FREE(modstr);
8648 8649
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   "%s", _("invalid sound model"));
8650 8651
                    goto error;
                }
8652

8653 8654
                if (sound->model == VIR_DOMAIN_SOUND_MODEL_ICH6 ||
                    sound->model == VIR_DOMAIN_SOUND_MODEL_ICH9) {
A
Alex Jia 已提交
8655
                    VIR_FREE(modstr);
8656 8657
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("this QEMU binary lacks hda support"));
8658 8659 8660
                    goto error;
                }

8661 8662 8663 8664 8665 8666 8667 8668 8669 8670 8671 8672 8673 8674 8675
                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;

8676
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8677 8678
            virCommandAddArg(cmd, "-device");

8679
            optstr = qemuBuildWatchdogDevStr(def, watchdog, qemuCaps);
8680 8681 8682 8683 8684 8685 8686
            if (!optstr)
                goto error;
        } else {
            virCommandAddArg(cmd, "-watchdog");

            const char *model = virDomainWatchdogModelTypeToString(watchdog->model);
            if (!model) {
8687 8688
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               "%s", _("missing watchdog model"));
8689 8690 8691
                goto error;
            }

8692 8693
            if (VIR_STRDUP(optstr, model) < 0)
                goto error;
8694 8695 8696 8697 8698 8699 8700 8701 8702
        }
        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) {
8703 8704
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("invalid watchdog action"));
8705 8706 8707 8708 8709
            goto error;
        }
        virCommandAddArgList(cmd, "-watchdog-action", action, NULL);
    }

8710
    /* Add redirected devices */
8711
    for (i = 0; i < def->nredirdevs; i++) {
8712 8713 8714 8715 8716 8717
        virDomainRedirdevDefPtr redirdev = def->redirdevs[i];
        char *devstr;

        virCommandAddArg(cmd, "-chardev");
        if (!(devstr = qemuBuildChrChardevStr(&redirdev->source.chr,
                                              redirdev->info.alias,
8718
                                              qemuCaps))) {
8719 8720 8721 8722 8723 8724
            goto error;
        }

        virCommandAddArg(cmd, devstr);
        VIR_FREE(devstr);

8725
        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
8726 8727 8728
            goto error;

        virCommandAddArg(cmd, "-device");
8729
        if (!(devstr = qemuBuildRedirdevDevStr(def, redirdev, qemuCaps)))
8730 8731 8732 8733 8734
            goto error;
        virCommandAddArg(cmd, devstr);
        VIR_FREE(devstr);
    }

8735
    /* Add host passthrough hardware */
8736
    for (i = 0; i < def->nhostdevs; i++) {
8737 8738 8739
        virDomainHostdevDefPtr hostdev = def->hostdevs[i];
        char *devstr;

8740
        if (hostdev->info->bootIndex) {
8741
            if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
8742
                (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
8743 8744
                 hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
                 hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI)) {
8745
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
8746
                               _("booting from assigned devices is only "
8747
                                 "supported for PCI, USB and SCSI devices"));
8748
                goto error;
8749
            } else {
8750 8751
                if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
                    if (hostdev->source.subsys.u.pci.backend
8752
                        == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
8753 8754 8755 8756 8757 8758 8759 8760 8761 8762 8763 8764 8765 8766
                        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;
                        }
                    }
8767 8768
                }
                if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
8769
                    !virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_HOST_BOOTINDEX)) {
8770
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
8771 8772
                                   _("booting from assigned USB devices is not "
                                     "supported with this version of qemu"));
8773 8774
                    goto error;
                }
8775 8776 8777 8778 8779 8780 8781
                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;
                }
8782 8783 8784
            }
        }

8785 8786 8787 8788
        /* USB */
        if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
            hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {

8789
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8790
                virCommandAddArg(cmd, "-device");
8791
                if (!(devstr = qemuBuildUSBHostdevDevStr(def, hostdev, qemuCaps)))
8792 8793 8794 8795 8796
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
            } else {
                virCommandAddArg(cmd, "-usbdevice");
8797
                if (!(devstr = qemuBuildUSBHostdevUSBDevStr(hostdev)))
8798 8799 8800 8801 8802 8803 8804 8805 8806
                    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) {
8807
            int backend = hostdev->source.subsys.u.pci.backend;
8808

8809
            if (backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
8810 8811 8812 8813 8814 8815
                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;
                }
8816 8817 8818
                /* VFIO requires all of the guest's memory to be locked
                 * resident */
                mlock = true;
8819 8820
            }

8821
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8822
                char *configfd_name = NULL;
8823
                if ((backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) &&
8824
                    virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
8825 8826 8827 8828 8829
                    int configfd = qemuOpenPCIConfig(hostdev);

                    if (configfd >= 0) {
                        if (virAsprintf(&configfd_name, "%d", configfd) < 0) {
                            VIR_FORCE_CLOSE(configfd);
8830
                            goto error;
8831 8832
                        }

8833 8834
                        virCommandPassFD(cmd, configfd,
                                         VIR_COMMAND_PASS_FD_CLOSE_PARENT);
8835 8836 8837
                    }
                }
                virCommandAddArg(cmd, "-device");
8838
                devstr = qemuBuildPCIHostdevDevStr(def, hostdev, configfd_name, qemuCaps);
8839 8840 8841 8842 8843
                VIR_FREE(configfd_name);
                if (!devstr)
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
8844
            } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCIDEVICE)) {
8845
                virCommandAddArg(cmd, "-pcidevice");
8846
                if (!(devstr = qemuBuildPCIHostdevPCIDevStr(hostdev, qemuCaps)))
8847 8848 8849 8850
                    goto error;
                virCommandAddArg(cmd, devstr);
                VIR_FREE(devstr);
            } else {
8851 8852
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("PCI device assignment is not supported by this version of qemu"));
8853 8854 8855
                goto error;
            }
        }
8856 8857 8858 8859 8860 8861 8862 8863 8864 8865

        /* 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");
8866
                if (!(drvstr = qemuBuildSCSIHostdevDrvStr(hostdev, qemuCaps, callbacks)))
8867 8868 8869 8870 8871 8872 8873 8874 8875 8876 8877 8878 8879 8880 8881
                    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;
            }
        }
8882 8883
    }

8884 8885 8886 8887 8888 8889
    /* 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")) {
8890
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_TCP)) {
8891 8892 8893
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("TCP migration is not supported with "
                                       "this QEMU binary"));
8894 8895 8896 8897
                goto error;
            }
            virCommandAddArg(cmd, migrateFrom);
        } else if (STREQ(migrateFrom, "stdio")) {
8898
            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) {
8899
                virCommandAddArgFormat(cmd, "fd:%d", migrateFd);
8900
                virCommandPassFD(cmd, migrateFd, 0);
8901
            } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) {
8902 8903
                virCommandAddArg(cmd, "exec:cat");
                virCommandSetInputFD(cmd, migrateFd);
8904
            } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_KVM_STDIO)) {
8905 8906 8907
                virCommandAddArg(cmd, migrateFrom);
                virCommandSetInputFD(cmd, migrateFd);
            } else {
8908 8909 8910
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("STDIO migration is not supported "
                                       "with this QEMU binary"));
8911 8912 8913
                goto error;
            }
        } else if (STRPREFIX(migrateFrom, "exec")) {
8914
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) {
8915 8916 8917
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("EXEC migration is not supported "
                                       "with this QEMU binary"));
8918 8919 8920 8921
                goto error;
            }
            virCommandAddArg(cmd, migrateFrom);
        } else if (STRPREFIX(migrateFrom, "fd")) {
8922
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD)) {
8923 8924 8925
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("FD migration is not supported "
                                       "with this QEMU binary"));
8926 8927 8928
                goto error;
            }
            virCommandAddArg(cmd, migrateFrom);
8929
            virCommandPassFD(cmd, migrateFd, 0);
8930
        } else if (STRPREFIX(migrateFrom, "unix")) {
8931
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_UNIX)) {
8932 8933 8934
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               "%s", _("UNIX migration is not supported "
                                       "with this QEMU binary"));
8935 8936 8937
                goto error;
            }
            virCommandAddArg(cmd, migrateFrom);
8938
        } else {
8939 8940
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           "%s", _("unknown migration protocol"));
8941 8942 8943
            goto error;
        }
    }
8944 8945 8946 8947 8948 8949 8950

    /* 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
     */
8951 8952
    if (STREQLEN(def->os.machine, "s390-virtio", 10) &&
        virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390) && def->memballoon)
8953 8954 8955 8956
        def->memballoon->model = VIR_DOMAIN_MEMBALLOON_MODEL_NONE;

    if (def->memballoon &&
        def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_NONE) {
8957
        if (def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO) {
8958 8959 8960
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("Memory balloon device type '%s' is not supported by this version of qemu"),
                           virDomainMemballoonModelTypeToString(def->memballoon->model));
8961 8962
            goto error;
        }
8963
        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
8964 8965 8966
            char *optstr;
            virCommandAddArg(cmd, "-device");

8967
            optstr = qemuBuildMemballoonDevStr(def, def->memballoon, qemuCaps);
8968 8969 8970 8971
            if (!optstr)
                goto error;
            virCommandAddArg(cmd, optstr);
            VIR_FREE(optstr);
8972
        } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BALLOON)) {
8973 8974 8975 8976
            virCommandAddArgList(cmd, "-balloon", "virtio", NULL);
        }
    }

8977 8978 8979 8980 8981 8982
    if (def->rng) {
        /* add the RNG source backend */
        if (qemuBuildRNGBackendArgs(cmd, def->rng, qemuCaps) < 0)
            goto error;

        /* add the device */
8983
        if (qemuBuildRNGDeviceArgs(cmd, def, def->rng, qemuCaps) < 0)
8984 8985 8986
            goto error;
    }

8987 8988 8989 8990 8991 8992 8993 8994 8995 8996 8997 8998 8999 9000 9001 9002 9003 9004 9005 9006 9007 9008 9009 9010
    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;
        }
    }
9011 9012
    if (snapshot)
        virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL);
9013 9014 9015 9016 9017 9018 9019 9020 9021 9022 9023 9024 9025

    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] : "");
    }

9026
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SECCOMP_SANDBOX)) {
9027
        if (cfg->seccompSandbox == 0)
9028
            virCommandAddArgList(cmd, "-sandbox", "off", NULL);
9029
        else if (cfg->seccompSandbox > 0)
9030
            virCommandAddArgList(cmd, "-sandbox", "on", NULL);
9031
    } else if (cfg->seccompSandbox > 0) {
9032 9033 9034 9035 9036
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("QEMU does not support seccomp sandboxes"));
        goto error;
    }

H
Hu Tao 已提交
9037 9038 9039 9040 9041 9042 9043 9044 9045 9046 9047 9048 9049 9050 9051 9052
    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;
        }
    }

9053 9054 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065
    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);
    }
9066

9067 9068 9069 9070
    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSG_TIMESTAMP) &&
        cfg->logTimestamp)
        virCommandAddArgList(cmd, "-msg", "timestamp=on", NULL);

9071
    virObjectUnref(cfg);
9072 9073
    return cmd;

9074
 error:
9075
    virObjectUnref(cfg);
9076 9077 9078
    /* free up any resources in the network driver
     * but don't overwrite the original error */
    originalError = virSaveLastError();
9079
    for (i = 0; last_good_net != -1 && i <= last_good_net; i++)
9080
        virDomainConfNWFilterTeardown(def->nets[i]);
9081
    virSetError(originalError);
J
John Ferlan 已提交
9082
    virFreeError(originalError);
9083 9084 9085 9086
    virCommandFree(cmd);
    return NULL;
}

9087 9088 9089
/* This function generates the correct '-device' string for character
 * devices of each architecture.
 */
9090 9091
static int
qemuBuildSerialChrDeviceStr(char **deviceStr,
9092
                            virDomainDefPtr def,
9093 9094 9095 9096
                            virDomainChrDefPtr serial,
                            virQEMUCapsPtr qemuCaps,
                            virArch arch,
                            char *machine)
9097 9098 9099
{
    virBuffer cmd = VIR_BUFFER_INITIALIZER;

9100
    if ((arch == VIR_ARCH_PPC64) && STREQ(machine, "pseries")) {
9101 9102 9103 9104
        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);
9105
            if (qemuBuildDeviceAddressStr(&cmd, def, &serial->info, qemuCaps) < 0)
9106 9107
                goto error;
        }
G
Guannan Ren 已提交
9108 9109 9110
    } else {
        virBufferAsprintf(&cmd, "%s,chardev=char%s,id=%s",
                          virDomainChrSerialTargetTypeToString(serial->targetType),
9111 9112
                          serial->info.alias, serial->info.alias);

G
Guannan Ren 已提交
9113
        if (serial->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB) {
9114
            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_SERIAL)) {
G
Guannan Ren 已提交
9115 9116 9117 9118 9119 9120 9121 9122 9123 9124 9125 9126
                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;
            }

9127
            if (qemuBuildDeviceAddressStr(&cmd, def, &serial->info, qemuCaps) < 0)
9128
                goto error;
G
Guannan Ren 已提交
9129 9130 9131
        }
    }

9132
    if (virBufferCheckError(&cmd) < 0)
9133 9134
        goto error;

9135 9136
    *deviceStr = virBufferContentAndReset(&cmd);
    return 0;
9137

9138
 error:
9139
    virBufferFreeAndReset(&cmd);
9140 9141 9142 9143 9144 9145 9146 9147
    return -1;
}

static int
qemuBuildParallelChrDeviceStr(char **deviceStr,
                              virDomainChrDefPtr chr)
{
    if (virAsprintf(deviceStr, "isa-parallel,chardev=char%s,id=%s",
J
Ján Tomko 已提交
9148
                    chr->info.alias, chr->info.alias) < 0)
9149 9150
        return -1;
    return 0;
9151
}
9152

9153 9154 9155 9156 9157 9158 9159 9160 9161
static int
qemuBuildChannelChrDeviceStr(char **deviceStr,
                             virDomainChrDefPtr chr,
                             virQEMUCapsPtr qemuCaps)
{
    int ret = -1;
    char *addr = NULL;
    int port;

9162
    switch ((virDomainChrChannelTargetType) chr->targetType) {
9163 9164 9165 9166 9167 9168 9169 9170
    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,
9171
                        "user,guestfwd=tcp:%s:%i-chardev:char%s,id=user-%s",
J
Ján Tomko 已提交
9172
                        addr, port, chr->info.alias, chr->info.alias) < 0)
9173 9174 9175 9176 9177 9178 9179 9180 9181 9182 9183 9184 9185 9186
            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;
9187
 cleanup:
9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198
    VIR_FREE(addr);
    return ret;
}

static int
qemuBuildConsoleChrDeviceStr(char **deviceStr,
                             virDomainChrDefPtr chr,
                             virQEMUCapsPtr qemuCaps)
{
    int ret = -1;

9199
    switch ((virDomainChrConsoleTargetType) chr->targetType) {
9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221
    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;
9222
 cleanup:
9223 9224 9225 9226 9227 9228 9229 9230 9231 9232 9233
    return ret;
}

int
qemuBuildChrDeviceStr(char **deviceStr,
                      virDomainDefPtr vmdef,
                      virDomainChrDefPtr chr,
                      virQEMUCapsPtr qemuCaps)
{
    int ret = -1;

9234
    switch ((virDomainChrDeviceType) chr->deviceType) {
9235
    case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL:
9236
        ret = qemuBuildSerialChrDeviceStr(deviceStr, vmdef, chr, qemuCaps,
9237 9238 9239 9240 9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 9259 9260
                                          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;
}


9261 9262 9263 9264 9265 9266 9267
/*
 * 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 已提交
9268 9269
                               char ***retenv,
                               char ***retargv)
9270 9271
{
    char **arglist = NULL;
9272 9273 9274
    size_t argcount = 0;
    size_t argalloc = 0;
    size_t envend;
9275
    size_t i;
9276 9277
    const char *curr = args;
    const char *start;
E
Eric Blake 已提交
9278 9279
    char **progenv = NULL;
    char **progargv = NULL;
9280 9281 9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296 9297 9298 9299 9300 9301 9302 9303 9304

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

9305
        if (VIR_STRNDUP(arg, curr, next ? next - curr : -1) < 0)
9306
            goto error;
9307

9308 9309
        if (next && (*next == '\'' || *next == '"'))
            next++;
9310

9311 9312 9313
        if (VIR_RESIZE_N(arglist, argalloc, argcount, 2) < 0) {
            VIR_FREE(arg);
            goto error;
9314 9315 9316
        }

        arglist[argcount++] = arg;
9317
        arglist[argcount] = NULL;
9318 9319 9320 9321 9322 9323 9324 9325 9326

        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) */
9327
    for (envend = 0; ((envend < argcount) &&
9328 9329 9330 9331 9332 9333 9334
                       (strchr(arglist[envend], '=') != NULL));
         envend++)
        ; /* nada */

    /* Copy the list of env vars */
    if (envend > 0) {
        if (VIR_REALLOC_N(progenv, envend+1) < 0)
9335
            goto error;
9336
        for (i = 0; i < envend; i++)
9337 9338 9339 9340 9341 9342
            progenv[i] = arglist[i];
        progenv[i] = NULL;
    }

    /* Copy the list of argv */
    if (VIR_REALLOC_N(progargv, argcount-envend + 1) < 0)
9343
        goto error;
9344
    for (i = envend; i < argcount; i++)
9345 9346 9347 9348 9349 9350 9351 9352 9353 9354
        progargv[i-envend] = arglist[i];
    progargv[i-envend] = NULL;

    VIR_FREE(arglist);

    *retenv = progenv;
    *retargv = progargv;

    return 0;

9355
 error:
9356 9357
    VIR_FREE(progenv);
    VIR_FREE(progargv);
E
Eric Blake 已提交
9358
    virStringFreeList(arglist);
9359 9360 9361 9362 9363 9364 9365
    return -1;
}


/*
 * Search for a named env variable, and return the value part
 */
E
Eric Blake 已提交
9366
static const char *qemuFindEnv(char **progenv,
9367 9368
                               const char *name)
{
9369
    size_t i;
9370 9371
    int len = strlen(name);

9372
    for (i = 0; progenv && progenv[i]; i++) {
9373 9374 9375 9376 9377 9378 9379 9380 9381 9382 9383 9384 9385 9386 9387 9388 9389 9390
        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,
9391
                  int *retnkeywords,
9392 9393 9394 9395 9396 9397 9398 9399
                  int allowEmptyValue)
{
    int keywordCount = 0;
    int keywordAlloc = 0;
    char **keywords = NULL;
    char **values = NULL;
    const char *start = str;
    const char *end;
9400
    size_t i;
9401 9402 9403

    *retkeywords = NULL;
    *retvalues = NULL;
9404
    *retnkeywords = 0;
9405 9406 9407 9408 9409 9410 9411 9412
    end = start + strlen(str);

    while (start) {
        const char *separator;
        const char *endmark;
        char *keyword;
        char *value = NULL;

9413 9414 9415 9416 9417 9418 9419 9420
        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)
9421 9422 9423 9424 9425 9426
            endmark = end;
        if (!(separator = strchr(start, '=')))
            separator = end;

        if (separator >= endmark) {
            if (!allowEmptyValue) {
9427 9428
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("malformed keyword arguments in '%s'"), str);
9429 9430 9431 9432 9433
                goto error;
            }
            separator = endmark;
        }

9434 9435
        if (VIR_STRNDUP(keyword, start, separator - start) < 0)
            goto error;
9436 9437 9438

        if (separator < endmark) {
            separator++;
9439
            if (VIR_STRNDUP(value, separator, endmark - separator) < 0) {
9440
                VIR_FREE(keyword);
9441
                goto error;
9442
            }
9443 9444 9445 9446 9447 9448 9449 9450 9451 9452
            if (strchr(value, ',')) {
                char *p = strchr(value, ',') + 1;
                char *q = p + 1;
                while (*q) {
                    if (*q == ',')
                        q++;
                    *p++ = *q++;
                }
                *p = '\0';
            }
9453 9454 9455 9456 9457 9458 9459
        }

        if (keywordAlloc == keywordCount) {
            if (VIR_REALLOC_N(keywords, keywordAlloc + 10) < 0 ||
                VIR_REALLOC_N(values, keywordAlloc + 10) < 0) {
                VIR_FREE(keyword);
                VIR_FREE(value);
9460
                goto error;
9461 9462 9463 9464 9465 9466 9467 9468 9469 9470 9471 9472 9473
            }
            keywordAlloc += 10;
        }

        keywords[keywordCount] = keyword;
        values[keywordCount] = value;
        keywordCount++;

        start = endmark < end ? endmark + 1 : NULL;
    }

    *retkeywords = keywords;
    *retvalues = values;
9474 9475
    *retnkeywords = keywordCount;
    return 0;
9476

9477
 error:
9478
    for (i = 0; i < keywordCount; i++) {
9479 9480 9481 9482 9483 9484 9485 9486 9487 9488 9489 9490 9491 9492 9493 9494
        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
9495
qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt,
9496
                         const char *val,
9497
                         virDomainDefPtr dom,
9498 9499
                         int nvirtiodisk,
                         bool old_style_ceph_args)
9500 9501 9502 9503 9504
{
    virDomainDiskDefPtr def = NULL;
    char **keywords;
    char **values;
    int nkeywords;
9505
    size_t i;
9506 9507 9508
    int idx = -1;
    int busid = -1;
    int unitid = -1;
9509
    int trans = VIR_DOMAIN_DISK_TRANS_DEFAULT;
9510

9511 9512 9513 9514 9515
    if (qemuParseKeywords(val,
                          &keywords,
                          &values,
                          &nkeywords,
                          0) < 0)
9516 9517
        return NULL;

9518
    if (VIR_ALLOC(def) < 0)
9519
        goto cleanup;
9520 9521
    if (VIR_ALLOC(def->src) < 0)
        goto error;
9522

9523 9524 9525 9526 9527
    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;
9528
    def->device = VIR_DOMAIN_DISK_DEVICE_DISK;
9529
    def->src->type = VIR_STORAGE_TYPE_FILE;
9530

9531
    for (i = 0; i < nkeywords; i++) {
9532 9533
        if (STREQ(keywords[i], "file")) {
            if (values[i] && STRNEQ(values[i], "")) {
9534
                def->src->path = values[i];
9535
                values[i] = NULL;
9536 9537 9538 9539 9540 9541
                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;
9542

9543 9544
                    if (qemuParseNBDString(def) < 0)
                        goto error;
9545 9546
                } else if (STRPREFIX(def->src->path, "rbd:")) {
                    char *p = def->src->path;
9547

9548 9549 9550
                    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)
9551
                        goto error;
9552
                    /* old-style CEPH_ARGS env variable is parsed later */
9553 9554 9555 9556
                    if (!old_style_ceph_args && qemuParseRBDString(def) < 0) {
                        VIR_FREE(p);
                        goto error;
                    }
9557 9558

                    VIR_FREE(p);
9559 9560 9561 9562
                } 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;
9563 9564

                    if (qemuParseGlusterString(def) < 0)
9565
                        goto error;
9566 9567 9568
                } 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 已提交
9569 9570 9571

                    if (qemuParseISCSIString(def) < 0)
                        goto error;
9572 9573
                } else if (STRPREFIX(def->src->path, "sheepdog:")) {
                    char *p = def->src->path;
9574 9575
                    char *port, *vdi;

9576 9577 9578
                    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)
9579
                        goto error;
9580
                    VIR_FREE(p);
9581

9582 9583
                    /* def->src->path must be [vdiname] or [host]:[port]:[vdiname] */
                    port = strchr(def->src->path, ':');
9584
                    if (port) {
9585 9586
                        *port = '\0';
                        vdi = strchr(port + 1, ':');
9587
                        if (!vdi) {
9588
                            *port = ':';
9589
                            virReportError(VIR_ERR_INTERNAL_ERROR,
9590
                                           _("cannot parse sheepdog filename '%s'"),
9591
                                           def->src->path);
9592
                            goto error;
9593
                        }
9594
                        port++;
9595
                        *vdi++ = '\0';
9596
                        if (VIR_ALLOC(def->src->hosts) < 0)
9597
                            goto error;
9598 9599 9600
                        def->src->nhosts = 1;
                        def->src->hosts->name = def->src->path;
                        if (VIR_STRDUP(def->src->hosts->port, port) < 0)
9601
                            goto error;
9602 9603 9604
                        def->src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
                        def->src->hosts->socket = NULL;
                        if (VIR_STRDUP(def->src->path, vdi) < 0)
9605
                            goto error;
9606 9607
                    }
                } else
9608
                    def->src->type = VIR_STORAGE_TYPE_FILE;
9609
            } else {
9610
                def->src->type = VIR_STORAGE_TYPE_FILE;
9611 9612
            }
        } else if (STREQ(keywords[i], "if")) {
9613
            if (STREQ(values[i], "ide")) {
9614
                def->bus = VIR_DOMAIN_DISK_BUS_IDE;
9615 9616 9617 9618 9619 9620 9621
                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"))
9622 9623 9624 9625 9626
                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;
9627 9628
            else if (STREQ(values[i], "sd"))
                def->bus = VIR_DOMAIN_DISK_BUS_SD;
9629 9630 9631
        } else if (STREQ(keywords[i], "media")) {
            if (STREQ(values[i], "cdrom")) {
                def->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
9632
                def->readonly = true;
9633 9634 9635
            } else if (STREQ(values[i], "floppy"))
                def->device = VIR_DOMAIN_DISK_DEVICE_FLOPPY;
        } else if (STREQ(keywords[i], "format")) {
9636
            if (VIR_STRDUP(def->src->driverName, "qemu") < 0)
9637
                goto error;
9638
            def->src->format = virStorageFileFormatTypeFromString(values[i]);
9639 9640 9641 9642 9643 9644 9645 9646 9647
        } 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;
9648 9649
            else if (STREQ(values[i], "directsync"))
                def->cachemode = VIR_DOMAIN_DISK_CACHE_DIRECTSYNC;
9650 9651
            else if (STREQ(values[i], "unsafe"))
                def->cachemode = VIR_DOMAIN_DISK_CACHE_UNSAFE;
9652
        } else if (STREQ(keywords[i], "werror")) {
9653 9654
            if (STREQ(values[i], "stop"))
                def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_STOP;
9655 9656
            else if (STREQ(values[i], "report"))
                def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_REPORT;
9657 9658
            else if (STREQ(values[i], "ignore"))
                def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_IGNORE;
9659
            else if (STREQ(values[i], "enospc"))
9660
                def->error_policy = VIR_DOMAIN_DISK_ERROR_POLICY_ENOSPACE;
9661 9662 9663 9664 9665 9666 9667
        } 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;
9668 9669
        } else if (STREQ(keywords[i], "index")) {
            if (virStrToLong_i(values[i], NULL, 10, &idx) < 0) {
9670 9671
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse drive index '%s'"), val);
9672
                goto error;
9673 9674 9675
            }
        } else if (STREQ(keywords[i], "bus")) {
            if (virStrToLong_i(values[i], NULL, 10, &busid) < 0) {
9676 9677
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse drive bus '%s'"), val);
9678
                goto error;
9679 9680 9681
            }
        } else if (STREQ(keywords[i], "unit")) {
            if (virStrToLong_i(values[i], NULL, 10, &unitid) < 0) {
9682 9683
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse drive unit '%s'"), val);
9684
                goto error;
9685 9686 9687
            }
        } else if (STREQ(keywords[i], "readonly")) {
            if ((values[i] == NULL) || STREQ(values[i], "on"))
9688
                def->readonly = true;
E
Eric Blake 已提交
9689 9690
        } else if (STREQ(keywords[i], "aio")) {
            if ((def->iomode = virDomainDiskIoTypeFromString(values[i])) < 0) {
9691 9692
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse io mode '%s'"), values[i]);
9693
                goto error;
E
Eric Blake 已提交
9694
            }
9695 9696 9697 9698 9699 9700 9701 9702
        } 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]);
9703
                goto error;
9704 9705 9706 9707 9708 9709 9710 9711 9712
            }
        } 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]);
9713
                goto error;
9714 9715 9716 9717 9718 9719 9720 9721 9722
            }
        } 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]);
9723
                goto error;
9724 9725 9726 9727 9728 9729 9730 9731 9732 9733 9734
            }
        } 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]);
9735
                goto error;
9736
            }
9737 9738 9739
        }
    }

9740 9741 9742
    if (def->rerror_policy == def->error_policy)
        def->rerror_policy = 0;

9743
    if (!def->src->path &&
9744
        def->device == VIR_DOMAIN_DISK_DEVICE_DISK &&
9745
        def->src->type != VIR_STORAGE_TYPE_NETWORK) {
9746 9747
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("missing file parameter in drive '%s'"), val);
9748
        goto error;
9749 9750 9751 9752 9753 9754 9755 9756
    }
    if (idx == -1 &&
        def->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
        idx = nvirtiodisk;

    if (idx == -1 &&
        unitid == -1 &&
        busid == -1) {
9757
        virReportError(VIR_ERR_INTERNAL_ERROR,
9758 9759 9760
                       _("missing index/unit/bus parameter in drive '%s'"),
                       val);
        goto error;
9761 9762 9763 9764 9765 9766 9767 9768 9769 9770 9771 9772 9773 9774 9775 9776 9777 9778 9779 9780 9781
    }

    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) {
9782
        ignore_value(VIR_STRDUP(def->dst, "hda"));
9783 9784
    } else if (def->bus == VIR_DOMAIN_DISK_BUS_SCSI ||
               def->bus == VIR_DOMAIN_DISK_BUS_SD) {
9785
        ignore_value(VIR_STRDUP(def->dst, "sda"));
9786
    } else if (def->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
9787
        ignore_value(VIR_STRDUP(def->dst, "vda"));
9788
    } else if (def->bus == VIR_DOMAIN_DISK_BUS_XEN) {
9789
        ignore_value(VIR_STRDUP(def->dst, "xvda"));
9790
    } else {
9791
        ignore_value(VIR_STRDUP(def->dst, "hda"));
9792 9793
    }

9794
    if (!def->dst)
9795
        goto error;
9796 9797 9798 9799 9800
    if (STREQ(def->dst, "xvda"))
        def->dst[3] = 'a' + idx;
    else
        def->dst[2] = 'a' + idx;

9801
    if (virDomainDiskDefAssignAddress(xmlopt, def) < 0) {
9802 9803
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("invalid device name '%s'"), def->dst);
9804 9805
        virDomainDiskDefFree(def);
        def = NULL;
9806
        goto cleanup;
9807 9808
    }

9809
 cleanup:
9810
    for (i = 0; i < nkeywords; i++) {
9811 9812 9813 9814 9815 9816
        VIR_FREE(keywords[i]);
        VIR_FREE(values[i]);
    }
    VIR_FREE(keywords);
    VIR_FREE(values);
    return def;
9817

9818
 error:
9819 9820 9821
    virDomainDiskDefFree(def);
    def = NULL;
    goto cleanup;
9822 9823 9824 9825 9826 9827 9828 9829 9830 9831
}

/*
 * Tries to find a NIC definition matching a vlan we want
 */
static const char *
qemuFindNICForVLAN(int nnics,
                   const char **nics,
                   int wantvlan)
{
9832
    size_t i;
9833
    for (i = 0; i < nnics; i++) {
9834 9835 9836 9837 9838 9839 9840 9841 9842
        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) {
9843 9844
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot parse NIC vlan in '%s'"), nics[i]);
9845 9846 9847 9848 9849 9850 9851 9852 9853 9854
            return NULL;
        }

        if (gotvlan == wantvlan)
            return nics[i];
    }

    if (wantvlan == 0 && nnics > 0)
        return nics[0];

9855 9856
    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("cannot find NIC definition for vlan %d"), wantvlan);
9857 9858 9859 9860 9861 9862 9863 9864 9865 9866
    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
9867
qemuParseCommandLineNet(virDomainXMLOptionPtr xmlopt,
9868 9869 9870 9871 9872 9873 9874 9875 9876 9877 9878
                        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;
9879
    bool genmac = true;
9880
    size_t i;
9881 9882 9883 9884

    tmp = strchr(val, ',');

    if (tmp) {
9885 9886 9887 9888 9889
        if (qemuParseKeywords(tmp+1,
                              &keywords,
                              &values,
                              &nkeywords,
                              0) < 0)
9890 9891 9892 9893 9894
            return NULL;
    } else {
        nkeywords = 0;
    }

9895
    if (VIR_ALLOC(def) < 0)
9896 9897 9898 9899 9900 9901 9902 9903 9904 9905 9906 9907 9908
        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;

9909
    for (i = 0; i < nkeywords; i++) {
9910 9911
        if (STREQ(keywords[i], "vlan")) {
            if (virStrToLong_i(values[i], NULL, 10, &wantvlan) < 0) {
9912 9913
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse vlan in '%s'"), val);
9914 9915 9916 9917 9918 9919
                virDomainNetDefFree(def);
                def = NULL;
                goto cleanup;
            }
        } else if (def->type == VIR_DOMAIN_NET_TYPE_ETHERNET &&
                   STREQ(keywords[i], "script") && STRNEQ(values[i], "")) {
9920
            def->script = values[i];
9921 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941
            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")) {
9942 9943
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot parse NIC definition '%s'"), nic);
9944 9945 9946 9947 9948
        virDomainNetDefFree(def);
        def = NULL;
        goto cleanup;
    }

9949
    for (i = 0; i < nkeywords; i++) {
9950 9951 9952 9953 9954 9955 9956
        VIR_FREE(keywords[i]);
        VIR_FREE(values[i]);
    }
    VIR_FREE(keywords);
    VIR_FREE(values);

    if (STRPREFIX(nic, "nic,")) {
9957 9958 9959 9960 9961
        if (qemuParseKeywords(nic + strlen("nic,"),
                              &keywords,
                              &values,
                              &nkeywords,
                              0) < 0) {
9962 9963 9964 9965 9966 9967 9968 9969
            virDomainNetDefFree(def);
            def = NULL;
            goto cleanup;
        }
    } else {
        nkeywords = 0;
    }

9970
    for (i = 0; i < nkeywords; i++) {
9971
        if (STREQ(keywords[i], "macaddr")) {
9972
            genmac = false;
9973
            if (virMacAddrParse(values[i], &def->mac) < 0) {
9974 9975 9976
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("unable to parse mac address '%s'"),
                               values[i]);
9977 9978 9979 9980 9981 9982 9983
                virDomainNetDefFree(def);
                def = NULL;
                goto cleanup;
            }
        } else if (STREQ(keywords[i], "model")) {
            def->model = values[i];
            values[i] = NULL;
9984 9985
        } else if (STREQ(keywords[i], "vhost")) {
            if ((values[i] == NULL) || STREQ(values[i], "on")) {
9986
                def->driver.virtio.name = VIR_DOMAIN_NET_BACKEND_TYPE_VHOST;
9987
            } else if (STREQ(keywords[i], "off")) {
9988
                def->driver.virtio.name = VIR_DOMAIN_NET_BACKEND_TYPE_QEMU;
9989
            }
9990 9991
        } else if (STREQ(keywords[i], "sndbuf") && values[i]) {
            if (virStrToLong_ul(values[i], NULL, 10, &def->tune.sndbuf) < 0) {
9992 9993
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("cannot parse sndbuf size in '%s'"), val);
9994 9995 9996 9997 9998
                virDomainNetDefFree(def);
                def = NULL;
                goto cleanup;
            }
            def->tune.sndbuf_specified = true;
9999 10000 10001 10002
        }
    }

    if (genmac)
10003
        virDomainNetGenerateMAC(xmlopt, &def->mac);
10004

10005
 cleanup:
10006
    for (i = 0; i < nkeywords; i++) {
10007 10008 10009 10010 10011 10012 10013 10014 10015 10016 10017 10018 10019 10020 10021 10022 10023 10024
        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;
10025 10026 10027 10028
    virDomainHostdevDefPtr def = virDomainHostdevDefAlloc();

    if (!def)
       goto error;
10029 10030

    if (!STRPREFIX(val, "host=")) {
10031 10032
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown PCI device syntax '%s'"), val);
10033
        goto error;
10034 10035 10036 10037
    }

    start = val + strlen("host=");
    if (virStrToLong_i(start, &end, 16, &bus) < 0 || *end != ':') {
10038 10039
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot extract PCI device bus '%s'"), val);
10040
        goto error;
10041 10042 10043
    }
    start = end + 1;
    if (virStrToLong_i(start, &end, 16, &slot) < 0 || *end != '.') {
10044 10045
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot extract PCI device slot '%s'"), val);
10046
        goto error;
10047 10048 10049
    }
    start = end + 1;
    if (virStrToLong_i(start, NULL, 16, &func) < 0) {
10050 10051
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot extract PCI device function '%s'"), val);
10052
        goto error;
10053 10054 10055
    }

    def->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
10056
    def->managed = true;
10057
    def->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
10058 10059 10060
    def->source.subsys.u.pci.addr.bus = bus;
    def->source.subsys.u.pci.addr.slot = slot;
    def->source.subsys.u.pci.addr.function = func;
10061
    return def;
10062 10063 10064 10065

 error:
    virDomainHostdevDefFree(def);
    return NULL;
10066 10067 10068 10069 10070 10071 10072 10073 10074
}


/*
 * Tries to parse a QEMU USB device
 */
static virDomainHostdevDefPtr
qemuParseCommandLineUSB(const char *val)
{
10075
    virDomainHostdevDefPtr def = virDomainHostdevDefAlloc();
10076 10077 10078 10079
    int first = 0, second = 0;
    const char *start;
    char *end;

10080 10081 10082
    if (!def)
       goto error;

10083
    if (!STRPREFIX(val, "host:")) {
10084 10085
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown USB device syntax '%s'"), val);
10086
        goto error;
10087 10088 10089 10090 10091
    }

    start = val + strlen("host:");
    if (strchr(start, ':')) {
        if (virStrToLong_i(start, &end, 16, &first) < 0 || *end != ':') {
10092 10093
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot extract USB device vendor '%s'"), val);
10094
            goto error;
10095 10096 10097
        }
        start = end + 1;
        if (virStrToLong_i(start, NULL, 16, &second) < 0) {
10098 10099
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot extract USB device product '%s'"), val);
10100
            goto error;
10101 10102 10103
        }
    } else {
        if (virStrToLong_i(start, &end, 10, &first) < 0 || *end != '.') {
10104 10105
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot extract USB device bus '%s'"), val);
10106
            goto error;
10107 10108 10109
        }
        start = end + 1;
        if (virStrToLong_i(start, NULL, 10, &second) < 0) {
10110 10111
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot extract USB device address '%s'"), val);
10112
            goto error;
10113 10114 10115 10116
        }
    }

    def->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
10117
    def->managed = false;
10118 10119 10120 10121 10122 10123 10124 10125 10126
    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;
10127 10128 10129 10130

 error:
    virDomainHostdevDefFree(def);
    return NULL;
10131 10132 10133 10134 10135 10136
}


/*
 * Tries to parse a QEMU serial/parallel device
 */
10137 10138 10139
static int
qemuParseCommandLineChr(virDomainChrSourceDefPtr source,
                        const char *val)
10140 10141
{
    if (STREQ(val, "null")) {
10142
        source->type = VIR_DOMAIN_CHR_TYPE_NULL;
10143
    } else if (STREQ(val, "vc")) {
10144
        source->type = VIR_DOMAIN_CHR_TYPE_VC;
10145
    } else if (STREQ(val, "pty")) {
10146
        source->type = VIR_DOMAIN_CHR_TYPE_PTY;
10147
    } else if (STRPREFIX(val, "file:")) {
10148
        source->type = VIR_DOMAIN_CHR_TYPE_FILE;
10149 10150
        if (VIR_STRDUP(source->data.file.path, val + strlen("file:")) < 0)
            goto error;
10151
    } else if (STRPREFIX(val, "pipe:")) {
10152
        source->type = VIR_DOMAIN_CHR_TYPE_PIPE;
10153 10154
        if (VIR_STRDUP(source->data.file.path, val + strlen("pipe:")) < 0)
            goto error;
10155
    } else if (STREQ(val, "stdio")) {
10156
        source->type = VIR_DOMAIN_CHR_TYPE_STDIO;
10157 10158
    } else if (STRPREFIX(val, "udp:")) {
        const char *svc1, *host2, *svc2;
10159
        source->type = VIR_DOMAIN_CHR_TYPE_UDP;
10160 10161 10162 10163 10164
        val += strlen("udp:");
        svc1 = strchr(val, ':');
        host2 = svc1 ? strchr(svc1, '@') : NULL;
        svc2 = host2 ? strchr(host2, ':') : NULL;

10165 10166 10167
        if (svc1 && svc1 != val &&
            VIR_STRNDUP(source->data.udp.connectHost, val, svc1 - val) < 0)
            goto error;
10168 10169 10170

        if (svc1) {
            svc1++;
10171 10172 10173
            if (VIR_STRNDUP(source->data.udp.connectService, svc1,
                            host2 ? host2 - svc1 : strlen(svc1)) < 0)
                goto error;
10174 10175 10176 10177
        }

        if (host2) {
            host2++;
10178 10179
            if (svc2 && svc2 != host2 &&
                VIR_STRNDUP(source->data.udp.bindHost, host2, svc2 - host2) < 0)
10180
                goto error;
10181
        }
10182

10183 10184
        if (svc2) {
            svc2++;
10185
            if (STRNEQ(svc2, "0")) {
10186 10187
                if (VIR_STRDUP(source->data.udp.bindService, svc2) < 0)
                    goto error;
10188
            }
10189 10190 10191 10192
        }
    } else if (STRPREFIX(val, "tcp:") ||
               STRPREFIX(val, "telnet:")) {
        const char *opt, *svc;
10193
        source->type = VIR_DOMAIN_CHR_TYPE_TCP;
10194 10195 10196 10197
        if (STRPREFIX(val, "tcp:")) {
            val += strlen("tcp:");
        } else {
            val += strlen("telnet:");
10198
            source->data.tcp.protocol = VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET;
10199 10200 10201
        }
        svc = strchr(val, ':');
        if (!svc) {
10202 10203
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot find port number in character device %s"), val);
10204 10205 10206 10207
            goto error;
        }
        opt = strchr(svc, ',');
        if (opt && strstr(opt, "server"))
10208
            source->data.tcp.listen = true;
10209

10210 10211
        if (VIR_STRNDUP(source->data.tcp.host, val, svc - val) < 0)
            goto error;
10212
        svc++;
10213
        if (VIR_STRNDUP(source->data.tcp.service, svc, opt ? opt - svc : -1) < 0)
10214
            goto error;
10215 10216 10217 10218
    } else if (STRPREFIX(val, "unix:")) {
        const char *opt;
        val += strlen("unix:");
        opt = strchr(val, ',');
10219
        source->type = VIR_DOMAIN_CHR_TYPE_UNIX;
10220
        if (VIR_STRNDUP(source->data.nix.path, val, opt ? opt - val : -1) < 0)
10221
            goto error;
10222 10223

    } else if (STRPREFIX(val, "/dev")) {
10224
        source->type = VIR_DOMAIN_CHR_TYPE_DEV;
10225 10226
        if (VIR_STRDUP(source->data.file.path, val) < 0)
            goto error;
10227
    } else {
10228 10229
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown character device syntax %s"), val);
10230 10231 10232
        goto error;
    }

10233
    return 0;
10234

10235
 error:
10236
    return -1;
10237 10238 10239 10240 10241 10242 10243 10244 10245
}


static virCPUDefPtr
qemuInitGuestCPU(virDomainDefPtr dom)
{
    if (!dom->cpu) {
        virCPUDefPtr cpu;

10246
        if (VIR_ALLOC(cpu) < 0)
10247 10248 10249 10250 10251 10252 10253 10254 10255 10256 10257 10258 10259 10260 10261
            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)
{
10262
    virCPUDefPtr cpu = NULL;
10263
    char **tokens;
10264
    char **hv_tokens = NULL;
10265
    char *model = NULL;
10266
    int ret = -1;
10267
    size_t i;
10268

10269 10270
    if (!(tokens = virStringSplit(val, ",", 0)))
        goto cleanup;
10271

10272 10273
    if (tokens[0] == NULL)
        goto syntax;
10274

10275 10276 10277 10278 10279 10280 10281
    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;
10282 10283 10284

            if (!STREQ(model, "qemu32") && !STREQ(model, "qemu64")) {
                if (!(cpu = qemuInitGuestCPU(dom)))
10285
                    goto cleanup;
10286 10287 10288 10289

                cpu->model = model;
                model = NULL;
            }
10290 10291
        } else if (*tokens[i] == '+' || *tokens[i] == '-') {
            const char *feature = tokens[i] + 1; /* '+' or '-' */
10292 10293
            int policy;

10294
            if (*tokens[i] == '+')
10295 10296 10297 10298
                policy = VIR_CPU_FEATURE_REQUIRE;
            else
                policy = VIR_CPU_FEATURE_DISABLE;

10299
            if (*feature == '\0')
10300 10301
                goto syntax;

10302 10303 10304 10305 10306 10307 10308 10309
            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;
             }

10310 10311
            if (STREQ(feature, "kvmclock")) {
                bool present = (policy == VIR_CPU_FEATURE_REQUIRE);
10312
                size_t j;
10313

10314 10315
                for (j = 0; j < dom->clock.ntimers; j++) {
                    if (dom->clock.timers[j]->name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK)
10316 10317 10318
                        break;
                }

10319
                if (j == dom->clock.ntimers) {
10320 10321 10322 10323 10324
                    virDomainTimerDefPtr timer;
                    if (VIR_ALLOC(timer) < 0 ||
                        VIR_APPEND_ELEMENT_COPY(dom->clock.timers,
                                                dom->clock.ntimers, timer) < 0) {
                        VIR_FREE(timer);
10325
                        goto cleanup;
10326 10327 10328 10329 10330 10331
                    }
                    timer->name = VIR_DOMAIN_TIMER_NAME_KVMCLOCK;
                    timer->present = present;
                    timer->tickpolicy = -1;
                    timer->track = -1;
                    timer->mode = -1;
10332 10333
                } else if (dom->clock.timers[j]->present != -1 &&
                    dom->clock.timers[j]->present != present) {
10334 10335
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                   _("conflicting occurrences of kvmclock feature"));
10336
                    goto cleanup;
10337
                }
10338 10339
            } else if (STREQ(feature, "kvm_pv_eoi")) {
                if (policy == VIR_CPU_FEATURE_REQUIRE)
10340
                    dom->apic_eoi = VIR_DOMAIN_FEATURE_STATE_ON;
10341
                else
10342
                    dom->apic_eoi = VIR_DOMAIN_FEATURE_STATE_OFF;
10343 10344 10345
            } else {
                if (!cpu) {
                    if (!(cpu = qemuInitGuestCPU(dom)))
10346
                        goto cleanup;
10347

10348 10349 10350 10351
                    cpu->model = model;
                    model = NULL;
                }

10352 10353
                if (virCPUDefAddFeature(cpu, feature, policy) < 0)
                    goto cleanup;
10354
            }
10355
        } else if (STRPREFIX(tokens[i], "hv_")) {
10356 10357
            const char *token = tokens[i] + 3; /* "hv_" */
            const char *feature, *value;
10358 10359
            int f;

10360 10361 10362 10363 10364 10365 10366 10367 10368
            if (*token == '\0')
                goto syntax;

            if (!(hv_tokens = virStringSplit(token, "=", 2)))
                goto cleanup;

            feature = hv_tokens[0];
            value = hv_tokens[1];

10369
            if (*feature == '\0')
10370 10371
                goto syntax;

10372
            dom->features[VIR_DOMAIN_FEATURE_HYPERV] = VIR_DOMAIN_FEATURE_STATE_ON;
10373 10374 10375 10376 10377

            if ((f = virDomainHypervTypeFromString(feature)) < 0) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                               _("unsupported HyperV Enlightenment feature "
                                 "'%s'"), feature);
10378
                goto cleanup;
10379 10380
            }

10381
            switch ((virDomainHyperv) f) {
10382
            case VIR_DOMAIN_HYPERV_RELAXED:
10383 10384 10385 10386 10387 10388 10389
            case VIR_DOMAIN_HYPERV_VAPIC:
                if (value) {
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                   _("HyperV feature '%s' should not "
                                     "have a value"), feature);
                    goto cleanup;
                }
10390 10391 10392
                dom->hyperv_features[f] = VIR_DOMAIN_FEATURE_STATE_ON;
                break;

10393
            case VIR_DOMAIN_HYPERV_SPINLOCKS:
10394 10395 10396 10397 10398 10399 10400 10401 10402 10403 10404 10405 10406 10407 10408
                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;
10409 10410
                break;

10411 10412 10413
            case VIR_DOMAIN_HYPERV_LAST:
                break;
            }
10414 10415
            virStringFreeList(hv_tokens);
            hv_tokens = NULL;
10416
        }
10417
    }
10418

10419
    if (dom->os.arch == VIR_ARCH_X86_64) {
10420
        bool is_32bit = false;
10421
        if (cpu) {
10422
            virCPUDataPtr cpuData = NULL;
10423

10424 10425 10426
            if (cpuEncode(VIR_ARCH_X86_64, cpu, NULL, &cpuData,
                          NULL, NULL, NULL, NULL) < 0)
                goto cleanup;
10427

J
Jiri Denemark 已提交
10428 10429
            is_32bit = (cpuHasFeature(cpuData, "lm") != 1);
            cpuDataFree(cpuData);
10430 10431 10432
        } else if (model) {
            is_32bit = STREQ(model, "qemu32");
        }
10433

10434
        if (is_32bit)
10435
            dom->os.arch = VIR_ARCH_I686;
10436
    }
10437 10438 10439

    ret = 0;

10440
 cleanup:
10441
    VIR_FREE(model);
10442
    virStringFreeList(tokens);
10443
    virStringFreeList(hv_tokens);
10444
    return ret;
10445

10446
 syntax:
10447 10448
    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("unknown CPU syntax '%s'"), val);
10449
    goto cleanup;
10450 10451 10452 10453 10454 10455 10456 10457 10458 10459 10460
}


static int
qemuParseCommandLineSmp(virDomainDefPtr dom,
                        const char *val)
{
    unsigned int sockets = 0;
    unsigned int cores = 0;
    unsigned int threads = 0;
    unsigned int maxcpus = 0;
10461
    size_t i;
10462 10463 10464 10465 10466 10467 10468
    int nkws;
    char **kws;
    char **vals;
    int n;
    char *end;
    int ret;

10469
    if (qemuParseKeywords(val, &kws, &vals, &nkws, 1) < 0)
10470 10471 10472 10473 10474 10475 10476 10477 10478 10479 10480 10481 10482 10483 10484 10485 10486 10487 10488 10489 10490 10491 10492 10493 10494 10495 10496 10497 10498 10499 10500 10501 10502 10503 10504 10505 10506 10507 10508
        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;

10509
 cleanup:
10510 10511 10512 10513 10514 10515 10516 10517 10518
    for (i = 0; i < nkws; i++) {
        VIR_FREE(kws[i]);
        VIR_FREE(vals[i]);
    }
    VIR_FREE(kws);
    VIR_FREE(vals);

    return ret;

10519
 syntax:
10520 10521
    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("cannot parse CPU topology '%s'"), val);
10522
 error:
10523 10524 10525 10526 10527
    ret = -1;
    goto cleanup;
}


10528
static void
10529 10530
qemuParseCommandLineBootDevs(virDomainDefPtr def, const char *str)
{
10531 10532
    int n, b = 0;

10533
    for (n = 0; str[n] && b < VIR_DOMAIN_BOOT_LAST; n++) {
10534 10535 10536 10537 10538 10539 10540 10541 10542 10543 10544 10545 10546 10547 10548
        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;
}


10549 10550 10551 10552 10553
/*
 * 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 已提交
10554 10555 10556 10557 10558 10559 10560 10561
static virDomainDefPtr
qemuParseCommandLine(virCapsPtr qemuCaps,
                     virDomainXMLOptionPtr xmlopt,
                     char **progenv,
                     char **progargv,
                     char **pidfile,
                     virDomainChrSourceDefPtr *monConfig,
                     bool *monJSON)
10562 10563
{
    virDomainDefPtr def;
10564
    size_t i;
10565
    bool nographics = false;
10566
    bool fullscreen = false;
10567
    char *path;
10568
    size_t nnics = 0;
10569 10570 10571
    const char **nics = NULL;
    int video = VIR_DOMAIN_VIDEO_TYPE_CIRRUS;
    int nvirtiodisk = 0;
W
Wen Congyang 已提交
10572
    qemuDomainCmdlineDefPtr cmd = NULL;
E
Eric Blake 已提交
10573
    virDomainDiskDefPtr disk = NULL;
10574
    const char *ceph_args = qemuFindEnv(progenv, "CEPH_ARGS");
10575

10576 10577 10578 10579 10580 10581 10582
    if (pidfile)
        *pidfile = NULL;
    if (monConfig)
        *monConfig = NULL;
    if (monJSON)
        *monJSON = false;

10583
    if (!progargv[0]) {
10584 10585
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("no emulator path found"));
10586 10587 10588 10589
        return NULL;
    }

    if (VIR_ALLOC(def) < 0)
10590
        goto error;
10591 10592 10593

    /* allocate the cmdlinedef up-front; if it's unused, we'll free it later */
    if (VIR_ALLOC(cmd) < 0)
10594
        goto error;
10595

E
Eric Blake 已提交
10596
    if (virUUIDGenerate(def->uuid) < 0) {
10597 10598
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to generate uuid"));
E
Eric Blake 已提交
10599 10600
        goto error;
    }
10601 10602 10603 10604 10605 10606

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

10608 10609 10610 10611
    def->onReboot = VIR_DOMAIN_LIFECYCLE_RESTART;
    def->onCrash = VIR_DOMAIN_LIFECYCLE_DESTROY;
    def->onPoweroff = VIR_DOMAIN_LIFECYCLE_DESTROY;
    def->virtType = VIR_DOMAIN_VIRT_QEMU;
10612 10613
    if (VIR_STRDUP(def->emulator, progargv[0]) < 0)
        goto error;
10614

10615 10616
    if (!(path = last_component(def->emulator)))
        goto error;
10617

10618
    if (strstr(path, "xenner")) {
10619
        def->virtType = VIR_DOMAIN_VIRT_KVM;
10620 10621
        if (VIR_STRDUP(def->os.type, "xen") < 0)
            goto error;
10622
    } else {
10623 10624
        if (VIR_STRDUP(def->os.type, "hvm") < 0)
            goto error;
10625 10626
        if (strstr(path, "kvm")) {
            def->virtType = VIR_DOMAIN_VIRT_KVM;
10627
            def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_DOMAIN_FEATURE_STATE_ON;
10628
        }
10629 10630
    }

10631
    if (def->virtType == VIR_DOMAIN_VIRT_KVM)
10632
        def->os.arch = qemuCaps->host.arch;
10633
    else if (STRPREFIX(path, "qemu-system-"))
10634
        def->os.arch = virArchFromString(path + strlen("qemu-system-"));
10635
    else
10636
        def->os.arch = VIR_ARCH_I686;
10637

10638 10639
    if ((def->os.arch == VIR_ARCH_I686) ||
        (def->os.arch == VIR_ARCH_X86_64))
10640
        def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_DOMAIN_FEATURE_STATE_ON;
10641

10642 10643 10644
#define WANT_VALUE()                                                   \
    const char *val = progargv[++i];                                   \
    if (!val) {                                                        \
10645
        virReportError(VIR_ERR_INTERNAL_ERROR,                         \
10646
                       _("missing value for %s argument"), arg);       \
10647 10648 10649 10650 10651
        goto error;                                                    \
    }

    /* One initial loop to get list of NICs, so we
     * can correlate them later */
10652
    for (i = 1; progargv[i]; i++) {
10653 10654 10655 10656 10657 10658 10659 10660
        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();
10661 10662 10663
            if (STRPREFIX(val, "nic") &&
                VIR_APPEND_ELEMENT(nics, nnics, val) < 0)
                goto error;
10664 10665 10666 10667
        }
    }

    /* Now the real processing loop */
10668
    for (i = 1; progargv[i]; i++) {
10669
        const char *arg = progargv[i];
L
Laine Stump 已提交
10670 10671
        bool argRecognized = true;

10672 10673 10674 10675 10676 10677 10678 10679 10680 10681
        /* 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)
10682
                goto error;
10683 10684
            vnc->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;

10685
            if (STRPREFIX(val, "unix:")) {
10686
                /* -vnc unix:/some/big/path */
10687
                if (VIR_STRDUP(vnc->data.vnc.socket, val + 5) < 0) {
10688
                    virDomainGraphicsDefFree(vnc);
10689
                    goto error;
10690 10691
                }
            } else {
10692 10693 10694 10695 10696 10697
                /*
                 * -vnc 127.0.0.1:4
                 * -vnc [2001:1:2:3:4:5:1234:1234]:4
                 * -vnc some.host.name:4
                 */
                char *opts;
10698
                char *port;
10699 10700 10701 10702 10703
                const char *sep = ":";
                if (val[0] == '[')
                    sep = "]:";
                tmp = strstr(val, sep);
                if (!tmp) {
10704
                    virDomainGraphicsDefFree(vnc);
10705 10706
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("missing VNC port number in '%s'"), val);
10707 10708
                    goto error;
                }
10709 10710
                port = tmp + strlen(sep);
                if (virStrToLong_i(port, &opts, 10,
10711
                                   &vnc->data.vnc.port) < 0) {
10712
                    virDomainGraphicsDefFree(vnc);
10713
                    virReportError(VIR_ERR_INTERNAL_ERROR,
10714
                                   _("cannot parse VNC port '%s'"), port);
10715 10716 10717
                    goto error;
                }
                if (val[0] == '[')
10718 10719
                    virDomainGraphicsListenSetAddress(vnc, 0,
                                                      val+1, tmp-(val+1), true);
10720
                else
10721 10722 10723 10724
                    virDomainGraphicsListenSetAddress(vnc, 0,
                                                      val, tmp-val, true);
                if (!virDomainGraphicsListenGetAddress(vnc, 0)) {
                    virDomainGraphicsDefFree(vnc);
10725
                    goto error;
10726
                }
10727 10728

                if (*opts == ',') {
10729 10730 10731
                    char *orig_opts;

                    if (VIR_STRDUP(orig_opts, opts + 1) < 0) {
10732
                        virDomainGraphicsDefFree(vnc);
10733
                        goto error;
10734 10735 10736 10737 10738 10739 10740 10741 10742 10743 10744 10745 10746 10747 10748 10749 10750 10751 10752 10753 10754 10755 10756 10757 10758 10759 10760 10761 10762 10763 10764 10765
                    }
                    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;
                            }
10766 10767 10768 10769 10770 10771 10772 10773 10774 10775 10776 10777 10778 10779 10780 10781 10782 10783 10784 10785 10786 10787 10788
                        } 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;
                            }
10789 10790 10791 10792 10793 10794
                        }

                        opts = nextopt;
                    }
                    VIR_FREE(orig_opts);
                }
10795
                vnc->data.vnc.port += 5900;
10796
                vnc->data.vnc.autoport = false;
10797 10798
            }

10799
            if (VIR_APPEND_ELEMENT(def->graphics, def->ngraphics, vnc) < 0) {
10800
                virDomainGraphicsDefFree(vnc);
10801
                goto error;
10802 10803 10804 10805 10806
            }
        } else if (STREQ(arg, "-m")) {
            int mem;
            WANT_VALUE();
            if (virStrToLong_i(val, NULL, 10, &mem) < 0) {
10807 10808
                virReportError(VIR_ERR_INTERNAL_ERROR, \
                               _("cannot parse memory level '%s'"), val);
10809 10810 10811 10812 10813 10814 10815 10816 10817 10818
                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) {
10819 10820
                virReportError(VIR_ERR_INTERNAL_ERROR, \
                               _("cannot parse UUID '%s'"), val);
10821 10822 10823 10824 10825 10826 10827
                goto error;
            }
        } else if (STRPREFIX(arg, "-hd") ||
                   STRPREFIX(arg, "-sd") ||
                   STRPREFIX(arg, "-fd") ||
                   STREQ(arg, "-cdrom")) {
            WANT_VALUE();
10828
            if (!(disk = virDomainDiskDefNew()))
10829
                goto error;
10830 10831

            if (STRPREFIX(val, "/dev/"))
10832
                disk->src->type = VIR_STORAGE_TYPE_BLOCK;
10833
            else if (STRPREFIX(val, "nbd:")) {
10834 10835
                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_NBD;
10836
            } else if (STRPREFIX(val, "rbd:")) {
10837 10838
                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_RBD;
10839
                val += strlen("rbd:");
10840
            } else if (STRPREFIX(val, "gluster")) {
10841 10842
                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_GLUSTER;
10843
            } else if (STRPREFIX(val, "sheepdog:")) {
10844 10845
                disk->src->type = VIR_STORAGE_TYPE_NETWORK;
                disk->src->protocol = VIR_STORAGE_NET_PROTOCOL_SHEEPDOG;
10846 10847
                val += strlen("sheepdog:");
            } else
10848
                disk->src->type = VIR_STORAGE_TYPE_FILE;
10849 10850
            if (STREQ(arg, "-cdrom")) {
                disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
10851 10852 10853
                if (((def->os.arch == VIR_ARCH_PPC64) &&
                    def->os.machine && STREQ(def->os.machine, "pseries")))
                    disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
10854 10855
                if (VIR_STRDUP(disk->dst, "hdc") < 0)
                    goto error;
10856
                disk->readonly = true;
10857 10858 10859 10860 10861 10862 10863 10864 10865 10866
            } 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;
10867 10868 10869
                   if (((def->os.arch == VIR_ARCH_PPC64) &&
                       def->os.machine && STREQ(def->os.machine, "pseries")))
                       disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
10870
                }
10871 10872
                if (VIR_STRDUP(disk->dst, arg + 1) < 0)
                    goto error;
10873
            }
10874
            if (VIR_STRDUP(disk->src->path, val) < 0)
10875
                goto error;
10876

10877
            if (disk->src->type == VIR_STORAGE_TYPE_NETWORK) {
10878
                char *port;
10879

10880
                switch ((virStorageNetProtocol) disk->src->protocol) {
10881
                case VIR_STORAGE_NET_PROTOCOL_NBD:
10882
                    if (qemuParseNBDString(disk) < 0)
10883 10884
                        goto error;
                    break;
10885
                case VIR_STORAGE_NET_PROTOCOL_RBD:
10886 10887 10888
                    /* old-style CEPH_ARGS env variable is parsed later */
                    if (!ceph_args && qemuParseRBDString(disk) < 0)
                        goto error;
10889
                    break;
10890
                case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
10891
                    /* disk->src must be [vdiname] or [host]:[port]:[vdiname] */
10892
                    port = strchr(disk->src->path, ':');
10893 10894 10895 10896 10897 10898
                    if (port) {
                        char *vdi;

                        *port++ = '\0';
                        vdi = strchr(port, ':');
                        if (!vdi) {
10899 10900
                            virReportError(VIR_ERR_INTERNAL_ERROR,
                                           _("cannot parse sheepdog filename '%s'"), val);
10901 10902 10903
                            goto error;
                        }
                        *vdi++ = '\0';
10904
                        if (VIR_ALLOC(disk->src->hosts) < 0)
10905
                            goto error;
10906 10907 10908
                        disk->src->nhosts = 1;
                        disk->src->hosts->name = disk->src->path;
                        if (VIR_STRDUP(disk->src->hosts->port, port) < 0)
10909
                            goto error;
10910
                        if (VIR_STRDUP(disk->src->path, vdi) < 0)
10911
                            goto error;
10912 10913
                    }
                    break;
10914
                case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
10915 10916 10917
                    if (qemuParseGlusterString(disk) < 0)
                        goto error;

P
Paolo Bonzini 已提交
10918
                    break;
10919
                case VIR_STORAGE_NET_PROTOCOL_ISCSI:
P
Paolo Bonzini 已提交
10920 10921 10922
                    if (qemuParseISCSIString(disk) < 0)
                        goto error;

10923
                    break;
10924 10925 10926 10927 10928 10929
                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:
10930
                case VIR_STORAGE_NET_PROTOCOL_NONE:
10931 10932
                    /* ignored for now */
                    break;
10933 10934 10935
                }
            }

10936
            if (virDomainDiskDefAssignAddress(xmlopt, disk) < 0) {
10937 10938 10939
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("Cannot assign address for device name '%s'"),
                               disk->dst);
10940
                goto error;
10941
            }
10942

10943
            if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
10944
                goto error;
10945
        } else if (STREQ(arg, "-no-acpi")) {
10946
            def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_DOMAIN_FEATURE_STATE_DEFAULT;
10947 10948 10949 10950
        } 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 已提交
10951 10952
        } else if (STREQ(arg, "-enable-kvm")) {
            def->virtType = VIR_DOMAIN_VIRT_KVM;
10953
        } else if (STREQ(arg, "-nographic")) {
10954
            nographics = true;
10955
        } else if (STREQ(arg, "-full-screen")) {
10956
            fullscreen = true;
10957 10958 10959 10960
        } else if (STREQ(arg, "-localtime")) {
            def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME;
        } else if (STREQ(arg, "-kernel")) {
            WANT_VALUE();
10961 10962
            if (VIR_STRDUP(def->os.kernel, val) < 0)
                goto error;
10963 10964
        } else if (STREQ(arg, "-bios")) {
            WANT_VALUE();
10965 10966
            if (VIR_STRDUP(def->os.loader, val) < 0)
                goto error;
10967 10968
        } else if (STREQ(arg, "-initrd")) {
            WANT_VALUE();
10969 10970
            if (VIR_STRDUP(def->os.initrd, val) < 0)
                goto error;
10971 10972
        } else if (STREQ(arg, "-append")) {
            WANT_VALUE();
10973 10974
            if (VIR_STRDUP(def->os.cmdline, val) < 0)
                goto error;
O
Olivia Yin 已提交
10975 10976
        } else if (STREQ(arg, "-dtb")) {
            WANT_VALUE();
10977 10978
            if (VIR_STRDUP(def->os.dtb, val) < 0)
                goto error;
10979
        } else if (STREQ(arg, "-boot")) {
10980
            const char *token = NULL;
10981 10982
            WANT_VALUE();

10983 10984 10985 10986 10987 10988 10989 10990 10991 10992
            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;
10993 10994 10995 10996 10997 10998 10999 11000 11001 11002 11003 11004 11005 11006 11007 11008
                    } 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;
11009 11010 11011 11012 11013 11014 11015 11016
                    }
                    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++;
                }
            }
11017 11018 11019 11020 11021
        } else if (STREQ(arg, "-name")) {
            char *process;
            WANT_VALUE();
            process = strstr(val, ",process=");
            if (process == NULL) {
11022 11023
                if (VIR_STRDUP(def->name, val) < 0)
                    goto error;
11024
            } else {
11025 11026
                if (VIR_STRNDUP(def->name, val, process - val) < 0)
                    goto error;
11027
            }
11028 11029
            if (STREQ(def->name, ""))
                VIR_FREE(def->name);
11030 11031
        } else if (STREQ(arg, "-M") ||
                   STREQ(arg, "-machine")) {
11032 11033 11034 11035 11036 11037 11038
            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='...' */
11039
            WANT_VALUE();
11040 11041
            if (!(list = virStringSplit(val, ",", 0)))
                goto error;
11042 11043 11044 11045 11046 11047 11048
            param = list[0];

            if (STRPREFIX(param, "type="))
                param += strlen("type=");
            if (!strchr(param, '=')) {
                if (VIR_STRDUP(def->os.machine, param) < 0) {
                    virStringFreeList(list);
11049
                    goto error;
11050 11051 11052 11053 11054 11055 11056 11057 11058 11059 11060 11061 11062 11063 11064
                }
                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;
11065
                    def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_DOMAIN_FEATURE_STATE_ON;
11066 11067
                }
            }
11068
            virStringFreeList(list);
11069 11070 11071 11072
        } else if (STREQ(arg, "-serial")) {
            WANT_VALUE();
            if (STRNEQ(val, "none")) {
                virDomainChrDefPtr chr;
11073 11074 11075 11076

                if (!(chr = virDomainChrDefNew()))
                    goto error;

E
Eric Blake 已提交
11077 11078
                if (qemuParseCommandLineChr(&chr->source, val) < 0) {
                    virDomainChrDefFree(chr);
11079
                    goto error;
E
Eric Blake 已提交
11080
                }
11081 11082 11083
                chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
                chr->target.port = def->nserials;
                if (VIR_APPEND_ELEMENT(def->serials, def->nserials, chr) < 0) {
11084
                    virDomainChrDefFree(chr);
11085
                    goto error;
11086 11087 11088 11089 11090 11091
                }
            }
        } else if (STREQ(arg, "-parallel")) {
            WANT_VALUE();
            if (STRNEQ(val, "none")) {
                virDomainChrDefPtr chr;
11092 11093 11094 11095

                if (!(chr = virDomainChrDefNew()))
                    goto error;

E
Eric Blake 已提交
11096 11097
                if (qemuParseCommandLineChr(&chr->source, val) < 0) {
                    virDomainChrDefFree(chr);
11098
                    goto error;
E
Eric Blake 已提交
11099
                }
11100 11101 11102
                chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL;
                chr->target.port = def->nparallels;
                if (VIR_APPEND_ELEMENT(def->parallels, def->nparallels, chr) < 0) {
11103
                    virDomainChrDefFree(chr);
11104
                    goto error;
11105 11106 11107 11108 11109
                }
            }
        } else if (STREQ(arg, "-usbdevice")) {
            WANT_VALUE();
            if (STREQ(val, "tablet") ||
11110 11111
                STREQ(val, "mouse") ||
                STREQ(val, "keyboard")) {
11112 11113
                virDomainInputDefPtr input;
                if (VIR_ALLOC(input) < 0)
11114
                    goto error;
11115 11116 11117
                input->bus = VIR_DOMAIN_INPUT_BUS_USB;
                if (STREQ(val, "tablet"))
                    input->type = VIR_DOMAIN_INPUT_TYPE_TABLET;
11118
                else if (STREQ(val, "mouse"))
11119
                    input->type = VIR_DOMAIN_INPUT_TYPE_MOUSE;
11120 11121 11122 11123
                else
                    input->type = VIR_DOMAIN_INPUT_TYPE_KBD;

                if (VIR_APPEND_ELEMENT(def->inputs, def->ninputs, input) < 0) {
11124
                    virDomainInputDefFree(input);
11125
                    goto error;
11126 11127
                }
            } else if (STRPREFIX(val, "disk:")) {
11128
                if (!(disk = virDomainDiskDefNew()))
11129
                    goto error;
11130
                if (VIR_STRDUP(disk->src->path, val + strlen("disk:")) < 0)
11131
                    goto error;
11132 11133
                if (STRPREFIX(disk->src->path, "/dev/"))
                    disk->src->type = VIR_STORAGE_TYPE_BLOCK;
11134
                else
11135
                    disk->src->type = VIR_STORAGE_TYPE_FILE;
11136 11137
                disk->device = VIR_DOMAIN_DISK_DEVICE_DISK;
                disk->bus = VIR_DOMAIN_DISK_BUS_USB;
11138
                disk->removable = VIR_DOMAIN_FEATURE_STATE_DEFAULT;
11139 11140
                if (VIR_STRDUP(disk->dst, "sda") < 0)
                    goto error;
11141
                if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
11142
                    goto error;
11143 11144 11145 11146
            } else {
                virDomainHostdevDefPtr hostdev;
                if (!(hostdev = qemuParseCommandLineUSB(val)))
                    goto error;
11147
                if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev) < 0) {
11148
                    virDomainHostdevDefFree(hostdev);
11149
                    goto error;
11150 11151 11152 11153 11154 11155
                }
            }
        } else if (STREQ(arg, "-net")) {
            WANT_VALUE();
            if (!STRPREFIX(val, "nic") && STRNEQ(val, "none")) {
                virDomainNetDefPtr net;
11156
                if (!(net = qemuParseCommandLineNet(xmlopt, val, nnics, nics)))
11157
                    goto error;
11158
                if (VIR_APPEND_ELEMENT(def->nets, def->nnets, net) < 0) {
11159
                    virDomainNetDefFree(net);
11160
                    goto error;
11161 11162 11163 11164
                }
            }
        } else if (STREQ(arg, "-drive")) {
            WANT_VALUE();
11165
            if (!(disk = qemuParseCommandLineDisk(xmlopt, val, def,
11166
                                                  nvirtiodisk,
11167
                                                  ceph_args != NULL)))
11168 11169 11170
                goto error;
            if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
                nvirtiodisk++;
11171 11172
            if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
                goto error;
11173 11174 11175 11176 11177
        } else if (STREQ(arg, "-pcidevice")) {
            virDomainHostdevDefPtr hostdev;
            WANT_VALUE();
            if (!(hostdev = qemuParseCommandLinePCI(val)))
                goto error;
11178
            if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev) < 0) {
11179
                virDomainHostdevDefFree(hostdev);
11180
                goto error;
11181 11182 11183 11184 11185 11186 11187 11188 11189 11190 11191 11192 11193 11194 11195 11196
            }
        } 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;
11197 11198
                } else if (STRPREFIX(start, "hda")) {
                    type = VIR_DOMAIN_SOUND_MODEL_ICH6;
11199 11200 11201 11202 11203
                }

                if (type != -1) {
                    virDomainSoundDefPtr snd;
                    if (VIR_ALLOC(snd) < 0)
11204
                        goto error;
11205
                    snd->model = type;
11206
                    if (VIR_APPEND_ELEMENT(def->sounds, def->nsounds, snd) < 0) {
11207
                        VIR_FREE(snd);
11208
                        goto error;
11209 11210 11211 11212 11213 11214 11215
                    }
                }

                start = tmp ? tmp + 1 : NULL;
            }
        } else if (STREQ(arg, "-watchdog")) {
            WANT_VALUE();
11216
            int model = virDomainWatchdogModelTypeFromString(val);
11217 11218 11219 11220

            if (model != -1) {
                virDomainWatchdogDefPtr wd;
                if (VIR_ALLOC(wd) < 0)
11221
                    goto error;
11222 11223 11224 11225 11226 11227
                wd->model = model;
                wd->action = VIR_DOMAIN_WATCHDOG_ACTION_RESET;
                def->watchdog = wd;
            }
        } else if (STREQ(arg, "-watchdog-action") && def->watchdog) {
            WANT_VALUE();
11228
            int action = virDomainWatchdogActionTypeFromString(val);
11229 11230 11231 11232 11233

            if (action != -1)
                def->watchdog->action = action;
        } else if (STREQ(arg, "-bootloader")) {
            WANT_VALUE();
11234 11235
            if (VIR_STRDUP(def->os.bootloader, val) < 0)
                goto error;
11236 11237 11238 11239 11240 11241 11242 11243 11244
        } 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) {
11245 11246
                    virReportError(VIR_ERR_INTERNAL_ERROR,
                                   _("unknown video adapter type '%s'"), val);
11247 11248 11249 11250 11251 11252 11253 11254 11255 11256 11257
                    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")) {
11258 11259
            virDomainControllerDefPtr ctldef;
            if (VIR_ALLOC(ctldef) < 0)
11260
                goto error;
11261 11262 11263
            ctldef->type = VIR_DOMAIN_CONTROLLER_TYPE_USB;
            ctldef->idx = 0;
            ctldef->model = -1;
11264 11265
            if (virDomainControllerInsert(def, ctldef) < 0) {
                VIR_FREE(ctldef);
11266
                goto error;
11267
            }
11268 11269
        } else if (STREQ(arg, "-pidfile")) {
            WANT_VALUE();
11270
            if (pidfile)
11271 11272
                if (VIR_STRDUP(*pidfile, val) < 0)
                    goto error;
11273 11274 11275 11276 11277
        } else if (STREQ(arg, "-incoming")) {
            WANT_VALUE();
            /* ignore, used via restore/migrate APIs */
        } else if (STREQ(arg, "-monitor")) {
            WANT_VALUE();
11278 11279 11280 11281
            if (monConfig) {
                virDomainChrSourceDefPtr chr;

                if (VIR_ALLOC(chr) < 0)
11282
                    goto error;
11283

E
Eric Blake 已提交
11284 11285
                if (qemuParseCommandLineChr(chr, val) < 0) {
                    virDomainChrSourceDefFree(chr);
11286
                    goto error;
E
Eric Blake 已提交
11287
                }
11288 11289 11290

                *monConfig = chr;
            }
11291 11292 11293 11294 11295 11296 11297 11298 11299 11300 11301 11302 11303 11304 11305 11306 11307 11308 11309 11310 11311 11312 11313 11314 11315 11316 11317 11318 11319 11320 11321 11322 11323 11324 11325 11326
        } 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;
            }

11327 11328 11329 11330 11331
        } else if (STREQ(arg, "-global") &&
                   STRPREFIX(progargv[i + 1], "spapr-nvram.reg=")) {
            WANT_VALUE();

            if (VIR_ALLOC(def->nvram) < 0)
11332
                goto error;
11333 11334 11335 11336 11337 11338 11339 11340 11341 11342 11343

            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;
            }
11344 11345 11346
        } else if (STREQ(arg, "-S") ||
                   STREQ(arg, "-nodefaults") ||
                   STREQ(arg, "-nodefconfig")) {
11347
            /* ignore, always added by libvirt */
L
Laine Stump 已提交
11348 11349 11350 11351 11352 11353 11354 11355 11356 11357 11358 11359 11360 11361 11362 11363 11364 11365
        } 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;
            }
11366
        } else {
L
Laine Stump 已提交
11367 11368 11369 11370
            argRecognized = false;
        }

        if (!argRecognized) {
11371
            char *tmp = NULL;
11372 11373 11374 11375 11376
            /* 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);
11377 11378 11379
            if (VIR_STRDUP(tmp, arg) < 0 ||
                VIR_APPEND_ELEMENT(cmd->args, cmd->num_args, tmp) < 0) {
                VIR_FREE(tmp);
11380
                goto error;
11381
            }
11382 11383 11384 11385
        }
    }

#undef WANT_VALUE
11386 11387 11388
    if (def->ndisks > 0 && ceph_args) {
        char *hosts, *port, *saveptr = NULL, *token;
        virDomainDiskDefPtr first_rbd_disk = NULL;
11389
        for (i = 0; i < def->ndisks; i++) {
11390 11391
            if (def->disks[i]->src->type == VIR_STORAGE_TYPE_NETWORK &&
                def->disks[i]->src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD) {
11392 11393
                first_rbd_disk = def->disks[i];
                break;
11394
            }
11395
        }
11396

11397
        if (!first_rbd_disk) {
11398 11399
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("CEPH_ARGS was set without an rbd disk"));
11400 11401
            goto error;
        }
11402

11403 11404
        /* CEPH_ARGS should be: -m host1[:port1][,host2[:port2]]... */
        if (!STRPREFIX(ceph_args, "-m ")) {
11405 11406
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("could not parse CEPH_ARGS '%s'"), ceph_args);
11407 11408
            goto error;
        }
11409 11410
        if (VIR_STRDUP(hosts, strchr(ceph_args, ' ') + 1) < 0)
            goto error;
11411
        first_rbd_disk->src->nhosts = 0;
11412 11413
        token = strtok_r(hosts, ",", &saveptr);
        while (token != NULL) {
11414 11415
            if (VIR_REALLOC_N(first_rbd_disk->src->hosts,
                              first_rbd_disk->src->nhosts + 1) < 0) {
11416
                VIR_FREE(hosts);
11417
                goto error;
11418 11419 11420 11421
            }
            port = strchr(token, ':');
            if (port) {
                *port++ = '\0';
11422
                if (VIR_STRDUP(port, port) < 0) {
11423
                    VIR_FREE(hosts);
11424
                    goto error;
11425 11426
                }
            }
11427 11428
            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,
11429
                           token) < 0) {
11430
                VIR_FREE(hosts);
11431
                goto error;
11432
            }
11433 11434
            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;
11435

11436
            first_rbd_disk->src->nhosts++;
11437 11438 11439 11440
            token = strtok_r(NULL, ",", &saveptr);
        }
        VIR_FREE(hosts);

11441
        if (first_rbd_disk->src->nhosts == 0) {
11442 11443
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("found no rbd hosts in CEPH_ARGS '%s'"), ceph_args);
11444
            goto error;
11445 11446 11447
        }
    }

11448 11449
    if (!def->os.machine) {
        const char *defaultMachine =
11450
                        virCapabilitiesDefaultGuestMachine(qemuCaps,
11451 11452 11453 11454
                                                           def->os.type,
                                                           def->os.arch,
                                                           virDomainVirtTypeToString(def->virtType));
        if (defaultMachine != NULL)
11455 11456
            if (VIR_STRDUP(def->os.machine, defaultMachine) < 0)
                goto error;
11457 11458
    }

11459 11460 11461 11462 11463
    if (!nographics && def->ngraphics == 0) {
        virDomainGraphicsDefPtr sdl;
        const char *display = qemuFindEnv(progenv, "DISPLAY");
        const char *xauth = qemuFindEnv(progenv, "XAUTHORITY");
        if (VIR_ALLOC(sdl) < 0)
11464
            goto error;
11465 11466
        sdl->type = VIR_DOMAIN_GRAPHICS_TYPE_SDL;
        sdl->data.sdl.fullscreen = fullscreen;
11467
        if (VIR_STRDUP(sdl->data.sdl.display, display) < 0) {
11468
            VIR_FREE(sdl);
11469
            goto error;
11470
        }
11471
        if (VIR_STRDUP(sdl->data.sdl.xauth, xauth) < 0) {
11472
            VIR_FREE(sdl);
11473
            goto error;
11474 11475
        }

11476
        if (VIR_APPEND_ELEMENT(def->graphics, def->ngraphics, sdl) < 0) {
11477
            virDomainGraphicsDefFree(sdl);
11478
            goto error;
11479 11480 11481 11482 11483 11484
        }
    }

    if (def->ngraphics) {
        virDomainVideoDefPtr vid;
        if (VIR_ALLOC(vid) < 0)
11485
            goto error;
11486 11487 11488 11489 11490
        if (def->virtType == VIR_DOMAIN_VIRT_XEN)
            vid->type = VIR_DOMAIN_VIDEO_TYPE_XEN;
        else
            vid->type = video;
        vid->vram = virDomainVideoDefaultRAM(def, vid->type);
11491 11492
        vid->ram = vid->type == VIR_DOMAIN_VIDEO_TYPE_QXL ?
                       virDomainVideoDefaultRAM(def, vid->type) : 0;
11493 11494
        vid->heads = 1;

11495
        if (VIR_APPEND_ELEMENT(def->videos, def->nvideos, vid) < 0) {
11496
            virDomainVideoDefFree(vid);
11497
            goto error;
11498 11499 11500 11501 11502 11503 11504 11505 11506
        }
    }

    /*
     * having a balloon is the default, define one with type="none" to avoid it
     */
    if (!def->memballoon) {
        virDomainMemballoonDefPtr memballoon;
        if (VIR_ALLOC(memballoon) < 0)
11507
            goto error;
L
Laine Stump 已提交
11508
        memballoon->model = VIR_DOMAIN_MEMBALLOON_MODEL_NONE;
11509 11510 11511 11512 11513 11514 11515 11516 11517

        def->memballoon = memballoon;
    }

    VIR_FREE(nics);

    if (virDomainDefAddImplicitControllers(def) < 0)
        goto error;

11518 11519 11520
    if (virDomainDefPostParse(def, qemuCaps, xmlopt) < 0)
        goto error;

11521
    if (cmd->num_args || cmd->num_env) {
11522
        def->ns = *virDomainXMLOptionGetNamespace(xmlopt);
11523 11524 11525
        def->namespaceData = cmd;
    }
    else
11526
        qemuDomainCmdlineDefFree(cmd);
11527 11528 11529

    return def;

11530
 error:
E
Eric Blake 已提交
11531
    virDomainDiskDefFree(disk);
11532
    qemuDomainCmdlineDefFree(cmd);
11533 11534
    virDomainDefFree(def);
    VIR_FREE(nics);
11535 11536 11537 11538 11539 11540
    if (monConfig) {
        virDomainChrSourceDefFree(*monConfig);
        *monConfig = NULL;
    }
    if (pidfile)
        VIR_FREE(*pidfile);
11541 11542 11543 11544
    return NULL;
}


11545
virDomainDefPtr qemuParseCommandLineString(virCapsPtr qemuCaps,
11546
                                           virDomainXMLOptionPtr xmlopt,
11547 11548 11549 11550
                                           const char *args,
                                           char **pidfile,
                                           virDomainChrSourceDefPtr *monConfig,
                                           bool *monJSON)
11551
{
E
Eric Blake 已提交
11552 11553
    char **progenv = NULL;
    char **progargv = NULL;
11554 11555 11556 11557 11558
    virDomainDefPtr def = NULL;

    if (qemuStringToArgvEnv(args, &progenv, &progargv) < 0)
        goto cleanup;

11559
    def = qemuParseCommandLine(qemuCaps, xmlopt, progenv, progargv,
11560
                               pidfile, monConfig, monJSON);
11561

11562
 cleanup:
E
Eric Blake 已提交
11563 11564
    virStringFreeList(progargv);
    virStringFreeList(progenv);
11565 11566 11567

    return def;
}
11568 11569


11570
static int qemuParseProcFileStrings(int pid_value,
11571
                                    const char *name,
E
Eric Blake 已提交
11572
                                    char ***list)
11573 11574 11575 11576 11577 11578 11579
{
    char *path = NULL;
    int ret = -1;
    char *data = NULL;
    ssize_t len;
    char *tmp;
    size_t nstr = 0;
11580
    char **str = NULL;
11581

11582
    if (virAsprintf(&path, "/proc/%d/%s", pid_value, name) < 0)
11583 11584 11585 11586 11587 11588 11589
        goto cleanup;

    if ((len = virFileReadAll(path, 1024*128, &data)) < 0)
        goto cleanup;

    tmp = data;
    while (tmp < (data + len)) {
11590
        if (VIR_EXPAND_N(str, nstr, 1) < 0)
11591 11592
            goto cleanup;

11593
        if (VIR_STRDUP(str[nstr-1], tmp) < 0)
11594 11595 11596 11597 11598 11599 11600
            goto cleanup;
        /* Skip arg */
        tmp += strlen(tmp);
        /* Skip \0 separator */
        tmp++;
    }

11601
    if (VIR_EXPAND_N(str, nstr, 1) < 0)
11602 11603 11604 11605 11606
        goto cleanup;

    str[nstr-1] = NULL;

    ret = nstr-1;
E
Eric Blake 已提交
11607
    *list = str;
11608

11609
 cleanup:
E
Eric Blake 已提交
11610 11611
    if (ret < 0)
        virStringFreeList(str);
11612 11613 11614 11615 11616
    VIR_FREE(data);
    VIR_FREE(path);
    return ret;
}

11617
virDomainDefPtr qemuParseCommandLinePid(virCapsPtr qemuCaps,
11618
                                        virDomainXMLOptionPtr xmlopt,
11619
                                        pid_t pid,
11620 11621 11622 11623 11624
                                        char **pidfile,
                                        virDomainChrSourceDefPtr *monConfig,
                                        bool *monJSON)
{
    virDomainDefPtr def = NULL;
E
Eric Blake 已提交
11625 11626
    char **progargv = NULL;
    char **progenv = NULL;
11627 11628 11629
    char *exepath = NULL;
    char *emulator;

11630 11631 11632 11633
    /* 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 ||
11634 11635 11636
        qemuParseProcFileStrings(pid, "environ", &progenv) < 0)
        goto cleanup;

11637
    if (!(def = qemuParseCommandLine(qemuCaps, xmlopt, progenv, progargv,
11638 11639 11640
                                     pidfile, monConfig, monJSON)))
        goto cleanup;

11641
    if (virAsprintf(&exepath, "/proc/%d/exe", (int) pid) < 0)
11642 11643 11644 11645 11646
        goto cleanup;

    if (virFileResolveLink(exepath, &emulator) < 0) {
        virReportSystemError(errno,
                             _("Unable to resolve %s for pid %u"),
11647
                             exepath, (int) pid);
11648 11649 11650 11651 11652
        goto cleanup;
    }
    VIR_FREE(def->emulator);
    def->emulator = emulator;

11653
 cleanup:
11654
    VIR_FREE(exepath);
E
Eric Blake 已提交
11655 11656
    virStringFreeList(progargv);
    virStringFreeList(progenv);
11657 11658
    return def;
}