2 * qemu_hotplug.c: QEMU device hotplug management
4 * Copyright (C) 2006-2014 Red Hat, Inc.
5 * Copyright (C) 2006 Daniel P. Berrange
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library. If not, see
19 * <http://www.gnu.org/licenses/>.
21 * Author: Daniel P. Berrange <berrange@redhat.com>
27 #include "qemu_hotplug.h"
28 #include "qemu_hotplugpriv.h"
29 #include "qemu_capabilities.h"
30 #include "qemu_domain.h"
31 #include "qemu_command.h"
32 #include "qemu_hostdev.h"
33 #include "domain_audit.h"
34 #include "domain_nwfilter.h"
36 #include "datatypes.h"
41 #include "virprocess.h"
42 #include "qemu_cgroup.h"
43 #include "locking/domain_lock.h"
44 #include "network/bridge_driver.h"
45 #include "virnetdev.h"
46 #include "virnetdevbridge.h"
47 #include "virnetdevtap.h"
48 #include "device_conf.h"
49 #include "virstoragefile.h"
50 #include "virstring.h"
53 #define VIR_FROM_THIS VIR_FROM_QEMU
55 VIR_LOG_INIT("qemu.qemu_hotplug");
57 #define CHANGE_MEDIA_RETRIES 10
59 /* Wait up to 5 seconds for device removal to finish. */
60 unsigned long long qemuDomainRemoveDeviceWaitTime = 1000ull * 5;
63 int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
65 virDomainDiskDefPtr disk,
66 virDomainDiskDefPtr origdisk,
70 char *driveAlias = NULL;
71 qemuDomainObjPrivatePtr priv = vm->privateData;
72 int retries = CHANGE_MEDIA_RETRIES;
73 virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
74 const char *src = NULL;
76 if (!origdisk->info.alias) {
77 virReportError(VIR_ERR_INTERNAL_ERROR,
78 _("missing disk device alias name for %s"), origdisk->dst);
82 if (origdisk->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY &&
83 origdisk->device != VIR_DOMAIN_DISK_DEVICE_CDROM) {
84 virReportError(VIR_ERR_INTERNAL_ERROR,
85 _("Removable media not supported for %s device"),
86 virDomainDiskDeviceTypeToString(disk->device));
90 if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
94 if (virSecurityManagerSetImageLabel(driver->securityManager,
96 if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
97 VIR_WARN("Unable to release lock on %s",
98 virDomainDiskGetSource(disk));
102 if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, priv->qemuCaps)))
105 qemuDomainObjEnterMonitor(driver, vm);
106 ret = qemuMonitorEjectMedia(priv->mon, driveAlias, force);
107 qemuDomainObjExitMonitor(driver, vm);
113 /* we don't want to report errors from media tray_open polling */
115 if (origdisk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)
120 VIR_DEBUG("Waiting 500ms for tray to open. Retries left %d", retries);
121 usleep(500 * 1000); /* sleep 500ms */
127 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
128 _("Unable to eject media"));
133 src = virDomainDiskGetSource(disk);
135 /* deliberately don't depend on 'ret' as 'eject' may have failed the
136 * first time and we are going to check the drive state anyway */
137 const char *format = NULL;
138 int type = virDomainDiskGetType(disk);
139 int diskFormat = virDomainDiskGetFormat(disk);
141 if (type != VIR_STORAGE_TYPE_DIR) {
142 if (diskFormat > 0) {
143 format = virStorageFileFormatTypeToString(diskFormat);
145 diskFormat = virDomainDiskGetFormat(origdisk);
147 format = virStorageFileFormatTypeToString(diskFormat);
150 qemuDomainObjEnterMonitor(driver, vm);
151 ret = qemuMonitorChangeMedia(priv->mon,
154 qemuDomainObjExitMonitor(driver, vm);
158 virDomainAuditDisk(vm, virDomainDiskGetSource(origdisk),
159 src, "update", ret >= 0);
164 if (virSecurityManagerRestoreImageLabel(driver->securityManager,
165 vm->def, origdisk) < 0)
166 VIR_WARN("Unable to restore security label on ejected image %s",
167 virDomainDiskGetSource(origdisk));
169 if (virDomainLockDiskDetach(driver->lockManager, vm, origdisk) < 0)
170 VIR_WARN("Unable to release lock on disk %s",
171 virDomainDiskGetSource(origdisk));
173 if (virDomainDiskSetSource(origdisk, src) < 0)
175 virDomainDiskSetType(origdisk, virDomainDiskGetType(disk));
177 virDomainDiskDefFree(disk);
180 VIR_FREE(driveAlias);
185 if (virSecurityManagerRestoreImageLabel(driver->securityManager,
187 VIR_WARN("Unable to restore security label on new media %s", src);
189 if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
190 VIR_WARN("Unable to release lock on %s", src);
196 qemuDomainCheckEjectableMedia(virQEMUDriverPtr driver,
198 enum qemuDomainAsyncJob asyncJob)
200 qemuDomainObjPrivatePtr priv = vm->privateData;
201 virHashTablePtr table = NULL;
205 if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
206 table = qemuMonitorGetBlockInfo(priv->mon);
207 qemuDomainObjExitMonitor(driver, vm);
213 for (i = 0; i < vm->def->ndisks; i++) {
214 virDomainDiskDefPtr disk = vm->def->disks[i];
215 struct qemuDomainDiskInfo *info;
217 if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK ||
218 disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
222 info = qemuMonitorBlockInfoLookup(table, disk->info.alias);
226 if (info->tray_open && virDomainDiskGetSource(disk))
227 ignore_value(virDomainDiskSetSource(disk, NULL));
238 qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
239 virQEMUDriverPtr driver,
241 virDomainDiskDefPtr disk)
245 const char* type = virDomainDiskBusTypeToString(disk->bus);
246 qemuDomainObjPrivatePtr priv = vm->privateData;
248 char *drivestr = NULL;
249 bool releaseaddr = false;
250 virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
251 const char *src = virDomainDiskGetSource(disk);
253 if (!disk->info.type) {
254 if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
255 virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW))
256 disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW;
257 else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_S390))
258 disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390;
261 for (i = 0; i < vm->def->ndisks; i++) {
262 if (STREQ(vm->def->disks[i]->dst, disk->dst)) {
263 virReportError(VIR_ERR_OPERATION_FAILED,
264 _("target %s already exists"), disk->dst);
269 if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
273 if (virSecurityManagerSetImageLabel(driver->securityManager,
274 vm->def, disk) < 0) {
275 if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
276 VIR_WARN("Unable to release lock on %s", src);
280 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
281 if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
282 if (qemuDomainCCWAddressAssign(&disk->info, priv->ccwaddrs,
283 !disk->info.addr.ccw.assigned) < 0)
285 } else if (!disk->info.type ||
286 disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
287 if (virDomainPCIAddressEnsureAddr(priv->pciaddrs, &disk->info) < 0)
291 if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
294 if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps)))
297 if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps)))
301 if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0)
304 qemuDomainObjEnterMonitor(driver, vm);
305 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
306 ret = qemuMonitorAddDrive(priv->mon, drivestr);
308 ret = qemuMonitorAddDevice(priv->mon, devstr);
310 virErrorPtr orig_err = virSaveLastError();
311 if (qemuMonitorDriveDel(priv->mon, drivestr) < 0) {
312 VIR_WARN("Unable to remove drive %s (%s) after failed "
313 "qemuMonitorAddDevice",
317 virSetError(orig_err);
318 virFreeError(orig_err);
322 } else if (!disk->info.type ||
323 disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
324 virDevicePCIAddress guestAddr = disk->info.addr.pci;
325 ret = qemuMonitorAddPCIDisk(priv->mon, src, type, &guestAddr);
327 disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
328 memcpy(&disk->info.addr.pci, &guestAddr, sizeof(guestAddr));
331 qemuDomainObjExitMonitor(driver, vm);
333 virDomainAuditDisk(vm, NULL, src, "attach", ret >= 0);
338 virDomainDiskInsertPreAlloced(vm->def, disk);
348 qemuDomainReleaseDeviceAddress(vm, &disk->info, src);
350 if (virSecurityManagerRestoreImageLabel(driver->securityManager,
352 VIR_WARN("Unable to restore security label on %s", src);
354 if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
355 VIR_WARN("Unable to release lock on %s", src);
361 int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver,
363 virDomainControllerDefPtr controller)
366 const char* type = virDomainControllerTypeToString(controller->type);
368 qemuDomainObjPrivatePtr priv = vm->privateData;
369 bool releaseaddr = false;
371 if (virDomainControllerFind(vm->def, controller->type, controller->idx) >= 0) {
372 virReportError(VIR_ERR_OPERATION_FAILED,
373 _("target %s:%d already exists"),
374 type, controller->idx);
378 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
379 if (controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
380 if (STRPREFIX(vm->def->os.machine, "s390-ccw") &&
381 virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW))
382 controller->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW;
383 else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_S390))
384 controller->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390;
387 if (controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE ||
388 controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
389 if (virDomainPCIAddressEnsureAddr(priv->pciaddrs, &controller->info) < 0)
391 } else if (controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
392 if (qemuDomainCCWAddressAssign(&controller->info, priv->ccwaddrs,
393 !controller->info.addr.ccw.assigned) < 0)
397 if (qemuAssignDeviceControllerAlias(controller) < 0)
400 if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
401 controller->model == -1 &&
402 !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI)) {
403 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
404 _("USB controller hotplug unsupported in this QEMU binary"));
408 if (!(devstr = qemuBuildControllerDevStr(vm->def, controller, priv->qemuCaps, NULL))) {
413 if (VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers+1) < 0)
416 qemuDomainObjEnterMonitor(driver, vm);
417 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
418 ret = qemuMonitorAddDevice(priv->mon, devstr);
420 ret = qemuMonitorAttachPCIDiskController(priv->mon,
422 &controller->info.addr.pci);
424 qemuDomainObjExitMonitor(driver, vm);
427 if (controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
428 controller->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
429 virDomainControllerInsertPreAlloced(vm->def, controller);
433 if (ret != 0 && releaseaddr)
434 qemuDomainReleaseDeviceAddress(vm, &controller->info, NULL);
440 static virDomainControllerDefPtr
441 qemuDomainFindOrCreateSCSIDiskController(virQEMUDriverPtr driver,
446 virDomainControllerDefPtr cont;
448 for (i = 0; i < vm->def->ncontrollers; i++) {
449 cont = vm->def->controllers[i];
451 if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
454 if (cont->idx == controller)
458 /* No SCSI controller present, for backward compatibility we
459 * now hotplug a controller */
460 if (VIR_ALLOC(cont) < 0)
462 cont->type = VIR_DOMAIN_CONTROLLER_TYPE_SCSI;
463 cont->idx = controller;
466 VIR_INFO("No SCSI controller present, hotplugging one");
467 if (qemuDomainAttachControllerDevice(driver,
473 if (!virDomainObjIsActive(vm)) {
474 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
475 _("guest unexpectedly quit"));
476 /* cont doesn't need freeing here, since the reference
477 * now held in def->controllers */
486 qemuDomainAttachSCSIDisk(virConnectPtr conn,
487 virQEMUDriverPtr driver,
489 virDomainDiskDefPtr disk)
492 qemuDomainObjPrivatePtr priv = vm->privateData;
493 virDomainControllerDefPtr cont = NULL;
494 char *drivestr = NULL;
497 virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
498 const char *src = virDomainDiskGetSource(disk);
500 for (i = 0; i < vm->def->ndisks; i++) {
501 if (STREQ(vm->def->disks[i]->dst, disk->dst)) {
502 virReportError(VIR_ERR_OPERATION_FAILED,
503 _("target %s already exists"), disk->dst);
508 if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
512 if (virSecurityManagerSetImageLabel(driver->securityManager,
513 vm->def, disk) < 0) {
514 if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
515 VIR_WARN("Unable to release lock on %s", src);
519 /* We should have an address already, so make sure */
520 if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
521 virReportError(VIR_ERR_INTERNAL_ERROR,
522 _("unexpected disk address type %s"),
523 virDomainDeviceAddressTypeToString(disk->info.type));
527 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
528 if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
530 if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps)))
534 if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps)))
537 for (i = 0; i <= disk->info.addr.drive.controller; i++) {
538 cont = qemuDomainFindOrCreateSCSIDiskController(driver, vm, i);
543 /* Tell clang that "cont" is non-NULL.
544 This is because disk->info.addr.driver.controller is unsigned,
545 and hence the above loop must iterate at least once. */
548 if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0)
551 qemuDomainObjEnterMonitor(driver, vm);
552 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
553 ret = qemuMonitorAddDrive(priv->mon, drivestr);
555 ret = qemuMonitorAddDevice(priv->mon, devstr);
557 VIR_WARN("qemuMonitorAddDevice failed on %s (%s)",
559 /* XXX should call 'drive_del' on error but this does not
564 if (cont->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
565 virReportError(VIR_ERR_INTERNAL_ERROR,
566 _("SCSI controller %d was missing its PCI address"),
571 virDomainDeviceDriveAddress driveAddr;
572 ret = qemuMonitorAttachDrive(priv->mon,
574 &cont->info.addr.pci,
577 /* XXX we should probably validate that the addr matches
578 * our existing defined addr instead of overwriting */
579 disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE;
580 disk->info.addr.drive.bus = driveAddr.bus;
581 disk->info.addr.drive.unit = driveAddr.unit;
584 qemuDomainObjExitMonitor(driver, vm);
586 virDomainAuditDisk(vm, NULL, src, "attach", ret >= 0);
591 virDomainDiskInsertPreAlloced(vm->def, disk);
600 if (virSecurityManagerRestoreImageLabel(driver->securityManager,
602 VIR_WARN("Unable to restore security label on %s", src);
604 if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
605 VIR_WARN("Unable to release lock on %s", src);
612 qemuDomainAttachUSBMassstorageDevice(virConnectPtr conn,
613 virQEMUDriverPtr driver,
615 virDomainDiskDefPtr disk)
617 qemuDomainObjPrivatePtr priv = vm->privateData;
620 char *drivestr = NULL;
622 virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
623 const char *src = virDomainDiskGetSource(disk);
625 for (i = 0; i < vm->def->ndisks; i++) {
626 if (STREQ(vm->def->disks[i]->dst, disk->dst)) {
627 virReportError(VIR_ERR_OPERATION_FAILED,
628 _("target %s already exists"), disk->dst);
633 if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
637 if (virSecurityManagerSetImageLabel(driver->securityManager,
638 vm->def, disk) < 0) {
639 if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
640 VIR_WARN("Unable to release lock on %s", src);
644 /* XXX not correct once we allow attaching a USB CDROM */
646 virReportError(VIR_ERR_INTERNAL_ERROR,
647 "%s", _("disk source path is missing"));
651 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
652 if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
654 if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps)))
656 if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps)))
660 if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0)
663 qemuDomainObjEnterMonitor(driver, vm);
664 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
665 ret = qemuMonitorAddDrive(priv->mon, drivestr);
667 ret = qemuMonitorAddDevice(priv->mon, devstr);
669 VIR_WARN("qemuMonitorAddDevice failed on %s (%s)",
671 /* XXX should call 'drive_del' on error but this does not
676 ret = qemuMonitorAddUSBDisk(priv->mon, src);
678 qemuDomainObjExitMonitor(driver, vm);
680 virDomainAuditDisk(vm, NULL, src, "attach", ret >= 0);
685 virDomainDiskInsertPreAlloced(vm->def, disk);
694 if (virSecurityManagerRestoreImageLabel(driver->securityManager,
696 VIR_WARN("Unable to restore security label on %s", src);
698 if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
699 VIR_WARN("Unable to release lock on %s", src);
706 qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
707 virQEMUDriverPtr driver,
709 virDomainDeviceDefPtr dev)
711 virDomainDiskDefPtr disk = dev->data.disk;
712 virDomainDiskDefPtr orig_disk = NULL;
713 virDomainDeviceDefPtr dev_copy = NULL;
714 virDomainDiskDefPtr tmp = NULL;
715 virCapsPtr caps = NULL;
717 const char *driverName = virDomainDiskGetDriver(disk);
718 const char *src = virDomainDiskGetSource(disk);
720 if (driverName && !STREQ(driverName, "qemu")) {
721 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
722 _("unsupported driver name '%s' for disk '%s'"),
727 if (qemuTranslateDiskSourcePool(conn, disk) < 0)
730 if (qemuAddSharedDevice(driver, dev, vm->def->name) < 0)
733 if (qemuSetUnprivSGIO(dev) < 0)
736 if (qemuDomainDetermineDiskChain(driver, vm, disk, false) < 0)
739 if (qemuSetupDiskCgroup(vm, disk) < 0)
742 switch (disk->device) {
743 case VIR_DOMAIN_DISK_DEVICE_CDROM:
744 case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
745 if (!(orig_disk = virDomainDiskFindByBusAndDst(vm->def,
746 disk->bus, disk->dst))) {
747 virReportError(VIR_ERR_INTERNAL_ERROR,
748 _("No device with bus '%s' and target '%s'"),
749 virDomainDiskBusTypeToString(disk->bus),
754 if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
757 tmp = dev->data.disk;
758 dev->data.disk = orig_disk;
760 if (!(dev_copy = virDomainDeviceDefCopy(dev, vm->def,
761 caps, driver->xmlopt))) {
762 dev->data.disk = tmp;
765 dev->data.disk = tmp;
767 ret = qemuDomainChangeEjectableMedia(driver, vm, disk, orig_disk, false);
768 /* 'disk' must not be accessed now - it has been free'd.
769 * 'orig_disk' now points to the new disk, while 'dev_copy'
770 * now points to the old disk */
772 /* Need to remove the shared disk entry for the original disk src
773 * if the operation is either ejecting or updating.
776 ignore_value(qemuRemoveSharedDevice(driver, dev_copy,
779 case VIR_DOMAIN_DISK_DEVICE_DISK:
780 case VIR_DOMAIN_DISK_DEVICE_LUN:
781 if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
782 if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
783 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
784 _("disk device='lun' is not supported for usb bus"));
787 ret = qemuDomainAttachUSBMassstorageDevice(conn, driver, vm,
789 } else if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
790 ret = qemuDomainAttachVirtioDiskDevice(conn, driver, vm, disk);
791 } else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
792 ret = qemuDomainAttachSCSIDisk(conn, driver, vm, disk);
794 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
795 _("disk bus '%s' cannot be hotplugged."),
796 virDomainDiskBusTypeToString(disk->bus));
800 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
801 _("disk device type '%s' cannot be hotplugged"),
802 virDomainDiskDeviceTypeToString(disk->device));
807 qemuTeardownDiskCgroup(vm, disk) < 0) {
808 VIR_WARN("Failed to teardown cgroup for disk path %s",
814 ignore_value(qemuRemoveSharedDevice(driver, dev, vm->def->name));
815 virObjectUnref(caps);
816 virDomainDeviceDefFree(dev_copy);
821 /* XXX conn required for network -> bridge resolution */
822 int qemuDomainAttachNetDevice(virConnectPtr conn,
823 virQEMUDriverPtr driver,
825 virDomainNetDefPtr net)
827 qemuDomainObjPrivatePtr priv = vm->privateData;
828 char **tapfdName = NULL;
831 char **vhostfdName = NULL;
836 virNetDevVPortProfilePtr vport = NULL;
838 virDevicePCIAddress guestAddr;
840 bool releaseaddr = false;
841 bool iface_connected = false;
843 virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
846 /* preallocate new slot for device */
847 if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets + 1) < 0)
850 /* If appropriate, grab a physical device from the configured
851 * network's pool of devices, or resolve bridge device name
852 * to the one defined in the network definition.
854 if (networkAllocateActualDevice(vm->def, net) < 0)
857 actualType = virDomainNetGetActualType(net);
859 if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
860 /* This is really a "smart hostdev", so it should be attached
861 * as a hostdev (the hostdev code will reach over into the
862 * netdev-specific code as appropriate), then also added to
863 * the nets list (see cleanup:) if successful.
865 ret = qemuDomainAttachHostDevice(driver, vm,
866 virDomainNetGetActualHostdev(net));
870 if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_HOST_NET_ADD)) {
871 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
872 _("installed qemu version does not support host_net_add"));
876 /* Currently nothing besides TAP devices supports multiqueue. */
877 if (net->driver.virtio.queues > 0 &&
878 !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
879 actualType == VIR_DOMAIN_NET_TYPE_BRIDGE)) {
880 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
881 _("Multiqueue network is not supported for: %s"),
882 virDomainNetTypeToString(actualType));
886 if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
887 actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
888 tapfdSize = vhostfdSize = net->driver.virtio.queues;
890 tapfdSize = vhostfdSize = 1;
891 if (VIR_ALLOC_N(tapfd, tapfdSize) < 0)
893 memset(tapfd, -1, sizeof(*tapfd) * tapfdSize);
894 if (VIR_ALLOC_N(vhostfd, vhostfdSize) < 0)
896 memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize);
897 if (qemuNetworkIfaceConnect(vm->def, conn, driver, net,
898 priv->qemuCaps, tapfd, &tapfdSize) < 0)
900 iface_connected = true;
901 if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
903 } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
904 tapfdSize = vhostfdSize = 1;
905 if (VIR_ALLOC(tapfd) < 0)
908 if (VIR_ALLOC(vhostfd) < 0)
911 if ((tapfd[0] = qemuPhysIfaceConnect(vm->def, driver, net,
913 VIR_NETDEV_VPORT_PROFILE_OP_CREATE)) < 0)
915 iface_connected = true;
916 if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
918 } else if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
920 if (VIR_ALLOC(vhostfd) < 0)
923 if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
927 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NET_NAME) ||
928 virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
929 if (qemuAssignDeviceNetAlias(vm->def, net, -1) < 0)
933 if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
934 virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
935 net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW;
936 if (qemuDomainCCWAddressAssign(&net->info, priv->ccwaddrs,
937 !net->info.addr.ccw.assigned) < 0)
939 } else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_S390))
940 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
941 _("virtio-s390 net device cannot be hotplugged."));
942 else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
943 virDomainPCIAddressEnsureAddr(priv->pciaddrs, &net->info) < 0)
948 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
949 virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
952 vlan = qemuDomainNetVLAN(net);
955 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
956 _("Unable to attach network devices without vlan"));
961 if (VIR_ALLOC_N(tapfdName, tapfdSize) < 0 ||
962 VIR_ALLOC_N(vhostfdName, vhostfdSize) < 0)
965 for (i = 0; i < tapfdSize; i++) {
966 if (virAsprintf(&tapfdName[i], "fd-%s%zu", net->info.alias, i) < 0)
970 for (i = 0; i < vhostfdSize; i++) {
971 if (virAsprintf(&vhostfdName[i], "vhostfd-%s%zu", net->info.alias, i) < 0)
975 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
976 virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
977 if (!(netstr = qemuBuildHostNetStr(net, driver,
979 tapfdName, tapfdSize,
980 vhostfdName, vhostfdSize)))
983 if (!(netstr = qemuBuildHostNetStr(net, driver,
985 tapfdName, tapfdSize,
986 vhostfdName, vhostfdSize)))
990 qemuDomainObjEnterMonitor(driver, vm);
991 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
992 virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
993 if (qemuMonitorAddNetdev(priv->mon, netstr,
994 tapfd, tapfdName, tapfdSize,
995 vhostfd, vhostfdName, vhostfdSize) < 0) {
996 qemuDomainObjExitMonitor(driver, vm);
997 virDomainAuditNet(vm, NULL, net, "attach", false);
1001 if (qemuMonitorAddHostNetwork(priv->mon, netstr,
1002 tapfd, tapfdName, tapfdSize,
1003 vhostfd, vhostfdName, vhostfdSize) < 0) {
1004 qemuDomainObjExitMonitor(driver, vm);
1005 virDomainAuditNet(vm, NULL, net, "attach", false);
1009 qemuDomainObjExitMonitor(driver, vm);
1011 for (i = 0; i < tapfdSize; i++)
1012 VIR_FORCE_CLOSE(tapfd[i]);
1013 for (i = 0; i < vhostfdSize; i++)
1014 VIR_FORCE_CLOSE(vhostfd[i]);
1016 if (!virDomainObjIsActive(vm)) {
1017 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1018 _("guest unexpectedly quit"));
1022 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
1023 if (!(nicstr = qemuBuildNicDevStr(vm->def, net, vlan, 0,
1024 vhostfdSize, priv->qemuCaps)))
1027 if (!(nicstr = qemuBuildNicStr(net, NULL, vlan)))
1031 qemuDomainObjEnterMonitor(driver, vm);
1032 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
1033 if (qemuMonitorAddDevice(priv->mon, nicstr) < 0) {
1034 qemuDomainObjExitMonitor(driver, vm);
1035 virDomainAuditNet(vm, NULL, net, "attach", false);
1039 guestAddr = net->info.addr.pci;
1040 if (qemuMonitorAddPCINetwork(priv->mon, nicstr,
1042 qemuDomainObjExitMonitor(driver, vm);
1043 virDomainAuditNet(vm, NULL, net, "attach", false);
1046 net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
1047 memcpy(&net->info.addr.pci, &guestAddr, sizeof(guestAddr));
1049 qemuDomainObjExitMonitor(driver, vm);
1051 /* set link state */
1052 if (net->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) {
1053 if (!net->info.alias) {
1054 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
1055 _("device alias not found: cannot set link state to down"));
1057 qemuDomainObjEnterMonitor(driver, vm);
1059 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV)) {
1060 if (qemuMonitorSetLink(priv->mon, net->info.alias, VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) < 0) {
1061 qemuDomainObjExitMonitor(driver, vm);
1062 virDomainAuditNet(vm, NULL, net, "attach", false);
1066 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
1067 _("setting of link state not supported: Link is up"));
1070 qemuDomainObjExitMonitor(driver, vm);
1072 /* link set to down */
1075 virDomainAuditNet(vm, NULL, net, "attach", true);
1081 vm->def->nets[vm->def->nnets++] = net;
1084 qemuDomainReleaseDeviceAddress(vm, &net->info, NULL);
1086 if (iface_connected) {
1087 virDomainConfNWFilterTeardown(net);
1089 if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) {
1090 ignore_value(virNetDevMacVLanDeleteWithVPortProfile(
1091 net->ifname, &net->mac,
1092 virDomainNetGetActualDirectDev(net),
1093 virDomainNetGetActualDirectMode(net),
1094 virDomainNetGetActualVirtPortProfile(net),
1096 VIR_FREE(net->ifname);
1099 vport = virDomainNetGetActualVirtPortProfile(net);
1100 if (vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH)
1101 ignore_value(virNetDevOpenvswitchRemovePort(
1102 virDomainNetGetActualBridgeName(net), net->ifname));
1105 virDomainNetRemoveHostdev(vm->def, net);
1107 networkReleaseActualDevice(vm->def, net);
1112 for (i = 0; tapfd && i < tapfdSize; i++) {
1113 VIR_FORCE_CLOSE(tapfd[i]);
1115 VIR_FREE(tapfdName[i]);
1118 VIR_FREE(tapfdName);
1119 for (i = 0; vhostfd && i < vhostfdSize; i++) {
1120 VIR_FORCE_CLOSE(vhostfd[i]);
1122 VIR_FREE(vhostfdName[i]);
1125 VIR_FREE(vhostfdName);
1126 virObjectUnref(cfg);
1131 if (!virDomainObjIsActive(vm))
1135 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
1136 virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
1138 if (virAsprintf(&netdev_name, "host%s", net->info.alias) < 0)
1140 qemuDomainObjEnterMonitor(driver, vm);
1141 if (qemuMonitorRemoveNetdev(priv->mon, netdev_name) < 0)
1142 VIR_WARN("Failed to remove network backend for netdev %s",
1144 qemuDomainObjExitMonitor(driver, vm);
1145 VIR_FREE(netdev_name);
1147 VIR_WARN("Unable to remove network backend");
1151 if (virAsprintf(&hostnet_name, "host%s", net->info.alias) < 0)
1153 qemuDomainObjEnterMonitor(driver, vm);
1154 if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0)
1155 VIR_WARN("Failed to remove network backend for vlan %d, net %s",
1156 vlan, hostnet_name);
1157 qemuDomainObjExitMonitor(driver, vm);
1158 VIR_FREE(hostnet_name);
1165 qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
1167 virDomainHostdevDefPtr hostdev)
1169 qemuDomainObjPrivatePtr priv = vm->privateData;
1171 char *devstr = NULL;
1173 char *configfd_name = NULL;
1174 bool releaseaddr = false;
1175 bool teardowncgroup = false;
1176 bool teardownlabel = false;
1178 unsigned long long memKB;
1179 virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
1180 unsigned int flags = 0;
1182 if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
1185 if (!cfg->relaxedACS)
1186 flags |= VIR_HOSTDEV_STRICT_ACS_CHECK;
1187 if (qemuPrepareHostdevPCIDevices(driver, vm->def->name, vm->def->uuid,
1188 &hostdev, 1, priv->qemuCaps, flags) < 0)
1191 /* this could have been changed by qemuPrepareHostdevPCIDevices */
1192 backend = hostdev->source.subsys.u.pci.backend;
1194 switch ((virDomainHostdevSubsysPCIBackendType) backend) {
1195 case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO:
1196 if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
1197 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
1198 _("VFIO PCI device assignment is not "
1199 "supported by this version of qemu"));
1203 /* VFIO requires all of the guest's memory to be locked
1204 * resident (plus an additional 1GiB to cover IO space). During
1205 * hotplug, the guest's memory may already be locked, but it
1206 * doesn't hurt to "change" the limit to the same value.
1207 * NB: the domain's memory tuning parameters are stored as
1208 * Kibibytes, but virProcessSetMaxMemLock expects the value in
1211 memKB = vm->def->mem.hard_limit
1212 ? vm->def->mem.hard_limit
1213 : vm->def->mem.max_balloon + (1024 * 1024);
1214 virProcessSetMaxMemLock(vm->pid, memKB * 1024);
1221 if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
1223 teardowncgroup = true;
1225 if (virSecurityManagerSetHostdevLabel(driver->securityManager,
1226 vm->def, hostdev, NULL) < 0)
1228 teardownlabel = true;
1230 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
1231 if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
1233 if (virDomainPCIAddressEnsureAddr(priv->pciaddrs, hostdev->info) < 0)
1236 if (backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO &&
1237 virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
1238 configfd = qemuOpenPCIConfig(hostdev);
1239 if (configfd >= 0) {
1240 if (virAsprintf(&configfd_name, "fd-%s",
1241 hostdev->info->alias) < 0)
1246 if (!virDomainObjIsActive(vm)) {
1247 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1248 _("guest unexpectedly quit during hotplug"));
1252 if (!(devstr = qemuBuildPCIHostdevDevStr(vm->def, hostdev, configfd_name,
1256 qemuDomainObjEnterMonitor(driver, vm);
1257 ret = qemuMonitorAddDeviceWithFd(priv->mon, devstr,
1258 configfd, configfd_name);
1259 qemuDomainObjExitMonitor(driver, vm);
1261 virDevicePCIAddressPtr guestAddr = &hostdev->info->addr.pci;
1262 virDevicePCIAddressPtr hostAddr = &hostdev->source.subsys.u.pci.addr;
1264 if (hostAddr->domain &&
1265 !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_HOST_PCI_MULTIDOMAIN)) {
1266 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
1267 _("non-zero domain='%.4x' in host device "
1268 "PCI address not supported in this QEMU binary"),
1273 qemuDomainObjEnterMonitor(driver, vm);
1274 ret = qemuMonitorAddPCIHostDevice(priv->mon, hostAddr, guestAddr);
1275 qemuDomainObjExitMonitor(driver, vm);
1277 hostdev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
1279 virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
1283 vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
1286 VIR_FREE(configfd_name);
1287 VIR_FORCE_CLOSE(configfd);
1288 virObjectUnref(cfg);
1293 if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
1294 VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
1295 if (teardownlabel &&
1296 virSecurityManagerRestoreHostdevLabel(driver->securityManager,
1297 vm->def, hostdev, NULL) < 0)
1298 VIR_WARN("Unable to restore host device labelling on hotplug fail");
1301 qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
1303 qemuDomainReAttachHostdevDevices(driver, vm->def->name, &hostdev, 1);
1306 VIR_FREE(configfd_name);
1307 VIR_FORCE_CLOSE(configfd);
1310 virObjectUnref(cfg);
1315 int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr driver,
1317 virDomainRedirdevDefPtr redirdev)
1320 qemuDomainObjPrivatePtr priv = vm->privateData;
1321 virDomainDefPtr def = vm->def;
1322 char *devstr = NULL;
1324 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
1325 if (qemuAssignDeviceRedirdevAlias(vm->def, redirdev, -1) < 0)
1327 if (!(devstr = qemuBuildRedirdevDevStr(def, redirdev, priv->qemuCaps)))
1331 if (VIR_REALLOC_N(vm->def->redirdevs, vm->def->nredirdevs+1) < 0)
1334 qemuDomainObjEnterMonitor(driver, vm);
1335 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE))
1336 ret = qemuMonitorAddDevice(priv->mon, devstr);
1340 qemuDomainObjExitMonitor(driver, vm);
1341 virDomainAuditRedirdev(vm, redirdev, "attach", ret == 0);
1345 vm->def->redirdevs[vm->def->nredirdevs++] = redirdev;
1358 qemuDomainChrInsert(virDomainDefPtr vmdef,
1359 virDomainChrDefPtr chr)
1361 if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
1362 chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) {
1363 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
1364 _("attaching serial console is not supported"));
1368 if (virDomainChrFind(vmdef, chr)) {
1369 virReportError(VIR_ERR_OPERATION_INVALID, "%s",
1370 _("chardev already exists"));
1374 if (virDomainChrInsert(vmdef, chr) < 0)
1377 /* Due to some crazy backcompat stuff, the first serial device is an alias
1378 * to the first console too. If this is the case, the definition must be
1379 * duplicated as first console device. */
1380 if (vmdef->nserials == 1 && vmdef->nconsoles == 0) {
1381 if ((!vmdef->consoles && VIR_ALLOC(vmdef->consoles) < 0) ||
1382 VIR_ALLOC(vmdef->consoles[0]) < 0) {
1383 virDomainChrRemove(vmdef, chr);
1386 vmdef->nconsoles = 1;
1388 /* Create an console alias for the serial port */
1389 vmdef->consoles[0]->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE;
1390 vmdef->consoles[0]->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
1397 qemuDomainChrRemove(virDomainDefPtr vmdef,
1398 virDomainChrDefPtr chr)
1400 virDomainChrDefPtr ret;
1403 if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
1404 chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) {
1405 virReportError(VIR_ERR_OPERATION_INVALID, "%s",
1406 _("detaching serial console is not supported"));
1410 /* Due to some crazy backcompat stuff, the first serial device is an alias
1411 * to the first console too. If this is the case, the definition must be
1412 * duplicated as first console device. */
1413 removeCompat = vmdef->nserials && vmdef->nconsoles &&
1414 vmdef->consoles[0]->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
1415 vmdef->consoles[0]->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL &&
1416 virDomainChrEquals(vmdef->serials[0], chr);
1418 if (!(ret = virDomainChrRemove(vmdef, chr))) {
1419 virReportError(VIR_ERR_INVALID_ARG, "%s",
1420 _("device not present in domain configuration"));
1425 VIR_DELETE_ELEMENT(vmdef->consoles, 0, vmdef->nconsoles);
1430 int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
1432 virDomainChrDefPtr chr)
1435 qemuDomainObjPrivatePtr priv = vm->privateData;
1436 virDomainDefPtr vmdef = vm->def;
1437 char *devstr = NULL;
1438 char *charAlias = NULL;
1439 bool need_remove = false;
1441 if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
1442 virReportError(VIR_ERR_OPERATION_INVALID, "%s",
1443 _("qemu does not support -device"));
1447 if (qemuAssignDeviceChrAlias(vmdef, chr, -1) < 0)
1450 if (qemuBuildChrDeviceStr(&devstr, vm->def, chr, priv->qemuCaps) < 0)
1453 if (virAsprintf(&charAlias, "char%s", chr->info.alias) < 0) {
1454 virReportOOMError();
1458 if (qemuDomainChrInsert(vmdef, chr) < 0)
1462 qemuDomainObjEnterMonitor(driver, vm);
1463 if (qemuMonitorAttachCharDev(priv->mon, charAlias, &chr->source) < 0) {
1464 qemuDomainObjExitMonitor(driver, vm);
1468 if (devstr && qemuMonitorAddDevice(priv->mon, devstr) < 0) {
1469 /* detach associated chardev on error */
1470 qemuMonitorDetachCharDev(priv->mon, charAlias);
1471 qemuDomainObjExitMonitor(driver, vm);
1474 qemuDomainObjExitMonitor(driver, vm);
1478 if (ret < 0 && need_remove)
1479 qemuDomainChrRemove(vmdef, chr);
1480 VIR_FREE(charAlias);
1486 qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
1488 virDomainHostdevDefPtr hostdev)
1490 qemuDomainObjPrivatePtr priv = vm->privateData;
1491 char *devstr = NULL;
1493 bool teardowncgroup = false;
1494 bool teardownlabel = false;
1497 if (qemuPrepareHostUSBDevices(driver, vm->def->name, &hostdev, 1, 0) < 0)
1502 if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
1504 teardowncgroup = true;
1506 if (virSecurityManagerSetHostdevLabel(driver->securityManager,
1507 vm->def, hostdev, NULL) < 0)
1509 teardownlabel = true;
1511 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
1512 if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
1514 if (!(devstr = qemuBuildUSBHostdevDevStr(vm->def, hostdev, priv->qemuCaps)))
1518 if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0)
1521 qemuDomainObjEnterMonitor(driver, vm);
1522 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE))
1523 ret = qemuMonitorAddDevice(priv->mon, devstr);
1525 ret = qemuMonitorAddUSBDeviceExact(priv->mon,
1526 hostdev->source.subsys.u.usb.bus,
1527 hostdev->source.subsys.u.usb.device);
1528 qemuDomainObjExitMonitor(driver, vm);
1529 virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
1533 vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
1538 if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
1539 VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
1540 if (teardownlabel &&
1541 virSecurityManagerRestoreHostdevLabel(driver->securityManager,
1542 vm->def, hostdev, NULL) < 0)
1543 VIR_WARN("Unable to restore host device labelling on hotplug fail");
1545 qemuDomainReAttachHostUSBDevices(driver, vm->def->name, &hostdev, 1);
1552 qemuDomainAttachHostSCSIDevice(virQEMUDriverPtr driver,
1554 virDomainHostdevDefPtr hostdev)
1557 qemuDomainObjPrivatePtr priv = vm->privateData;
1558 virDomainControllerDefPtr cont = NULL;
1559 char *devstr = NULL;
1560 char *drvstr = NULL;
1561 bool teardowncgroup = false;
1562 bool teardownlabel = false;
1564 if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE) ||
1565 !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) ||
1566 !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_SCSI_GENERIC)) {
1567 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
1568 _("SCSI passthrough is not supported by this version of qemu"));
1572 cont = qemuDomainFindOrCreateSCSIDiskController(driver, vm, hostdev->info->addr.drive.controller);
1576 if (qemuPrepareHostdevSCSIDevices(driver, vm->def->name,
1578 virReportError(VIR_ERR_INTERNAL_ERROR,
1579 _("Unable to prepare scsi hostdev: %s:%d:%d:%d"),
1580 hostdev->source.subsys.u.scsi.adapter,
1581 hostdev->source.subsys.u.scsi.bus,
1582 hostdev->source.subsys.u.scsi.target,
1583 hostdev->source.subsys.u.scsi.unit);
1587 if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
1589 teardowncgroup = true;
1591 if (virSecurityManagerSetHostdevLabel(driver->securityManager,
1592 vm->def, hostdev, NULL) < 0)
1594 teardownlabel = true;
1596 if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
1599 if (!(drvstr = qemuBuildSCSIHostdevDrvStr(hostdev, priv->qemuCaps,
1600 &buildCommandLineCallbacks)))
1603 if (!(devstr = qemuBuildSCSIHostdevDevStr(vm->def, hostdev, priv->qemuCaps)))
1606 if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
1609 qemuDomainObjEnterMonitor(driver, vm);
1610 if ((ret = qemuMonitorAddDrive(priv->mon, drvstr)) == 0) {
1611 if ((ret = qemuMonitorAddDevice(priv->mon, devstr)) < 0) {
1612 virErrorPtr orig_err = virSaveLastError();
1613 if (qemuMonitorDriveDel(priv->mon, drvstr) < 0)
1614 VIR_WARN("Unable to remove drive %s (%s) after failed "
1615 "qemuMonitorAddDevice",
1618 virSetError(orig_err);
1619 virFreeError(orig_err);
1623 qemuDomainObjExitMonitor(driver, vm);
1625 virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
1629 vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
1634 qemuDomainReAttachHostSCSIDevices(driver, vm->def->name, &hostdev, 1);
1635 if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
1636 VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
1637 if (teardownlabel &&
1638 virSecurityManagerRestoreHostdevLabel(driver->securityManager,
1639 vm->def, hostdev, NULL) < 0)
1640 VIR_WARN("Unable to restore host device labelling on hotplug fail");
1647 int qemuDomainAttachHostDevice(virQEMUDriverPtr driver,
1649 virDomainHostdevDefPtr hostdev)
1651 if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
1652 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
1653 _("hostdev mode '%s' not supported"),
1654 virDomainHostdevModeTypeToString(hostdev->mode));
1658 switch (hostdev->source.subsys.type) {
1659 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
1660 if (qemuDomainAttachHostPCIDevice(driver, vm,
1665 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
1666 if (qemuDomainAttachHostUSBDevice(driver, vm,
1671 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
1672 if (qemuDomainAttachHostSCSIDevice(driver, vm,
1678 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
1679 _("hostdev subsys type '%s' not supported"),
1680 virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type));
1690 static virDomainNetDefPtr *qemuDomainFindNet(virDomainObjPtr vm,
1691 virDomainNetDefPtr dev)
1695 for (i = 0; i < vm->def->nnets; i++) {
1696 if (virMacAddrCmp(&vm->def->nets[i]->mac, &dev->mac) == 0)
1697 return &vm->def->nets[i];
1704 qemuDomainNetGetBridgeName(virConnectPtr conn, virDomainNetDefPtr net)
1706 char *brname = NULL;
1707 int actualType = virDomainNetGetActualType(net);
1709 if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
1710 const char *tmpbr = virDomainNetGetActualBridgeName(net);
1712 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1713 _("interface is missing bridge name"));
1716 /* we need a copy, not just a pointer to the original */
1717 if (VIR_STRDUP(brname, tmpbr) < 0)
1719 } else if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
1721 virNetworkPtr network;
1723 if (!(network = virNetworkLookupByName(conn, net->data.network.name))) {
1724 virReportError(VIR_ERR_INTERNAL_ERROR,
1725 _("Couldn't find network '%s'"),
1726 net->data.network.name);
1729 brname = virNetworkGetBridgeName(network);
1731 /* Make sure any above failure is preserved */
1732 errobj = virSaveLastError();
1733 virNetworkFree(network);
1734 virSetError(errobj);
1735 virFreeError(errobj);
1738 virReportError(VIR_ERR_INTERNAL_ERROR,
1739 _("Interface type %d has no bridge name"),
1740 virDomainNetGetActualType(net));
1748 qemuDomainChangeNetBridge(virConnectPtr conn,
1750 virDomainNetDefPtr olddev,
1751 virDomainNetDefPtr newdev)
1754 char *oldbridge = NULL, *newbridge = NULL;
1756 if (!(oldbridge = qemuDomainNetGetBridgeName(conn, olddev)))
1759 if (!(newbridge = qemuDomainNetGetBridgeName(conn, newdev)))
1762 VIR_DEBUG("Change bridge for interface %s: %s -> %s",
1763 olddev->ifname, oldbridge, newbridge);
1765 if (virNetDevExists(newbridge) != 1) {
1766 virReportError(VIR_ERR_OPERATION_FAILED,
1767 _("bridge %s doesn't exist"), newbridge);
1772 ret = virNetDevBridgeRemovePort(oldbridge, olddev->ifname);
1773 virDomainAuditNet(vm, olddev, NULL, "detach", ret == 0);
1775 /* warn but continue - possibly the old network
1776 * had been destroyed and reconstructed, leaving the
1777 * tap device orphaned.
1779 VIR_WARN("Unable to detach device %s from bridge %s",
1780 olddev->ifname, oldbridge);
1784 ret = virNetDevBridgeAddPort(newbridge, olddev->ifname);
1785 virDomainAuditNet(vm, NULL, newdev, "attach", ret == 0);
1787 ret = virNetDevBridgeAddPort(oldbridge, olddev->ifname);
1788 virDomainAuditNet(vm, NULL, olddev, "attach", ret == 0);
1790 virReportError(VIR_ERR_OPERATION_FAILED,
1791 _("unable to recover former state by adding port "
1792 "to bridge %s"), oldbridge);
1796 /* caller will replace entire olddev with newdev in domain nets list */
1799 VIR_FREE(oldbridge);
1800 VIR_FREE(newbridge);
1805 qemuDomainChangeNetFilter(virConnectPtr conn,
1807 virDomainNetDefPtr olddev,
1808 virDomainNetDefPtr newdev)
1810 /* make sure this type of device supports filters. */
1811 switch (virDomainNetGetActualType(newdev)) {
1812 case VIR_DOMAIN_NET_TYPE_ETHERNET:
1813 case VIR_DOMAIN_NET_TYPE_BRIDGE:
1814 case VIR_DOMAIN_NET_TYPE_NETWORK:
1817 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
1818 _("filters not supported on interfaces of type %s"),
1819 virDomainNetTypeToString(virDomainNetGetActualType(newdev)));
1823 virDomainConfNWFilterTeardown(olddev);
1825 if (newdev->filter &&
1826 virDomainConfNWFilterInstantiate(conn, vm->def->uuid, newdev) < 0) {
1829 virReportError(VIR_ERR_OPERATION_FAILED,
1830 _("failed to add new filter rules to '%s' "
1831 "- attempting to restore old rules"),
1833 errobj = virSaveLastError();
1834 ignore_value(virDomainConfNWFilterInstantiate(conn, vm->def->uuid, olddev));
1835 virSetError(errobj);
1836 virFreeError(errobj);
1842 int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver,
1844 virDomainNetDefPtr dev,
1848 qemuDomainObjPrivatePtr priv = vm->privateData;
1850 VIR_DEBUG("dev: %s, state: %d", dev->info.alias, linkstate);
1852 if (!dev->info.alias) {
1853 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
1854 _("can't change link state: device alias not found"));
1858 qemuDomainObjEnterMonitor(driver, vm);
1860 ret = qemuMonitorSetLink(priv->mon, dev->info.alias, linkstate);
1864 /* modify the device configuration */
1865 dev->linkstate = linkstate;
1868 qemuDomainObjExitMonitor(driver, vm);
1874 qemuDomainChangeNet(virQEMUDriverPtr driver,
1877 virDomainDeviceDefPtr dev)
1879 virDomainNetDefPtr newdev = dev->data.net;
1880 virDomainNetDefPtr *devslot = qemuDomainFindNet(vm, newdev);
1881 virDomainNetDefPtr olddev;
1882 int oldType, newType;
1883 bool needReconnect = false;
1884 bool needBridgeChange = false;
1885 bool needFilterChange = false;
1886 bool needLinkStateChange = false;
1887 bool needReplaceDevDef = false;
1888 bool needBandwidthSet = false;
1891 if (!devslot || !(olddev = *devslot)) {
1892 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
1893 _("cannot find existing network device to modify"));
1897 oldType = virDomainNetGetActualType(olddev);
1898 if (oldType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
1899 /* no changes are possible to a type='hostdev' interface */
1900 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
1901 _("cannot change config of '%s' network type"),
1902 virDomainNetTypeToString(oldType));
1906 /* Check individual attributes for changes that can't be done to a
1907 * live netdev. These checks *mostly* go in order of the
1908 * declarations in virDomainNetDef in order to assure nothing is
1909 * omitted. (exceptiong where noted in comments - in particular,
1910 * some things require that a new "actual device" be allocated
1911 * from the network driver first, but we delay doing that until
1912 * after we've made as many other checks as possible)
1915 /* type: this can change (with some restrictions), but the actual
1916 * type of the new device connection isn't known until after we
1917 * allocate the "actual" device.
1920 if (virMacAddrCmp(&olddev->mac, &newdev->mac)) {
1921 char oldmac[VIR_MAC_STRING_BUFLEN], newmac[VIR_MAC_STRING_BUFLEN];
1923 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
1924 _("cannot change network interface mac address "
1926 virMacAddrFormat(&olddev->mac, oldmac),
1927 virMacAddrFormat(&newdev->mac, newmac));
1931 if (STRNEQ_NULLABLE(olddev->model, newdev->model)) {
1932 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
1933 _("cannot modify network device model from %s to %s"),
1934 olddev->model ? olddev->model : "(default)",
1935 newdev->model ? newdev->model : "(default)");
1939 if (olddev->model && STREQ(olddev->model, "virtio") &&
1940 (olddev->driver.virtio.name != newdev->driver.virtio.name ||
1941 olddev->driver.virtio.txmode != newdev->driver.virtio.txmode ||
1942 olddev->driver.virtio.ioeventfd != newdev->driver.virtio.ioeventfd ||
1943 olddev->driver.virtio.event_idx != newdev->driver.virtio.event_idx ||
1944 olddev->driver.virtio.queues != newdev->driver.virtio.queues)) {
1945 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
1946 _("cannot modify virtio network device driver attributes"));
1950 /* data: this union will be examined later, after allocating new actualdev */
1951 /* virtPortProfile: will be examined later, after allocating new actualdev */
1953 if (olddev->tune.sndbuf_specified != newdev->tune.sndbuf_specified ||
1954 olddev->tune.sndbuf != newdev->tune.sndbuf) {
1955 needReconnect = true;
1958 if (STRNEQ_NULLABLE(olddev->script, newdev->script)) {
1959 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
1960 _("cannot modify network device script attribute"));
1964 /* ifname: check if it's set in newdev. If not, retain the autogenerated one */
1965 if (!newdev->ifname && VIR_STRDUP(newdev->ifname, olddev->ifname) < 0)
1967 if (STRNEQ_NULLABLE(olddev->ifname, newdev->ifname)) {
1968 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
1969 _("cannot modify network device tap name"));
1973 /* info: if newdev->info is empty, fill it in from olddev,
1974 * otherwise verify that it matches - nothing is allowed to
1975 * change. (There is no helper function to do this, so
1976 * individually check the few feidls of virDomainDeviceInfo that
1977 * are relevant in this case).
1979 if (!virDomainDeviceAddressIsValid(&newdev->info,
1980 VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
1981 virDomainDeviceInfoCopy(&newdev->info, &olddev->info) < 0) {
1984 if (!virDevicePCIAddressEqual(&olddev->info.addr.pci,
1985 &newdev->info.addr.pci)) {
1986 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
1987 _("cannot modify network device guest PCI address"));
1990 /* grab alias from olddev if not set in newdev */
1991 if (!newdev->info.alias &&
1992 VIR_STRDUP(newdev->info.alias, olddev->info.alias) < 0)
1994 if (STRNEQ_NULLABLE(olddev->info.alias, newdev->info.alias)) {
1995 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
1996 _("cannot modify network device alias"));
1999 if (olddev->info.rombar != newdev->info.rombar) {
2000 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
2001 _("cannot modify network device rom bar setting"));
2004 if (STRNEQ_NULLABLE(olddev->info.romfile, newdev->info.romfile)) {
2005 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
2006 _("cannot modify network rom file"));
2009 if (olddev->info.bootIndex != newdev->info.bootIndex) {
2010 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
2011 _("cannot modify network device boot index setting"));
2014 /* (end of device info checks) */
2016 if (STRNEQ_NULLABLE(olddev->filter, newdev->filter) ||
2017 !virNWFilterHashTableEqual(olddev->filterparams, newdev->filterparams)) {
2018 needFilterChange = true;
2021 /* bandwidth can be modified, and will be checked later */
2022 /* vlan can be modified, and will be checked later */
2023 /* linkstate can be modified */
2025 /* allocate new actual device to compare to old - we will need to
2026 * free it if we fail for any reason
2028 if (newdev->type == VIR_DOMAIN_NET_TYPE_NETWORK &&
2029 networkAllocateActualDevice(vm->def, newdev) < 0) {
2033 newType = virDomainNetGetActualType(newdev);
2035 if (newType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
2036 /* can't turn it into a type='hostdev' interface */
2037 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
2038 _("cannot change network interface type to '%s'"),
2039 virDomainNetTypeToString(newType));
2043 if (olddev->type == newdev->type && oldType == newType) {
2045 /* if type hasn't changed, check the relevant fields for the type */
2046 switch (newdev->type) {
2047 case VIR_DOMAIN_NET_TYPE_USER:
2050 case VIR_DOMAIN_NET_TYPE_ETHERNET:
2051 if (STRNEQ_NULLABLE(olddev->data.ethernet.dev,
2052 newdev->data.ethernet.dev) ||
2053 STRNEQ_NULLABLE(olddev->data.ethernet.ipaddr,
2054 newdev->data.ethernet.ipaddr)) {
2055 needReconnect = true;
2059 case VIR_DOMAIN_NET_TYPE_SERVER:
2060 case VIR_DOMAIN_NET_TYPE_CLIENT:
2061 case VIR_DOMAIN_NET_TYPE_MCAST:
2062 if (STRNEQ_NULLABLE(olddev->data.socket.address,
2063 newdev->data.socket.address) ||
2064 olddev->data.socket.port != newdev->data.socket.port) {
2065 needReconnect = true;
2069 case VIR_DOMAIN_NET_TYPE_NETWORK:
2070 if (STRNEQ(olddev->data.network.name, newdev->data.network.name)) {
2071 if (virDomainNetGetActualVirtPortProfile(newdev))
2072 needReconnect = true;
2074 needBridgeChange = true;
2076 /* other things handled in common code directly below this switch */
2079 case VIR_DOMAIN_NET_TYPE_BRIDGE:
2080 /* all handled in bridge name checked in common code below */
2083 case VIR_DOMAIN_NET_TYPE_INTERNAL:
2084 if (STRNEQ_NULLABLE(olddev->data.internal.name,
2085 newdev->data.internal.name)) {
2086 needReconnect = true;
2090 case VIR_DOMAIN_NET_TYPE_DIRECT:
2091 /* all handled in common code directly below this switch */
2095 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
2096 _("unable to change config on '%s' network type"),
2097 virDomainNetTypeToString(newdev->type));
2102 /* interface type has changed. There are a few special cases
2103 * where this can only require a minor (or even no) change,
2104 * but in most cases we need to do a full reconnection.
2106 * If we switch (in either direction) between type='bridge'
2107 * and type='network' (for a traditional managed virtual
2108 * network that uses a host bridge, i.e. forward
2109 * mode='route|nat'), we just need to change the bridge.
2111 if ((oldType == VIR_DOMAIN_NET_TYPE_NETWORK &&
2112 newType == VIR_DOMAIN_NET_TYPE_BRIDGE) ||
2113 (oldType == VIR_DOMAIN_NET_TYPE_BRIDGE &&
2114 newType == VIR_DOMAIN_NET_TYPE_NETWORK)) {
2116 needBridgeChange = true;
2118 } else if (oldType == VIR_DOMAIN_NET_TYPE_DIRECT &&
2119 newType == VIR_DOMAIN_NET_TYPE_DIRECT) {
2121 /* this is the case of switching from type='direct' to
2122 * type='network' for a network that itself uses direct
2123 * (macvtap) devices. If the physical device and mode are
2124 * the same, this doesn't require any actual setup
2125 * change. If the physical device or mode *does* change,
2126 * that will be caught in the common section below */
2130 /* for all other combinations, we'll need a full reconnect */
2131 needReconnect = true;
2136 /* now several things that are in multiple (but not all)
2137 * different types, and can be safely compared even for those
2138 * cases where they don't apply to a particular type.
2140 if (STRNEQ_NULLABLE(virDomainNetGetActualBridgeName(olddev),
2141 virDomainNetGetActualBridgeName(newdev))) {
2142 if (virDomainNetGetActualVirtPortProfile(newdev))
2143 needReconnect = true;
2145 needBridgeChange = true;
2148 if (STRNEQ_NULLABLE(virDomainNetGetActualDirectDev(olddev),
2149 virDomainNetGetActualDirectDev(newdev)) ||
2150 virDomainNetGetActualDirectMode(olddev) != virDomainNetGetActualDirectMode(olddev) ||
2151 !virNetDevVPortProfileEqual(virDomainNetGetActualVirtPortProfile(olddev),
2152 virDomainNetGetActualVirtPortProfile(newdev)) ||
2153 !virNetDevVlanEqual(virDomainNetGetActualVlan(olddev),
2154 virDomainNetGetActualVlan(newdev))) {
2155 needReconnect = true;
2158 if (olddev->linkstate != newdev->linkstate)
2159 needLinkStateChange = true;
2161 if (!virNetDevBandwidthEqual(virDomainNetGetActualBandwidth(olddev),
2162 virDomainNetGetActualBandwidth(newdev)))
2163 needBandwidthSet = true;
2165 /* FINALLY - actually perform the required actions */
2167 if (needReconnect) {
2168 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
2169 _("unable to change config on '%s' network type"),
2170 virDomainNetTypeToString(newdev->type));
2174 if (needBandwidthSet) {
2175 if (virNetDevBandwidthSet(newdev->ifname,
2176 virDomainNetGetActualBandwidth(newdev),
2178 virReportError(VIR_ERR_INTERNAL_ERROR,
2179 _("cannot set bandwidth limits on %s"),
2183 needReplaceDevDef = true;
2186 if (needBridgeChange) {
2187 if (qemuDomainChangeNetBridge(dom->conn, vm, olddev, newdev) < 0)
2189 /* we successfully switched to the new bridge, and we've
2190 * determined that the rest of newdev is equivalent to olddev,
2191 * so move newdev into place */
2192 needReplaceDevDef = true;
2195 if (needFilterChange) {
2196 if (qemuDomainChangeNetFilter(dom->conn, vm, olddev, newdev) < 0)
2198 /* we successfully switched to the new filter, and we've
2199 * determined that the rest of newdev is equivalent to olddev,
2200 * so move newdev into place */
2201 needReplaceDevDef = true;
2204 if (needLinkStateChange &&
2205 qemuDomainChangeNetLinkState(driver, vm, olddev, newdev->linkstate) < 0) {
2209 if (needReplaceDevDef) {
2210 /* the changes above warrant replacing olddev with newdev in
2211 * the domain's nets list.
2214 /* this function doesn't work with HOSTDEV networks yet, thus
2215 * no need to change the pointer in the hostdev structure */
2216 networkReleaseActualDevice(vm->def, olddev);
2217 virDomainNetDefFree(olddev);
2218 /* move newdev into the nets list, and NULL it out from the
2219 * virDomainDeviceDef that we were given so that the caller
2220 * won't delete it on return.
2223 newdev = dev->data.net = NULL;
2224 dev->type = VIR_DOMAIN_DEVICE_NONE;
2229 /* When we get here, we will be in one of these two states:
2231 * 1) newdev has been moved into the domain's list of nets and
2232 * newdev set to NULL, and dev->data.net will be NULL (and
2233 * dev->type is NONE). olddev will have been completely
2234 * released and freed. (aka success) In this case no extra
2235 * cleanup is needed.
2237 * 2) newdev has *not* been moved into the domain's list of nets,
2238 * and dev->data.net == newdev (and dev->type == NET). In this *
2239 * case, we need to at least release the "actual device" from *
2240 * newdev (the caller will free dev->data.net a.k.a. newdev, and
2241 * the original olddev is still in used)
2243 * Note that case (2) isn't necessarily a failure. It may just be
2244 * that the changes were minor enough that we didn't need to
2245 * replace the entire device object.
2248 networkReleaseActualDevice(vm->def, newdev);
2255 static virDomainGraphicsDefPtr qemuDomainFindGraphics(virDomainObjPtr vm,
2256 virDomainGraphicsDefPtr dev)
2260 for (i = 0; i < vm->def->ngraphics; i++) {
2261 if (vm->def->graphics[i]->type == dev->type)
2262 return vm->def->graphics[i];
2270 qemuDomainChangeGraphics(virQEMUDriverPtr driver,
2272 virDomainGraphicsDefPtr dev)
2274 virDomainGraphicsDefPtr olddev = qemuDomainFindGraphics(vm, dev);
2276 virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
2280 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2281 _("cannot find existing graphics device to modify"));
2285 if (dev->nListens != olddev->nListens) {
2286 virReportError(VIR_ERR_INVALID_ARG, "%s",
2287 _("cannot change the number of listen addresses"));
2291 for (i = 0; i < dev->nListens; i++) {
2292 virDomainGraphicsListenDefPtr newlisten = &dev->listens[i];
2293 virDomainGraphicsListenDefPtr oldlisten = &olddev->listens[i];
2295 if (newlisten->type != oldlisten->type) {
2296 virReportError(VIR_ERR_INVALID_ARG, "%s",
2297 _("cannot change the type of listen address"));
2301 switch ((enum virDomainGraphicsListenType) newlisten->type) {
2302 case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
2303 if (STRNEQ_NULLABLE(newlisten->address, oldlisten->address)) {
2304 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2305 dev->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC ?
2306 _("cannot change listen address setting on vnc graphics") :
2307 _("cannot change listen address setting on spice graphics"));
2312 case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK:
2313 if (STRNEQ_NULLABLE(newlisten->network, oldlisten->network)) {
2314 virReportError(VIR_ERR_INVALID_ARG, "%s",
2315 dev->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC ?
2316 _("cannot change listen network setting on vnc graphics") :
2317 _("cannot change listen network setting on spice graphics"));
2322 case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
2323 case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
2329 switch (dev->type) {
2330 case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
2331 if ((olddev->data.vnc.autoport != dev->data.vnc.autoport) ||
2332 (!dev->data.vnc.autoport &&
2333 (olddev->data.vnc.port != dev->data.vnc.port))) {
2334 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2335 _("cannot change port settings on vnc graphics"));
2338 if (STRNEQ_NULLABLE(olddev->data.vnc.keymap, dev->data.vnc.keymap)) {
2339 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2340 _("cannot change keymap setting on vnc graphics"));
2344 /* If a password lifetime was, or is set, or action if connected has
2345 * changed, then we must always run, even if new password matches
2347 if (olddev->data.vnc.auth.expires ||
2348 dev->data.vnc.auth.expires ||
2349 olddev->data.vnc.auth.connected != dev->data.vnc.auth.connected ||
2350 STRNEQ_NULLABLE(olddev->data.vnc.auth.passwd,
2351 dev->data.vnc.auth.passwd)) {
2352 VIR_DEBUG("Updating password on VNC server %p %p",
2353 dev->data.vnc.auth.passwd, cfg->vncPassword);
2354 ret = qemuDomainChangeGraphicsPasswords(driver, vm,
2355 VIR_DOMAIN_GRAPHICS_TYPE_VNC,
2356 &dev->data.vnc.auth,
2361 /* Steal the new dev's char * reference */
2362 VIR_FREE(olddev->data.vnc.auth.passwd);
2363 olddev->data.vnc.auth.passwd = dev->data.vnc.auth.passwd;
2364 dev->data.vnc.auth.passwd = NULL;
2365 olddev->data.vnc.auth.validTo = dev->data.vnc.auth.validTo;
2366 olddev->data.vnc.auth.expires = dev->data.vnc.auth.expires;
2367 olddev->data.vnc.auth.connected = dev->data.vnc.auth.connected;
2373 case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
2374 if ((olddev->data.spice.autoport != dev->data.spice.autoport) ||
2375 (!dev->data.spice.autoport &&
2376 (olddev->data.spice.port != dev->data.spice.port)) ||
2377 (!dev->data.spice.autoport &&
2378 (olddev->data.spice.tlsPort != dev->data.spice.tlsPort))) {
2379 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2380 _("cannot change port settings on spice graphics"));
2383 if (STRNEQ_NULLABLE(olddev->data.spice.keymap,
2384 dev->data.spice.keymap)) {
2385 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2386 _("cannot change keymap setting on spice graphics"));
2390 /* We must reset the password if it has changed but also if:
2391 * - password lifetime is or was set
2392 * - the requested action has changed
2393 * - the action is "disconnect"
2395 if (olddev->data.spice.auth.expires ||
2396 dev->data.spice.auth.expires ||
2397 olddev->data.spice.auth.connected != dev->data.spice.auth.connected ||
2398 dev->data.spice.auth.connected ==
2399 VIR_DOMAIN_GRAPHICS_AUTH_CONNECTED_DISCONNECT ||
2400 STRNEQ_NULLABLE(olddev->data.spice.auth.passwd,
2401 dev->data.spice.auth.passwd)) {
2402 VIR_DEBUG("Updating password on SPICE server %p %p",
2403 dev->data.spice.auth.passwd, cfg->spicePassword);
2404 ret = qemuDomainChangeGraphicsPasswords(driver, vm,
2405 VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
2406 &dev->data.spice.auth,
2407 cfg->spicePassword);
2412 /* Steal the new dev's char * reference */
2413 VIR_FREE(olddev->data.spice.auth.passwd);
2414 olddev->data.spice.auth.passwd = dev->data.spice.auth.passwd;
2415 dev->data.spice.auth.passwd = NULL;
2416 olddev->data.spice.auth.validTo = dev->data.spice.auth.validTo;
2417 olddev->data.spice.auth.expires = dev->data.spice.auth.expires;
2418 olddev->data.spice.auth.connected = dev->data.spice.auth.connected;
2420 VIR_DEBUG("Not updating since password didn't change");
2426 virReportError(VIR_ERR_INTERNAL_ERROR,
2427 _("unable to change config on '%s' graphics type"),
2428 virDomainGraphicsTypeToString(dev->type));
2433 virObjectUnref(cfg);
2438 static int qemuComparePCIDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
2439 virDomainDeviceDefPtr device ATTRIBUTE_UNUSED,
2440 virDomainDeviceInfoPtr info1,
2443 virDomainDeviceInfoPtr info2 = opaque;
2445 if (info1->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI ||
2446 info2->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
2449 if (info1->addr.pci.domain == info2->addr.pci.domain &&
2450 info1->addr.pci.bus == info2->addr.pci.bus &&
2451 info1->addr.pci.slot == info2->addr.pci.slot &&
2452 info1->addr.pci.function != info2->addr.pci.function)
2457 static bool qemuIsMultiFunctionDevice(virDomainDefPtr def,
2458 virDomainDeviceInfoPtr dev)
2460 if (virDomainDeviceInfoIterate(def, qemuComparePCIDevice, dev) < 0)
2467 qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
2469 virDomainDiskDefPtr disk)
2471 virDomainDeviceDef dev;
2472 virObjectEventPtr event;
2474 const char *src = virDomainDiskGetSource(disk);
2476 VIR_DEBUG("Removing disk %s from domain %p %s",
2477 disk->info.alias, vm, vm->def->name);
2479 virDomainAuditDisk(vm, src, NULL, "detach", true);
2481 event = virDomainEventDeviceRemovedNewFromObj(vm, disk->info.alias);
2483 qemuDomainEventQueue(driver, event);
2485 for (i = 0; i < vm->def->ndisks; i++) {
2486 if (vm->def->disks[i] == disk) {
2487 virDomainDiskRemove(vm->def, i);
2492 qemuDomainReleaseDeviceAddress(vm, &disk->info, src);
2494 if (virSecurityManagerRestoreImageLabel(driver->securityManager,
2496 VIR_WARN("Unable to restore security label on %s", src);
2498 if (qemuTeardownDiskCgroup(vm, disk) < 0)
2499 VIR_WARN("Failed to tear down cgroup for disk path %s", src);
2501 if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
2502 VIR_WARN("Unable to release lock on %s", src);
2504 dev.type = VIR_DOMAIN_DEVICE_DISK;
2505 dev.data.disk = disk;
2506 ignore_value(qemuRemoveSharedDevice(driver, &dev, vm->def->name));
2508 virDomainDiskDefFree(disk);
2513 qemuDomainRemoveControllerDevice(virQEMUDriverPtr driver,
2515 virDomainControllerDefPtr controller)
2517 virObjectEventPtr event;
2520 VIR_DEBUG("Removing controller %s from domain %p %s",
2521 controller->info.alias, vm, vm->def->name);
2523 event = virDomainEventDeviceRemovedNewFromObj(vm, controller->info.alias);
2525 qemuDomainEventQueue(driver, event);
2527 for (i = 0; i < vm->def->ncontrollers; i++) {
2528 if (vm->def->controllers[i] == controller) {
2529 virDomainControllerRemove(vm->def, i);
2534 qemuDomainReleaseDeviceAddress(vm, &controller->info, NULL);
2535 virDomainControllerDefFree(controller);
2540 qemuDomainRemovePCIHostDevice(virQEMUDriverPtr driver,
2542 virDomainHostdevDefPtr hostdev)
2544 qemuDomainReAttachHostdevDevices(driver, vm->def->name, &hostdev, 1);
2545 qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
2549 qemuDomainRemoveUSBHostDevice(virQEMUDriverPtr driver,
2551 virDomainHostdevDefPtr hostdev)
2553 qemuDomainReAttachHostUSBDevices(driver, vm->def->name, &hostdev, 1);
2557 qemuDomainRemoveSCSIHostDevice(virQEMUDriverPtr driver,
2559 virDomainHostdevDefPtr hostdev)
2561 qemuDomainReAttachHostSCSIDevices(driver, vm->def->name, &hostdev, 1);
2565 qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
2567 virDomainHostdevDefPtr hostdev)
2569 virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
2570 virDomainNetDefPtr net = NULL;
2571 virObjectEventPtr event;
2574 VIR_DEBUG("Removing host device %s from domain %p %s",
2575 hostdev->info->alias, vm, vm->def->name);
2577 event = virDomainEventDeviceRemovedNewFromObj(vm, hostdev->info->alias);
2579 qemuDomainEventQueue(driver, event);
2581 if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET) {
2582 net = hostdev->parent.data.net;
2584 for (i = 0; i < vm->def->nnets; i++) {
2585 if (vm->def->nets[i] == net) {
2586 virDomainNetRemove(vm->def, i);
2592 for (i = 0; i < vm->def->nhostdevs; i++) {
2593 if (vm->def->hostdevs[i] == hostdev) {
2594 virDomainHostdevRemove(vm->def, i);
2599 virDomainAuditHostdev(vm, hostdev, "detach", true);
2601 switch ((enum virDomainHostdevSubsysType) hostdev->source.subsys.type) {
2602 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
2603 qemuDomainRemovePCIHostDevice(driver, vm, hostdev);
2605 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
2606 qemuDomainRemoveUSBHostDevice(driver, vm, hostdev);
2608 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
2609 qemuDomainRemoveSCSIHostDevice(driver, vm, hostdev);
2611 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
2615 if (qemuTeardownHostdevCgroup(vm, hostdev) < 0)
2616 VIR_WARN("Failed to remove host device cgroup ACL");
2618 if (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
2619 vm->def, hostdev, NULL) < 0) {
2620 VIR_WARN("Failed to restore host device labelling");
2623 virDomainHostdevDefFree(hostdev);
2626 networkReleaseActualDevice(vm->def, net);
2627 virDomainNetDefFree(net);
2629 virObjectUnref(cfg);
2634 qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
2636 virDomainNetDefPtr net)
2638 virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
2639 virNetDevVPortProfilePtr vport;
2640 virObjectEventPtr event;
2643 if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
2644 /* this function handles all hostdev and netdev cleanup */
2645 qemuDomainRemoveHostDevice(driver, vm, virDomainNetGetActualHostdev(net));
2649 VIR_DEBUG("Removing network interface %s from domain %p %s",
2650 net->info.alias, vm, vm->def->name);
2652 virDomainAuditNet(vm, net, NULL, "detach", true);
2654 event = virDomainEventDeviceRemovedNewFromObj(vm, net->info.alias);
2656 qemuDomainEventQueue(driver, event);
2658 for (i = 0; i < vm->def->nnets; i++) {
2659 if (vm->def->nets[i] == net) {
2660 virDomainNetRemove(vm->def, i);
2665 qemuDomainReleaseDeviceAddress(vm, &net->info, NULL);
2666 virDomainConfNWFilterTeardown(net);
2668 if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) {
2669 ignore_value(virNetDevMacVLanDeleteWithVPortProfile(
2670 net->ifname, &net->mac,
2671 virDomainNetGetActualDirectDev(net),
2672 virDomainNetGetActualDirectMode(net),
2673 virDomainNetGetActualVirtPortProfile(net),
2675 VIR_FREE(net->ifname);
2678 if (cfg->macFilter && (net->ifname != NULL)) {
2679 ignore_value(ebtablesRemoveForwardAllowIn(driver->ebtables,
2684 vport = virDomainNetGetActualVirtPortProfile(net);
2685 if (vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH)
2686 ignore_value(virNetDevOpenvswitchRemovePort(
2687 virDomainNetGetActualBridgeName(net),
2690 networkReleaseActualDevice(vm->def, net);
2691 virDomainNetDefFree(net);
2692 virObjectUnref(cfg);
2697 qemuDomainRemoveChrDevice(virQEMUDriverPtr driver,
2699 virDomainChrDefPtr chr)
2701 virObjectEventPtr event;
2703 VIR_DEBUG("Removing character device %s from domain %p %s",
2704 chr->info.alias, vm, vm->def->name);
2706 event = virDomainEventDeviceRemovedNewFromObj(vm, chr->info.alias);
2708 qemuDomainEventQueue(driver, event);
2710 qemuDomainChrRemove(vm->def, chr);
2711 virDomainChrDefFree(chr);
2716 qemuDomainRemoveDevice(virQEMUDriverPtr driver,
2718 virDomainDeviceDefPtr dev)
2720 switch ((virDomainDeviceType) dev->type) {
2721 case VIR_DOMAIN_DEVICE_DISK:
2722 qemuDomainRemoveDiskDevice(driver, vm, dev->data.disk);
2724 case VIR_DOMAIN_DEVICE_CONTROLLER:
2725 qemuDomainRemoveControllerDevice(driver, vm, dev->data.controller);
2727 case VIR_DOMAIN_DEVICE_NET:
2728 qemuDomainRemoveNetDevice(driver, vm, dev->data.net);
2730 case VIR_DOMAIN_DEVICE_HOSTDEV:
2731 qemuDomainRemoveHostDevice(driver, vm, dev->data.hostdev);
2734 case VIR_DOMAIN_DEVICE_CHR:
2735 qemuDomainRemoveChrDevice(driver, vm, dev->data.chr);
2738 case VIR_DOMAIN_DEVICE_NONE:
2739 case VIR_DOMAIN_DEVICE_LEASE:
2740 case VIR_DOMAIN_DEVICE_FS:
2741 case VIR_DOMAIN_DEVICE_INPUT:
2742 case VIR_DOMAIN_DEVICE_SOUND:
2743 case VIR_DOMAIN_DEVICE_VIDEO:
2744 case VIR_DOMAIN_DEVICE_WATCHDOG:
2745 case VIR_DOMAIN_DEVICE_GRAPHICS:
2746 case VIR_DOMAIN_DEVICE_HUB:
2747 case VIR_DOMAIN_DEVICE_REDIRDEV:
2748 case VIR_DOMAIN_DEVICE_SMARTCARD:
2749 case VIR_DOMAIN_DEVICE_MEMBALLOON:
2750 case VIR_DOMAIN_DEVICE_NVRAM:
2751 case VIR_DOMAIN_DEVICE_RNG:
2752 case VIR_DOMAIN_DEVICE_LAST:
2753 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
2754 _("don't know how to remove a %s device"),
2755 virDomainDeviceTypeToString(dev->type));
2762 qemuDomainMarkDeviceForRemoval(virDomainObjPtr vm,
2763 virDomainDeviceInfoPtr info)
2765 qemuDomainObjPrivatePtr priv = vm->privateData;
2767 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_DEL_EVENT))
2768 priv->unpluggingDevice = info->alias;
2770 priv->unpluggingDevice = NULL;
2774 qemuDomainResetDeviceRemoval(virDomainObjPtr vm)
2776 qemuDomainObjPrivatePtr priv = vm->privateData;
2777 priv->unpluggingDevice = NULL;
2782 * 0 when DEVICE_DELETED event is unsupported
2783 * 1 when device removal finished
2784 * 2 device removal did not finish in QEMU_REMOVAL_WAIT_TIME
2787 qemuDomainWaitForDeviceRemoval(virDomainObjPtr vm)
2789 qemuDomainObjPrivatePtr priv = vm->privateData;
2790 unsigned long long until;
2792 if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_DEL_EVENT))
2795 if (virTimeMillisNow(&until) < 0)
2797 until += qemuDomainRemoveDeviceWaitTime;
2799 while (priv->unpluggingDevice) {
2800 if (virCondWaitUntil(&priv->unplugFinished,
2801 &vm->parent.lock, until) < 0) {
2802 if (errno == ETIMEDOUT) {
2805 virReportSystemError(errno, "%s",
2806 _("Unable to wait on unplug condition"));
2816 qemuDomainSignalDeviceRemoval(virDomainObjPtr vm,
2817 const char *devAlias)
2819 qemuDomainObjPrivatePtr priv = vm->privateData;
2821 if (STREQ_NULLABLE(priv->unpluggingDevice, devAlias)) {
2822 qemuDomainResetDeviceRemoval(vm);
2823 virCondSignal(&priv->unplugFinished);
2829 qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
2831 virDomainDiskDefPtr detach)
2834 qemuDomainObjPrivatePtr priv = vm->privateData;
2835 char *drivestr = NULL;
2837 if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
2838 virReportError(VIR_ERR_OPERATION_FAILED,
2839 _("cannot hot unplug multifunction PCI device: %s"),
2844 if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
2845 virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
2846 if (!virDomainDeviceAddressIsValid(&detach->info,
2847 VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)) {
2848 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
2849 _("device cannot be detached without a valid CCW address"));
2853 if (!virDomainDeviceAddressIsValid(&detach->info,
2854 VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) {
2855 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
2856 _("device cannot be detached without a valid PCI address"));
2861 /* build the actual drive id string as the disk->info.alias doesn't
2862 * contain the QEMU_DRIVE_HOST_PREFIX that is passed to qemu */
2863 if (virAsprintf(&drivestr, "%s%s",
2864 QEMU_DRIVE_HOST_PREFIX, detach->info.alias) < 0)
2867 qemuDomainMarkDeviceForRemoval(vm, &detach->info);
2869 qemuDomainObjEnterMonitor(driver, vm);
2870 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
2871 if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
2872 qemuDomainObjExitMonitor(driver, vm);
2873 virDomainAuditDisk(vm, virDomainDiskGetSource(detach),
2874 NULL, "detach", false);
2878 if (qemuMonitorRemovePCIDevice(priv->mon,
2879 &detach->info.addr.pci) < 0) {
2880 qemuDomainObjExitMonitor(driver, vm);
2881 virDomainAuditDisk(vm, virDomainDiskGetSource(detach),
2882 NULL, "detach", false);
2887 /* disconnect guest from host device */
2888 qemuMonitorDriveDel(priv->mon, drivestr);
2890 qemuDomainObjExitMonitor(driver, vm);
2892 if (!qemuDomainWaitForDeviceRemoval(vm))
2893 qemuDomainRemoveDiskDevice(driver, vm, detach);
2897 qemuDomainResetDeviceRemoval(vm);
2903 qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
2905 virDomainDiskDefPtr detach)
2908 qemuDomainObjPrivatePtr priv = vm->privateData;
2909 char *drivestr = NULL;
2911 if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
2912 virReportError(VIR_ERR_OPERATION_FAILED,
2913 _("Underlying qemu does not support %s disk removal"),
2914 virDomainDiskBusTypeToString(detach->bus));
2918 if (detach->mirror) {
2919 virReportError(VIR_ERR_BLOCK_COPY_ACTIVE,
2920 _("disk '%s' is in an active block copy job"),
2925 /* build the actual drive id string as the disk->info.alias doesn't
2926 * contain the QEMU_DRIVE_HOST_PREFIX that is passed to qemu */
2927 if (virAsprintf(&drivestr, "%s%s",
2928 QEMU_DRIVE_HOST_PREFIX, detach->info.alias) < 0)
2931 qemuDomainMarkDeviceForRemoval(vm, &detach->info);
2933 qemuDomainObjEnterMonitor(driver, vm);
2934 if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
2935 qemuDomainObjExitMonitor(driver, vm);
2936 virDomainAuditDisk(vm, virDomainDiskGetSource(detach),
2937 NULL, "detach", false);
2941 /* disconnect guest from host device */
2942 qemuMonitorDriveDel(priv->mon, drivestr);
2944 qemuDomainObjExitMonitor(driver, vm);
2946 if (!qemuDomainWaitForDeviceRemoval(vm))
2947 qemuDomainRemoveDiskDevice(driver, vm, detach);
2951 qemuDomainResetDeviceRemoval(vm);
2957 qemuFindDisk(virDomainDefPtr def, const char *dst)
2961 for (i = 0; i < def->ndisks; i++) {
2962 if (STREQ(def->disks[i]->dst, dst)) {
2971 qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver,
2973 virDomainDeviceDefPtr dev)
2975 virDomainDiskDefPtr disk;
2979 if ((idx = qemuFindDisk(vm->def, dev->data.disk->dst)) < 0) {
2980 virReportError(VIR_ERR_OPERATION_FAILED,
2981 _("disk %s not found"), dev->data.disk->dst);
2984 disk = vm->def->disks[idx];
2986 switch (disk->device) {
2987 case VIR_DOMAIN_DISK_DEVICE_DISK:
2988 case VIR_DOMAIN_DISK_DEVICE_LUN:
2989 if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
2990 ret = qemuDomainDetachVirtioDiskDevice(driver, vm, disk);
2991 else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI ||
2992 disk->bus == VIR_DOMAIN_DISK_BUS_USB)
2993 ret = qemuDomainDetachDiskDevice(driver, vm, disk);
2995 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
2996 _("This type of disk cannot be hot unplugged"));
2999 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
3000 _("disk device type '%s' cannot be detached"),
3001 virDomainDiskDeviceTypeToString(disk->device));
3009 static bool qemuDomainDiskControllerIsBusy(virDomainObjPtr vm,
3010 virDomainControllerDefPtr detach)
3013 virDomainDiskDefPtr disk;
3015 for (i = 0; i < vm->def->ndisks; i++) {
3016 disk = vm->def->disks[i];
3017 if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE)
3018 /* the disk does not use disk controller */
3021 /* check whether the disk uses this type controller */
3022 if (disk->bus == VIR_DOMAIN_DISK_BUS_IDE &&
3023 detach->type != VIR_DOMAIN_CONTROLLER_TYPE_IDE)
3025 if (disk->bus == VIR_DOMAIN_DISK_BUS_FDC &&
3026 detach->type != VIR_DOMAIN_CONTROLLER_TYPE_FDC)
3028 if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI &&
3029 detach->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
3032 if (disk->info.addr.drive.controller == detach->idx)
3039 static bool qemuDomainControllerIsBusy(virDomainObjPtr vm,
3040 virDomainControllerDefPtr detach)
3042 switch (detach->type) {
3043 case VIR_DOMAIN_CONTROLLER_TYPE_IDE:
3044 case VIR_DOMAIN_CONTROLLER_TYPE_FDC:
3045 case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
3046 return qemuDomainDiskControllerIsBusy(vm, detach);
3048 case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
3049 case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
3050 case VIR_DOMAIN_CONTROLLER_TYPE_CCID:
3052 /* libvirt does not support sata controller, and does not support to
3053 * detach virtio and smart card controller.
3059 int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
3061 virDomainDeviceDefPtr dev)
3064 virDomainControllerDefPtr detach = NULL;
3065 qemuDomainObjPrivatePtr priv = vm->privateData;
3067 if ((idx = virDomainControllerFind(vm->def,
3068 dev->data.controller->type,
3069 dev->data.controller->idx)) < 0) {
3070 virReportError(VIR_ERR_OPERATION_FAILED,
3071 _("controller %s:%d not found"),
3072 virDomainControllerTypeToString(dev->data.controller->type),
3073 dev->data.controller->idx);
3077 detach = vm->def->controllers[idx];
3079 if (detach->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
3080 detach->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW &&
3081 detach->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) {
3082 virReportError(VIR_ERR_OPERATION_FAILED,
3083 _("device with '%s' address cannot be detached"),
3084 virDomainDeviceAddressTypeToString(detach->info.type));
3088 if (!virDomainDeviceAddressIsValid(&detach->info, detach->info.type)) {
3089 virReportError(VIR_ERR_OPERATION_FAILED,
3090 _("device with invalid '%s' address cannot be detached"),
3091 virDomainDeviceAddressTypeToString(detach->info.type));
3095 if (detach->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
3096 qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
3097 virReportError(VIR_ERR_OPERATION_FAILED,
3098 _("cannot hot unplug multifunction PCI device: %s"),
3099 dev->data.disk->dst);
3103 if (qemuDomainControllerIsBusy(vm, detach)) {
3104 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
3105 _("device cannot be detached: device is busy"));
3109 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
3110 if (qemuAssignDeviceControllerAlias(detach) < 0)
3114 qemuDomainMarkDeviceForRemoval(vm, &detach->info);
3116 qemuDomainObjEnterMonitor(driver, vm);
3117 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
3118 if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) {
3119 qemuDomainObjExitMonitor(driver, vm);
3123 if (qemuMonitorRemovePCIDevice(priv->mon,
3124 &detach->info.addr.pci) < 0) {
3125 qemuDomainObjExitMonitor(driver, vm);
3129 qemuDomainObjExitMonitor(driver, vm);
3131 if (!qemuDomainWaitForDeviceRemoval(vm))
3132 qemuDomainRemoveControllerDevice(driver, vm, detach);
3137 qemuDomainResetDeviceRemoval(vm);
3142 qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver,
3144 virDomainHostdevDefPtr detach)
3146 qemuDomainObjPrivatePtr priv = vm->privateData;
3147 virDomainHostdevSubsysPtr subsys = &detach->source.subsys;
3150 if (qemuIsMultiFunctionDevice(vm->def, detach->info)) {
3151 virReportError(VIR_ERR_OPERATION_FAILED,
3152 _("cannot hot unplug multifunction PCI device: %.4x:%.2x:%.2x.%.1x"),
3153 subsys->u.pci.addr.domain, subsys->u.pci.addr.bus,
3154 subsys->u.pci.addr.slot, subsys->u.pci.addr.function);
3158 if (!virDomainDeviceAddressIsValid(detach->info,
3159 VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) {
3160 virReportError(VIR_ERR_OPERATION_FAILED,
3161 "%s", _("device cannot be detached without a PCI address"));
3165 qemuDomainMarkDeviceForRemoval(vm, detach->info);
3167 qemuDomainObjEnterMonitor(driver, vm);
3168 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
3169 ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
3171 ret = qemuMonitorRemovePCIDevice(priv->mon, &detach->info->addr.pci);
3173 qemuDomainObjExitMonitor(driver, vm);
3179 qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver,
3181 virDomainHostdevDefPtr detach)
3183 qemuDomainObjPrivatePtr priv = vm->privateData;
3186 if (!detach->info->alias) {
3187 virReportError(VIR_ERR_OPERATION_FAILED,
3188 "%s", _("device cannot be detached without a device alias"));
3192 if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
3193 virReportError(VIR_ERR_OPERATION_FAILED,
3194 "%s", _("device cannot be detached with this QEMU version"));
3198 qemuDomainMarkDeviceForRemoval(vm, detach->info);
3200 qemuDomainObjEnterMonitor(driver, vm);
3201 ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
3202 qemuDomainObjExitMonitor(driver, vm);
3208 qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver,
3210 virDomainHostdevDefPtr detach)
3212 qemuDomainObjPrivatePtr priv = vm->privateData;
3213 char *drvstr = NULL;
3214 char *devstr = NULL;
3217 if (!detach->info->alias) {
3218 virReportError(VIR_ERR_OPERATION_FAILED,
3219 "%s", _("device cannot be detached without a device alias"));
3223 if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
3224 virReportError(VIR_ERR_OPERATION_FAILED,
3225 "%s", _("device cannot be detached with this QEMU version"));
3229 if (!(drvstr = qemuBuildSCSIHostdevDrvStr(detach, priv->qemuCaps,
3230 &buildCommandLineCallbacks)))
3232 if (!(devstr = qemuBuildSCSIHostdevDevStr(vm->def, detach, priv->qemuCaps)))
3235 qemuDomainMarkDeviceForRemoval(vm, detach->info);
3237 qemuDomainObjEnterMonitor(driver, vm);
3238 if ((ret = qemuMonitorDelDevice(priv->mon, detach->info->alias)) == 0) {
3239 if ((ret = qemuMonitorDriveDel(priv->mon, drvstr)) < 0) {
3240 virErrorPtr orig_err = virSaveLastError();
3241 if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
3242 VIR_WARN("Unable to add device %s (%s) after failed "
3243 "qemuMonitorDriveDel",
3246 virSetError(orig_err);
3247 virFreeError(orig_err);
3251 qemuDomainObjExitMonitor(driver, vm);
3260 qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
3262 virDomainHostdevDefPtr detach)
3266 switch (detach->source.subsys.type) {
3267 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
3268 ret = qemuDomainDetachHostPCIDevice(driver, vm, detach);
3270 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
3271 ret = qemuDomainDetachHostUSBDevice(driver, vm, detach);
3273 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
3274 ret = qemuDomainDetachHostSCSIDevice(driver, vm, detach);
3277 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
3278 _("hostdev subsys type '%s' not supported"),
3279 virDomainHostdevSubsysTypeToString(detach->source.subsys.type));
3284 virDomainAuditHostdev(vm, detach, "detach", false);
3285 else if (!qemuDomainWaitForDeviceRemoval(vm))
3286 qemuDomainRemoveHostDevice(driver, vm, detach);
3288 qemuDomainResetDeviceRemoval(vm);
3293 /* search for a hostdev matching dev and detach it */
3294 int qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
3296 virDomainDeviceDefPtr dev)
3298 virDomainHostdevDefPtr hostdev = dev->data.hostdev;
3299 virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
3300 virDomainHostdevDefPtr detach = NULL;
3303 if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
3304 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
3305 _("hostdev mode '%s' not supported"),
3306 virDomainHostdevModeTypeToString(hostdev->mode));
3310 idx = virDomainHostdevFind(vm->def, hostdev, &detach);
3313 switch (subsys->type) {
3314 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
3315 virReportError(VIR_ERR_OPERATION_FAILED,
3316 _("host pci device %.4x:%.2x:%.2x.%.1x not found"),
3317 subsys->u.pci.addr.domain, subsys->u.pci.addr.bus,
3318 subsys->u.pci.addr.slot, subsys->u.pci.addr.function);
3320 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
3321 if (subsys->u.usb.bus && subsys->u.usb.device) {
3322 virReportError(VIR_ERR_OPERATION_FAILED,
3323 _("host usb device %03d.%03d not found"),
3324 subsys->u.usb.bus, subsys->u.usb.device);
3326 virReportError(VIR_ERR_OPERATION_FAILED,
3327 _("host usb device vendor=0x%.4x product=0x%.4x not found"),
3328 subsys->u.usb.vendor, subsys->u.usb.product);
3331 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
3332 virReportError(VIR_ERR_OPERATION_FAILED,
3333 _("host scsi device %s:%d:%d.%d not found"),
3334 subsys->u.scsi.adapter, subsys->u.scsi.bus,
3335 subsys->u.scsi.target, subsys->u.scsi.unit);
3338 virReportError(VIR_ERR_INTERNAL_ERROR,
3339 _("unexpected hostdev type %d"), subsys->type);
3345 /* If this is a network hostdev, we need to use the higher-level detach
3346 * function so that mac address / virtualport are reset
3348 if (detach->parent.type == VIR_DOMAIN_DEVICE_NET)
3349 return qemuDomainDetachNetDevice(driver, vm, &detach->parent);
3351 return qemuDomainDetachThisHostDevice(driver, vm, detach);
3355 qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
3357 virDomainDeviceDefPtr dev)
3359 int detachidx, ret = -1;
3360 virDomainNetDefPtr detach = NULL;
3361 qemuDomainObjPrivatePtr priv = vm->privateData;
3363 char *hostnet_name = NULL;
3365 if ((detachidx = virDomainNetFindIdx(vm->def, dev->data.net)) < 0)
3368 detach = vm->def->nets[detachidx];
3370 if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
3371 /* coverity[negative_returns] */
3372 ret = qemuDomainDetachThisHostDevice(driver, vm,
3373 virDomainNetGetActualHostdev(detach));
3376 if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
3377 virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
3378 if (!virDomainDeviceAddressIsValid(&detach->info,
3379 VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)) {
3380 virReportError(VIR_ERR_OPERATION_FAILED,
3381 "%s", _("device cannot be detached without a CCW address"));
3385 if (!virDomainDeviceAddressIsValid(&detach->info,
3386 VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) {
3387 virReportError(VIR_ERR_OPERATION_FAILED,
3388 "%s", _("device cannot be detached without a PCI address"));
3392 if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
3393 virReportError(VIR_ERR_OPERATION_FAILED,
3394 _("cannot hot unplug multifunction PCI device :%s"),
3395 dev->data.disk->dst);
3400 if ((vlan = qemuDomainNetVLAN(detach)) < 0) {
3401 virReportError(VIR_ERR_OPERATION_FAILED,
3402 "%s", _("unable to determine original VLAN"));
3406 if (virAsprintf(&hostnet_name, "host%s", detach->info.alias) < 0)
3409 qemuDomainMarkDeviceForRemoval(vm, &detach->info);
3411 qemuDomainObjEnterMonitor(driver, vm);
3412 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
3413 if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
3414 qemuDomainObjExitMonitor(driver, vm);
3415 virDomainAuditNet(vm, detach, NULL, "detach", false);
3419 if (qemuMonitorRemovePCIDevice(priv->mon,
3420 &detach->info.addr.pci) < 0) {
3421 qemuDomainObjExitMonitor(driver, vm);
3422 virDomainAuditNet(vm, detach, NULL, "detach", false);
3427 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
3428 virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
3429 if (qemuMonitorRemoveNetdev(priv->mon, hostnet_name) < 0) {
3430 qemuDomainObjExitMonitor(driver, vm);
3431 virDomainAuditNet(vm, detach, NULL, "detach", false);
3435 if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0) {
3436 qemuDomainObjExitMonitor(driver, vm);
3437 virDomainAuditNet(vm, detach, NULL, "detach", false);
3441 qemuDomainObjExitMonitor(driver, vm);
3443 if (!qemuDomainWaitForDeviceRemoval(vm))
3444 qemuDomainRemoveNetDevice(driver, vm, detach);
3449 qemuDomainResetDeviceRemoval(vm);
3450 VIR_FREE(hostnet_name);
3455 qemuDomainChangeGraphicsPasswords(virQEMUDriverPtr driver,
3458 virDomainGraphicsAuthDefPtr auth,
3459 const char *defaultPasswd)
3461 qemuDomainObjPrivatePtr priv = vm->privateData;
3462 time_t now = time(NULL);
3463 char expire_time [64];
3464 const char *connected = NULL;
3466 virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
3468 if (!auth->passwd && !defaultPasswd) {
3473 if (auth->connected)
3474 connected = virDomainGraphicsAuthConnectedTypeToString(auth->connected);
3476 qemuDomainObjEnterMonitor(driver, vm);
3477 ret = qemuMonitorSetPassword(priv->mon,
3479 auth->passwd ? auth->passwd : defaultPasswd,
3483 if (type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
3484 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3485 _("Graphics password only supported for VNC"));
3488 ret = qemuMonitorSetVNCPassword(priv->mon,
3489 auth->passwd ? auth->passwd : defaultPasswd);
3495 if (auth->expires) {
3496 time_t lifetime = auth->validTo - now;
3498 snprintf(expire_time, sizeof(expire_time), "now");
3500 snprintf(expire_time, sizeof(expire_time), "%lu", (long unsigned)auth->validTo);
3502 snprintf(expire_time, sizeof(expire_time), "never");
3505 ret = qemuMonitorExpirePassword(priv->mon, type, expire_time);
3508 /* XXX we could fake this with a timer */
3509 if (auth->expires) {
3510 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3511 _("Expiry of passwords is not supported"));
3519 qemuDomainObjExitMonitor(driver, vm);
3521 virObjectUnref(cfg);
3525 int qemuDomainAttachLease(virQEMUDriverPtr driver,
3527 virDomainLeaseDefPtr lease)
3530 virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
3532 if (virDomainLeaseInsertPreAlloc(vm->def) < 0)
3535 if (virDomainLockLeaseAttach(driver->lockManager, cfg->uri,
3537 virDomainLeaseInsertPreAlloced(vm->def, NULL);
3541 virDomainLeaseInsertPreAlloced(vm->def, lease);
3545 virObjectUnref(cfg);
3549 int qemuDomainDetachLease(virQEMUDriverPtr driver,
3551 virDomainLeaseDefPtr lease)
3553 virDomainLeaseDefPtr det_lease;
3556 if ((idx = virDomainLeaseIndex(vm->def, lease)) < 0) {
3557 virReportError(VIR_ERR_INVALID_ARG,
3558 _("Lease %s in lockspace %s does not exist"),
3559 lease->key, NULLSTR(lease->lockspace));
3563 if (virDomainLockLeaseDetach(driver->lockManager, vm, lease) < 0)
3566 det_lease = virDomainLeaseRemoveAt(vm->def, idx);
3567 virDomainLeaseDefFree(det_lease);
3571 int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
3573 virDomainChrDefPtr chr)
3576 qemuDomainObjPrivatePtr priv = vm->privateData;
3577 virDomainDefPtr vmdef = vm->def;
3578 virDomainChrDefPtr tmpChr;
3579 char *charAlias = NULL;
3580 char *devstr = NULL;
3582 if (!(tmpChr = virDomainChrFind(vmdef, chr))) {
3583 virReportError(VIR_ERR_OPERATION_INVALID, "%s",
3584 _("device not present in domain configuration"));
3588 if (qemuBuildChrDeviceStr(&devstr, vm->def, chr, priv->qemuCaps) < 0)
3591 if (virAsprintf(&charAlias, "char%s", tmpChr->info.alias) < 0)
3594 qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info);
3596 qemuDomainObjEnterMonitor(driver, vm);
3597 if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) {
3598 qemuDomainObjExitMonitor(driver, vm);
3602 if (qemuMonitorDetachCharDev(priv->mon, charAlias) < 0) {
3603 qemuDomainObjExitMonitor(driver, vm);
3606 qemuDomainObjExitMonitor(driver, vm);
3608 if (!qemuDomainWaitForDeviceRemoval(vm))
3609 qemuDomainRemoveChrDevice(driver, vm, tmpChr);
3613 qemuDomainResetDeviceRemoval(vm);
3615 VIR_FREE(charAlias);