Imported Upstream version 1.2.5
[archive/platform/upstream/libvirt.git] / src / qemu / qemu_hotplug.c
1 /*
2  * qemu_hotplug.c: QEMU device hotplug management
3  *
4  * Copyright (C) 2006-2014 Red Hat, Inc.
5  * Copyright (C) 2006 Daniel P. Berrange
6  *
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.
11  *
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.
16  *
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/>.
20  *
21  * Author: Daniel P. Berrange <berrange@redhat.com>
22  */
23
24
25 #include <config.h>
26
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"
35 #include "virlog.h"
36 #include "datatypes.h"
37 #include "virerror.h"
38 #include "viralloc.h"
39 #include "virpci.h"
40 #include "virfile.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"
51 #include "virtime.h"
52
53 #define VIR_FROM_THIS VIR_FROM_QEMU
54
55 VIR_LOG_INIT("qemu.qemu_hotplug");
56
57 #define CHANGE_MEDIA_RETRIES 10
58
59 /* Wait up to 5 seconds for device removal to finish. */
60 unsigned long long qemuDomainRemoveDeviceWaitTime = 1000ull * 5;
61
62
63 int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
64                                    virDomainObjPtr vm,
65                                    virDomainDiskDefPtr disk,
66                                    virDomainDiskDefPtr origdisk,
67                                    bool force)
68 {
69     int ret = -1;
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;
75
76     if (!origdisk->info.alias) {
77         virReportError(VIR_ERR_INTERNAL_ERROR,
78                        _("missing disk device alias name for %s"), origdisk->dst);
79         goto cleanup;
80     }
81
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));
87         goto cleanup;
88     }
89
90     if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
91                                 vm, disk) < 0)
92         goto cleanup;
93
94     if (virSecurityManagerSetImageLabel(driver->securityManager,
95                                         vm->def, disk) < 0) {
96         if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
97             VIR_WARN("Unable to release lock on %s",
98                      virDomainDiskGetSource(disk));
99         goto cleanup;
100     }
101
102     if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, priv->qemuCaps)))
103         goto error;
104
105     qemuDomainObjEnterMonitor(driver, vm);
106     ret = qemuMonitorEjectMedia(priv->mon, driveAlias, force);
107     qemuDomainObjExitMonitor(driver, vm);
108
109     if (ret < 0)
110         goto audit;
111
112     virObjectRef(vm);
113     /* we don't want to report errors from media tray_open polling */
114     while (retries) {
115         if (origdisk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)
116             break;
117
118         retries--;
119         virObjectUnlock(vm);
120         VIR_DEBUG("Waiting 500ms for tray to open. Retries left %d", retries);
121         usleep(500 * 1000); /* sleep 500ms */
122         virObjectLock(vm);
123     }
124     virObjectUnref(vm);
125
126     if (retries <= 0) {
127         virReportError(VIR_ERR_OPERATION_FAILED, "%s",
128                        _("Unable to eject media"));
129         ret = -1;
130         goto audit;
131     }
132
133     src = virDomainDiskGetSource(disk);
134     if (src) {
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);
140
141         if (type != VIR_STORAGE_TYPE_DIR) {
142             if (diskFormat > 0) {
143                 format = virStorageFileFormatTypeToString(diskFormat);
144             } else {
145                 diskFormat = virDomainDiskGetFormat(origdisk);
146                 if (diskFormat > 0)
147                     format = virStorageFileFormatTypeToString(diskFormat);
148             }
149         }
150         qemuDomainObjEnterMonitor(driver, vm);
151         ret = qemuMonitorChangeMedia(priv->mon,
152                                      driveAlias,
153                                      src, format);
154         qemuDomainObjExitMonitor(driver, vm);
155     }
156  audit:
157     if (src)
158         virDomainAuditDisk(vm, virDomainDiskGetSource(origdisk),
159                            src, "update", ret >= 0);
160
161     if (ret < 0)
162         goto error;
163
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));
168
169     if (virDomainLockDiskDetach(driver->lockManager, vm, origdisk) < 0)
170         VIR_WARN("Unable to release lock on disk %s",
171                  virDomainDiskGetSource(origdisk));
172
173     if (virDomainDiskSetSource(origdisk, src) < 0)
174         goto error;
175     virDomainDiskSetType(origdisk, virDomainDiskGetType(disk));
176
177     virDomainDiskDefFree(disk);
178
179  cleanup:
180     VIR_FREE(driveAlias);
181     virObjectUnref(cfg);
182     return ret;
183
184  error:
185     if (virSecurityManagerRestoreImageLabel(driver->securityManager,
186                                             vm->def, disk) < 0)
187         VIR_WARN("Unable to restore security label on new media %s", src);
188
189     if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
190         VIR_WARN("Unable to release lock on %s", src);
191
192     goto cleanup;
193 }
194
195 int
196 qemuDomainCheckEjectableMedia(virQEMUDriverPtr driver,
197                              virDomainObjPtr vm,
198                              enum qemuDomainAsyncJob asyncJob)
199 {
200     qemuDomainObjPrivatePtr priv = vm->privateData;
201     virHashTablePtr table = NULL;
202     int ret = -1;
203     size_t i;
204
205     if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
206         table = qemuMonitorGetBlockInfo(priv->mon);
207         qemuDomainObjExitMonitor(driver, vm);
208     }
209
210     if (!table)
211         goto cleanup;
212
213     for (i = 0; i < vm->def->ndisks; i++) {
214         virDomainDiskDefPtr disk = vm->def->disks[i];
215         struct qemuDomainDiskInfo *info;
216
217         if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK ||
218             disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
219                  continue;
220         }
221
222         info = qemuMonitorBlockInfoLookup(table, disk->info.alias);
223         if (!info)
224             goto cleanup;
225
226         if (info->tray_open && virDomainDiskGetSource(disk))
227             ignore_value(virDomainDiskSetSource(disk, NULL));
228     }
229
230     ret = 0;
231
232  cleanup:
233     virHashFree(table);
234     return ret;
235 }
236
237 static int
238 qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
239                                  virQEMUDriverPtr driver,
240                                  virDomainObjPtr vm,
241                                  virDomainDiskDefPtr disk)
242 {
243     size_t i;
244     int ret = -1;
245     const char* type = virDomainDiskBusTypeToString(disk->bus);
246     qemuDomainObjPrivatePtr priv = vm->privateData;
247     char *devstr = NULL;
248     char *drivestr = NULL;
249     bool releaseaddr = false;
250     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
251     const char *src = virDomainDiskGetSource(disk);
252
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;
259     }
260
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);
265             goto cleanup;
266         }
267     }
268
269     if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
270                                 vm, disk) < 0)
271         goto cleanup;
272
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);
277         goto cleanup;
278     }
279
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)
284                 goto error;
285         } else if (!disk->info.type ||
286                     disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
287             if (virDomainPCIAddressEnsureAddr(priv->pciaddrs, &disk->info) < 0)
288                 goto error;
289         }
290         releaseaddr = true;
291         if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
292             goto error;
293
294         if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps)))
295             goto error;
296
297         if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps)))
298             goto error;
299     }
300
301     if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0)
302         goto error;
303
304     qemuDomainObjEnterMonitor(driver, vm);
305     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
306         ret = qemuMonitorAddDrive(priv->mon, drivestr);
307         if (ret == 0) {
308             ret = qemuMonitorAddDevice(priv->mon, devstr);
309             if (ret < 0) {
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",
314                              drivestr, devstr);
315                 }
316                 if (orig_err) {
317                     virSetError(orig_err);
318                     virFreeError(orig_err);
319                 }
320             }
321         }
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);
326         if (ret == 0) {
327             disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
328             memcpy(&disk->info.addr.pci, &guestAddr, sizeof(guestAddr));
329         }
330     }
331     qemuDomainObjExitMonitor(driver, vm);
332
333     virDomainAuditDisk(vm, NULL, src, "attach", ret >= 0);
334
335     if (ret < 0)
336         goto error;
337
338     virDomainDiskInsertPreAlloced(vm->def, disk);
339
340  cleanup:
341     VIR_FREE(devstr);
342     VIR_FREE(drivestr);
343     virObjectUnref(cfg);
344     return ret;
345
346  error:
347     if (releaseaddr)
348         qemuDomainReleaseDeviceAddress(vm, &disk->info, src);
349
350     if (virSecurityManagerRestoreImageLabel(driver->securityManager,
351                                             vm->def, disk) < 0)
352         VIR_WARN("Unable to restore security label on %s", src);
353
354     if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
355         VIR_WARN("Unable to release lock on %s", src);
356
357     goto cleanup;
358 }
359
360
361 int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver,
362                                      virDomainObjPtr vm,
363                                      virDomainControllerDefPtr controller)
364 {
365     int ret = -1;
366     const char* type = virDomainControllerTypeToString(controller->type);
367     char *devstr = NULL;
368     qemuDomainObjPrivatePtr priv = vm->privateData;
369     bool releaseaddr = false;
370
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);
375         return -1;
376     }
377
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;
385         }
386
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)
390                 goto cleanup;
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)
394                 goto cleanup;
395         }
396         releaseaddr = true;
397         if (qemuAssignDeviceControllerAlias(controller) < 0)
398             goto cleanup;
399
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"));
405             goto cleanup;
406         }
407
408         if (!(devstr = qemuBuildControllerDevStr(vm->def, controller, priv->qemuCaps, NULL))) {
409             goto cleanup;
410         }
411     }
412
413     if (VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers+1) < 0)
414         goto cleanup;
415
416     qemuDomainObjEnterMonitor(driver, vm);
417     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
418         ret = qemuMonitorAddDevice(priv->mon, devstr);
419     } else {
420         ret = qemuMonitorAttachPCIDiskController(priv->mon,
421                                                  type,
422                                                  &controller->info.addr.pci);
423     }
424     qemuDomainObjExitMonitor(driver, vm);
425
426     if (ret == 0) {
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);
430     }
431
432  cleanup:
433     if (ret != 0 && releaseaddr)
434         qemuDomainReleaseDeviceAddress(vm, &controller->info, NULL);
435
436     VIR_FREE(devstr);
437     return ret;
438 }
439
440 static virDomainControllerDefPtr
441 qemuDomainFindOrCreateSCSIDiskController(virQEMUDriverPtr driver,
442                                          virDomainObjPtr vm,
443                                          int controller)
444 {
445     size_t i;
446     virDomainControllerDefPtr cont;
447
448     for (i = 0; i < vm->def->ncontrollers; i++) {
449         cont = vm->def->controllers[i];
450
451         if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
452             continue;
453
454         if (cont->idx == controller)
455             return cont;
456     }
457
458     /* No SCSI controller present, for backward compatibility we
459      * now hotplug a controller */
460     if (VIR_ALLOC(cont) < 0)
461         return NULL;
462     cont->type = VIR_DOMAIN_CONTROLLER_TYPE_SCSI;
463     cont->idx = controller;
464     cont->model = -1;
465
466     VIR_INFO("No SCSI controller present, hotplugging one");
467     if (qemuDomainAttachControllerDevice(driver,
468                                          vm, cont) < 0) {
469         VIR_FREE(cont);
470         return NULL;
471     }
472
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 */
478         return NULL;
479     }
480
481     return cont;
482 }
483
484
485 static int
486 qemuDomainAttachSCSIDisk(virConnectPtr conn,
487                          virQEMUDriverPtr driver,
488                          virDomainObjPtr vm,
489                          virDomainDiskDefPtr disk)
490 {
491     size_t i;
492     qemuDomainObjPrivatePtr priv = vm->privateData;
493     virDomainControllerDefPtr cont = NULL;
494     char *drivestr = NULL;
495     char *devstr = NULL;
496     int ret = -1;
497     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
498     const char *src = virDomainDiskGetSource(disk);
499
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);
504             goto cleanup;
505         }
506     }
507
508     if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
509                                 vm, disk) < 0)
510         goto cleanup;
511
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);
516         goto cleanup;
517     }
518
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));
524         goto error;
525     }
526
527     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
528         if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
529             goto error;
530         if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps)))
531             goto error;
532     }
533
534     if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps)))
535         goto error;
536
537     for (i = 0; i <= disk->info.addr.drive.controller; i++) {
538         cont = qemuDomainFindOrCreateSCSIDiskController(driver, vm, i);
539         if (!cont)
540             goto error;
541     }
542
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.  */
546     sa_assert(cont);
547
548     if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0)
549         goto error;
550
551     qemuDomainObjEnterMonitor(driver, vm);
552     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
553         ret = qemuMonitorAddDrive(priv->mon, drivestr);
554         if (ret == 0) {
555             ret = qemuMonitorAddDevice(priv->mon, devstr);
556             if (ret < 0) {
557                 VIR_WARN("qemuMonitorAddDevice failed on %s (%s)",
558                          drivestr, devstr);
559                 /* XXX should call 'drive_del' on error but this does not
560                    exist yet */
561             }
562         }
563     } else {
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"),
567                            cont->idx);
568             goto error;
569         }
570
571         virDomainDeviceDriveAddress driveAddr;
572         ret = qemuMonitorAttachDrive(priv->mon,
573                                      drivestr,
574                                      &cont->info.addr.pci,
575                                      &driveAddr);
576         if (ret == 0) {
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;
582         }
583     }
584     qemuDomainObjExitMonitor(driver, vm);
585
586     virDomainAuditDisk(vm, NULL, src, "attach", ret >= 0);
587
588     if (ret < 0)
589         goto error;
590
591     virDomainDiskInsertPreAlloced(vm->def, disk);
592
593  cleanup:
594     VIR_FREE(devstr);
595     VIR_FREE(drivestr);
596     virObjectUnref(cfg);
597     return ret;
598
599  error:
600     if (virSecurityManagerRestoreImageLabel(driver->securityManager,
601                                             vm->def, disk) < 0)
602         VIR_WARN("Unable to restore security label on %s", src);
603
604     if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
605         VIR_WARN("Unable to release lock on %s", src);
606
607     goto cleanup;
608 }
609
610
611 static int
612 qemuDomainAttachUSBMassstorageDevice(virConnectPtr conn,
613                                      virQEMUDriverPtr driver,
614                                      virDomainObjPtr vm,
615                                      virDomainDiskDefPtr disk)
616 {
617     qemuDomainObjPrivatePtr priv = vm->privateData;
618     size_t i;
619     int ret = -1;
620     char *drivestr = NULL;
621     char *devstr = NULL;
622     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
623     const char *src = virDomainDiskGetSource(disk);
624
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);
629             goto cleanup;
630         }
631     }
632
633     if (virDomainLockDiskAttach(driver->lockManager, cfg->uri,
634                                 vm, disk) < 0)
635         goto cleanup;
636
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);
641         goto cleanup;
642     }
643
644     /* XXX not correct once we allow attaching a USB CDROM */
645     if (!src) {
646         virReportError(VIR_ERR_INTERNAL_ERROR,
647                        "%s", _("disk source path is missing"));
648         goto error;
649     }
650
651     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
652         if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
653             goto error;
654         if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps)))
655             goto error;
656         if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps)))
657             goto error;
658     }
659
660     if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0)
661         goto error;
662
663     qemuDomainObjEnterMonitor(driver, vm);
664     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
665         ret = qemuMonitorAddDrive(priv->mon, drivestr);
666         if (ret == 0) {
667             ret = qemuMonitorAddDevice(priv->mon, devstr);
668             if (ret < 0) {
669                 VIR_WARN("qemuMonitorAddDevice failed on %s (%s)",
670                          drivestr, devstr);
671                 /* XXX should call 'drive_del' on error but this does not
672                    exist yet */
673             }
674         }
675     } else {
676         ret = qemuMonitorAddUSBDisk(priv->mon, src);
677     }
678     qemuDomainObjExitMonitor(driver, vm);
679
680     virDomainAuditDisk(vm, NULL, src, "attach", ret >= 0);
681
682     if (ret < 0)
683         goto error;
684
685     virDomainDiskInsertPreAlloced(vm->def, disk);
686
687  cleanup:
688     VIR_FREE(devstr);
689     VIR_FREE(drivestr);
690     virObjectUnref(cfg);
691     return ret;
692
693  error:
694     if (virSecurityManagerRestoreImageLabel(driver->securityManager,
695                                             vm->def, disk) < 0)
696         VIR_WARN("Unable to restore security label on %s", src);
697
698     if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
699         VIR_WARN("Unable to release lock on %s", src);
700
701     goto cleanup;
702 }
703
704
705 int
706 qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
707                                virQEMUDriverPtr driver,
708                                virDomainObjPtr vm,
709                                virDomainDeviceDefPtr dev)
710 {
711     virDomainDiskDefPtr disk = dev->data.disk;
712     virDomainDiskDefPtr orig_disk = NULL;
713     virDomainDeviceDefPtr dev_copy = NULL;
714     virDomainDiskDefPtr tmp = NULL;
715     virCapsPtr caps = NULL;
716     int ret = -1;
717     const char *driverName = virDomainDiskGetDriver(disk);
718     const char *src = virDomainDiskGetSource(disk);
719
720     if (driverName && !STREQ(driverName, "qemu")) {
721         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
722                        _("unsupported driver name '%s' for disk '%s'"),
723                        driverName, src);
724         goto end;
725     }
726
727     if (qemuTranslateDiskSourcePool(conn, disk) < 0)
728         goto end;
729
730     if (qemuAddSharedDevice(driver, dev, vm->def->name) < 0)
731         goto end;
732
733     if (qemuSetUnprivSGIO(dev) < 0)
734         goto end;
735
736     if (qemuDomainDetermineDiskChain(driver, vm, disk, false) < 0)
737         goto end;
738
739     if (qemuSetupDiskCgroup(vm, disk) < 0)
740         goto end;
741
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),
750                            disk->dst);
751             goto end;
752         }
753
754         if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
755             goto end;
756
757         tmp = dev->data.disk;
758         dev->data.disk = orig_disk;
759
760         if (!(dev_copy = virDomainDeviceDefCopy(dev, vm->def,
761                                                 caps, driver->xmlopt))) {
762             dev->data.disk = tmp;
763             goto end;
764         }
765         dev->data.disk = tmp;
766
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 */
771
772         /* Need to remove the shared disk entry for the original disk src
773          * if the operation is either ejecting or updating.
774          */
775         if (ret == 0)
776             ignore_value(qemuRemoveSharedDevice(driver, dev_copy,
777                                                 vm->def->name));
778         break;
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"));
785                 break;
786             }
787             ret = qemuDomainAttachUSBMassstorageDevice(conn, driver, vm,
788                                                        disk);
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);
793         } else {
794             virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
795                            _("disk bus '%s' cannot be hotplugged."),
796                            virDomainDiskBusTypeToString(disk->bus));
797         }
798         break;
799     default:
800         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
801                        _("disk device type '%s' cannot be hotplugged"),
802                        virDomainDiskDeviceTypeToString(disk->device));
803         break;
804     }
805
806     if (ret != 0 &&
807         qemuTeardownDiskCgroup(vm, disk) < 0) {
808         VIR_WARN("Failed to teardown cgroup for disk path %s",
809                  NULLSTR(src));
810     }
811
812  end:
813     if (ret != 0)
814         ignore_value(qemuRemoveSharedDevice(driver, dev, vm->def->name));
815     virObjectUnref(caps);
816     virDomainDeviceDefFree(dev_copy);
817     return ret;
818 }
819
820
821 /* XXX conn required for network -> bridge resolution */
822 int qemuDomainAttachNetDevice(virConnectPtr conn,
823                               virQEMUDriverPtr driver,
824                               virDomainObjPtr vm,
825                               virDomainNetDefPtr net)
826 {
827     qemuDomainObjPrivatePtr priv = vm->privateData;
828     char **tapfdName = NULL;
829     int *tapfd = NULL;
830     int tapfdSize = 0;
831     char **vhostfdName = NULL;
832     int *vhostfd = NULL;
833     int vhostfdSize = 0;
834     char *nicstr = NULL;
835     char *netstr = NULL;
836     virNetDevVPortProfilePtr vport = NULL;
837     int ret = -1;
838     virDevicePCIAddress guestAddr;
839     int vlan;
840     bool releaseaddr = false;
841     bool iface_connected = false;
842     int actualType;
843     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
844     size_t i;
845
846     /* preallocate new slot for device */
847     if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets + 1) < 0)
848         goto cleanup;
849
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.
853      */
854     if (networkAllocateActualDevice(vm->def, net) < 0)
855         goto cleanup;
856
857     actualType = virDomainNetGetActualType(net);
858
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.
864          */
865         ret = qemuDomainAttachHostDevice(driver, vm,
866                                          virDomainNetGetActualHostdev(net));
867         goto cleanup;
868     }
869
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"));
873         goto cleanup;
874     }
875
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));
883         return -1;
884     }
885
886     if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
887         actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
888         tapfdSize = vhostfdSize = net->driver.virtio.queues;
889         if (!tapfdSize)
890             tapfdSize = vhostfdSize = 1;
891         if (VIR_ALLOC_N(tapfd, tapfdSize) < 0)
892             goto cleanup;
893         memset(tapfd, -1, sizeof(*tapfd) * tapfdSize);
894         if (VIR_ALLOC_N(vhostfd, vhostfdSize) < 0)
895             goto cleanup;
896         memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize);
897         if (qemuNetworkIfaceConnect(vm->def, conn, driver, net,
898                                     priv->qemuCaps, tapfd, &tapfdSize) < 0)
899             goto cleanup;
900         iface_connected = true;
901         if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
902             goto cleanup;
903     } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
904         tapfdSize = vhostfdSize = 1;
905         if (VIR_ALLOC(tapfd) < 0)
906             goto cleanup;
907         *tapfd = -1;
908         if (VIR_ALLOC(vhostfd) < 0)
909             goto cleanup;
910         *vhostfd = -1;
911         if ((tapfd[0] = qemuPhysIfaceConnect(vm->def, driver, net,
912                                              priv->qemuCaps,
913                                              VIR_NETDEV_VPORT_PROFILE_OP_CREATE)) < 0)
914             goto cleanup;
915         iface_connected = true;
916         if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
917             goto cleanup;
918     } else if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
919         vhostfdSize = 1;
920         if (VIR_ALLOC(vhostfd) < 0)
921             goto cleanup;
922         *vhostfd = -1;
923         if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
924             goto cleanup;
925     }
926
927     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NET_NAME) ||
928         virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
929         if (qemuAssignDeviceNetAlias(vm->def, net, -1) < 0)
930             goto cleanup;
931     }
932
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)
938             goto cleanup;
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)
944              goto cleanup;
945
946     releaseaddr = true;
947
948     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
949         virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
950         vlan = -1;
951     } else {
952         vlan = qemuDomainNetVLAN(net);
953
954         if (vlan < 0) {
955             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
956                            _("Unable to attach network devices without vlan"));
957             goto cleanup;
958         }
959     }
960
961     if (VIR_ALLOC_N(tapfdName, tapfdSize) < 0 ||
962         VIR_ALLOC_N(vhostfdName, vhostfdSize) < 0)
963         goto cleanup;
964
965     for (i = 0; i < tapfdSize; i++) {
966         if (virAsprintf(&tapfdName[i], "fd-%s%zu", net->info.alias, i) < 0)
967             goto cleanup;
968     }
969
970     for (i = 0; i < vhostfdSize; i++) {
971         if (virAsprintf(&vhostfdName[i], "vhostfd-%s%zu", net->info.alias, i) < 0)
972             goto cleanup;
973     }
974
975     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
976         virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
977         if (!(netstr = qemuBuildHostNetStr(net, driver,
978                                            ',', -1,
979                                            tapfdName, tapfdSize,
980                                            vhostfdName, vhostfdSize)))
981             goto cleanup;
982     } else {
983         if (!(netstr = qemuBuildHostNetStr(net, driver,
984                                            ' ', vlan,
985                                            tapfdName, tapfdSize,
986                                            vhostfdName, vhostfdSize)))
987             goto cleanup;
988     }
989
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);
998             goto cleanup;
999         }
1000     } else {
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);
1006             goto cleanup;
1007         }
1008     }
1009     qemuDomainObjExitMonitor(driver, vm);
1010
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]);
1015
1016     if (!virDomainObjIsActive(vm)) {
1017         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1018                        _("guest unexpectedly quit"));
1019         goto cleanup;
1020     }
1021
1022     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
1023         if (!(nicstr = qemuBuildNicDevStr(vm->def, net, vlan, 0,
1024                                           vhostfdSize, priv->qemuCaps)))
1025             goto try_remove;
1026     } else {
1027         if (!(nicstr = qemuBuildNicStr(net, NULL, vlan)))
1028             goto try_remove;
1029     }
1030
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);
1036             goto try_remove;
1037         }
1038     } else {
1039         guestAddr = net->info.addr.pci;
1040         if (qemuMonitorAddPCINetwork(priv->mon, nicstr,
1041                                      &guestAddr) < 0) {
1042             qemuDomainObjExitMonitor(driver, vm);
1043             virDomainAuditNet(vm, NULL, net, "attach", false);
1044             goto try_remove;
1045         }
1046         net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
1047         memcpy(&net->info.addr.pci, &guestAddr, sizeof(guestAddr));
1048     }
1049     qemuDomainObjExitMonitor(driver, vm);
1050
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"));
1056         } else {
1057             qemuDomainObjEnterMonitor(driver, vm);
1058
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);
1063                     goto try_remove;
1064                 }
1065             } else {
1066                 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
1067                                _("setting of link state not supported: Link is up"));
1068             }
1069
1070             qemuDomainObjExitMonitor(driver, vm);
1071         }
1072         /* link set to down */
1073     }
1074
1075     virDomainAuditNet(vm, NULL, net, "attach", true);
1076
1077     ret = 0;
1078
1079  cleanup:
1080     if (!ret) {
1081         vm->def->nets[vm->def->nnets++] = net;
1082     } else {
1083         if (releaseaddr)
1084             qemuDomainReleaseDeviceAddress(vm, &net->info, NULL);
1085
1086         if (iface_connected) {
1087             virDomainConfNWFilterTeardown(net);
1088
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),
1095                                  cfg->stateDir));
1096                 VIR_FREE(net->ifname);
1097             }
1098
1099             vport = virDomainNetGetActualVirtPortProfile(net);
1100             if (vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH)
1101                ignore_value(virNetDevOpenvswitchRemovePort(
1102                                virDomainNetGetActualBridgeName(net), net->ifname));
1103         }
1104
1105         virDomainNetRemoveHostdev(vm->def, net);
1106
1107         networkReleaseActualDevice(vm->def, net);
1108     }
1109
1110     VIR_FREE(nicstr);
1111     VIR_FREE(netstr);
1112     for (i = 0; tapfd && i < tapfdSize; i++) {
1113         VIR_FORCE_CLOSE(tapfd[i]);
1114         if (tapfdName)
1115             VIR_FREE(tapfdName[i]);
1116     }
1117     VIR_FREE(tapfd);
1118     VIR_FREE(tapfdName);
1119     for (i = 0; vhostfd && i < vhostfdSize; i++) {
1120         VIR_FORCE_CLOSE(vhostfd[i]);
1121         if (vhostfdName)
1122             VIR_FREE(vhostfdName[i]);
1123     }
1124     VIR_FREE(vhostfd);
1125     VIR_FREE(vhostfdName);
1126     virObjectUnref(cfg);
1127
1128     return ret;
1129
1130  try_remove:
1131     if (!virDomainObjIsActive(vm))
1132         goto cleanup;
1133
1134     if (vlan < 0) {
1135         if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
1136             virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
1137             char *netdev_name;
1138             if (virAsprintf(&netdev_name, "host%s", net->info.alias) < 0)
1139                 goto cleanup;
1140             qemuDomainObjEnterMonitor(driver, vm);
1141             if (qemuMonitorRemoveNetdev(priv->mon, netdev_name) < 0)
1142                 VIR_WARN("Failed to remove network backend for netdev %s",
1143                          netdev_name);
1144             qemuDomainObjExitMonitor(driver, vm);
1145             VIR_FREE(netdev_name);
1146         } else {
1147             VIR_WARN("Unable to remove network backend");
1148         }
1149     } else {
1150         char *hostnet_name;
1151         if (virAsprintf(&hostnet_name, "host%s", net->info.alias) < 0)
1152             goto cleanup;
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);
1159     }
1160     goto cleanup;
1161 }
1162
1163
1164 static int
1165 qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
1166                               virDomainObjPtr vm,
1167                               virDomainHostdevDefPtr hostdev)
1168 {
1169     qemuDomainObjPrivatePtr priv = vm->privateData;
1170     int ret;
1171     char *devstr = NULL;
1172     int configfd = -1;
1173     char *configfd_name = NULL;
1174     bool releaseaddr = false;
1175     bool teardowncgroup = false;
1176     bool teardownlabel = false;
1177     int backend;
1178     unsigned long long memKB;
1179     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
1180     unsigned int flags = 0;
1181
1182     if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
1183         return -1;
1184
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)
1189         goto cleanup;
1190
1191     /* this could have been changed by qemuPrepareHostdevPCIDevices */
1192     backend = hostdev->source.subsys.u.pci.backend;
1193
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"));
1200             goto error;
1201         }
1202
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
1209          * bytes.
1210          */
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);
1215         break;
1216
1217     default:
1218         break;
1219     }
1220
1221     if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
1222         goto error;
1223     teardowncgroup = true;
1224
1225     if (virSecurityManagerSetHostdevLabel(driver->securityManager,
1226                                           vm->def, hostdev, NULL) < 0)
1227         goto error;
1228     teardownlabel = true;
1229
1230     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
1231         if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
1232             goto error;
1233         if (virDomainPCIAddressEnsureAddr(priv->pciaddrs, hostdev->info) < 0)
1234             goto error;
1235         releaseaddr = true;
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)
1242                     goto error;
1243             }
1244         }
1245
1246         if (!virDomainObjIsActive(vm)) {
1247             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1248                            _("guest unexpectedly quit during hotplug"));
1249             goto error;
1250         }
1251
1252         if (!(devstr = qemuBuildPCIHostdevDevStr(vm->def, hostdev, configfd_name,
1253                                                  priv->qemuCaps)))
1254             goto error;
1255
1256         qemuDomainObjEnterMonitor(driver, vm);
1257         ret = qemuMonitorAddDeviceWithFd(priv->mon, devstr,
1258                                          configfd, configfd_name);
1259         qemuDomainObjExitMonitor(driver, vm);
1260     } else {
1261         virDevicePCIAddressPtr guestAddr = &hostdev->info->addr.pci;
1262         virDevicePCIAddressPtr hostAddr = &hostdev->source.subsys.u.pci.addr;
1263
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"),
1269                            hostAddr->domain);
1270             goto error;
1271         }
1272
1273         qemuDomainObjEnterMonitor(driver, vm);
1274         ret = qemuMonitorAddPCIHostDevice(priv->mon, hostAddr, guestAddr);
1275         qemuDomainObjExitMonitor(driver, vm);
1276
1277         hostdev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
1278     }
1279     virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
1280     if (ret < 0)
1281         goto error;
1282
1283     vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
1284
1285     VIR_FREE(devstr);
1286     VIR_FREE(configfd_name);
1287     VIR_FORCE_CLOSE(configfd);
1288     virObjectUnref(cfg);
1289
1290     return 0;
1291
1292  error:
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");
1299
1300     if (releaseaddr)
1301         qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
1302
1303     qemuDomainReAttachHostdevDevices(driver, vm->def->name, &hostdev, 1);
1304
1305     VIR_FREE(devstr);
1306     VIR_FREE(configfd_name);
1307     VIR_FORCE_CLOSE(configfd);
1308
1309  cleanup:
1310     virObjectUnref(cfg);
1311     return -1;
1312 }
1313
1314
1315 int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr driver,
1316                                    virDomainObjPtr vm,
1317                                    virDomainRedirdevDefPtr redirdev)
1318 {
1319     int ret;
1320     qemuDomainObjPrivatePtr priv = vm->privateData;
1321     virDomainDefPtr def = vm->def;
1322     char *devstr = NULL;
1323
1324     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
1325         if (qemuAssignDeviceRedirdevAlias(vm->def, redirdev, -1) < 0)
1326             goto error;
1327         if (!(devstr = qemuBuildRedirdevDevStr(def, redirdev, priv->qemuCaps)))
1328             goto error;
1329     }
1330
1331     if (VIR_REALLOC_N(vm->def->redirdevs, vm->def->nredirdevs+1) < 0)
1332         goto error;
1333
1334     qemuDomainObjEnterMonitor(driver, vm);
1335     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE))
1336         ret = qemuMonitorAddDevice(priv->mon, devstr);
1337     else
1338         goto error;
1339
1340     qemuDomainObjExitMonitor(driver, vm);
1341     virDomainAuditRedirdev(vm, redirdev, "attach", ret == 0);
1342     if (ret < 0)
1343         goto error;
1344
1345     vm->def->redirdevs[vm->def->nredirdevs++] = redirdev;
1346
1347     VIR_FREE(devstr);
1348
1349     return 0;
1350
1351  error:
1352     VIR_FREE(devstr);
1353     return -1;
1354
1355 }
1356
1357 int
1358 qemuDomainChrInsert(virDomainDefPtr vmdef,
1359                     virDomainChrDefPtr chr)
1360 {
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"));
1365         return -1;
1366     }
1367
1368     if (virDomainChrFind(vmdef, chr)) {
1369         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
1370                        _("chardev already exists"));
1371         return -1;
1372     }
1373
1374     if (virDomainChrInsert(vmdef, chr) < 0)
1375         return -1;
1376
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);
1384             return -1;
1385         }
1386         vmdef->nconsoles = 1;
1387
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;
1391     }
1392
1393     return 0;
1394 }
1395
1396 virDomainChrDefPtr
1397 qemuDomainChrRemove(virDomainDefPtr vmdef,
1398                     virDomainChrDefPtr chr)
1399 {
1400     virDomainChrDefPtr ret;
1401     bool removeCompat;
1402
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"));
1407         return NULL;
1408     }
1409
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);
1417
1418     if (!(ret = virDomainChrRemove(vmdef, chr))) {
1419         virReportError(VIR_ERR_INVALID_ARG, "%s",
1420                        _("device not present in domain configuration"));
1421             return NULL;
1422     }
1423
1424     if (removeCompat)
1425         VIR_DELETE_ELEMENT(vmdef->consoles, 0, vmdef->nconsoles);
1426
1427     return ret;
1428 }
1429
1430 int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
1431                               virDomainObjPtr vm,
1432                               virDomainChrDefPtr chr)
1433 {
1434     int ret = -1;
1435     qemuDomainObjPrivatePtr priv = vm->privateData;
1436     virDomainDefPtr vmdef = vm->def;
1437     char *devstr = NULL;
1438     char *charAlias = NULL;
1439     bool need_remove = false;
1440
1441     if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
1442         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
1443                        _("qemu does not support -device"));
1444         return ret;
1445     }
1446
1447     if (qemuAssignDeviceChrAlias(vmdef, chr, -1) < 0)
1448         return ret;
1449
1450     if (qemuBuildChrDeviceStr(&devstr, vm->def, chr, priv->qemuCaps) < 0)
1451         return ret;
1452
1453     if (virAsprintf(&charAlias, "char%s", chr->info.alias) < 0) {
1454         virReportOOMError();
1455         goto cleanup;
1456     }
1457
1458     if (qemuDomainChrInsert(vmdef, chr) < 0)
1459         goto cleanup;
1460     need_remove = true;
1461
1462     qemuDomainObjEnterMonitor(driver, vm);
1463     if (qemuMonitorAttachCharDev(priv->mon, charAlias, &chr->source) < 0) {
1464         qemuDomainObjExitMonitor(driver, vm);
1465         goto cleanup;
1466     }
1467
1468     if (devstr && qemuMonitorAddDevice(priv->mon, devstr) < 0) {
1469         /* detach associated chardev on error */
1470         qemuMonitorDetachCharDev(priv->mon, charAlias);
1471         qemuDomainObjExitMonitor(driver, vm);
1472         goto cleanup;
1473     }
1474     qemuDomainObjExitMonitor(driver, vm);
1475
1476     ret = 0;
1477  cleanup:
1478     if (ret < 0 && need_remove)
1479         qemuDomainChrRemove(vmdef, chr);
1480     VIR_FREE(charAlias);
1481     VIR_FREE(devstr);
1482     return ret;
1483 }
1484
1485 static int
1486 qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
1487                               virDomainObjPtr vm,
1488                               virDomainHostdevDefPtr hostdev)
1489 {
1490     qemuDomainObjPrivatePtr priv = vm->privateData;
1491     char *devstr = NULL;
1492     bool added = false;
1493     bool teardowncgroup = false;
1494     bool teardownlabel = false;
1495     int ret = -1;
1496
1497     if (qemuPrepareHostUSBDevices(driver, vm->def->name, &hostdev, 1, 0) < 0)
1498         goto cleanup;
1499
1500     added = true;
1501
1502     if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
1503         goto cleanup;
1504     teardowncgroup = true;
1505
1506     if (virSecurityManagerSetHostdevLabel(driver->securityManager,
1507                                           vm->def, hostdev, NULL) < 0)
1508         goto cleanup;
1509     teardownlabel = true;
1510
1511     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
1512         if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
1513             goto cleanup;
1514         if (!(devstr = qemuBuildUSBHostdevDevStr(vm->def, hostdev, priv->qemuCaps)))
1515             goto cleanup;
1516     }
1517
1518     if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0)
1519         goto cleanup;
1520
1521     qemuDomainObjEnterMonitor(driver, vm);
1522     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE))
1523         ret = qemuMonitorAddDevice(priv->mon, devstr);
1524     else
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);
1530     if (ret < 0)
1531         goto cleanup;
1532
1533     vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
1534
1535     ret = 0;
1536  cleanup:
1537     if (ret < 0) {
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");
1544         if (added)
1545             qemuDomainReAttachHostUSBDevices(driver, vm->def->name, &hostdev, 1);
1546     }
1547     VIR_FREE(devstr);
1548     return ret;
1549 }
1550
1551 static int
1552 qemuDomainAttachHostSCSIDevice(virQEMUDriverPtr driver,
1553                                virDomainObjPtr vm,
1554                                virDomainHostdevDefPtr hostdev)
1555 {
1556     int ret = -1;
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;
1563
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"));
1569         return -1;
1570     }
1571
1572     cont = qemuDomainFindOrCreateSCSIDiskController(driver, vm, hostdev->info->addr.drive.controller);
1573     if (!cont)
1574         return -1;
1575
1576     if (qemuPrepareHostdevSCSIDevices(driver, vm->def->name,
1577                                       &hostdev, 1)) {
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);
1584         return -1;
1585     }
1586
1587     if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
1588         goto cleanup;
1589     teardowncgroup = true;
1590
1591     if (virSecurityManagerSetHostdevLabel(driver->securityManager,
1592                                           vm->def, hostdev, NULL) < 0)
1593         goto cleanup;
1594     teardownlabel = true;
1595
1596     if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
1597         goto cleanup;
1598
1599     if (!(drvstr = qemuBuildSCSIHostdevDrvStr(hostdev, priv->qemuCaps,
1600                                               &buildCommandLineCallbacks)))
1601         goto cleanup;
1602
1603     if (!(devstr = qemuBuildSCSIHostdevDevStr(vm->def, hostdev, priv->qemuCaps)))
1604         goto cleanup;
1605
1606     if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
1607         goto cleanup;
1608
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",
1616                          drvstr, devstr);
1617             if (orig_err) {
1618                 virSetError(orig_err);
1619                 virFreeError(orig_err);
1620             }
1621         }
1622     }
1623     qemuDomainObjExitMonitor(driver, vm);
1624
1625     virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
1626     if (ret < 0)
1627         goto cleanup;
1628
1629     vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
1630
1631     ret = 0;
1632  cleanup:
1633     if (ret < 0) {
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");
1641     }
1642     VIR_FREE(drvstr);
1643     VIR_FREE(devstr);
1644     return ret;
1645 }
1646
1647 int qemuDomainAttachHostDevice(virQEMUDriverPtr driver,
1648                                virDomainObjPtr vm,
1649                                virDomainHostdevDefPtr hostdev)
1650 {
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));
1655         return -1;
1656     }
1657
1658     switch (hostdev->source.subsys.type) {
1659     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
1660         if (qemuDomainAttachHostPCIDevice(driver, vm,
1661                                           hostdev) < 0)
1662             goto error;
1663         break;
1664
1665     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
1666         if (qemuDomainAttachHostUSBDevice(driver, vm,
1667                                           hostdev) < 0)
1668             goto error;
1669         break;
1670
1671     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
1672         if (qemuDomainAttachHostSCSIDevice(driver, vm,
1673                                            hostdev) < 0)
1674             goto error;
1675         break;
1676
1677     default:
1678         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
1679                        _("hostdev subsys type '%s' not supported"),
1680                        virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type));
1681         goto error;
1682     }
1683
1684     return 0;
1685
1686  error:
1687     return -1;
1688 }
1689
1690 static virDomainNetDefPtr *qemuDomainFindNet(virDomainObjPtr vm,
1691                                              virDomainNetDefPtr dev)
1692 {
1693     size_t i;
1694
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];
1698     }
1699
1700     return NULL;
1701 }
1702
1703 static char *
1704 qemuDomainNetGetBridgeName(virConnectPtr conn, virDomainNetDefPtr net)
1705 {
1706     char *brname = NULL;
1707     int actualType = virDomainNetGetActualType(net);
1708
1709     if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
1710         const char *tmpbr = virDomainNetGetActualBridgeName(net);
1711         if (!tmpbr) {
1712             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1713                            _("interface is missing bridge name"));
1714             goto cleanup;
1715         }
1716         /* we need a copy, not just a pointer to the original */
1717         if (VIR_STRDUP(brname, tmpbr) < 0)
1718             goto cleanup;
1719     } else if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
1720         virErrorPtr errobj;
1721         virNetworkPtr network;
1722
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);
1727             goto cleanup;
1728         }
1729         brname = virNetworkGetBridgeName(network);
1730
1731         /* Make sure any above failure is preserved */
1732         errobj = virSaveLastError();
1733         virNetworkFree(network);
1734         virSetError(errobj);
1735         virFreeError(errobj);
1736
1737     } else {
1738         virReportError(VIR_ERR_INTERNAL_ERROR,
1739                        _("Interface type %d has no bridge name"),
1740                        virDomainNetGetActualType(net));
1741     }
1742
1743  cleanup:
1744     return brname;
1745 }
1746
1747 static int
1748 qemuDomainChangeNetBridge(virConnectPtr conn,
1749                           virDomainObjPtr vm,
1750                           virDomainNetDefPtr olddev,
1751                           virDomainNetDefPtr newdev)
1752 {
1753     int ret = -1;
1754     char *oldbridge = NULL, *newbridge = NULL;
1755
1756     if (!(oldbridge = qemuDomainNetGetBridgeName(conn, olddev)))
1757         goto cleanup;
1758
1759     if (!(newbridge = qemuDomainNetGetBridgeName(conn, newdev)))
1760         goto cleanup;
1761
1762     VIR_DEBUG("Change bridge for interface %s: %s -> %s",
1763               olddev->ifname, oldbridge, newbridge);
1764
1765     if (virNetDevExists(newbridge) != 1) {
1766         virReportError(VIR_ERR_OPERATION_FAILED,
1767                        _("bridge %s doesn't exist"), newbridge);
1768         goto cleanup;
1769     }
1770
1771     if (oldbridge) {
1772         ret = virNetDevBridgeRemovePort(oldbridge, olddev->ifname);
1773         virDomainAuditNet(vm, olddev, NULL, "detach", ret == 0);
1774         if (ret < 0) {
1775             /* warn but continue - possibly the old network
1776              * had been destroyed and reconstructed, leaving the
1777              * tap device orphaned.
1778              */
1779             VIR_WARN("Unable to detach device %s from bridge %s",
1780                      olddev->ifname, oldbridge);
1781         }
1782     }
1783
1784     ret = virNetDevBridgeAddPort(newbridge, olddev->ifname);
1785     virDomainAuditNet(vm, NULL, newdev, "attach", ret == 0);
1786     if (ret < 0) {
1787         ret = virNetDevBridgeAddPort(oldbridge, olddev->ifname);
1788         virDomainAuditNet(vm, NULL, olddev, "attach", ret == 0);
1789         if (ret < 0) {
1790             virReportError(VIR_ERR_OPERATION_FAILED,
1791                            _("unable to recover former state by adding port "
1792                              "to bridge %s"), oldbridge);
1793         }
1794         goto cleanup;
1795     }
1796     /* caller will replace entire olddev with newdev in domain nets list */
1797     ret = 0;
1798  cleanup:
1799     VIR_FREE(oldbridge);
1800     VIR_FREE(newbridge);
1801     return ret;
1802 }
1803
1804 static int
1805 qemuDomainChangeNetFilter(virConnectPtr conn,
1806                           virDomainObjPtr vm,
1807                           virDomainNetDefPtr olddev,
1808                           virDomainNetDefPtr newdev)
1809 {
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:
1815         break;
1816     default:
1817         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
1818                        _("filters not supported on interfaces of type %s"),
1819                        virDomainNetTypeToString(virDomainNetGetActualType(newdev)));
1820         return -1;
1821     }
1822
1823     virDomainConfNWFilterTeardown(olddev);
1824
1825     if (newdev->filter &&
1826         virDomainConfNWFilterInstantiate(conn, vm->def->uuid, newdev) < 0) {
1827         virErrorPtr errobj;
1828
1829         virReportError(VIR_ERR_OPERATION_FAILED,
1830                        _("failed to add new filter rules to '%s' "
1831                          "- attempting to restore old rules"),
1832                        olddev->ifname);
1833         errobj = virSaveLastError();
1834         ignore_value(virDomainConfNWFilterInstantiate(conn, vm->def->uuid, olddev));
1835         virSetError(errobj);
1836         virFreeError(errobj);
1837         return -1;
1838     }
1839     return 0;
1840 }
1841
1842 int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver,
1843                                  virDomainObjPtr vm,
1844                                  virDomainNetDefPtr dev,
1845                                  int linkstate)
1846 {
1847     int ret = -1;
1848     qemuDomainObjPrivatePtr priv = vm->privateData;
1849
1850     VIR_DEBUG("dev: %s, state: %d", dev->info.alias, linkstate);
1851
1852     if (!dev->info.alias) {
1853         virReportError(VIR_ERR_OPERATION_FAILED, "%s",
1854                        _("can't change link state: device alias not found"));
1855         return -1;
1856     }
1857
1858     qemuDomainObjEnterMonitor(driver, vm);
1859
1860     ret = qemuMonitorSetLink(priv->mon, dev->info.alias, linkstate);
1861     if (ret < 0)
1862         goto cleanup;
1863
1864     /* modify the device configuration */
1865     dev->linkstate = linkstate;
1866
1867  cleanup:
1868     qemuDomainObjExitMonitor(driver, vm);
1869
1870     return ret;
1871 }
1872
1873 int
1874 qemuDomainChangeNet(virQEMUDriverPtr driver,
1875                     virDomainObjPtr vm,
1876                     virDomainPtr dom,
1877                     virDomainDeviceDefPtr dev)
1878 {
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;
1889     int ret = -1;
1890
1891     if (!devslot || !(olddev = *devslot)) {
1892         virReportError(VIR_ERR_OPERATION_FAILED, "%s",
1893                        _("cannot find existing network device to modify"));
1894         goto cleanup;
1895     }
1896
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));
1903         goto cleanup;
1904     }
1905
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)
1913      */
1914
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.
1918      */
1919
1920     if (virMacAddrCmp(&olddev->mac, &newdev->mac)) {
1921         char oldmac[VIR_MAC_STRING_BUFLEN], newmac[VIR_MAC_STRING_BUFLEN];
1922
1923         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
1924                        _("cannot change network interface mac address "
1925                          "from %s to %s"),
1926                        virMacAddrFormat(&olddev->mac, oldmac),
1927                        virMacAddrFormat(&newdev->mac, newmac));
1928         goto cleanup;
1929     }
1930
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)");
1936         goto cleanup;
1937     }
1938
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"));
1947         goto cleanup;
1948     }
1949
1950     /* data: this union will be examined later, after allocating new actualdev */
1951     /* virtPortProfile: will be examined later, after allocating new actualdev */
1952
1953     if (olddev->tune.sndbuf_specified != newdev->tune.sndbuf_specified ||
1954         olddev->tune.sndbuf != newdev->tune.sndbuf) {
1955         needReconnect = true;
1956     }
1957
1958     if (STRNEQ_NULLABLE(olddev->script, newdev->script)) {
1959         virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
1960                        _("cannot modify network device script attribute"));
1961         goto cleanup;
1962     }
1963
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)
1966         goto cleanup;
1967     if (STRNEQ_NULLABLE(olddev->ifname, newdev->ifname)) {
1968         virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
1969                        _("cannot modify network device tap name"));
1970         goto cleanup;
1971     }
1972
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).
1978      */
1979     if (!virDomainDeviceAddressIsValid(&newdev->info,
1980                                        VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
1981         virDomainDeviceInfoCopy(&newdev->info, &olddev->info) < 0) {
1982         goto cleanup;
1983     }
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"));
1988         goto cleanup;
1989     }
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)
1993         goto cleanup;
1994     if (STRNEQ_NULLABLE(olddev->info.alias, newdev->info.alias)) {
1995         virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
1996                        _("cannot modify network device alias"));
1997         goto cleanup;
1998     }
1999     if (olddev->info.rombar != newdev->info.rombar) {
2000         virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
2001                        _("cannot modify network device rom bar setting"));
2002         goto cleanup;
2003     }
2004     if (STRNEQ_NULLABLE(olddev->info.romfile, newdev->info.romfile)) {
2005         virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
2006                        _("cannot modify network rom file"));
2007         goto cleanup;
2008     }
2009     if (olddev->info.bootIndex != newdev->info.bootIndex) {
2010         virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
2011                        _("cannot modify network device boot index setting"));
2012         goto cleanup;
2013     }
2014     /* (end of device info checks) */
2015
2016     if (STRNEQ_NULLABLE(olddev->filter, newdev->filter) ||
2017         !virNWFilterHashTableEqual(olddev->filterparams, newdev->filterparams)) {
2018         needFilterChange = true;
2019     }
2020
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 */
2024
2025     /* allocate new actual device to compare to old - we will need to
2026      * free it if we fail for any reason
2027      */
2028     if (newdev->type == VIR_DOMAIN_NET_TYPE_NETWORK &&
2029         networkAllocateActualDevice(vm->def, newdev) < 0) {
2030         goto cleanup;
2031     }
2032
2033     newType = virDomainNetGetActualType(newdev);
2034
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));
2040         goto cleanup;
2041     }
2042
2043     if (olddev->type == newdev->type && oldType == newType) {
2044
2045         /* if type hasn't changed, check the relevant fields for the type */
2046         switch (newdev->type) {
2047         case VIR_DOMAIN_NET_TYPE_USER:
2048             break;
2049
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;
2056             }
2057         break;
2058
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;
2066             }
2067             break;
2068
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;
2073                 else
2074                     needBridgeChange = true;
2075             }
2076             /* other things handled in common code directly below this switch */
2077             break;
2078
2079         case VIR_DOMAIN_NET_TYPE_BRIDGE:
2080             /* all handled in bridge name checked in common code below */
2081             break;
2082
2083         case VIR_DOMAIN_NET_TYPE_INTERNAL:
2084             if (STRNEQ_NULLABLE(olddev->data.internal.name,
2085                                 newdev->data.internal.name)) {
2086                 needReconnect = true;
2087             }
2088             break;
2089
2090         case VIR_DOMAIN_NET_TYPE_DIRECT:
2091             /* all handled in common code directly below this switch */
2092             break;
2093
2094         default:
2095             virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
2096                            _("unable to change config on '%s' network type"),
2097                            virDomainNetTypeToString(newdev->type));
2098             break;
2099
2100         }
2101     } else {
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.
2105          *
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.
2110          */
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)) {
2115
2116             needBridgeChange = true;
2117
2118         } else if (oldType == VIR_DOMAIN_NET_TYPE_DIRECT &&
2119                    newType == VIR_DOMAIN_NET_TYPE_DIRECT) {
2120
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 */
2127
2128         } else {
2129
2130             /* for all other combinations, we'll need a full reconnect */
2131             needReconnect = true;
2132
2133         }
2134     }
2135
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.
2139      */
2140     if (STRNEQ_NULLABLE(virDomainNetGetActualBridgeName(olddev),
2141                         virDomainNetGetActualBridgeName(newdev))) {
2142         if (virDomainNetGetActualVirtPortProfile(newdev))
2143             needReconnect = true;
2144         else
2145             needBridgeChange = true;
2146     }
2147
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;
2156     }
2157
2158     if (olddev->linkstate != newdev->linkstate)
2159         needLinkStateChange = true;
2160
2161     if (!virNetDevBandwidthEqual(virDomainNetGetActualBandwidth(olddev),
2162                                  virDomainNetGetActualBandwidth(newdev)))
2163         needBandwidthSet = true;
2164
2165     /* FINALLY - actually perform the required actions */
2166
2167     if (needReconnect) {
2168         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
2169                        _("unable to change config on '%s' network type"),
2170                        virDomainNetTypeToString(newdev->type));
2171         goto cleanup;
2172     }
2173
2174     if (needBandwidthSet) {
2175         if (virNetDevBandwidthSet(newdev->ifname,
2176                                   virDomainNetGetActualBandwidth(newdev),
2177                                   false) < 0) {
2178             virReportError(VIR_ERR_INTERNAL_ERROR,
2179                            _("cannot set bandwidth limits on %s"),
2180                            newdev->ifname);
2181             goto cleanup;
2182         }
2183         needReplaceDevDef = true;
2184     }
2185
2186     if (needBridgeChange) {
2187         if (qemuDomainChangeNetBridge(dom->conn, vm, olddev, newdev) < 0)
2188             goto cleanup;
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;
2193     }
2194
2195     if (needFilterChange) {
2196         if (qemuDomainChangeNetFilter(dom->conn, vm, olddev, newdev) < 0)
2197             goto cleanup;
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;
2202     }
2203
2204     if (needLinkStateChange &&
2205         qemuDomainChangeNetLinkState(driver, vm, olddev, newdev->linkstate) < 0) {
2206         goto cleanup;
2207     }
2208
2209     if (needReplaceDevDef) {
2210         /* the changes above warrant replacing olddev with newdev in
2211          * the domain's nets list.
2212          */
2213
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.
2221          */
2222         *devslot = newdev;
2223         newdev = dev->data.net = NULL;
2224         dev->type = VIR_DOMAIN_DEVICE_NONE;
2225     }
2226
2227     ret = 0;
2228  cleanup:
2229     /* When we get here, we will be in one of these two states:
2230      *
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.
2236      *
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)
2242      *
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.
2246      */
2247     if (newdev)
2248         networkReleaseActualDevice(vm->def, newdev);
2249
2250     return ret;
2251 }
2252
2253
2254
2255 static virDomainGraphicsDefPtr qemuDomainFindGraphics(virDomainObjPtr vm,
2256                                                       virDomainGraphicsDefPtr dev)
2257 {
2258     size_t i;
2259
2260     for (i = 0; i < vm->def->ngraphics; i++) {
2261         if (vm->def->graphics[i]->type == dev->type)
2262             return vm->def->graphics[i];
2263     }
2264
2265     return NULL;
2266 }
2267
2268
2269 int
2270 qemuDomainChangeGraphics(virQEMUDriverPtr driver,
2271                          virDomainObjPtr vm,
2272                          virDomainGraphicsDefPtr dev)
2273 {
2274     virDomainGraphicsDefPtr olddev = qemuDomainFindGraphics(vm, dev);
2275     int ret = -1;
2276     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
2277     size_t i;
2278
2279     if (!olddev) {
2280         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
2281                        _("cannot find existing graphics device to modify"));
2282         goto cleanup;
2283     }
2284
2285     if (dev->nListens != olddev->nListens) {
2286         virReportError(VIR_ERR_INVALID_ARG, "%s",
2287                        _("cannot change the number of listen addresses"));
2288         goto cleanup;
2289     }
2290
2291     for (i = 0; i < dev->nListens; i++) {
2292         virDomainGraphicsListenDefPtr newlisten = &dev->listens[i];
2293         virDomainGraphicsListenDefPtr oldlisten = &olddev->listens[i];
2294
2295         if (newlisten->type != oldlisten->type) {
2296             virReportError(VIR_ERR_INVALID_ARG, "%s",
2297                            _("cannot change the type of listen address"));
2298             goto cleanup;
2299         }
2300
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"));
2308                 goto cleanup;
2309             }
2310             break;
2311
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"));
2318                 goto cleanup;
2319             }
2320             break;
2321
2322         case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
2323         case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
2324             /* nada */
2325             break;
2326         }
2327     }
2328
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"));
2336             goto cleanup;
2337         }
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"));
2341             goto cleanup;
2342         }
2343
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
2346          * old password */
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,
2357                                                     cfg->vncPassword);
2358             if (ret < 0)
2359                 goto cleanup;
2360
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;
2368         } else {
2369             ret = 0;
2370         }
2371         break;
2372
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"));
2381             goto cleanup;
2382         }
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"));
2387             goto cleanup;
2388         }
2389
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"
2394          */
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);
2408
2409             if (ret < 0)
2410                 goto cleanup;
2411
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;
2419         } else {
2420             VIR_DEBUG("Not updating since password didn't change");
2421             ret = 0;
2422         }
2423         break;
2424
2425     default:
2426         virReportError(VIR_ERR_INTERNAL_ERROR,
2427                        _("unable to change config on '%s' graphics type"),
2428                        virDomainGraphicsTypeToString(dev->type));
2429         break;
2430     }
2431
2432  cleanup:
2433     virObjectUnref(cfg);
2434     return ret;
2435 }
2436
2437
2438 static int qemuComparePCIDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
2439                                 virDomainDeviceDefPtr device ATTRIBUTE_UNUSED,
2440                                 virDomainDeviceInfoPtr info1,
2441                                 void *opaque)
2442 {
2443     virDomainDeviceInfoPtr info2 = opaque;
2444
2445     if (info1->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI ||
2446         info2->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
2447         return 0;
2448
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)
2453         return -1;
2454     return 0;
2455 }
2456
2457 static bool qemuIsMultiFunctionDevice(virDomainDefPtr def,
2458                                       virDomainDeviceInfoPtr dev)
2459 {
2460     if (virDomainDeviceInfoIterate(def, qemuComparePCIDevice, dev) < 0)
2461         return true;
2462     return false;
2463 }
2464
2465
2466 static void
2467 qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
2468                            virDomainObjPtr vm,
2469                            virDomainDiskDefPtr disk)
2470 {
2471     virDomainDeviceDef dev;
2472     virObjectEventPtr event;
2473     size_t i;
2474     const char *src = virDomainDiskGetSource(disk);
2475
2476     VIR_DEBUG("Removing disk %s from domain %p %s",
2477               disk->info.alias, vm, vm->def->name);
2478
2479     virDomainAuditDisk(vm, src, NULL, "detach", true);
2480
2481     event = virDomainEventDeviceRemovedNewFromObj(vm, disk->info.alias);
2482     if (event)
2483         qemuDomainEventQueue(driver, event);
2484
2485     for (i = 0; i < vm->def->ndisks; i++) {
2486         if (vm->def->disks[i] == disk) {
2487             virDomainDiskRemove(vm->def, i);
2488             break;
2489         }
2490     }
2491
2492     qemuDomainReleaseDeviceAddress(vm, &disk->info, src);
2493
2494     if (virSecurityManagerRestoreImageLabel(driver->securityManager,
2495                                             vm->def, disk) < 0)
2496         VIR_WARN("Unable to restore security label on %s", src);
2497
2498     if (qemuTeardownDiskCgroup(vm, disk) < 0)
2499         VIR_WARN("Failed to tear down cgroup for disk path %s", src);
2500
2501     if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
2502         VIR_WARN("Unable to release lock on %s", src);
2503
2504     dev.type = VIR_DOMAIN_DEVICE_DISK;
2505     dev.data.disk = disk;
2506     ignore_value(qemuRemoveSharedDevice(driver, &dev, vm->def->name));
2507
2508     virDomainDiskDefFree(disk);
2509 }
2510
2511
2512 static void
2513 qemuDomainRemoveControllerDevice(virQEMUDriverPtr driver,
2514                                  virDomainObjPtr vm,
2515                                  virDomainControllerDefPtr controller)
2516 {
2517     virObjectEventPtr event;
2518     size_t i;
2519
2520     VIR_DEBUG("Removing controller %s from domain %p %s",
2521               controller->info.alias, vm, vm->def->name);
2522
2523     event = virDomainEventDeviceRemovedNewFromObj(vm, controller->info.alias);
2524     if (event)
2525         qemuDomainEventQueue(driver, event);
2526
2527     for (i = 0; i < vm->def->ncontrollers; i++) {
2528         if (vm->def->controllers[i] == controller) {
2529             virDomainControllerRemove(vm->def, i);
2530             break;
2531         }
2532     }
2533
2534     qemuDomainReleaseDeviceAddress(vm, &controller->info, NULL);
2535     virDomainControllerDefFree(controller);
2536 }
2537
2538
2539 static void
2540 qemuDomainRemovePCIHostDevice(virQEMUDriverPtr driver,
2541                               virDomainObjPtr vm,
2542                               virDomainHostdevDefPtr hostdev)
2543 {
2544     qemuDomainReAttachHostdevDevices(driver, vm->def->name, &hostdev, 1);
2545     qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
2546 }
2547
2548 static void
2549 qemuDomainRemoveUSBHostDevice(virQEMUDriverPtr driver,
2550                               virDomainObjPtr vm,
2551                               virDomainHostdevDefPtr hostdev)
2552 {
2553     qemuDomainReAttachHostUSBDevices(driver, vm->def->name, &hostdev, 1);
2554 }
2555
2556 static void
2557 qemuDomainRemoveSCSIHostDevice(virQEMUDriverPtr driver,
2558                                virDomainObjPtr vm,
2559                                virDomainHostdevDefPtr hostdev)
2560 {
2561     qemuDomainReAttachHostSCSIDevices(driver, vm->def->name, &hostdev, 1);
2562 }
2563
2564 static void
2565 qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
2566                            virDomainObjPtr vm,
2567                            virDomainHostdevDefPtr hostdev)
2568 {
2569     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
2570     virDomainNetDefPtr net = NULL;
2571     virObjectEventPtr event;
2572     size_t i;
2573
2574     VIR_DEBUG("Removing host device %s from domain %p %s",
2575               hostdev->info->alias, vm, vm->def->name);
2576
2577     event = virDomainEventDeviceRemovedNewFromObj(vm, hostdev->info->alias);
2578     if (event)
2579         qemuDomainEventQueue(driver, event);
2580
2581     if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET) {
2582         net = hostdev->parent.data.net;
2583
2584         for (i = 0; i < vm->def->nnets; i++) {
2585             if (vm->def->nets[i] == net) {
2586                 virDomainNetRemove(vm->def, i);
2587                 break;
2588             }
2589         }
2590     }
2591
2592     for (i = 0; i < vm->def->nhostdevs; i++) {
2593         if (vm->def->hostdevs[i] == hostdev) {
2594             virDomainHostdevRemove(vm->def, i);
2595             break;
2596         }
2597     }
2598
2599     virDomainAuditHostdev(vm, hostdev, "detach", true);
2600
2601     switch ((enum virDomainHostdevSubsysType) hostdev->source.subsys.type) {
2602     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
2603         qemuDomainRemovePCIHostDevice(driver, vm, hostdev);
2604         break;
2605     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
2606         qemuDomainRemoveUSBHostDevice(driver, vm, hostdev);
2607         break;
2608     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
2609         qemuDomainRemoveSCSIHostDevice(driver, vm, hostdev);
2610         break;
2611     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
2612         break;
2613     }
2614
2615     if (qemuTeardownHostdevCgroup(vm, hostdev) < 0)
2616         VIR_WARN("Failed to remove host device cgroup ACL");
2617
2618     if (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
2619                                               vm->def, hostdev, NULL) < 0) {
2620         VIR_WARN("Failed to restore host device labelling");
2621     }
2622
2623     virDomainHostdevDefFree(hostdev);
2624
2625     if (net) {
2626         networkReleaseActualDevice(vm->def, net);
2627         virDomainNetDefFree(net);
2628     }
2629     virObjectUnref(cfg);
2630 }
2631
2632
2633 static void
2634 qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
2635                           virDomainObjPtr vm,
2636                           virDomainNetDefPtr net)
2637 {
2638     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
2639     virNetDevVPortProfilePtr vport;
2640     virObjectEventPtr event;
2641     size_t i;
2642
2643     if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
2644         /* this function handles all hostdev and netdev cleanup */
2645         qemuDomainRemoveHostDevice(driver, vm, virDomainNetGetActualHostdev(net));
2646         return;
2647     }
2648
2649     VIR_DEBUG("Removing network interface %s from domain %p %s",
2650               net->info.alias, vm, vm->def->name);
2651
2652     virDomainAuditNet(vm, net, NULL, "detach", true);
2653
2654     event = virDomainEventDeviceRemovedNewFromObj(vm, net->info.alias);
2655     if (event)
2656         qemuDomainEventQueue(driver, event);
2657
2658     for (i = 0; i < vm->def->nnets; i++) {
2659         if (vm->def->nets[i] == net) {
2660             virDomainNetRemove(vm->def, i);
2661             break;
2662         }
2663     }
2664
2665     qemuDomainReleaseDeviceAddress(vm, &net->info, NULL);
2666     virDomainConfNWFilterTeardown(net);
2667
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),
2674                          cfg->stateDir));
2675         VIR_FREE(net->ifname);
2676     }
2677
2678     if (cfg->macFilter && (net->ifname != NULL)) {
2679         ignore_value(ebtablesRemoveForwardAllowIn(driver->ebtables,
2680                                                   net->ifname,
2681                                                   &net->mac));
2682     }
2683
2684     vport = virDomainNetGetActualVirtPortProfile(net);
2685     if (vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH)
2686         ignore_value(virNetDevOpenvswitchRemovePort(
2687                         virDomainNetGetActualBridgeName(net),
2688                         net->ifname));
2689
2690     networkReleaseActualDevice(vm->def, net);
2691     virDomainNetDefFree(net);
2692     virObjectUnref(cfg);
2693 }
2694
2695
2696 static void
2697 qemuDomainRemoveChrDevice(virQEMUDriverPtr driver,
2698                           virDomainObjPtr vm,
2699                           virDomainChrDefPtr chr)
2700 {
2701     virObjectEventPtr event;
2702
2703     VIR_DEBUG("Removing character device %s from domain %p %s",
2704               chr->info.alias, vm, vm->def->name);
2705
2706     event = virDomainEventDeviceRemovedNewFromObj(vm, chr->info.alias);
2707     if (event)
2708         qemuDomainEventQueue(driver, event);
2709
2710     qemuDomainChrRemove(vm->def, chr);
2711     virDomainChrDefFree(chr);
2712 }
2713
2714
2715 void
2716 qemuDomainRemoveDevice(virQEMUDriverPtr driver,
2717                        virDomainObjPtr vm,
2718                        virDomainDeviceDefPtr dev)
2719 {
2720     switch ((virDomainDeviceType) dev->type) {
2721     case VIR_DOMAIN_DEVICE_DISK:
2722         qemuDomainRemoveDiskDevice(driver, vm, dev->data.disk);
2723         break;
2724     case VIR_DOMAIN_DEVICE_CONTROLLER:
2725         qemuDomainRemoveControllerDevice(driver, vm, dev->data.controller);
2726         break;
2727     case VIR_DOMAIN_DEVICE_NET:
2728         qemuDomainRemoveNetDevice(driver, vm, dev->data.net);
2729         break;
2730     case VIR_DOMAIN_DEVICE_HOSTDEV:
2731         qemuDomainRemoveHostDevice(driver, vm, dev->data.hostdev);
2732         break;
2733
2734     case VIR_DOMAIN_DEVICE_CHR:
2735         qemuDomainRemoveChrDevice(driver, vm, dev->data.chr);
2736         break;
2737
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));
2756         break;
2757     }
2758 }
2759
2760
2761 static void
2762 qemuDomainMarkDeviceForRemoval(virDomainObjPtr vm,
2763                                virDomainDeviceInfoPtr info)
2764 {
2765     qemuDomainObjPrivatePtr priv = vm->privateData;
2766
2767     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_DEL_EVENT))
2768         priv->unpluggingDevice = info->alias;
2769     else
2770         priv->unpluggingDevice = NULL;
2771 }
2772
2773 static void
2774 qemuDomainResetDeviceRemoval(virDomainObjPtr vm)
2775 {
2776     qemuDomainObjPrivatePtr priv = vm->privateData;
2777     priv->unpluggingDevice = NULL;
2778 }
2779
2780 /* Returns:
2781  *  -1 on error
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
2785  */
2786 static int
2787 qemuDomainWaitForDeviceRemoval(virDomainObjPtr vm)
2788 {
2789     qemuDomainObjPrivatePtr priv = vm->privateData;
2790     unsigned long long until;
2791
2792     if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_DEL_EVENT))
2793         return 0;
2794
2795     if (virTimeMillisNow(&until) < 0)
2796         return -1;
2797     until += qemuDomainRemoveDeviceWaitTime;
2798
2799     while (priv->unpluggingDevice) {
2800         if (virCondWaitUntil(&priv->unplugFinished,
2801                              &vm->parent.lock, until) < 0) {
2802             if (errno == ETIMEDOUT) {
2803                 return 2;
2804             } else {
2805                 virReportSystemError(errno, "%s",
2806                                      _("Unable to wait on unplug condition"));
2807                 return -1;
2808             }
2809         }
2810     }
2811
2812     return 1;
2813 }
2814
2815 void
2816 qemuDomainSignalDeviceRemoval(virDomainObjPtr vm,
2817                               const char *devAlias)
2818 {
2819     qemuDomainObjPrivatePtr priv = vm->privateData;
2820
2821     if (STREQ_NULLABLE(priv->unpluggingDevice, devAlias)) {
2822         qemuDomainResetDeviceRemoval(vm);
2823         virCondSignal(&priv->unplugFinished);
2824     }
2825 }
2826
2827
2828 static int
2829 qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
2830                                  virDomainObjPtr vm,
2831                                  virDomainDiskDefPtr detach)
2832 {
2833     int ret = -1;
2834     qemuDomainObjPrivatePtr priv = vm->privateData;
2835     char *drivestr = NULL;
2836
2837     if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
2838         virReportError(VIR_ERR_OPERATION_FAILED,
2839                        _("cannot hot unplug multifunction PCI device: %s"),
2840                        detach->dst);
2841         goto cleanup;
2842     }
2843
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"));
2850             goto cleanup;
2851         }
2852     } else {
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"));
2857             goto cleanup;
2858         }
2859     }
2860
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)
2865         goto cleanup;
2866
2867     qemuDomainMarkDeviceForRemoval(vm, &detach->info);
2868
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);
2875             goto cleanup;
2876         }
2877     } else {
2878         if (qemuMonitorRemovePCIDevice(priv->mon,
2879                                        &detach->info.addr.pci) < 0) {
2880             qemuDomainObjExitMonitor(driver, vm);
2881             virDomainAuditDisk(vm, virDomainDiskGetSource(detach),
2882                                NULL, "detach", false);
2883             goto cleanup;
2884         }
2885     }
2886
2887     /* disconnect guest from host device */
2888     qemuMonitorDriveDel(priv->mon, drivestr);
2889
2890     qemuDomainObjExitMonitor(driver, vm);
2891
2892     if (!qemuDomainWaitForDeviceRemoval(vm))
2893         qemuDomainRemoveDiskDevice(driver, vm, detach);
2894     ret = 0;
2895
2896  cleanup:
2897     qemuDomainResetDeviceRemoval(vm);
2898     VIR_FREE(drivestr);
2899     return ret;
2900 }
2901
2902 static int
2903 qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
2904                            virDomainObjPtr vm,
2905                            virDomainDiskDefPtr detach)
2906 {
2907     int ret = -1;
2908     qemuDomainObjPrivatePtr priv = vm->privateData;
2909     char *drivestr = NULL;
2910
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));
2915         goto cleanup;
2916     }
2917
2918     if (detach->mirror) {
2919         virReportError(VIR_ERR_BLOCK_COPY_ACTIVE,
2920                        _("disk '%s' is in an active block copy job"),
2921                        detach->dst);
2922         goto cleanup;
2923     }
2924
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)
2929         goto cleanup;
2930
2931     qemuDomainMarkDeviceForRemoval(vm, &detach->info);
2932
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);
2938         goto cleanup;
2939     }
2940
2941     /* disconnect guest from host device */
2942     qemuMonitorDriveDel(priv->mon, drivestr);
2943
2944     qemuDomainObjExitMonitor(driver, vm);
2945
2946     if (!qemuDomainWaitForDeviceRemoval(vm))
2947         qemuDomainRemoveDiskDevice(driver, vm, detach);
2948     ret = 0;
2949
2950  cleanup:
2951     qemuDomainResetDeviceRemoval(vm);
2952     VIR_FREE(drivestr);
2953     return ret;
2954 }
2955
2956 static int
2957 qemuFindDisk(virDomainDefPtr def, const char *dst)
2958 {
2959     size_t i;
2960
2961     for (i = 0; i < def->ndisks; i++) {
2962         if (STREQ(def->disks[i]->dst, dst)) {
2963             return i;
2964         }
2965     }
2966
2967     return -1;
2968 }
2969
2970 int
2971 qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver,
2972                                virDomainObjPtr vm,
2973                                virDomainDeviceDefPtr dev)
2974 {
2975     virDomainDiskDefPtr disk;
2976     int ret = -1;
2977     int idx;
2978
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);
2982         return -1;
2983     }
2984     disk = vm->def->disks[idx];
2985
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);
2994         else
2995             virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
2996                            _("This type of disk cannot be hot unplugged"));
2997         break;
2998     default:
2999         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
3000                        _("disk device type '%s' cannot be detached"),
3001                        virDomainDiskDeviceTypeToString(disk->device));
3002         break;
3003     }
3004
3005     return ret;
3006 }
3007
3008
3009 static bool qemuDomainDiskControllerIsBusy(virDomainObjPtr vm,
3010                                            virDomainControllerDefPtr detach)
3011 {
3012     size_t i;
3013     virDomainDiskDefPtr disk;
3014
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 */
3019             continue;
3020
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)
3024             continue;
3025         if (disk->bus == VIR_DOMAIN_DISK_BUS_FDC &&
3026             detach->type != VIR_DOMAIN_CONTROLLER_TYPE_FDC)
3027             continue;
3028         if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI &&
3029             detach->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
3030             continue;
3031
3032         if (disk->info.addr.drive.controller == detach->idx)
3033             return true;
3034     }
3035
3036     return false;
3037 }
3038
3039 static bool qemuDomainControllerIsBusy(virDomainObjPtr vm,
3040                                        virDomainControllerDefPtr detach)
3041 {
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);
3047
3048     case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
3049     case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
3050     case VIR_DOMAIN_CONTROLLER_TYPE_CCID:
3051     default:
3052         /* libvirt does not support sata controller, and does not support to
3053          * detach virtio and smart card controller.
3054          */
3055         return true;
3056     }
3057 }
3058
3059 int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
3060                                      virDomainObjPtr vm,
3061                                      virDomainDeviceDefPtr dev)
3062 {
3063     int idx, ret = -1;
3064     virDomainControllerDefPtr detach = NULL;
3065     qemuDomainObjPrivatePtr priv = vm->privateData;
3066
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);
3074         goto cleanup;
3075     }
3076
3077     detach = vm->def->controllers[idx];
3078
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));
3085         goto cleanup;
3086     }
3087
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));
3092         goto cleanup;
3093     }
3094
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);
3100         goto cleanup;
3101     }
3102
3103     if (qemuDomainControllerIsBusy(vm, detach)) {
3104         virReportError(VIR_ERR_OPERATION_FAILED, "%s",
3105                        _("device cannot be detached: device is busy"));
3106         goto cleanup;
3107     }
3108
3109     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
3110         if (qemuAssignDeviceControllerAlias(detach) < 0)
3111             goto cleanup;
3112     }
3113
3114     qemuDomainMarkDeviceForRemoval(vm, &detach->info);
3115
3116     qemuDomainObjEnterMonitor(driver, vm);
3117     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
3118         if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) {
3119             qemuDomainObjExitMonitor(driver, vm);
3120             goto cleanup;
3121         }
3122     } else {
3123         if (qemuMonitorRemovePCIDevice(priv->mon,
3124                                        &detach->info.addr.pci) < 0) {
3125             qemuDomainObjExitMonitor(driver, vm);
3126             goto cleanup;
3127         }
3128     }
3129     qemuDomainObjExitMonitor(driver, vm);
3130
3131     if (!qemuDomainWaitForDeviceRemoval(vm))
3132         qemuDomainRemoveControllerDevice(driver, vm, detach);
3133
3134     ret = 0;
3135
3136  cleanup:
3137     qemuDomainResetDeviceRemoval(vm);
3138     return ret;
3139 }
3140
3141 static int
3142 qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver,
3143                               virDomainObjPtr vm,
3144                               virDomainHostdevDefPtr detach)
3145 {
3146     qemuDomainObjPrivatePtr priv = vm->privateData;
3147     virDomainHostdevSubsysPtr subsys = &detach->source.subsys;
3148     int ret;
3149
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);
3155         return -1;
3156     }
3157
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"));
3162         return -1;
3163     }
3164
3165     qemuDomainMarkDeviceForRemoval(vm, detach->info);
3166
3167     qemuDomainObjEnterMonitor(driver, vm);
3168     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
3169         ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
3170     } else {
3171         ret = qemuMonitorRemovePCIDevice(priv->mon, &detach->info->addr.pci);
3172     }
3173     qemuDomainObjExitMonitor(driver, vm);
3174
3175     return ret;
3176 }
3177
3178 static int
3179 qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver,
3180                               virDomainObjPtr vm,
3181                               virDomainHostdevDefPtr detach)
3182 {
3183     qemuDomainObjPrivatePtr priv = vm->privateData;
3184     int ret;
3185
3186     if (!detach->info->alias) {
3187         virReportError(VIR_ERR_OPERATION_FAILED,
3188                        "%s", _("device cannot be detached without a device alias"));
3189         return -1;
3190     }
3191
3192     if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
3193         virReportError(VIR_ERR_OPERATION_FAILED,
3194                        "%s", _("device cannot be detached with this QEMU version"));
3195         return -1;
3196     }
3197
3198     qemuDomainMarkDeviceForRemoval(vm, detach->info);
3199
3200     qemuDomainObjEnterMonitor(driver, vm);
3201     ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
3202     qemuDomainObjExitMonitor(driver, vm);
3203
3204     return ret;
3205 }
3206
3207 static int
3208 qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver,
3209                                virDomainObjPtr vm,
3210                                virDomainHostdevDefPtr detach)
3211 {
3212     qemuDomainObjPrivatePtr priv = vm->privateData;
3213     char *drvstr = NULL;
3214     char *devstr = NULL;
3215     int ret = -1;
3216
3217     if (!detach->info->alias) {
3218         virReportError(VIR_ERR_OPERATION_FAILED,
3219                        "%s", _("device cannot be detached without a device alias"));
3220         return -1;
3221     }
3222
3223     if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
3224         virReportError(VIR_ERR_OPERATION_FAILED,
3225                        "%s", _("device cannot be detached with this QEMU version"));
3226         return -1;
3227     }
3228
3229     if (!(drvstr = qemuBuildSCSIHostdevDrvStr(detach, priv->qemuCaps,
3230                                               &buildCommandLineCallbacks)))
3231         goto cleanup;
3232     if (!(devstr = qemuBuildSCSIHostdevDevStr(vm->def, detach, priv->qemuCaps)))
3233         goto cleanup;
3234
3235     qemuDomainMarkDeviceForRemoval(vm, detach->info);
3236
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",
3244                          drvstr, devstr);
3245             if (orig_err) {
3246                 virSetError(orig_err);
3247                 virFreeError(orig_err);
3248             }
3249         }
3250     }
3251     qemuDomainObjExitMonitor(driver, vm);
3252
3253  cleanup:
3254     VIR_FREE(drvstr);
3255     VIR_FREE(devstr);
3256     return ret;
3257 }
3258
3259 static int
3260 qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
3261                                virDomainObjPtr vm,
3262                                virDomainHostdevDefPtr detach)
3263 {
3264     int ret = -1;
3265
3266     switch (detach->source.subsys.type) {
3267     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
3268         ret = qemuDomainDetachHostPCIDevice(driver, vm, detach);
3269         break;
3270     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
3271         ret = qemuDomainDetachHostUSBDevice(driver, vm, detach);
3272         break;
3273     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
3274         ret = qemuDomainDetachHostSCSIDevice(driver, vm, detach);
3275         break;
3276     default:
3277         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
3278                        _("hostdev subsys type '%s' not supported"),
3279                        virDomainHostdevSubsysTypeToString(detach->source.subsys.type));
3280         return -1;
3281     }
3282
3283     if (ret < 0)
3284         virDomainAuditHostdev(vm, detach, "detach", false);
3285     else if (!qemuDomainWaitForDeviceRemoval(vm))
3286         qemuDomainRemoveHostDevice(driver, vm, detach);
3287
3288     qemuDomainResetDeviceRemoval(vm);
3289
3290     return ret;
3291 }
3292
3293 /* search for a hostdev matching dev and detach it */
3294 int qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
3295                                virDomainObjPtr vm,
3296                                virDomainDeviceDefPtr dev)
3297 {
3298     virDomainHostdevDefPtr hostdev = dev->data.hostdev;
3299     virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
3300     virDomainHostdevDefPtr detach = NULL;
3301     int idx;
3302
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));
3307         return -1;
3308     }
3309
3310     idx = virDomainHostdevFind(vm->def, hostdev, &detach);
3311
3312     if (idx < 0) {
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);
3319             break;
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);
3325             } else {
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);
3329             }
3330             break;
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);
3336             break;
3337         default:
3338             virReportError(VIR_ERR_INTERNAL_ERROR,
3339                            _("unexpected hostdev type %d"), subsys->type);
3340             break;
3341         }
3342         return -1;
3343     }
3344
3345     /* If this is a network hostdev, we need to use the higher-level detach
3346      * function so that mac address / virtualport are reset
3347      */
3348     if (detach->parent.type == VIR_DOMAIN_DEVICE_NET)
3349         return qemuDomainDetachNetDevice(driver, vm, &detach->parent);
3350     else
3351         return qemuDomainDetachThisHostDevice(driver, vm, detach);
3352 }
3353
3354 int
3355 qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
3356                           virDomainObjPtr vm,
3357                           virDomainDeviceDefPtr dev)
3358 {
3359     int detachidx, ret = -1;
3360     virDomainNetDefPtr detach = NULL;
3361     qemuDomainObjPrivatePtr priv = vm->privateData;
3362     int vlan;
3363     char *hostnet_name = NULL;
3364
3365     if ((detachidx = virDomainNetFindIdx(vm->def, dev->data.net)) < 0)
3366         goto cleanup;
3367
3368     detach = vm->def->nets[detachidx];
3369
3370     if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
3371         /* coverity[negative_returns] */
3372         ret = qemuDomainDetachThisHostDevice(driver, vm,
3373                                              virDomainNetGetActualHostdev(detach));
3374         goto cleanup;
3375     }
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"));
3382             goto cleanup;
3383         }
3384     } else {
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"));
3389             goto cleanup;
3390         }
3391
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);
3396             goto cleanup;
3397         }
3398     }
3399
3400     if ((vlan = qemuDomainNetVLAN(detach)) < 0) {
3401         virReportError(VIR_ERR_OPERATION_FAILED,
3402                        "%s", _("unable to determine original VLAN"));
3403         goto cleanup;
3404     }
3405
3406     if (virAsprintf(&hostnet_name, "host%s", detach->info.alias) < 0)
3407         goto cleanup;
3408
3409     qemuDomainMarkDeviceForRemoval(vm, &detach->info);
3410
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);
3416             goto cleanup;
3417         }
3418     } else {
3419         if (qemuMonitorRemovePCIDevice(priv->mon,
3420                                        &detach->info.addr.pci) < 0) {
3421             qemuDomainObjExitMonitor(driver, vm);
3422             virDomainAuditNet(vm, detach, NULL, "detach", false);
3423             goto cleanup;
3424         }
3425     }
3426
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);
3432             goto cleanup;
3433         }
3434     } else {
3435         if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0) {
3436             qemuDomainObjExitMonitor(driver, vm);
3437             virDomainAuditNet(vm, detach, NULL, "detach", false);
3438             goto cleanup;
3439         }
3440     }
3441     qemuDomainObjExitMonitor(driver, vm);
3442
3443     if (!qemuDomainWaitForDeviceRemoval(vm))
3444         qemuDomainRemoveNetDevice(driver, vm, detach);
3445
3446     ret = 0;
3447
3448  cleanup:
3449     qemuDomainResetDeviceRemoval(vm);
3450     VIR_FREE(hostnet_name);
3451     return ret;
3452 }
3453
3454 int
3455 qemuDomainChangeGraphicsPasswords(virQEMUDriverPtr driver,
3456                                   virDomainObjPtr vm,
3457                                   int type,
3458                                   virDomainGraphicsAuthDefPtr auth,
3459                                   const char *defaultPasswd)
3460 {
3461     qemuDomainObjPrivatePtr priv = vm->privateData;
3462     time_t now = time(NULL);
3463     char expire_time [64];
3464     const char *connected = NULL;
3465     int ret = -1;
3466     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
3467
3468     if (!auth->passwd && !defaultPasswd) {
3469         ret = 0;
3470         goto cleanup;
3471     }
3472
3473     if (auth->connected)
3474         connected = virDomainGraphicsAuthConnectedTypeToString(auth->connected);
3475
3476     qemuDomainObjEnterMonitor(driver, vm);
3477     ret = qemuMonitorSetPassword(priv->mon,
3478                                  type,
3479                                  auth->passwd ? auth->passwd : defaultPasswd,
3480                                  connected);
3481
3482     if (ret == -2) {
3483         if (type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
3484             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3485                            _("Graphics password only supported for VNC"));
3486             ret = -1;
3487         } else {
3488             ret = qemuMonitorSetVNCPassword(priv->mon,
3489                                             auth->passwd ? auth->passwd : defaultPasswd);
3490         }
3491     }
3492     if (ret != 0)
3493         goto end_job;
3494
3495     if (auth->expires) {
3496         time_t lifetime = auth->validTo - now;
3497         if (lifetime <= 0)
3498             snprintf(expire_time, sizeof(expire_time), "now");
3499         else
3500             snprintf(expire_time, sizeof(expire_time), "%lu", (long unsigned)auth->validTo);
3501     } else {
3502         snprintf(expire_time, sizeof(expire_time), "never");
3503     }
3504
3505     ret = qemuMonitorExpirePassword(priv->mon, type, expire_time);
3506
3507     if (ret == -2) {
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"));
3512             ret = -1;
3513         } else {
3514             ret = 0;
3515         }
3516     }
3517
3518  end_job:
3519     qemuDomainObjExitMonitor(driver, vm);
3520  cleanup:
3521     virObjectUnref(cfg);
3522     return ret;
3523 }
3524
3525 int qemuDomainAttachLease(virQEMUDriverPtr driver,
3526                           virDomainObjPtr vm,
3527                           virDomainLeaseDefPtr lease)
3528 {
3529     int ret = -1;
3530     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
3531
3532     if (virDomainLeaseInsertPreAlloc(vm->def) < 0)
3533         goto cleanup;
3534
3535     if (virDomainLockLeaseAttach(driver->lockManager, cfg->uri,
3536                                  vm, lease) < 0) {
3537         virDomainLeaseInsertPreAlloced(vm->def, NULL);
3538         goto cleanup;
3539     }
3540
3541     virDomainLeaseInsertPreAlloced(vm->def, lease);
3542     ret = 0;
3543
3544  cleanup:
3545     virObjectUnref(cfg);
3546     return ret;
3547 }
3548
3549 int qemuDomainDetachLease(virQEMUDriverPtr driver,
3550                           virDomainObjPtr vm,
3551                           virDomainLeaseDefPtr lease)
3552 {
3553     virDomainLeaseDefPtr det_lease;
3554     int idx;
3555
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));
3560         return -1;
3561     }
3562
3563     if (virDomainLockLeaseDetach(driver->lockManager, vm, lease) < 0)
3564         return -1;
3565
3566     det_lease = virDomainLeaseRemoveAt(vm->def, idx);
3567     virDomainLeaseDefFree(det_lease);
3568     return 0;
3569 }
3570
3571 int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
3572                               virDomainObjPtr vm,
3573                               virDomainChrDefPtr chr)
3574 {
3575     int ret = -1;
3576     qemuDomainObjPrivatePtr priv = vm->privateData;
3577     virDomainDefPtr vmdef = vm->def;
3578     virDomainChrDefPtr tmpChr;
3579     char *charAlias = NULL;
3580     char *devstr = NULL;
3581
3582     if (!(tmpChr = virDomainChrFind(vmdef, chr))) {
3583         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
3584                        _("device not present in domain configuration"));
3585         return ret;
3586     }
3587
3588     if (qemuBuildChrDeviceStr(&devstr, vm->def, chr, priv->qemuCaps) < 0)
3589         return ret;
3590
3591     if (virAsprintf(&charAlias, "char%s", tmpChr->info.alias) < 0)
3592         goto cleanup;
3593
3594     qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info);
3595
3596     qemuDomainObjEnterMonitor(driver, vm);
3597     if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) {
3598         qemuDomainObjExitMonitor(driver, vm);
3599         goto cleanup;
3600     }
3601
3602     if (qemuMonitorDetachCharDev(priv->mon, charAlias) < 0) {
3603         qemuDomainObjExitMonitor(driver, vm);
3604         goto cleanup;
3605     }
3606     qemuDomainObjExitMonitor(driver, vm);
3607
3608     if (!qemuDomainWaitForDeviceRemoval(vm))
3609         qemuDomainRemoveChrDevice(driver, vm, tmpChr);
3610     ret = 0;
3611
3612  cleanup:
3613     qemuDomainResetDeviceRemoval(vm);
3614     VIR_FREE(devstr);
3615     VIR_FREE(charAlias);
3616     return ret;
3617 }