1 /*
2 * qemu_hotplug.c: QEMU device hotplug management
3 *
4 * Copyright (C) 2006-2016 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
22
23 #include <config.h>
24
25 #include "qemu_hotplug.h"
26 #include "qemu_alias.h"
27 #include "qemu_capabilities.h"
28 #include "qemu_domain.h"
29 #include "qemu_domain_address.h"
30 #include "qemu_namespace.h"
31 #include "qemu_command.h"
32 #include "qemu_hostdev.h"
33 #include "qemu_interface.h"
34 #include "qemu_process.h"
35 #include "qemu_security.h"
36 #include "qemu_block.h"
37 #include "qemu_snapshot.h"
38 #include "qemu_virtiofs.h"
39 #include "domain_audit.h"
40 #include "netdev_bandwidth_conf.h"
41 #include "domain_nwfilter.h"
42 #include "virlog.h"
43 #include "datatypes.h"
44 #include "virerror.h"
45 #include "viralloc.h"
46 #include "virpci.h"
47 #include "virfile.h"
48 #include "virprocess.h"
49 #include "qemu_cgroup.h"
50 #include "locking/domain_lock.h"
51 #include "virnetdev.h"
52 #include "virnetdevbridge.h"
53 #include "virnetdevtap.h"
54 #include "virnetdevopenvswitch.h"
55 #include "virnetdevmidonet.h"
56 #include "device_conf.h"
57 #include "storage_source.h"
58 #include "storage_source_conf.h"
59 #include "virstring.h"
60 #include "virtime.h"
61 #include "virqemu.h"
62
63 #define VIR_FROM_THIS VIR_FROM_QEMU
64
65 VIR_LOG_INIT("qemu.qemu_hotplug");
66
67 #define CHANGE_MEDIA_TIMEOUT 5000
68
69 /* Timeout in milliseconds for device removal. PPC64 domains
70 * can experience a bigger delay in unplug operations during
71 * heavy guest activity (vcpu being the most notable case), thus
72 * the timeout for PPC64 is also bigger. */
73 #define QEMU_UNPLUG_TIMEOUT 1000ull * 5
74 #define QEMU_UNPLUG_TIMEOUT_PPC64 1000ull * 10
75
76
77 static void
78 qemuDomainResetDeviceRemoval(virDomainObj *vm);
79
80 /**
81 * qemuDomainDeleteDevice:
82 * @vm: domain object
83 * @alias: device to remove
84 *
85 * This is a wrapper over qemuMonitorDelDevice() plus enter/exit
86 * monitor calls. This function MUST be used instead of plain
87 * qemuMonitorDelDevice() in all places where @alias represents a
88 * device from domain XML, i.e. caller marks the device for
89 * removal and then calls qemuDomainWaitForDeviceRemoval()
90 * followed by qemuDomainRemove*Device().
91 *
92 * For collateral devices (e.g. extension devices like zPCI) it
93 * is safe to use plain qemuMonitorDelDevice().
94 *
95 * Upon entry, @vm must be locked.
96 *
97 * Returns: 0 on success,
98 * -1 otherwise.
99 */
100 static int
qemuDomainDeleteDevice(virDomainObj * vm,const char * alias)101 qemuDomainDeleteDevice(virDomainObj *vm,
102 const char *alias)
103 {
104 qemuDomainObjPrivate *priv = vm->privateData;
105 virQEMUDriver *driver = priv->driver;
106 int rc;
107
108 qemuDomainObjEnterMonitor(driver, vm);
109
110 rc = qemuMonitorDelDevice(priv->mon, alias);
111
112 if (qemuDomainObjExitMonitor(driver, vm) < 0) {
113 /* Domain is no longer running. No cleanup needed. */
114 return -1;
115 }
116
117 if (rc < 0) {
118 /* Deleting device failed. Let's check if DEVICE_DELETED
119 * even arrived. If it did, we need to claim success to
120 * make the caller remove device from domain XML. */
121
122 if (priv->unplug.eventSeen) {
123 /* The event arrived. Return success. */
124 VIR_DEBUG("Detaching of device %s failed, but event arrived", alias);
125 qemuDomainResetDeviceRemoval(vm);
126 rc = 0;
127 } else if (rc == -2) {
128 /* The device does not exist in qemu, but it still
129 * exists in libvirt. Claim success to make caller
130 * qemuDomainWaitForDeviceRemoval(). Otherwise if
131 * domain XML is queried right after detach API the
132 * device would still be there. */
133 VIR_DEBUG("Detaching of device %s failed and no event arrived", alias);
134 rc = 0;
135 }
136 }
137
138 return rc;
139 }
140
141
142 static int
qemuDomainDetachZPCIDevice(qemuMonitor * mon,virDomainDeviceInfo * info)143 qemuDomainDetachZPCIDevice(qemuMonitor *mon,
144 virDomainDeviceInfo *info)
145 {
146 g_autofree char *zpciAlias = NULL;
147
148 zpciAlias = g_strdup_printf("zpci%d", info->addr.pci.zpci.uid.value);
149
150 if (qemuMonitorDelDevice(mon, zpciAlias) < 0)
151 return -1;
152
153 return 0;
154 }
155
156
157 static int
qemuDomainAttachExtensionDevice(qemuMonitor * mon,virDomainDeviceInfo * info)158 qemuDomainAttachExtensionDevice(qemuMonitor *mon,
159 virDomainDeviceInfo *info)
160 {
161 if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI ||
162 info->addr.pci.extFlags == VIR_PCI_ADDRESS_EXTENSION_NONE) {
163 return 0;
164 }
165
166 if (info->addr.pci.extFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI) {
167 g_autoptr(virJSONValue) devprops = NULL;
168
169 if (!(devprops = qemuBuildZPCIDevProps(info)))
170 return -1;
171
172 if (qemuMonitorAddDeviceProps(mon, &devprops) < 0)
173 return -1;
174 }
175
176 return 0;
177 }
178
179
180 static int
qemuDomainDetachExtensionDevice(qemuMonitor * mon,virDomainDeviceInfo * info)181 qemuDomainDetachExtensionDevice(qemuMonitor *mon,
182 virDomainDeviceInfo *info)
183 {
184 if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI ||
185 info->addr.pci.extFlags == VIR_PCI_ADDRESS_EXTENSION_NONE) {
186 return 0;
187 }
188
189 if (info->addr.pci.extFlags & VIR_PCI_ADDRESS_EXTENSION_ZPCI)
190 return qemuDomainDetachZPCIDevice(mon, info);
191
192 return 0;
193 }
194
195
196 static int
qemuHotplugChardevAttach(qemuMonitor * mon,const char * alias,virDomainChrSourceDef * def)197 qemuHotplugChardevAttach(qemuMonitor *mon,
198 const char *alias,
199 virDomainChrSourceDef *def)
200 {
201 return qemuMonitorAttachCharDev(mon, alias, def);
202 }
203
204
205 static int
qemuHotplugWaitForTrayEject(virDomainObj * vm,virDomainDiskDef * disk)206 qemuHotplugWaitForTrayEject(virDomainObj *vm,
207 virDomainDiskDef *disk)
208 {
209 unsigned long long now;
210 int rc;
211
212 if (virTimeMillisNow(&now) < 0)
213 return -1;
214
215 while (disk->tray_status != VIR_DOMAIN_DISK_TRAY_OPEN) {
216 if ((rc = virDomainObjWaitUntil(vm, now + CHANGE_MEDIA_TIMEOUT)) < 0)
217 return -1;
218
219 if (rc > 0) {
220 /* the caller called qemuMonitorEjectMedia which usually reports an
221 * error. Report the failure in an off-chance that it didn't. */
222 if (virGetLastErrorCode() == VIR_ERR_OK) {
223 virReportError(VIR_ERR_OPERATION_FAILED,
224 _("timed out waiting to open tray of '%s'"),
225 disk->dst);
226 }
227 return -1;
228 }
229 }
230
231 return 0;
232 }
233
234
235 /**
236 * qemuDomainChangeMediaLegacy:
237 * @driver: qemu driver structure
238 * @vm: domain definition
239 * @disk: disk definition to change the source of
240 * @newsrc: new disk source to change to
241 * @force: force the change of media
242 *
243 * Change the media in an ejectable device to the one described by
244 * @newsrc. This function also removes the old source from the
245 * shared device table if appropriate. Note that newsrc is consumed
246 * on success and the old source is freed on success.
247 *
248 * Returns 0 on success, -1 on error and reports libvirt error
249 */
250 static int
qemuDomainChangeMediaLegacy(virQEMUDriver * driver,virDomainObj * vm,virDomainDiskDef * disk,virStorageSource * newsrc,bool force)251 qemuDomainChangeMediaLegacy(virQEMUDriver *driver,
252 virDomainObj *vm,
253 virDomainDiskDef *disk,
254 virStorageSource *newsrc,
255 bool force)
256 {
257 int rc;
258 g_autofree char *driveAlias = NULL;
259 qemuDomainObjPrivate *priv = vm->privateData;
260 qemuDomainDiskPrivate *diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
261 const char *format = NULL;
262 g_autofree char *sourcestr = NULL;
263
264 if (!disk->info.alias) {
265 virReportError(VIR_ERR_INTERNAL_ERROR,
266 _("missing disk device alias name for %s"), disk->dst);
267 return -1;
268 }
269
270 if (!(driveAlias = qemuAliasDiskDriveFromDisk(disk)))
271 return -1;
272
273 qemuDomainObjEnterMonitor(driver, vm);
274 rc = qemuMonitorEjectMedia(priv->mon, driveAlias, force);
275 if (qemuDomainObjExitMonitor(driver, vm) < 0)
276 return -1;
277
278 /* If the tray is present wait for it to open. */
279 if (!force && diskPriv->tray) {
280 rc = qemuHotplugWaitForTrayEject(vm, disk);
281 if (rc < 0)
282 return -1;
283
284 /* re-issue ejection command to pop out the media */
285 qemuDomainObjEnterMonitor(driver, vm);
286 rc = qemuMonitorEjectMedia(priv->mon, driveAlias, false);
287 if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
288 return -1;
289
290 } else {
291 /* otherwise report possible errors from the attempt to eject the media */
292 if (rc < 0)
293 return -1;
294 }
295
296 if (!virStorageSourceIsEmpty(newsrc)) {
297 if (qemuGetDriveSourceString(newsrc, NULL, &sourcestr) < 0)
298 return -1;
299
300 if (virStorageSourceGetActualType(newsrc) != VIR_STORAGE_TYPE_DIR)
301 format = virStorageFileFormatTypeToString(newsrc->format);
302
303 qemuDomainObjEnterMonitor(driver, vm);
304 rc = qemuMonitorChangeMedia(priv->mon,
305 driveAlias,
306 sourcestr,
307 format);
308 if (qemuDomainObjExitMonitor(driver, vm) < 0)
309 return -1;
310 }
311
312 if (rc < 0)
313 return -1;
314
315 return 0;
316 }
317
318
319 /**
320 * qemuHotplugAttachDBusVMState:
321 * @driver: QEMU driver object
322 * @vm: domain object
323 * @asyncJob: asynchronous job identifier
324 *
325 * Add -object dbus-vmstate if necessary.
326 *
327 * Returns: 0 on success, -1 on error.
328 */
329 int
qemuHotplugAttachDBusVMState(virQEMUDriver * driver,virDomainObj * vm,qemuDomainAsyncJob asyncJob)330 qemuHotplugAttachDBusVMState(virQEMUDriver *driver,
331 virDomainObj *vm,
332 qemuDomainAsyncJob asyncJob)
333 {
334 qemuDomainObjPrivate *priv = vm->privateData;
335 g_autoptr(virJSONValue) props = NULL;
336 int ret;
337
338 if (priv->dbusVMState)
339 return 0;
340
341 if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DBUS_VMSTATE)) {
342 VIR_DEBUG("dbus-vmstate object is not supported by this QEMU binary");
343 return 0;
344 }
345
346 if (!(props = qemuBuildDBusVMStateInfoProps(driver, vm)))
347 return -1;
348
349 if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
350 return -1;
351
352 ret = qemuMonitorAddObject(priv->mon, &props, NULL);
353
354 if (ret == 0)
355 priv->dbusVMState = true;
356
357 if (qemuDomainObjExitMonitor(driver, vm) < 0)
358 return -1;
359
360 return ret;
361 }
362
363
364 /**
365 * qemuHotplugRemoveDBusVMState:
366 * @driver: QEMU driver object
367 * @vm: domain object
368 * @asyncJob: asynchronous job identifier
369 *
370 * Remove -object dbus-vmstate from @vm if the configuration does not require
371 * it any more.
372 *
373 * Returns: 0 on success, -1 on error.
374 */
375 int
qemuHotplugRemoveDBusVMState(virQEMUDriver * driver,virDomainObj * vm,qemuDomainAsyncJob asyncJob)376 qemuHotplugRemoveDBusVMState(virQEMUDriver *driver,
377 virDomainObj *vm,
378 qemuDomainAsyncJob asyncJob)
379 {
380 qemuDomainObjPrivate *priv = vm->privateData;
381 int ret;
382
383 if (!priv->dbusVMState)
384 return 0;
385
386 if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
387 return -1;
388
389 ret = qemuMonitorDelObject(priv->mon, qemuDomainGetDBusVMStateAlias(), true);
390
391 if (ret == 0)
392 priv->dbusVMState = false;
393
394 if (qemuDomainObjExitMonitor(driver, vm) < 0)
395 return -1;
396
397 return ret;
398 }
399
400
401 /**
402 * qemuHotplugAttachManagedPR:
403 * @driver: QEMU driver object
404 * @vm: domain object
405 * @src: new disk source to be attached to @vm
406 * @asyncJob: asynchronous job identifier
407 *
408 * Checks if it's needed to start qemu-pr-helper and add the corresponding
409 * pr-manager-helper object.
410 *
411 * Returns: 0 on success, -1 on error.
412 */
413 static int
qemuHotplugAttachManagedPR(virQEMUDriver * driver,virDomainObj * vm,virStorageSource * src,qemuDomainAsyncJob asyncJob)414 qemuHotplugAttachManagedPR(virQEMUDriver *driver,
415 virDomainObj *vm,
416 virStorageSource *src,
417 qemuDomainAsyncJob asyncJob)
418 {
419 qemuDomainObjPrivate *priv = vm->privateData;
420 virJSONValue *props = NULL;
421 bool daemonStarted = false;
422 int ret = -1;
423 int rc;
424
425 if (priv->prDaemonRunning ||
426 !virStorageSourceChainHasManagedPR(src))
427 return 0;
428
429 if (!(props = qemuBuildPRManagedManagerInfoProps(priv)))
430 return -1;
431
432 if (qemuProcessStartManagedPRDaemon(vm) < 0)
433 goto cleanup;
434
435 daemonStarted = true;
436
437 if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
438 goto cleanup;
439
440 rc = qemuMonitorAddObject(priv->mon, &props, NULL);
441
442 if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
443 goto cleanup;
444
445 ret = 0;
446
447 cleanup:
448 if (ret < 0 && daemonStarted)
449 qemuProcessKillManagedPRDaemon(vm);
450 virJSONValueFree(props);
451 return ret;
452 }
453
454
455 /**
456 * qemuHotplugRemoveManagedPR:
457 * @driver: QEMU driver object
458 * @vm: domain object
459 * @asyncJob: asynchronous job identifier
460 *
461 * Removes the managed PR object from @vm if the configuration does not require
462 * it any more.
463 */
464 static int
qemuHotplugRemoveManagedPR(virQEMUDriver * driver,virDomainObj * vm,qemuDomainAsyncJob asyncJob)465 qemuHotplugRemoveManagedPR(virQEMUDriver *driver,
466 virDomainObj *vm,
467 qemuDomainAsyncJob asyncJob)
468 {
469 qemuDomainObjPrivate *priv = vm->privateData;
470 virErrorPtr orig_err;
471 int ret = -1;
472
473 if (qemuDomainDefHasManagedPR(vm))
474 return 0;
475
476 virErrorPreserveLast(&orig_err);
477
478 if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
479 goto cleanup;
480 ignore_value(qemuMonitorDelObject(priv->mon, qemuDomainGetManagedPRAlias(),
481 false));
482 if (qemuDomainObjExitMonitor(driver, vm) < 0)
483 goto cleanup;
484
485 qemuProcessKillManagedPRDaemon(vm);
486
487 ret = 0;
488 cleanup:
489 virErrorRestore(&orig_err);
490 return ret;
491 }
492
493
494 /**
495 * qemuDomainChangeMediaBlockdev:
496 * @driver: qemu driver structure
497 * @vm: domain definition
498 * @disk: disk definition to change the source of
499 * @oldsrc: old source definition
500 * @newsrc: new disk source to change to
501 * @force: force the change of media
502 *
503 * Change the media in an ejectable device to the one described by
504 * @newsrc. This function also removes the old source from the
505 * shared device table if appropriate. Note that newsrc is consumed
506 * on success and the old source is freed on success.
507 *
508 * Returns 0 on success, -1 on error and reports libvirt error
509 */
510 static int
qemuDomainChangeMediaBlockdev(virQEMUDriver * driver,virDomainObj * vm,virDomainDiskDef * disk,virStorageSource * oldsrc,virStorageSource * newsrc,bool force)511 qemuDomainChangeMediaBlockdev(virQEMUDriver *driver,
512 virDomainObj *vm,
513 virDomainDiskDef *disk,
514 virStorageSource *oldsrc,
515 virStorageSource *newsrc,
516 bool force)
517 {
518 qemuDomainObjPrivate *priv = vm->privateData;
519 qemuDomainDiskPrivate *diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
520 g_autoptr(qemuBlockStorageSourceChainData) newbackend = NULL;
521 g_autoptr(qemuBlockStorageSourceChainData) oldbackend = NULL;
522 g_autofree char *nodename = NULL;
523 int rc;
524
525 if (!virStorageSourceIsEmpty(oldsrc) &&
526 !(oldbackend = qemuBlockStorageSourceChainDetachPrepareBlockdev(oldsrc)))
527 return -1;
528
529 if (!virStorageSourceIsEmpty(newsrc)) {
530 if (!(newbackend = qemuBuildStorageSourceChainAttachPrepareBlockdev(newsrc)))
531 return -1;
532
533 if (qemuDomainDiskGetBackendAlias(disk, priv->qemuCaps, &nodename) < 0)
534 return -1;
535 }
536
537 if (diskPriv->tray && disk->tray_status != VIR_DOMAIN_DISK_TRAY_OPEN) {
538 qemuDomainObjEnterMonitor(driver, vm);
539 rc = qemuMonitorBlockdevTrayOpen(priv->mon, diskPriv->qomName, force);
540 if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
541 return -1;
542
543 if (!force && qemuHotplugWaitForTrayEject(vm, disk) < 0)
544 return -1;
545 }
546
547 qemuDomainObjEnterMonitor(driver, vm);
548
549 rc = qemuMonitorBlockdevMediumRemove(priv->mon, diskPriv->qomName);
550
551 if (rc == 0 && oldbackend)
552 qemuBlockStorageSourceChainDetach(priv->mon, oldbackend);
553
554 if (newbackend && nodename) {
555 if (rc == 0)
556 rc = qemuBlockStorageSourceChainAttach(priv->mon, newbackend);
557
558 if (rc == 0)
559 rc = qemuMonitorBlockdevMediumInsert(priv->mon, diskPriv->qomName,
560 nodename);
561 }
562
563 /* set throttling for the new image */
564 if (rc == 0 &&
565 !virStorageSourceIsEmpty(newsrc) &&
566 qemuDiskConfigBlkdeviotuneEnabled(disk)) {
567 rc = qemuMonitorSetBlockIoThrottle(priv->mon, NULL,
568 diskPriv->qomName,
569 &disk->blkdeviotune);
570 }
571
572 if (rc == 0)
573 rc = qemuMonitorBlockdevTrayClose(priv->mon, diskPriv->qomName);
574
575 if (rc < 0 && newbackend)
576 qemuBlockStorageSourceChainDetach(priv->mon, newbackend);
577
578 if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
579 return -1;
580
581 return 0;
582 }
583
584
585 /**
586 * qemuDomainChangeEjectableMedia:
587 * @driver: qemu driver structure
588 * @vm: domain definition
589 * @disk: disk definition to change the source of
590 * @newsrc: new disk source to change to
591 * @force: force the change of media
592 *
593 * Change the media in an ejectable device to the one described by
594 * @newsrc. This function also removes the old source from the
595 * shared device table if appropriate. Note that newsrc is consumed
596 * on success and the old source is freed on success.
597 *
598 * Returns 0 on success, -1 on error and reports libvirt error
599 */
600 int
qemuDomainChangeEjectableMedia(virQEMUDriver * driver,virDomainObj * vm,virDomainDiskDef * disk,virStorageSource * newsrc,bool force)601 qemuDomainChangeEjectableMedia(virQEMUDriver *driver,
602 virDomainObj *vm,
603 virDomainDiskDef *disk,
604 virStorageSource *newsrc,
605 bool force)
606 {
607 g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
608 qemuDomainObjPrivate *priv = vm->privateData;
609 virStorageSource *oldsrc = disk->src;
610 qemuDomainDiskPrivate *diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
611 bool sharedAdded = false;
612 bool managedpr = virStorageSourceChainHasManagedPR(oldsrc) ||
613 virStorageSourceChainHasManagedPR(newsrc);
614 int ret = -1;
615 int rc;
616
617 if (diskPriv->blockjob && qemuBlockJobIsRunning(diskPriv->blockjob)) {
618 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
619 _("can't change media while a block job is running on the device"));
620 return -1;
621 }
622
623 disk->src = newsrc;
624
625 if (virDomainDiskTranslateSourcePool(disk) < 0)
626 goto cleanup;
627
628 if (qemuAddSharedDisk(driver, disk, vm->def->name) < 0)
629 goto cleanup;
630
631 sharedAdded = true;
632
633 if (qemuDomainDetermineDiskChain(driver, vm, disk, NULL, true) < 0)
634 goto cleanup;
635
636 if (qemuDomainPrepareDiskSource(disk, priv, cfg) < 0)
637 goto cleanup;
638
639 if (qemuDomainStorageSourceChainAccessAllow(driver, vm, newsrc) < 0)
640 goto cleanup;
641
642 if (qemuHotplugAttachManagedPR(driver, vm, newsrc, QEMU_ASYNC_JOB_NONE) < 0)
643 goto cleanup;
644
645 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV))
646 rc = qemuDomainChangeMediaBlockdev(driver, vm, disk, oldsrc, newsrc, force);
647 else
648 rc = qemuDomainChangeMediaLegacy(driver, vm, disk, newsrc, force);
649
650 virDomainAuditDisk(vm, oldsrc, newsrc, "update", rc >= 0);
651
652 if (rc < 0)
653 goto cleanup;
654
655 /* remove the old source from shared device list */
656 disk->src = oldsrc;
657 ignore_value(qemuRemoveSharedDisk(driver, disk, vm->def->name));
658 ignore_value(qemuDomainStorageSourceChainAccessRevoke(driver, vm, oldsrc));
659
660 /* media was changed, so we can remove the old media definition now */
661 virObjectUnref(oldsrc);
662 oldsrc = NULL;
663 disk->src = newsrc;
664
665 ret = 0;
666
667 cleanup:
668 /* undo changes to the new disk */
669 if (ret < 0) {
670 if (sharedAdded)
671 ignore_value(qemuRemoveSharedDisk(driver, disk, vm->def->name));
672
673 ignore_value(qemuDomainStorageSourceChainAccessRevoke(driver, vm, newsrc));
674 }
675
676 /* remove PR manager object if unneeded */
677 if (managedpr)
678 ignore_value(qemuHotplugRemoveManagedPR(driver, vm, QEMU_ASYNC_JOB_NONE));
679
680 /* revert old image do the disk definition */
681 if (oldsrc)
682 disk->src = oldsrc;
683
684 return ret;
685 }
686
687
688 static qemuSnapshotDiskContext *
qemuDomainAttachDiskGenericTransient(virDomainObj * vm,virDomainDiskDef * disk,GHashTable * blockNamedNodeData,qemuDomainAsyncJob asyncJob)689 qemuDomainAttachDiskGenericTransient(virDomainObj *vm,
690 virDomainDiskDef *disk,
691 GHashTable *blockNamedNodeData,
692 qemuDomainAsyncJob asyncJob)
693 {
694 g_autoptr(qemuSnapshotDiskContext) snapctxt = NULL;
695 g_autoptr(virDomainSnapshotDiskDef) snapdiskdef = NULL;
696
697 if (!(snapdiskdef = qemuSnapshotGetTransientDiskDef(disk, vm->def->name)))
698 return NULL;
699
700 snapctxt = qemuSnapshotDiskContextNew(1, vm, asyncJob);
701
702 if (qemuSnapshotDiskPrepareOne(snapctxt, disk, snapdiskdef,
703 blockNamedNodeData, false, false) < 0)
704 return NULL;
705
706 return g_steal_pointer(&snapctxt);
707 }
708
709
710 /**
711 * qemuDomainAttachDiskGeneric:
712 *
713 * Attaches disk to a VM. This function aggregates common code for all bus types.
714 * In cases when the VM crashed while adding the disk, -2 is returned. */
715 int
qemuDomainAttachDiskGeneric(virQEMUDriver * driver,virDomainObj * vm,virDomainDiskDef * disk,qemuDomainAsyncJob asyncJob)716 qemuDomainAttachDiskGeneric(virQEMUDriver *driver,
717 virDomainObj *vm,
718 virDomainDiskDef *disk,
719 qemuDomainAsyncJob asyncJob)
720 {
721 g_autoptr(qemuBlockStorageSourceChainData) data = NULL;
722 qemuDomainObjPrivate *priv = vm->privateData;
723 g_autoptr(virJSONValue) devprops = NULL;
724 bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);
725 bool extensionDeviceAttached = false;
726 int rc;
727 g_autoptr(qemuSnapshotDiskContext) transientDiskSnapshotCtxt = NULL;
728 bool origReadonly = disk->src->readonly;
729
730 if (disk->transient)
731 disk->src->readonly = true;
732
733 if (virStorageSourceGetActualType(disk->src) == VIR_STORAGE_TYPE_VHOST_USER) {
734 if (!(data = qemuBuildStorageSourceChainAttachPrepareChardev(disk)))
735 return -1;
736 } else if (blockdev) {
737 if (!(data = qemuBuildStorageSourceChainAttachPrepareBlockdev(disk->src)))
738 return -1;
739
740 if (disk->copy_on_read == VIR_TRISTATE_SWITCH_ON) {
741 if (!(data->copyOnReadProps = qemuBlockStorageGetCopyOnReadProps(disk)))
742 return -1;
743
744 data->copyOnReadNodename = g_strdup(QEMU_DOMAIN_DISK_PRIVATE(disk)->nodeCopyOnRead);
745 }
746
747 } else {
748 if (!(data = qemuBuildStorageSourceChainAttachPrepareDrive(disk,
749 priv->qemuCaps)))
750 return -1;
751 }
752
753 disk->src->readonly = origReadonly;
754
755 if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
756 return -1;
757
758 rc = qemuBlockStorageSourceChainAttach(priv->mon, data);
759
760 if (qemuDomainObjExitMonitor(driver, vm) < 0)
761 return -2;
762
763 if (rc < 0)
764 goto rollback;
765
766 if (disk->transient) {
767 g_autoptr(qemuBlockStorageSourceAttachData) backend = NULL;
768 g_autoptr(GHashTable) blockNamedNodeData = NULL;
769
770 if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, asyncJob)))
771 goto rollback;
772
773 if (!(transientDiskSnapshotCtxt = qemuDomainAttachDiskGenericTransient(vm, disk, blockNamedNodeData, asyncJob)))
774 goto rollback;
775
776
777 if (qemuSnapshotDiskCreate(transientDiskSnapshotCtxt) < 0)
778 goto rollback;
779
780 QEMU_DOMAIN_DISK_PRIVATE(disk)->transientOverlayCreated = true;
781 backend = qemuBlockStorageSourceDetachPrepare(disk->src, NULL);
782 ignore_value(VIR_INSERT_ELEMENT(data->srcdata, 0, data->nsrcdata, backend));
783 }
784
785 if (!(devprops = qemuBuildDiskDeviceProps(vm->def, disk, priv->qemuCaps)))
786 goto rollback;
787
788 if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
789 goto rollback;
790
791 if ((rc = qemuDomainAttachExtensionDevice(priv->mon, &disk->info)) == 0)
792 extensionDeviceAttached = true;
793
794 if (rc == 0)
795 rc = qemuMonitorAddDeviceProps(priv->mon, &devprops);
796
797 /* Setup throttling of disk via block_set_io_throttle QMP command. This
798 * is a hack until the 'throttle' blockdev driver will support modification
799 * of the trhottle group. See also qemuProcessSetupDiskThrottlingBlockdev.
800 * As there isn't anything sane to do if this fails, let's just return
801 * success.
802 */
803 if (blockdev && rc == 0 &&
804 qemuDiskConfigBlkdeviotuneEnabled(disk)) {
805 qemuDomainDiskPrivate *diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
806 if (qemuMonitorSetBlockIoThrottle(priv->mon, NULL, diskPriv->qomName,
807 &disk->blkdeviotune) < 0)
808 VIR_WARN("failed to set blkdeviotune for '%s' of '%s'", disk->dst, vm->def->name);
809 }
810
811 if (qemuDomainObjExitMonitor(driver, vm) < 0)
812 return -2;
813
814 if (rc < 0)
815 goto rollback;
816
817 return 0;
818
819 rollback:
820 if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
821 return -1;
822
823 if (extensionDeviceAttached)
824 ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &disk->info));
825
826 qemuBlockStorageSourceChainDetach(priv->mon, data);
827
828 if (qemuDomainObjExitMonitor(driver, vm) < 0)
829 return -2;
830
831 return -1;
832 }
833
834
qemuDomainAttachControllerDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainControllerDef * controller)835 int qemuDomainAttachControllerDevice(virQEMUDriver *driver,
836 virDomainObj *vm,
837 virDomainControllerDef *controller)
838 {
839 int ret = -1;
840 const char* type = virDomainControllerTypeToString(controller->type);
841 g_autoptr(virJSONValue) devprops = NULL;
842 qemuDomainObjPrivate *priv = vm->privateData;
843 virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_CONTROLLER,
844 { .controller = controller } };
845 bool releaseaddr = false;
846
847 if (controller->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
848 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
849 _("'%s' controller cannot be hot plugged."),
850 virDomainControllerTypeToString(controller->type));
851 return -1;
852 }
853
854 /* default idx would normally be set by virDomainDefPostParse(),
855 * which isn't called in the case of live attach of a single
856 * device.
857 */
858 if (controller->idx == -1)
859 controller->idx = virDomainControllerFindUnusedIndex(vm->def,
860 controller->type);
861
862 if (virDomainControllerFind(vm->def, controller->type, controller->idx) >= 0) {
863 virReportError(VIR_ERR_OPERATION_FAILED,
864 _("target %s:%d already exists"),
865 type, controller->idx);
866 return -1;
867 }
868
869 if (qemuDomainEnsureVirtioAddress(&releaseaddr, vm, &dev) < 0)
870 return -1;
871
872 qemuAssignDeviceControllerAlias(vm->def, controller);
873
874 if (qemuBuildControllerDevProps(vm->def, controller, priv->qemuCaps, &devprops) < 0)
875 goto cleanup;
876
877 if (!devprops)
878 goto cleanup;
879
880 VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers+1);
881
882 qemuDomainObjEnterMonitor(driver, vm);
883
884 if ((ret = qemuDomainAttachExtensionDevice(priv->mon,
885 &controller->info)) < 0) {
886 goto exit_monitor;
887 }
888
889 if ((ret = qemuMonitorAddDeviceProps(priv->mon, &devprops)) < 0)
890 ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &controller->info));
891
892 exit_monitor:
893 if (qemuDomainObjExitMonitor(driver, vm) < 0) {
894 releaseaddr = false;
895 ret = -1;
896 goto cleanup;
897 }
898
899 if (ret == 0)
900 virDomainControllerInsertPreAlloced(vm->def, controller);
901
902 cleanup:
903 if (ret != 0 && releaseaddr)
904 qemuDomainReleaseDeviceAddress(vm, &controller->info);
905
906 return ret;
907 }
908
909 static virDomainControllerDef *
qemuDomainFindOrCreateSCSIDiskController(virQEMUDriver * driver,virDomainObj * vm,int controller)910 qemuDomainFindOrCreateSCSIDiskController(virQEMUDriver *driver,
911 virDomainObj *vm,
912 int controller)
913 {
914 size_t i;
915 virDomainControllerDef *cont;
916 qemuDomainObjPrivate *priv = vm->privateData;
917 int model = -1;
918
919 for (i = 0; i < vm->def->ncontrollers; i++) {
920 cont = vm->def->controllers[i];
921
922 if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
923 continue;
924
925 if (cont->idx == controller)
926 return cont;
927
928 /* Because virDomainHostdevAssignAddress called during
929 * virDomainHostdevDefPostParse cannot add a new controller
930 * it will assign a controller index to a controller that doesn't
931 * exist leaving this code to perform the magic of adding the
932 * controller. Because that code would be attempting to add a
933 * SCSI disk to an existing controller, let's save the model
934 * of the "last" SCSI controller we find so that if we end up
935 * creating a controller below it uses the same controller model. */
936 model = cont->model;
937 }
938
939 /* No SCSI controller present, for backward compatibility we
940 * now hotplug a controller */
941 cont = g_new0(virDomainControllerDef, 1);
942 cont->type = VIR_DOMAIN_CONTROLLER_TYPE_SCSI;
943 cont->idx = controller;
944 if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_DEFAULT)
945 cont->model = qemuDomainGetSCSIControllerModel(vm->def, cont, priv->qemuCaps);
946 else
947 cont->model = model;
948
949 VIR_INFO("No SCSI controller present, hotplugging one model=%s",
950 virDomainControllerModelSCSITypeToString(cont->model));
951 if (qemuDomainAttachControllerDevice(driver, vm, cont) < 0) {
952 VIR_FREE(cont);
953 return NULL;
954 }
955
956 if (!virDomainObjIsActive(vm)) {
957 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
958 _("guest unexpectedly quit"));
959 /* cont doesn't need freeing here, since the reference
960 * now held in def->controllers */
961 return NULL;
962 }
963
964 return cont;
965 }
966
967
968 static int
qemuDomainAttachDeviceDiskLiveInternal(virQEMUDriver * driver,virDomainObj * vm,virDomainDeviceDef * dev)969 qemuDomainAttachDeviceDiskLiveInternal(virQEMUDriver *driver,
970 virDomainObj *vm,
971 virDomainDeviceDef *dev)
972 {
973 g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
974 qemuDomainObjPrivate *priv = vm->privateData;
975 size_t i;
976 virDomainDiskDef *disk = dev->data.disk;
977 bool releaseUSB = false;
978 bool releaseVirtio = false;
979 bool releaseSeclabel = false;
980 int ret = -1;
981
982 if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM ||
983 disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
984 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
985 _("cdrom/floppy device hotplug isn't supported"));
986 return -1;
987 }
988
989 if (virDomainDiskTranslateSourcePool(disk) < 0)
990 goto cleanup;
991
992 if (qemuAddSharedDevice(driver, dev, vm->def->name) < 0)
993 goto cleanup;
994
995 if (qemuSetUnprivSGIO(dev) < 0)
996 goto cleanup;
997
998 if (qemuDomainDetermineDiskChain(driver, vm, disk, NULL, true) < 0)
999 goto cleanup;
1000
1001 for (i = 0; i < vm->def->ndisks; i++) {
1002 if (virDomainDiskDefCheckDuplicateInfo(vm->def->disks[i], disk) < 0)
1003 goto cleanup;
1004 }
1005
1006 switch ((virDomainDiskBus) disk->bus) {
1007 case VIR_DOMAIN_DISK_BUS_USB:
1008 if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
1009 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
1010 _("disk device='lun' is not supported for usb bus"));
1011 break;
1012 }
1013
1014 if (virDomainUSBAddressEnsure(priv->usbaddrs, &disk->info) < 0)
1015 goto cleanup;
1016
1017 releaseUSB = true;
1018 break;
1019
1020 case VIR_DOMAIN_DISK_BUS_VIRTIO:
1021 if (qemuDomainEnsureVirtioAddress(&releaseVirtio, vm, dev) < 0)
1022 goto cleanup;
1023 break;
1024
1025 case VIR_DOMAIN_DISK_BUS_SCSI:
1026 /* We should have an address already, so make sure */
1027 if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
1028 virReportError(VIR_ERR_INTERNAL_ERROR,
1029 _("unexpected disk address type %s"),
1030 virDomainDeviceAddressTypeToString(disk->info.type));
1031 goto cleanup;
1032 }
1033
1034 if (virDomainSCSIDriveAddressIsUsed(vm->def, &disk->info.addr.drive)) {
1035 virReportError(VIR_ERR_OPERATION_INVALID, "%s",
1036 _("Domain already contains a disk with that address"));
1037 goto cleanup;
1038 }
1039
1040 /* Let's make sure the disk has a controller defined and loaded before
1041 * trying to add it. The controller used by the disk must exist before a
1042 * qemu command line string is generated.
1043 *
1044 * Ensure that the given controller and all controllers with a smaller index
1045 * exist; there must not be any missing index in between.
1046 */
1047 for (i = 0; i <= disk->info.addr.drive.controller; i++) {
1048 if (!qemuDomainFindOrCreateSCSIDiskController(driver, vm, i))
1049 goto cleanup;
1050 }
1051 break;
1052
1053 case VIR_DOMAIN_DISK_BUS_IDE:
1054 case VIR_DOMAIN_DISK_BUS_FDC:
1055 case VIR_DOMAIN_DISK_BUS_XEN:
1056 case VIR_DOMAIN_DISK_BUS_UML:
1057 case VIR_DOMAIN_DISK_BUS_SATA:
1058 case VIR_DOMAIN_DISK_BUS_SD:
1059 /* Note that SD card hotplug support should be added only once
1060 * they support '-device' (don't require -drive only).
1061 * See also: qemuDiskBusIsSD */
1062 case VIR_DOMAIN_DISK_BUS_NONE:
1063 case VIR_DOMAIN_DISK_BUS_LAST:
1064 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
1065 _("disk bus '%s' cannot be hotplugged."),
1066 virDomainDiskBusTypeToString(disk->bus));
1067 }
1068
1069 if (qemuDomainStorageSourceChainAccessAllow(driver, vm, disk->src) < 0)
1070 goto cleanup;
1071
1072 releaseSeclabel = true;
1073
1074 if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
1075 goto cleanup;
1076
1077 if (qemuDomainPrepareDiskSource(disk, priv, cfg) < 0)
1078 goto cleanup;
1079
1080 if (qemuHotplugAttachManagedPR(driver, vm, disk->src, QEMU_ASYNC_JOB_NONE) < 0)
1081 goto cleanup;
1082
1083 ret = qemuDomainAttachDiskGeneric(driver, vm, disk, QEMU_ASYNC_JOB_NONE);
1084
1085 virDomainAuditDisk(vm, NULL, disk->src, "attach", ret == 0);
1086
1087 if (ret < 0)
1088 goto cleanup;
1089
1090 virDomainDiskInsert(vm->def, disk);
1091
1092 cleanup:
1093 if (ret < 0) {
1094 ignore_value(qemuRemoveSharedDevice(driver, dev, vm->def->name));
1095
1096 if (releaseUSB)
1097 virDomainUSBAddressRelease(priv->usbaddrs, &disk->info);
1098
1099 if (releaseVirtio && ret == -1)
1100 qemuDomainReleaseDeviceAddress(vm, &disk->info);
1101
1102 if (releaseSeclabel)
1103 ignore_value(qemuDomainStorageSourceChainAccessRevoke(driver, vm, disk->src));
1104
1105 if (virStorageSourceChainHasManagedPR(disk->src))
1106 ignore_value(qemuHotplugRemoveManagedPR(driver, vm, QEMU_ASYNC_JOB_NONE));
1107 }
1108 qemuDomainSecretDiskDestroy(disk);
1109
1110 return ret;
1111 }
1112
1113
1114 /**
1115 * qemuDomainAttachDeviceDiskLive:
1116 * @driver: qemu driver struct
1117 * @vm: domain object
1118 * @dev: device to attach (expected type is DISK)
1119 *
1120 * Attach a new disk or in case of cdroms/floppies change the media in the drive.
1121 * This function handles all the necessary steps to attach a new storage source
1122 * to the VM.
1123 */
1124 int
qemuDomainAttachDeviceDiskLive(virQEMUDriver * driver,virDomainObj * vm,virDomainDeviceDef * dev)1125 qemuDomainAttachDeviceDiskLive(virQEMUDriver *driver,
1126 virDomainObj *vm,
1127 virDomainDeviceDef *dev)
1128 {
1129 virDomainDiskDef *disk = dev->data.disk;
1130 virDomainDiskDef *orig_disk = NULL;
1131
1132 /* this API overloads media change semantics on disk hotplug
1133 * for devices supporting media changes */
1134 if ((disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM ||
1135 disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) &&
1136 (orig_disk = virDomainDiskByTarget(vm->def, disk->dst))) {
1137 if (qemuDomainChangeEjectableMedia(driver, vm, orig_disk,
1138 disk->src, false) < 0)
1139 return -1;
1140
1141 disk->src = NULL;
1142 virDomainDiskDefFree(disk);
1143 return 0;
1144 }
1145
1146 return qemuDomainAttachDeviceDiskLiveInternal(driver, vm, dev);
1147 }
1148
1149
1150 static void
qemuDomainNetDeviceVportRemove(virDomainNetDef * net)1151 qemuDomainNetDeviceVportRemove(virDomainNetDef *net)
1152 {
1153 const virNetDevVPortProfile *vport = virDomainNetGetActualVirtPortProfile(net);
1154 const char *brname;
1155
1156 if (!vport)
1157 return;
1158
1159 if (vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_MIDONET) {
1160 ignore_value(virNetDevMidonetUnbindPort(vport));
1161 } else if (vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) {
1162 brname = virDomainNetGetActualBridgeName(net);
1163 ignore_value(virNetDevOpenvswitchRemovePort(brname, net->ifname));
1164 }
1165 }
1166
1167
1168 int
qemuDomainAttachNetDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainNetDef * net)1169 qemuDomainAttachNetDevice(virQEMUDriver *driver,
1170 virDomainObj *vm,
1171 virDomainNetDef *net)
1172 {
1173 qemuDomainObjPrivate *priv = vm->privateData;
1174 virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_NET, { .net = net } };
1175 virErrorPtr originalError = NULL;
1176 g_autofree char *slirpfdName = NULL;
1177 int slirpfd = -1;
1178 g_autofree char *vdpafdName = NULL;
1179 int vdpafd = -1;
1180 char **tapfdName = NULL;
1181 int *tapfd = NULL;
1182 size_t tapfdSize = 0;
1183 char **vhostfdName = NULL;
1184 int *vhostfd = NULL;
1185 size_t vhostfdSize = 0;
1186 size_t queueSize = 0;
1187 g_autoptr(virJSONValue) nicprops = NULL;
1188 g_autoptr(virJSONValue) netprops = NULL;
1189 int ret = -1;
1190 bool releaseaddr = false;
1191 bool iface_connected = false;
1192 bool adjustmemlock = false;
1193 virDomainNetType actualType;
1194 const virNetDevBandwidth *actualBandwidth;
1195 g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
1196 virDomainCCWAddressSet *ccwaddrs = NULL;
1197 size_t i;
1198 g_autofree char *charDevAlias = NULL;
1199 bool charDevPlugged = false;
1200 bool netdevPlugged = false;
1201 g_autofree char *netdev_name = NULL;
1202 g_autoptr(virConnect) conn = NULL;
1203 virErrorPtr save_err = NULL;
1204 bool teardownlabel = false;
1205
1206 /* If appropriate, grab a physical device from the configured
1207 * network's pool of devices, or resolve bridge device name
1208 * to the one defined in the network definition.
1209 */
1210 if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
1211 if (!(conn = virGetConnectNetwork()))
1212 goto cleanup;
1213 if (virDomainNetAllocateActualDevice(conn, vm->def, net) < 0)
1214 goto cleanup;
1215 }
1216
1217 /* final validation now that we have full info on the type */
1218 if (qemuDomainValidateActualNetDef(net, priv->qemuCaps) < 0)
1219 goto cleanup;
1220
1221 actualType = virDomainNetGetActualType(net);
1222
1223 qemuAssignDeviceNetAlias(vm->def, net, -1);
1224
1225 if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
1226 /* This is really a "smart hostdev", so it should be attached
1227 * as a hostdev (the hostdev code will reach over into the
1228 * netdev-specific code as appropriate), then also added to
1229 * the nets list if successful.
1230 */
1231 if (qemuDomainAttachHostDevice(driver, vm,
1232 virDomainNetGetActualHostdev(net)) < 0) {
1233 goto cleanup;
1234 }
1235 VIR_APPEND_ELEMENT_COPY(vm->def->nets, vm->def->nnets, net);
1236
1237 /* the rest of the setup doesn't apply to hostdev interfaces, so
1238 * we can skip straight to the cleanup (nothing there applies to
1239 * hostdev interfaces either, but it might in the future, so we
1240 * may as well be consistent)
1241 */
1242 ret = 0;
1243 goto cleanup;
1244 }
1245
1246 if (qemuDomainIsS390CCW(vm->def) &&
1247 net->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
1248 virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_CCW)) {
1249 net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW;
1250 if (!(ccwaddrs = virDomainCCWAddressSetCreateFromDomain(vm->def)))
1251 goto cleanup;
1252 if (virDomainCCWAddressAssign(&net->info, ccwaddrs,
1253 !net->info.addr.ccw.assigned) < 0)
1254 goto cleanup;
1255 } else if (qemuDomainEnsurePCIAddress(vm, &dev) < 0) {
1256 goto cleanup;
1257 }
1258
1259 releaseaddr = true;
1260
1261 /* We've completed all examinations of the full domain definition
1262 * that require the new device to *not* be present (e.g. PCI
1263 * address allocation and alias name assignment) so it is now safe
1264 * to add the new device to the domain's nets list (in order for
1265 * it to be in place for checks that *do* need it present in the
1266 * domain definition, e.g. checking if we need to adjust the
1267 * locked memory limit). This means we will need to remove it if
1268 * there is a failure.
1269 */
1270 VIR_APPEND_ELEMENT_COPY(vm->def->nets, vm->def->nnets, net);
1271
1272 switch (actualType) {
1273 case VIR_DOMAIN_NET_TYPE_BRIDGE:
1274 case VIR_DOMAIN_NET_TYPE_NETWORK:
1275 tapfdSize = vhostfdSize = net->driver.virtio.queues;
1276 if (!tapfdSize)
1277 tapfdSize = vhostfdSize = 1;
1278 queueSize = tapfdSize;
1279 tapfd = g_new0(int, tapfdSize);
1280 memset(tapfd, -1, sizeof(*tapfd) * tapfdSize);
1281 vhostfd = g_new0(int, vhostfdSize);
1282 memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize);
1283 if (qemuInterfaceBridgeConnect(vm->def, driver, net,
1284 tapfd, &tapfdSize) < 0)
1285 goto cleanup;
1286 iface_connected = true;
1287 if (qemuInterfaceOpenVhostNet(vm->def, net, vhostfd, &vhostfdSize) < 0)
1288 goto cleanup;
1289 break;
1290
1291 case VIR_DOMAIN_NET_TYPE_DIRECT:
1292 tapfdSize = vhostfdSize = net->driver.virtio.queues;
1293 if (!tapfdSize)
1294 tapfdSize = vhostfdSize = 1;
1295 queueSize = tapfdSize;
1296 tapfd = g_new0(int, tapfdSize);
1297 memset(tapfd, -1, sizeof(*tapfd) * tapfdSize);
1298 vhostfd = g_new0(int, vhostfdSize);
1299 memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize);
1300 if (qemuInterfaceDirectConnect(vm->def, driver, net,
1301 tapfd, tapfdSize,
1302 VIR_NETDEV_VPORT_PROFILE_OP_CREATE) < 0)
1303 goto cleanup;
1304 iface_connected = true;
1305 if (qemuInterfaceOpenVhostNet(vm->def, net, vhostfd, &vhostfdSize) < 0)
1306 goto cleanup;
1307 break;
1308
1309 case VIR_DOMAIN_NET_TYPE_ETHERNET:
1310 tapfdSize = vhostfdSize = net->driver.virtio.queues;
1311 if (!tapfdSize)
1312 tapfdSize = vhostfdSize = 1;
1313 queueSize = tapfdSize;
1314 tapfd = g_new0(int, tapfdSize);
1315 memset(tapfd, -1, sizeof(*tapfd) * tapfdSize);
1316 vhostfd = g_new0(int, vhostfdSize);
1317 memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize);
1318 if (qemuInterfaceEthernetConnect(vm->def, driver, net,
1319 tapfd, tapfdSize) < 0)
1320 goto cleanup;
1321 iface_connected = true;
1322 if (qemuInterfaceOpenVhostNet(vm->def, net, vhostfd, &vhostfdSize) < 0)
1323 goto cleanup;
1324 break;
1325
1326 case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
1327 queueSize = net->driver.virtio.queues;
1328 if (!queueSize)
1329 queueSize = 1;
1330 if (!qemuDomainSupportsNicdev(vm->def, net)) {
1331 virReportError(VIR_ERR_INTERNAL_ERROR,
1332 "%s", _("Nicdev support unavailable"));
1333 goto cleanup;
1334 }
1335
1336 if (!(charDevAlias = qemuAliasChardevFromDevAlias(net->info.alias)))
1337 goto cleanup;
1338
1339 if (virNetDevOpenvswitchGetVhostuserIfname(net->data.vhostuser->data.nix.path,
1340 net->data.vhostuser->data.nix.listen,
1341 &net->ifname) < 0)
1342 goto cleanup;
1343
1344 if (qemuSecuritySetNetdevLabel(driver, vm, net) < 0)
1345 goto cleanup;
1346 teardownlabel = true;
1347 break;
1348
1349 case VIR_DOMAIN_NET_TYPE_USER:
1350 if (!priv->disableSlirp &&
1351 virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DBUS_VMSTATE)) {
1352 qemuSlirp *slirp = NULL;
1353 int rv = qemuInterfacePrepareSlirp(driver, net, &slirp);
1354
1355 if (rv == -1)
1356 goto cleanup;
1357 if (rv == 0)
1358 break;
1359
1360 QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp = slirp;
1361
1362 if (qemuSlirpOpen(slirp, driver, vm->def) < 0 ||
1363 qemuSlirpStart(slirp, vm, driver, net, NULL) < 0) {
1364 virReportError(VIR_ERR_INTERNAL_ERROR,
1365 "%s", _("Failed to start slirp"));
1366 goto cleanup;
1367 }
1368
1369 slirpfd = qemuSlirpGetFD(slirp);
1370 slirpfdName = g_strdup_printf("slirpfd-%s", net->info.alias);
1371 }
1372 break;
1373
1374 case VIR_DOMAIN_NET_TYPE_HOSTDEV:
1375 /* hostdev interfaces were handled earlier in this function */
1376 break;
1377
1378 case VIR_DOMAIN_NET_TYPE_VDPA:
1379 if (qemuDomainAdjustMaxMemLock(vm, false) < 0)
1380 goto cleanup;
1381 adjustmemlock = true;
1382
1383 if ((vdpafd = qemuInterfaceVDPAConnect(net)) < 0)
1384 goto cleanup;
1385 break;
1386
1387 case VIR_DOMAIN_NET_TYPE_SERVER:
1388 case VIR_DOMAIN_NET_TYPE_CLIENT:
1389 case VIR_DOMAIN_NET_TYPE_MCAST:
1390 case VIR_DOMAIN_NET_TYPE_INTERNAL:
1391 case VIR_DOMAIN_NET_TYPE_UDP:
1392 case VIR_DOMAIN_NET_TYPE_LAST:
1393 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
1394 _("hotplug of interface type of %s is not implemented yet"),
1395 virDomainNetTypeToString(actualType));
1396 goto cleanup;
1397 }
1398
1399 /* Set device online immediately */
1400 if (qemuInterfaceStartDevice(net) < 0)
1401 goto cleanup;
1402
1403 qemuDomainInterfaceSetDefaultQDisc(driver, net);
1404
1405 /* Set bandwidth or warn if requested and not supported. */
1406 actualBandwidth = virDomainNetGetActualBandwidth(net);
1407 if (actualBandwidth) {
1408 if (virNetDevSupportsBandwidth(actualType)) {
1409 if (virDomainNetDefIsOvsport(net)) {
1410 if (virNetDevOpenvswitchInterfaceSetQos(net->ifname, actualBandwidth,
1411 vm->def->uuid,
1412 !virDomainNetTypeSharesHostView(net)) < 0)
1413 goto cleanup;
1414 } else if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false,
1415 !virDomainNetTypeSharesHostView(net)) < 0) {
1416 goto cleanup;
1417 }
1418 } else {
1419 VIR_WARN("setting bandwidth on interfaces of "
1420 "type '%s' is not implemented yet",
1421 virDomainNetTypeToString(actualType));
1422 }
1423 }
1424
1425 if (net->mtu && net->managed_tap != VIR_TRISTATE_BOOL_NO &&
1426 virNetDevSetMTU(net->ifname, net->mtu) < 0)
1427 goto cleanup;
1428
1429 for (i = 0; i < tapfdSize; i++) {
1430 if (qemuSecuritySetTapFDLabel(driver->securityManager,
1431 vm->def, tapfd[i]) < 0)
1432 goto cleanup;
1433 }
1434
1435 tapfdName = g_new0(char *, tapfdSize);
1436 vhostfdName = g_new0(char *, vhostfdSize);
1437
1438 for (i = 0; i < tapfdSize; i++)
1439 tapfdName[i] = g_strdup_printf("fd-%s%zu", net->info.alias, i);
1440
1441 for (i = 0; i < vhostfdSize; i++)
1442 vhostfdName[i] = g_strdup_printf("vhostfd-%s%zu", net->info.alias, i);
1443
1444 qemuDomainObjEnterMonitor(driver, vm);
1445
1446 if (vdpafd > 0) {
1447 /* vhost-vdpa only accepts a filename. We can pass an open fd by
1448 * filename if we add the fd to an fdset and then pass a filename of
1449 * /dev/fdset/$FDSETID. */
1450 qemuMonitorAddFdInfo fdinfo;
1451 if (qemuMonitorAddFileHandleToSet(priv->mon, vdpafd, -1,
1452 net->data.vdpa.devicepath,
1453 &fdinfo) < 0) {
1454 ignore_value(qemuDomainObjExitMonitor(driver, vm));
1455 goto cleanup;
1456 }
1457 vdpafdName = g_strdup_printf("/dev/fdset/%d", fdinfo.fdset);
1458 }
1459
1460 if (!(netprops = qemuBuildHostNetProps(net,
1461 tapfdName, tapfdSize,
1462 vhostfdName, vhostfdSize,
1463 slirpfdName, vdpafdName))) {
1464 ignore_value(qemuDomainObjExitMonitor(driver, vm));
1465 goto cleanup;
1466 }
1467
1468 if (actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
1469 if (qemuHotplugChardevAttach(priv->mon, charDevAlias, net->data.vhostuser) < 0) {
1470 ignore_value(qemuDomainObjExitMonitor(driver, vm));
1471 virDomainAuditNet(vm, NULL, net, "attach", false);
1472 goto cleanup;
1473 }
1474 charDevPlugged = true;
1475 }
1476
1477 if (qemuMonitorAddNetdev(priv->mon, &netprops,
1478 tapfd, tapfdName, tapfdSize,
1479 vhostfd, vhostfdName, vhostfdSize,
1480 slirpfd, slirpfdName) < 0) {
1481 ignore_value(qemuDomainObjExitMonitor(driver, vm));
1482 virDomainAuditNet(vm, NULL, net, "attach", false);
1483 goto try_remove;
1484 }
1485 netdevPlugged = true;
1486
1487 if (qemuDomainObjExitMonitor(driver, vm) < 0)
1488 goto cleanup;
1489
1490 for (i = 0; i < tapfdSize; i++)
1491 VIR_FORCE_CLOSE(tapfd[i]);
1492 for (i = 0; i < vhostfdSize; i++)
1493 VIR_FORCE_CLOSE(vhostfd[i]);
1494
1495 if (!(nicprops = qemuBuildNicDevProps(vm->def, net, queueSize, priv->qemuCaps)))
1496 goto try_remove;
1497
1498 qemuDomainObjEnterMonitor(driver, vm);
1499
1500 if (qemuDomainAttachExtensionDevice(priv->mon, &net->info) < 0) {
1501 ignore_value(qemuDomainObjExitMonitor(driver, vm));
1502 virDomainAuditNet(vm, NULL, net, "attach", false);
1503 goto try_remove;
1504 }
1505
1506 if (qemuMonitorAddDeviceProps(priv->mon, &nicprops) < 0) {
1507 ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &net->info));
1508 ignore_value(qemuDomainObjExitMonitor(driver, vm));
1509 virDomainAuditNet(vm, NULL, net, "attach", false);
1510 goto try_remove;
1511 }
1512 if (qemuDomainObjExitMonitor(driver, vm) < 0)
1513 goto cleanup;
1514
1515 /* set link state */
1516 if (net->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) {
1517 if (!net->info.alias) {
1518 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
1519 _("device alias not found: cannot set link state to down"));
1520 } else {
1521 qemuDomainObjEnterMonitor(driver, vm);
1522
1523 if (qemuMonitorSetLink(priv->mon, net->info.alias, VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) < 0) {
1524 ignore_value(qemuDomainObjExitMonitor(driver, vm));
1525 virDomainAuditNet(vm, NULL, net, "attach", false);
1526 goto try_remove;
1527 }
1528
1529 if (qemuDomainObjExitMonitor(driver, vm) < 0)
1530 goto cleanup;
1531 }
1532 /* link set to down */
1533 }
1534
1535 virDomainAuditNet(vm, NULL, net, "attach", true);
1536
1537 ret = 0;
1538
1539 cleanup:
1540 if (ret < 0) {
1541 virErrorPreserveLast(&save_err);
1542 if (releaseaddr)
1543 qemuDomainReleaseDeviceAddress(vm, &net->info);
1544
1545 if (iface_connected) {
1546 virErrorPreserveLast(&originalError);
1547 virDomainConfNWFilterTeardown(net);
1548 virErrorRestore(&originalError);
1549
1550 if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) {
1551 ignore_value(virNetDevMacVLanDeleteWithVPortProfile(
1552 net->ifname, &net->mac,
1553 virDomainNetGetActualDirectDev(net),
1554 virDomainNetGetActualDirectMode(net),
1555 virDomainNetGetActualVirtPortProfile(net),
1556 cfg->stateDir));
1557 }
1558
1559 qemuDomainNetDeviceVportRemove(net);
1560 }
1561
1562 if (teardownlabel &&
1563 qemuSecurityRestoreNetdevLabel(driver, vm, net) < 0)
1564 VIR_WARN("Unable to restore network device labelling on hotplug fail");
1565
1566 /* we had potentially pre-added the device to the domain
1567 * device lists, if so we need to remove it (from def->nets
1568 * and/or def->hostdevs) on failure
1569 */
1570 virDomainNetRemoveByObj(vm->def, net);
1571
1572 /* if we adjusted the memlock limit (for a vDPA device) then
1573 * we need to re-adjust since we won't be using the device
1574 * after all
1575 */
1576 if (adjustmemlock)
1577 qemuDomainAdjustMaxMemLock(vm, false);
1578
1579 if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
1580 if (conn)
1581 virDomainNetReleaseActualDevice(conn, vm->def, net);
1582 else
1583 VIR_WARN("Unable to release network device '%s'", NULLSTR(net->ifname));
1584 }
1585 virErrorRestore(&save_err);
1586 }
1587
1588 for (i = 0; tapfd && i < tapfdSize; i++) {
1589 VIR_FORCE_CLOSE(tapfd[i]);
1590 if (tapfdName)
1591 VIR_FREE(tapfdName[i]);
1592 }
1593 VIR_FREE(tapfd);
1594 VIR_FREE(tapfdName);
1595 for (i = 0; vhostfd && i < vhostfdSize; i++) {
1596 VIR_FORCE_CLOSE(vhostfd[i]);
1597 if (vhostfdName)
1598 VIR_FREE(vhostfdName[i]);
1599 }
1600 VIR_FREE(vhostfd);
1601 VIR_FREE(vhostfdName);
1602 virDomainCCWAddressSetFree(ccwaddrs);
1603 VIR_FORCE_CLOSE(slirpfd);
1604 VIR_FORCE_CLOSE(vdpafd);
1605
1606 return ret;
1607
1608 try_remove:
1609 if (!virDomainObjIsActive(vm))
1610 goto cleanup;
1611
1612 virErrorPreserveLast(&originalError);
1613 netdev_name = g_strdup_printf("host%s", net->info.alias);
1614 if (QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp)
1615 qemuSlirpStop(QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp, vm, driver, net);
1616 qemuDomainObjEnterMonitor(driver, vm);
1617 if (charDevPlugged &&
1618 qemuMonitorDetachCharDev(priv->mon, charDevAlias) < 0)
1619 VIR_WARN("Failed to remove associated chardev %s", charDevAlias);
1620 if (netdevPlugged &&
1621 qemuMonitorRemoveNetdev(priv->mon, netdev_name) < 0)
1622 VIR_WARN("Failed to remove network backend for netdev %s",
1623 netdev_name);
1624 ignore_value(qemuDomainObjExitMonitor(driver, vm));
1625 virErrorRestore(&originalError);
1626 goto cleanup;
1627 }
1628
1629
1630 static int
qemuDomainAttachHostPCIDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainHostdevDef * hostdev)1631 qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
1632 virDomainObj *vm,
1633 virDomainHostdevDef *hostdev)
1634 {
1635 qemuDomainObjPrivate *priv = vm->privateData;
1636 virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_HOSTDEV,
1637 { .hostdev = hostdev } };
1638 virDomainDeviceInfo *info = hostdev->info;
1639 int ret;
1640 g_autoptr(virJSONValue) devprops = NULL;
1641 bool releaseaddr = false;
1642 bool teardowncgroup = false;
1643 bool teardownlabel = false;
1644 bool teardowndevice = false;
1645 bool teardownmemlock = false;
1646 int backend;
1647 g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
1648 unsigned int flags = 0;
1649
1650 VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1);
1651
1652 if (!cfg->relaxedACS)
1653 flags |= VIR_HOSTDEV_STRICT_ACS_CHECK;
1654 if (qemuHostdevPreparePCIDevices(driver, vm->def->name, vm->def->uuid,
1655 &hostdev, 1, priv->qemuCaps, flags) < 0)
1656 return -1;
1657
1658 /* this could have been changed by qemuHostdevPreparePCIDevices */
1659 backend = hostdev->source.subsys.u.pci.backend;
1660
1661 switch ((virDomainHostdevSubsysPCIBackendType)backend) {
1662 case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO:
1663 if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI)) {
1664 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
1665 _("VFIO PCI device assignment is not "
1666 "supported by this version of qemu"));
1667 goto error;
1668 }
1669 break;
1670
1671 case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT:
1672 case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
1673 break;
1674
1675 case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN:
1676 case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST:
1677 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
1678 _("QEMU does not support device assignment mode '%s'"),
1679 virDomainHostdevSubsysPCIBackendTypeToString(backend));
1680 goto error;
1681 break;
1682 }
1683
1684 if (qemuDomainAdjustMaxMemLockHostdev(vm, hostdev) < 0)
1685 goto error;
1686 teardownmemlock = true;
1687
1688 if (qemuDomainNamespaceSetupHostdev(vm, hostdev, &teardowndevice) < 0)
1689 goto error;
1690
1691 if (qemuSetupHostdevCgroup(vm, hostdev) < 0)
1692 goto error;
1693 teardowncgroup = true;
1694
1695 if (qemuSecuritySetHostdevLabel(driver, vm, hostdev) < 0)
1696 goto error;
1697 if (backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO)
1698 teardownlabel = true;
1699
1700 qemuAssignDeviceHostdevAlias(vm->def, &info->alias, -1);
1701
1702 if (qemuDomainIsPSeries(vm->def))
1703 /* Isolation groups are only relevant for pSeries guests */
1704 qemuDomainFillDeviceIsolationGroup(vm->def, &dev);
1705
1706 if (qemuDomainEnsurePCIAddress(vm, &dev) < 0)
1707 goto error;
1708 releaseaddr = true;
1709
1710 if (!virDomainObjIsActive(vm)) {
1711 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1712 _("guest unexpectedly quit during hotplug"));
1713 goto error;
1714 }
1715
1716 if (!(devprops = qemuBuildPCIHostdevDevProps(vm->def, hostdev)))
1717 goto error;
1718
1719 qemuDomainObjEnterMonitor(driver, vm);
1720
1721 if ((ret = qemuDomainAttachExtensionDevice(priv->mon, hostdev->info)) < 0)
1722 goto exit_monitor;
1723
1724 if ((ret = qemuMonitorAddDeviceProps(priv->mon, &devprops)) < 0)
1725 ignore_value(qemuDomainDetachExtensionDevice(priv->mon, hostdev->info));
1726
1727 exit_monitor:
1728 if (qemuDomainObjExitMonitor(driver, vm) < 0)
1729 goto error;
1730
1731 virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
1732 if (ret < 0)
1733 goto error;
1734
1735 vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
1736
1737 return 0;
1738
1739 error:
1740 if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
1741 VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
1742 if (teardownlabel &&
1743 qemuSecurityRestoreHostdevLabel(driver, vm, hostdev) < 0)
1744 VIR_WARN("Unable to restore host device labelling on hotplug fail");
1745 if (teardowndevice &&
1746 qemuDomainNamespaceTeardownHostdev(vm, hostdev) < 0)
1747 VIR_WARN("Unable to remove host device from /dev");
1748 if (teardownmemlock && qemuDomainAdjustMaxMemLock(vm, false) < 0)
1749 VIR_WARN("Unable to reset maximum locked memory on hotplug fail");
1750
1751 if (releaseaddr)
1752 qemuDomainReleaseDeviceAddress(vm, info);
1753
1754 qemuHostdevReAttachPCIDevices(driver, vm->def->name, &hostdev, 1);
1755
1756 return -1;
1757 }
1758
1759
1760 void
qemuDomainDelTLSObjects(virQEMUDriver * driver,virDomainObj * vm,qemuDomainAsyncJob asyncJob,const char * secAlias,const char * tlsAlias)1761 qemuDomainDelTLSObjects(virQEMUDriver *driver,
1762 virDomainObj *vm,
1763 qemuDomainAsyncJob asyncJob,
1764 const char *secAlias,
1765 const char *tlsAlias)
1766 {
1767 qemuDomainObjPrivate *priv = vm->privateData;
1768 virErrorPtr orig_err;
1769
1770 if (!tlsAlias && !secAlias)
1771 return;
1772
1773 virErrorPreserveLast(&orig_err);
1774
1775 if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
1776 goto cleanup;
1777
1778 if (tlsAlias)
1779 ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias, false));
1780
1781 if (secAlias)
1782 ignore_value(qemuMonitorDelObject(priv->mon, secAlias, false));
1783
1784 ignore_value(qemuDomainObjExitMonitor(driver, vm));
1785
1786 cleanup:
1787 virErrorRestore(&orig_err);
1788 }
1789
1790
1791 int
qemuDomainAddTLSObjects(virQEMUDriver * driver,virDomainObj * vm,qemuDomainAsyncJob asyncJob,virJSONValue ** secProps,virJSONValue ** tlsProps)1792 qemuDomainAddTLSObjects(virQEMUDriver *driver,
1793 virDomainObj *vm,
1794 qemuDomainAsyncJob asyncJob,
1795 virJSONValue **secProps,
1796 virJSONValue **tlsProps)
1797 {
1798 qemuDomainObjPrivate *priv = vm->privateData;
1799 virErrorPtr orig_err;
1800 g_autofree char *secAlias = NULL;
1801
1802 if (!tlsProps && !secProps)
1803 return 0;
1804
1805 if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
1806 return -1;
1807
1808 if (secProps && *secProps &&
1809 qemuMonitorAddObject(priv->mon, secProps, &secAlias) < 0)
1810 goto error;
1811
1812 if (tlsProps &&
1813 qemuMonitorAddObject(priv->mon, tlsProps, NULL) < 0)
1814 goto error;
1815
1816 return qemuDomainObjExitMonitor(driver, vm);
1817
1818 error:
1819 virErrorPreserveLast(&orig_err);
1820 ignore_value(qemuDomainObjExitMonitor(driver, vm));
1821 virErrorRestore(&orig_err);
1822 qemuDomainDelTLSObjects(driver, vm, asyncJob, secAlias, NULL);
1823
1824 return -1;
1825 }
1826
1827
1828 int
qemuDomainGetTLSObjects(qemuDomainSecretInfo * secinfo,const char * tlsCertdir,bool tlsListen,bool tlsVerify,const char * alias,virJSONValue ** tlsProps,virJSONValue ** secProps)1829 qemuDomainGetTLSObjects(qemuDomainSecretInfo *secinfo,
1830 const char *tlsCertdir,
1831 bool tlsListen,
1832 bool tlsVerify,
1833 const char *alias,
1834 virJSONValue **tlsProps,
1835 virJSONValue **secProps)
1836 {
1837 const char *secAlias = NULL;
1838
1839 if (secinfo) {
1840 if (qemuBuildSecretInfoProps(secinfo, secProps) < 0)
1841 return -1;
1842
1843 secAlias = secinfo->alias;
1844 }
1845
1846 if (qemuBuildTLSx509BackendProps(tlsCertdir, tlsListen, tlsVerify,
1847 alias, secAlias, tlsProps) < 0)
1848 return -1;
1849
1850 return 0;
1851 }
1852
1853
1854 static int
qemuDomainAddChardevTLSObjects(virQEMUDriver * driver,virDomainObj * vm,virDomainChrSourceDef * dev,char * devAlias,char * charAlias,char ** tlsAlias,const char ** secAlias)1855 qemuDomainAddChardevTLSObjects(virQEMUDriver *driver,
1856 virDomainObj *vm,
1857 virDomainChrSourceDef *dev,
1858 char *devAlias,
1859 char *charAlias,
1860 char **tlsAlias,
1861 const char **secAlias)
1862 {
1863 g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
1864 qemuDomainObjPrivate *priv = vm->privateData;
1865 qemuDomainChrSourcePrivate *chrSourcePriv;
1866 qemuDomainSecretInfo *secinfo = NULL;
1867 g_autoptr(virJSONValue) tlsProps = NULL;
1868 g_autoptr(virJSONValue) secProps = NULL;
1869
1870 /* NB: This may alter haveTLS based on cfg */
1871 qemuDomainPrepareChardevSourceTLS(dev, cfg);
1872
1873 if (dev->type != VIR_DOMAIN_CHR_TYPE_TCP ||
1874 dev->data.tcp.haveTLS != VIR_TRISTATE_BOOL_YES)
1875 return 0;
1876
1877 if (qemuDomainSecretChardevPrepare(cfg, priv, devAlias, dev) < 0)
1878 return -1;
1879
1880 if ((chrSourcePriv = QEMU_DOMAIN_CHR_SOURCE_PRIVATE(dev)))
1881 secinfo = chrSourcePriv->secinfo;
1882
1883 if (secinfo)
1884 *secAlias = secinfo->alias;
1885
1886 if (!(*tlsAlias = qemuAliasTLSObjFromSrcAlias(charAlias)))
1887 return -1;
1888
1889 if (qemuDomainGetTLSObjects(secinfo,
1890 cfg->chardevTLSx509certdir,
1891 dev->data.tcp.listen,
1892 cfg->chardevTLSx509verify,
1893 *tlsAlias, &tlsProps, &secProps) < 0)
1894 return -1;
1895
1896 dev->data.tcp.tlscreds = true;
1897
1898 if (qemuDomainAddTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE,
1899 &secProps, &tlsProps) < 0)
1900 return -1;
1901
1902 return 0;
1903 }
1904
1905
1906 static int
qemuDomainDelChardevTLSObjects(virQEMUDriver * driver,virDomainObj * vm,virDomainChrSourceDef * dev,const char * inAlias)1907 qemuDomainDelChardevTLSObjects(virQEMUDriver *driver,
1908 virDomainObj *vm,
1909 virDomainChrSourceDef *dev,
1910 const char *inAlias)
1911 {
1912 g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
1913 qemuDomainObjPrivate *priv = vm->privateData;
1914 g_autofree char *tlsAlias = NULL;
1915 g_autofree char *secAlias = NULL;
1916
1917 if (dev->type != VIR_DOMAIN_CHR_TYPE_TCP ||
1918 dev->data.tcp.haveTLS != VIR_TRISTATE_BOOL_YES) {
1919 return 0;
1920 }
1921
1922 if (!(tlsAlias = qemuAliasTLSObjFromSrcAlias(inAlias)))
1923 return -1;
1924
1925 /* Best shot at this as the secinfo is destroyed after process launch
1926 * and this path does not recreate it. Thus, if the config has the
1927 * secret UUID and we have a serial TCP chardev, then formulate a
1928 * secAlias which we'll attempt to destroy. */
1929 if (cfg->chardevTLSx509secretUUID &&
1930 !(secAlias = qemuAliasForSecret(inAlias, NULL)))
1931 return -1;
1932
1933 qemuDomainObjEnterMonitor(driver, vm);
1934
1935 ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias, false));
1936 if (secAlias)
1937 ignore_value(qemuMonitorDelObject(priv->mon, secAlias, false));
1938
1939 if (qemuDomainObjExitMonitor(driver, vm) < 0)
1940 return -1;
1941
1942 return 0;
1943 }
1944
1945
qemuDomainAttachRedirdevDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainRedirdevDef * redirdev)1946 int qemuDomainAttachRedirdevDevice(virQEMUDriver *driver,
1947 virDomainObj *vm,
1948 virDomainRedirdevDef *redirdev)
1949 {
1950 int ret = -1;
1951 qemuDomainObjPrivate *priv = vm->privateData;
1952 virDomainDef *def = vm->def;
1953 g_autofree char *charAlias = NULL;
1954 g_autoptr(virJSONValue) devprops = NULL;
1955 bool chardevAdded = false;
1956 g_autofree char *tlsAlias = NULL;
1957 const char *secAlias = NULL;
1958 virErrorPtr orig_err;
1959
1960 qemuAssignDeviceRedirdevAlias(def, redirdev, -1);
1961
1962 if (!(charAlias = qemuAliasChardevFromDevAlias(redirdev->info.alias)))
1963 return -1;
1964
1965 if ((virDomainUSBAddressEnsure(priv->usbaddrs, &redirdev->info)) < 0)
1966 return -1;
1967
1968 if (!(devprops = qemuBuildRedirdevDevProps(def, redirdev)))
1969 goto cleanup;
1970
1971 VIR_REALLOC_N(def->redirdevs, def->nredirdevs+1);
1972
1973 if (qemuDomainAddChardevTLSObjects(driver, vm, redirdev->source,
1974 redirdev->info.alias, charAlias,
1975 &tlsAlias, &secAlias) < 0)
1976 goto audit;
1977
1978 qemuDomainObjEnterMonitor(driver, vm);
1979
1980 if (qemuHotplugChardevAttach(priv->mon, charAlias, redirdev->source) < 0)
1981 goto exit_monitor;
1982 chardevAdded = true;
1983
1984 if (qemuMonitorAddDeviceProps(priv->mon, &devprops) < 0)
1985 goto exit_monitor;
1986
1987 if (qemuDomainObjExitMonitor(driver, vm) < 0)
1988 goto audit;
1989
1990 def->redirdevs[def->nredirdevs++] = redirdev;
1991 ret = 0;
1992 audit:
1993 virDomainAuditRedirdev(vm, redirdev, "attach", ret == 0);
1994 cleanup:
1995 if (ret < 0)
1996 qemuDomainReleaseDeviceAddress(vm, &redirdev->info);
1997 return ret;
1998
1999 exit_monitor:
2000 virErrorPreserveLast(&orig_err);
2001 /* detach associated chardev on error */
2002 if (chardevAdded)
2003 ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
2004 ignore_value(qemuDomainObjExitMonitor(driver, vm));
2005 virErrorRestore(&orig_err);
2006 qemuDomainDelTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE,
2007 secAlias, tlsAlias);
2008 goto audit;
2009 }
2010
2011 static int
qemuDomainChrPreInsert(virDomainDef * vmdef,virDomainChrDef * chr)2012 qemuDomainChrPreInsert(virDomainDef *vmdef,
2013 virDomainChrDef *chr)
2014 {
2015 if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
2016 chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) {
2017 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
2018 _("attaching serial console is not supported"));
2019 return -1;
2020 }
2021
2022 if (virDomainChrFind(vmdef, chr)) {
2023 virReportError(VIR_ERR_OPERATION_INVALID, "%s",
2024 _("chardev already exists"));
2025 return -1;
2026 }
2027
2028 if (virDomainChrPreAlloc(vmdef, chr) < 0)
2029 return -1;
2030
2031 /* Due to historical reasons, the first console is an alias to the
2032 * first serial device (if such exists). If this is the case, we need to
2033 * create an object for the first console as well.
2034 */
2035 if (vmdef->nserials == 0 && vmdef->nconsoles == 0 &&
2036 chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL) {
2037 if (!vmdef->consoles)
2038 vmdef->consoles = g_new0(virDomainChrDef *, 1);
2039
2040 /* We'll be dealing with serials[0] directly, so NULL is fine here. */
2041 if (!(vmdef->consoles[0] = virDomainChrDefNew(NULL))) {
2042 VIR_FREE(vmdef->consoles);
2043 return -1;
2044 }
2045 vmdef->nconsoles++;
2046 }
2047 return 0;
2048 }
2049
2050 static void
qemuDomainChrInsertPreAlloced(virDomainDef * vmdef,virDomainChrDef * chr)2051 qemuDomainChrInsertPreAlloced(virDomainDef *vmdef,
2052 virDomainChrDef *chr)
2053 {
2054 virDomainChrInsertPreAlloced(vmdef, chr);
2055 if (vmdef->nserials == 1 && vmdef->nconsoles == 0 &&
2056 chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL) {
2057 vmdef->nconsoles = 1;
2058
2059 /* Create an console alias for the serial port */
2060 vmdef->consoles[0]->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE;
2061 vmdef->consoles[0]->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
2062 }
2063 }
2064
2065 static void
qemuDomainChrInsertPreAllocCleanup(virDomainDef * vmdef,virDomainChrDef * chr)2066 qemuDomainChrInsertPreAllocCleanup(virDomainDef *vmdef,
2067 virDomainChrDef *chr)
2068 {
2069 /* Remove the stub console added by qemuDomainChrPreInsert */
2070 if (vmdef->nserials == 0 && vmdef->nconsoles == 1 &&
2071 chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL) {
2072 virDomainChrDefFree(vmdef->consoles[0]);
2073 VIR_FREE(vmdef->consoles);
2074 vmdef->nconsoles = 0;
2075 }
2076 }
2077
2078 int
qemuDomainChrInsert(virDomainDef * vmdef,virDomainChrDef * chr)2079 qemuDomainChrInsert(virDomainDef *vmdef,
2080 virDomainChrDef *chr)
2081 {
2082 if (qemuDomainChrPreInsert(vmdef, chr) < 0) {
2083 qemuDomainChrInsertPreAllocCleanup(vmdef, chr);
2084 return -1;
2085 }
2086 qemuDomainChrInsertPreAlloced(vmdef, chr);
2087 return 0;
2088 }
2089
2090 virDomainChrDef *
qemuDomainChrRemove(virDomainDef * vmdef,virDomainChrDef * chr)2091 qemuDomainChrRemove(virDomainDef *vmdef,
2092 virDomainChrDef *chr)
2093 {
2094 virDomainChrDef *ret;
2095 bool removeCompat;
2096
2097 if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
2098 chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) {
2099 virReportError(VIR_ERR_OPERATION_INVALID, "%s",
2100 _("detaching serial console is not supported"));
2101 return NULL;
2102 }
2103
2104 /* Due to some crazy backcompat stuff, the first serial device is an alias
2105 * to the first console too. If this is the case, the definition must be
2106 * duplicated as first console device. */
2107 removeCompat = vmdef->nserials && vmdef->nconsoles &&
2108 vmdef->consoles[0]->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
2109 vmdef->consoles[0]->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL &&
2110 virDomainChrEquals(vmdef->serials[0], chr);
2111
2112 if (!(ret = virDomainChrRemove(vmdef, chr))) {
2113 virReportError(VIR_ERR_INVALID_ARG, "%s",
2114 _("device not present in domain configuration"));
2115 return NULL;
2116 }
2117
2118 if (removeCompat)
2119 VIR_DELETE_ELEMENT(vmdef->consoles, 0, vmdef->nconsoles);
2120
2121 return ret;
2122 }
2123
2124
2125
2126 static int
qemuDomainAttachChrDeviceAssignAddr(virDomainObj * vm,virDomainChrDef * chr,bool * need_release)2127 qemuDomainAttachChrDeviceAssignAddr(virDomainObj *vm,
2128 virDomainChrDef *chr,
2129 bool *need_release)
2130 {
2131 virDomainDef *def = vm->def;
2132 qemuDomainObjPrivate *priv = vm->privateData;
2133 virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_CHR, { .chr = chr } };
2134
2135 if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
2136 chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO) {
2137 if (virDomainVirtioSerialAddrAutoAssign(def, &chr->info, true) < 0)
2138 return -1;
2139 return 0;
2140
2141 } else if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
2142 chr->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_PCI) {
2143 if (qemuDomainEnsurePCIAddress(vm, &dev) < 0)
2144 return -1;
2145
2146 *need_release = true;
2147 return 0;
2148 } else if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
2149 chr->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB) {
2150 if (virDomainUSBAddressEnsure(priv->usbaddrs, &chr->info) < 0)
2151 return -1;
2152
2153 *need_release = true;
2154 return 0;
2155
2156 } else if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
2157 chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO) {
2158 if (virDomainVirtioSerialAddrAutoAssign(def, &chr->info, false) < 0)
2159 return -1;
2160 return 0;
2161 }
2162
2163 if (chr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL ||
2164 chr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
2165 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
2166 _("Unsupported address type for character device"));
2167 return -1;
2168 }
2169
2170 return 0;
2171 }
2172
qemuDomainAttachChrDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainChrDef * chr)2173 int qemuDomainAttachChrDevice(virQEMUDriver *driver,
2174 virDomainObj *vm,
2175 virDomainChrDef *chr)
2176 {
2177 int ret = -1;
2178 qemuDomainObjPrivate *priv = vm->privateData;
2179 virErrorPtr orig_err;
2180 virDomainDef *vmdef = vm->def;
2181 g_autoptr(virJSONValue) devprops = NULL;
2182 g_autoptr(virJSONValue) netdevprops = NULL;
2183 g_autofree char *charAlias = NULL;
2184 bool chardevAttached = false;
2185 bool teardowncgroup = false;
2186 bool teardowndevice = false;
2187 bool teardownlabel = false;
2188 g_autofree char *tlsAlias = NULL;
2189 const char *secAlias = NULL;
2190 bool need_release = false;
2191 bool guestfwd = false;
2192
2193 if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL) {
2194 guestfwd = chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD;
2195
2196 if (qemuDomainPrepareChannel(chr, priv->channelTargetDir) < 0)
2197 goto cleanup;
2198 }
2199
2200 if (qemuAssignDeviceChrAlias(vmdef, chr, -1) < 0)
2201 goto cleanup;
2202
2203 if (qemuDomainAttachChrDeviceAssignAddr(vm, chr, &need_release) < 0)
2204 goto cleanup;
2205
2206 if (qemuDomainNamespaceSetupChardev(vm, chr, &teardowndevice) < 0)
2207 goto cleanup;
2208
2209 if (qemuSecuritySetChardevLabel(driver, vm, chr) < 0)
2210 goto cleanup;
2211 teardownlabel = true;
2212
2213 if (qemuSetupChardevCgroup(vm, chr) < 0)
2214 goto cleanup;
2215 teardowncgroup = true;
2216
2217 if (guestfwd) {
2218 if (!(netdevprops = qemuBuildChannelGuestfwdNetdevProps(chr)))
2219 goto cleanup;
2220 } else {
2221 if (!(devprops = qemuBuildChrDeviceProps(vmdef, chr, priv->qemuCaps)))
2222 goto cleanup;
2223 }
2224
2225 if (!(charAlias = qemuAliasChardevFromDevAlias(chr->info.alias)))
2226 goto cleanup;
2227
2228 if (qemuDomainChrPreInsert(vmdef, chr) < 0)
2229 goto cleanup;
2230
2231 if (qemuDomainAddChardevTLSObjects(driver, vm, chr->source,
2232 chr->info.alias, charAlias,
2233 &tlsAlias, &secAlias) < 0)
2234 goto audit;
2235
2236 qemuDomainObjEnterMonitor(driver, vm);
2237
2238 if (qemuHotplugChardevAttach(priv->mon, charAlias, chr->source) < 0)
2239 goto exit_monitor;
2240 chardevAttached = true;
2241
2242 if (netdevprops) {
2243 if (qemuMonitorAddNetdev(priv->mon, &netdevprops,
2244 NULL, NULL, 0, NULL, NULL, 0, -1, NULL) < 0)
2245 goto exit_monitor;
2246 }
2247
2248 if (devprops) {
2249 if (qemuMonitorAddDeviceProps(priv->mon, &devprops) < 0)
2250 goto exit_monitor;
2251 }
2252
2253 if (qemuDomainObjExitMonitor(driver, vm) < 0)
2254 goto audit;
2255
2256 qemuDomainChrInsertPreAlloced(vmdef, chr);
2257 ret = 0;
2258 audit:
2259 virDomainAuditChardev(vm, NULL, chr, "attach", ret == 0);
2260 cleanup:
2261 if (ret < 0) {
2262 if (virDomainObjIsActive(vm))
2263 qemuDomainChrInsertPreAllocCleanup(vmdef, chr);
2264 if (need_release)
2265 qemuDomainReleaseDeviceAddress(vm, &chr->info);
2266 if (teardowncgroup && qemuTeardownChardevCgroup(vm, chr) < 0)
2267 VIR_WARN("Unable to remove chr device cgroup ACL on hotplug fail");
2268 if (teardownlabel && qemuSecurityRestoreChardevLabel(driver, vm, chr) < 0)
2269 VIR_WARN("Unable to restore security label on char device");
2270 if (teardowndevice && qemuDomainNamespaceTeardownChardev(vm, chr) < 0)
2271 VIR_WARN("Unable to remove chr device from /dev");
2272 }
2273 return ret;
2274
2275 exit_monitor:
2276 virErrorPreserveLast(&orig_err);
2277 /* detach associated chardev on error */
2278 if (chardevAttached)
2279 qemuMonitorDetachCharDev(priv->mon, charAlias);
2280 ignore_value(qemuDomainObjExitMonitor(driver, vm));
2281 virErrorRestore(&orig_err);
2282
2283 qemuDomainDelTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE,
2284 secAlias, tlsAlias);
2285 goto audit;
2286 }
2287
2288
2289 int
qemuDomainAttachRNGDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainRNGDef * rng)2290 qemuDomainAttachRNGDevice(virQEMUDriver *driver,
2291 virDomainObj *vm,
2292 virDomainRNGDef *rng)
2293 {
2294 qemuDomainObjPrivate *priv = vm->privateData;
2295 virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_RNG, { .rng = rng } };
2296 virErrorPtr orig_err;
2297 g_autoptr(virJSONValue) devprops = NULL;
2298 g_autofree char *charAlias = NULL;
2299 g_autofree char *objAlias = NULL;
2300 g_autofree char *tlsAlias = NULL;
2301 const char *secAlias = NULL;
2302 bool releaseaddr = false;
2303 bool teardowncgroup = false;
2304 bool teardowndevice = false;
2305 bool chardevAdded = false;
2306 virJSONValue *props = NULL;
2307 int ret = -1;
2308
2309 qemuAssignDeviceRNGAlias(vm->def, rng);
2310
2311 /* preallocate space for the device definition */
2312 VIR_REALLOC_N(vm->def->rngs, vm->def->nrngs + 1);
2313
2314 if (qemuDomainEnsureVirtioAddress(&releaseaddr, vm, &dev) < 0)
2315 return -1;
2316
2317 if (qemuDomainNamespaceSetupRNG(vm, rng, &teardowndevice) < 0)
2318 goto cleanup;
2319
2320 if (qemuSetupRNGCgroup(vm, rng) < 0)
2321 goto cleanup;
2322 teardowncgroup = true;
2323
2324 /* build required metadata */
2325 if (!(devprops = qemuBuildRNGDevProps(vm->def, rng, priv->qemuCaps)))
2326 goto cleanup;
2327
2328 if (qemuBuildRNGBackendProps(rng, &props) < 0)
2329 goto cleanup;
2330
2331 if (!(charAlias = qemuAliasChardevFromDevAlias(rng->info.alias)))
2332 goto cleanup;
2333
2334 if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD) {
2335 if (qemuDomainAddChardevTLSObjects(driver, vm,
2336 rng->source.chardev,
2337 rng->info.alias, charAlias,
2338 &tlsAlias, &secAlias) < 0)
2339 goto audit;
2340 }
2341
2342 qemuDomainObjEnterMonitor(driver, vm);
2343
2344 if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD &&
2345 qemuHotplugChardevAttach(priv->mon, charAlias, rng->source.chardev) < 0)
2346 goto exit_monitor;
2347 chardevAdded = true;
2348
2349 if (qemuMonitorAddObject(priv->mon, &props, &objAlias) < 0)
2350 goto exit_monitor;
2351
2352 if (qemuDomainAttachExtensionDevice(priv->mon, &rng->info) < 0)
2353 goto exit_monitor;
2354
2355 if (qemuMonitorAddDeviceProps(priv->mon, &devprops) < 0) {
2356 ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &rng->info));
2357 goto exit_monitor;
2358 }
2359
2360 if (qemuDomainObjExitMonitor(driver, vm) < 0) {
2361 releaseaddr = false;
2362 goto cleanup;
2363 }
2364
2365 VIR_APPEND_ELEMENT_INPLACE(vm->def->rngs, vm->def->nrngs, rng);
2366
2367 ret = 0;
2368
2369 audit:
2370 virDomainAuditRNG(vm, NULL, rng, "attach", ret == 0);
2371 cleanup:
2372 virJSONValueFree(props);
2373 if (ret < 0) {
2374 if (releaseaddr)
2375 qemuDomainReleaseDeviceAddress(vm, &rng->info);
2376 if (teardowncgroup && qemuTeardownRNGCgroup(vm, rng) < 0)
2377 VIR_WARN("Unable to remove RNG device cgroup ACL on hotplug fail");
2378 if (teardowndevice && qemuDomainNamespaceTeardownRNG(vm, rng) < 0)
2379 VIR_WARN("Unable to remove chr device from /dev");
2380 }
2381
2382 return ret;
2383
2384 exit_monitor:
2385 virErrorPreserveLast(&orig_err);
2386 if (objAlias)
2387 ignore_value(qemuMonitorDelObject(priv->mon, objAlias, false));
2388 if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD && chardevAdded)
2389 ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
2390 if (qemuDomainObjExitMonitor(driver, vm) < 0)
2391 releaseaddr = false;
2392 virErrorRestore(&orig_err);
2393
2394 qemuDomainDelTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE,
2395 secAlias, tlsAlias);
2396 goto audit;
2397 }
2398
2399
2400 /**
2401 * qemuDomainAttachMemory:
2402 * @driver: qemu driver data
2403 * @vm: VM object
2404 * @mem: Definition of the memory device to be attached. @mem is always consumed
2405 *
2406 * Attaches memory device described by @mem to domain @vm.
2407 *
2408 * Returns 0 on success -1 on error.
2409 */
2410 int
qemuDomainAttachMemory(virQEMUDriver * driver,virDomainObj * vm,virDomainMemoryDef * mem)2411 qemuDomainAttachMemory(virQEMUDriver *driver,
2412 virDomainObj *vm,
2413 virDomainMemoryDef *mem)
2414 {
2415 qemuDomainObjPrivate *priv = vm->privateData;
2416 virErrorPtr orig_err;
2417 g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
2418 unsigned long long oldmem = virDomainDefGetMemoryTotal(vm->def);
2419 unsigned long long newmem = oldmem + mem->size;
2420 g_autoptr(virJSONValue) devprops = NULL;
2421 g_autofree char *objalias = NULL;
2422 bool objAdded = false;
2423 bool releaseaddr = false;
2424 bool teardownlabel = false;
2425 bool teardowncgroup = false;
2426 bool teardowndevice = false;
2427 virJSONValue *props = NULL;
2428 virObjectEvent *event;
2429 int id;
2430 int ret = -1;
2431
2432 if (qemuDomainMemoryDeviceAlignSize(vm->def, mem) < 0)
2433 goto cleanup;
2434
2435 if (qemuDomainDefValidateMemoryHotplug(vm->def, mem) < 0)
2436 goto cleanup;
2437
2438 if (qemuDomainAssignMemoryDeviceSlot(vm, mem) < 0)
2439 goto cleanup;
2440 releaseaddr = true;
2441
2442 /* in cases where we are using a VM with aliases generated according to the
2443 * index of the memory device we need to keep continue using that scheme */
2444 if (qemuAssignDeviceMemoryAlias(vm->def, mem, priv->memAliasOrderMismatch) < 0)
2445 goto cleanup;
2446
2447 objalias = g_strdup_printf("mem%s", mem->info.alias);
2448
2449 if (!(devprops = qemuBuildMemoryDeviceProps(vm->def, mem)))
2450 goto cleanup;
2451
2452 if (qemuBuildMemoryBackendProps(&props, objalias, cfg,
2453 priv, vm->def, mem, true, false) < 0)
2454 goto cleanup;
2455
2456 if (qemuProcessBuildDestroyMemoryPaths(driver, vm, mem, true) < 0)
2457 goto cleanup;
2458
2459 if (qemuDomainNamespaceSetupMemory(vm, mem, &teardowndevice) < 0)
2460 goto cleanup;
2461
2462 if (qemuSetupMemoryDevicesCgroup(vm, mem) < 0)
2463 goto cleanup;
2464 teardowncgroup = true;
2465
2466 if (qemuSecuritySetMemoryLabel(driver, vm, mem) < 0)
2467 goto cleanup;
2468 teardownlabel = true;
2469
2470 if (virDomainMemoryInsert(vm->def, mem) < 0)
2471 goto cleanup;
2472
2473 if (qemuDomainAdjustMaxMemLock(vm, false) < 0)
2474 goto removedef;
2475
2476 qemuDomainObjEnterMonitor(driver, vm);
2477 if (qemuMonitorAddObject(priv->mon, &props, NULL) < 0)
2478 goto exit_monitor;
2479 objAdded = true;
2480
2481 if (qemuMonitorAddDeviceProps(priv->mon, &devprops) < 0)
2482 goto exit_monitor;
2483
2484 if (qemuDomainObjExitMonitor(driver, vm) < 0) {
2485 /* we shouldn't touch mem now, as the def might be freed */
2486 mem = NULL;
2487 goto audit;
2488 }
2489
2490 event = virDomainEventDeviceAddedNewFromObj(vm, objalias);
2491 virObjectEventStateQueue(driver->domainEventState, event);
2492
2493 /* fix the balloon size */
2494 ignore_value(qemuProcessRefreshBalloonState(driver, vm, QEMU_ASYNC_JOB_NONE));
2495
2496 /* mem is consumed by vm->def */
2497 mem = NULL;
2498
2499 /* this step is best effort, removing the device would be so much trouble */
2500 ignore_value(qemuDomainUpdateMemoryDeviceInfo(driver, vm,
2501 QEMU_ASYNC_JOB_NONE));
2502
2503 ret = 0;
2504
2505 audit:
2506 virDomainAuditMemory(vm, oldmem, newmem, "update", ret == 0);
2507 cleanup:
2508 if (mem && ret < 0) {
2509 if (teardowncgroup && qemuTeardownMemoryDevicesCgroup(vm, mem) < 0)
2510 VIR_WARN("Unable to remove memory device cgroup ACL on hotplug fail");
2511 if (teardownlabel && qemuSecurityRestoreMemoryLabel(driver, vm, mem) < 0)
2512 VIR_WARN("Unable to restore security label on memdev");
2513 if (teardowndevice &&
2514 qemuDomainNamespaceTeardownMemory(vm, mem) < 0)
2515 VIR_WARN("Unable to remove memory device from /dev");
2516 if (releaseaddr)
2517 qemuDomainReleaseMemoryDeviceSlot(vm, mem);
2518 }
2519
2520 virJSONValueFree(props);
2521 virDomainMemoryDefFree(mem);
2522 return ret;
2523
2524 exit_monitor:
2525 virErrorPreserveLast(&orig_err);
2526 if (objAdded)
2527 ignore_value(qemuMonitorDelObject(priv->mon, objalias, false));
2528 if (qemuDomainObjExitMonitor(driver, vm) < 0)
2529 mem = NULL;
2530
2531 if (objAdded && mem)
2532 ignore_value(qemuProcessDestroyMemoryBackingPath(driver, vm, mem));
2533
2534 virErrorRestore(&orig_err);
2535 if (!mem)
2536 goto audit;
2537
2538 removedef:
2539 if ((id = virDomainMemoryFindByDef(vm->def, mem)) >= 0)
2540 mem = virDomainMemoryRemove(vm->def, id);
2541 else
2542 mem = NULL;
2543
2544 /* reset the mlock limit */
2545 virErrorPreserveLast(&orig_err);
2546 ignore_value(qemuDomainAdjustMaxMemLock(vm, false));
2547 virErrorRestore(&orig_err);
2548
2549 goto audit;
2550 }
2551
2552
2553 static int
qemuDomainAttachHostUSBDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainHostdevDef * hostdev)2554 qemuDomainAttachHostUSBDevice(virQEMUDriver *driver,
2555 virDomainObj *vm,
2556 virDomainHostdevDef *hostdev)
2557 {
2558 qemuDomainObjPrivate *priv = vm->privateData;
2559 g_autoptr(virJSONValue) devprops = NULL;
2560 bool added = false;
2561 bool teardowncgroup = false;
2562 bool teardownlabel = false;
2563 bool teardowndevice = false;
2564 int ret = -1;
2565
2566 if (virDomainUSBAddressEnsure(priv->usbaddrs, hostdev->info) < 0)
2567 return -1;
2568
2569 if (qemuHostdevPrepareUSBDevices(driver, vm->def->name, &hostdev, 1, 0) < 0)
2570 goto cleanup;
2571
2572 added = true;
2573
2574 if (qemuDomainNamespaceSetupHostdev(vm, hostdev, &teardowndevice) < 0)
2575 goto cleanup;
2576
2577 if (qemuSetupHostdevCgroup(vm, hostdev) < 0)
2578 goto cleanup;
2579 teardowncgroup = true;
2580
2581 if (qemuSecuritySetHostdevLabel(driver, vm, hostdev) < 0)
2582 goto cleanup;
2583 teardownlabel = true;
2584
2585 qemuAssignDeviceHostdevAlias(vm->def, &hostdev->info->alias, -1);
2586
2587 if (!(devprops = qemuBuildUSBHostdevDevProps(vm->def, hostdev, priv->qemuCaps)))
2588 goto cleanup;
2589
2590 VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1);
2591
2592 qemuDomainObjEnterMonitor(driver, vm);
2593 ret = qemuMonitorAddDeviceProps(priv->mon, &devprops);
2594 if (qemuDomainObjExitMonitor(driver, vm) < 0) {
2595 ret = -1;
2596 goto cleanup;
2597 }
2598 virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
2599 if (ret < 0)
2600 goto cleanup;
2601
2602 vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
2603
2604 ret = 0;
2605 cleanup:
2606 if (ret < 0) {
2607 if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
2608 VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
2609 if (teardownlabel &&
2610 qemuSecurityRestoreHostdevLabel(driver, vm, hostdev) < 0)
2611 VIR_WARN("Unable to restore host device labelling on hotplug fail");
2612 if (teardowndevice &&
2613 qemuDomainNamespaceTeardownHostdev(vm, hostdev) < 0)
2614 VIR_WARN("Unable to remove host device from /dev");
2615 if (added)
2616 qemuHostdevReAttachUSBDevices(driver, vm->def->name, &hostdev, 1);
2617 virDomainUSBAddressRelease(priv->usbaddrs, hostdev->info);
2618 }
2619 return ret;
2620 }
2621
2622
2623 static int
qemuDomainAttachHostSCSIDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainHostdevDef * hostdev)2624 qemuDomainAttachHostSCSIDevice(virQEMUDriver *driver,
2625 virDomainObj *vm,
2626 virDomainHostdevDef *hostdev)
2627 {
2628 size_t i;
2629 int ret = -1;
2630 qemuDomainObjPrivate *priv = vm->privateData;
2631 virErrorPtr orig_err;
2632 g_autoptr(qemuBlockStorageSourceAttachData) data = NULL;
2633 const char *backendalias = NULL;
2634 g_autoptr(virJSONValue) devprops = NULL;
2635 bool teardowncgroup = false;
2636 bool teardownlabel = false;
2637 bool teardowndevice = false;
2638
2639 /* Let's make sure the disk has a controller defined and loaded before
2640 * trying to add it. The controller used by the disk must exist before a
2641 * qemu command line string is generated.
2642 *
2643 * Ensure that the given controller and all controllers with a smaller index
2644 * exist; there must not be any missing index in between.
2645 */
2646 for (i = 0; i <= hostdev->info->addr.drive.controller; i++) {
2647 if (!qemuDomainFindOrCreateSCSIDiskController(driver, vm, i))
2648 return -1;
2649 }
2650
2651 if (qemuHostdevPrepareSCSIDevices(driver, vm->def->name, &hostdev, 1) < 0)
2652 return -1;
2653
2654 if (qemuDomainNamespaceSetupHostdev(vm, hostdev, &teardowndevice) < 0)
2655 goto cleanup;
2656
2657 if (qemuSetupHostdevCgroup(vm, hostdev) < 0)
2658 goto cleanup;
2659 teardowncgroup = true;
2660
2661 if (qemuSecuritySetHostdevLabel(driver, vm, hostdev) < 0)
2662 goto cleanup;
2663 teardownlabel = true;
2664
2665 qemuAssignDeviceHostdevAlias(vm->def, &hostdev->info->alias, -1);
2666
2667 if (qemuDomainPrepareHostdev(hostdev, priv) < 0)
2668 goto cleanup;
2669
2670 if (qemuProcessPrepareHostHostdev(hostdev) < 0)
2671 goto cleanup;
2672
2673 if (!(data = qemuBuildHostdevSCSIAttachPrepare(hostdev, &backendalias,
2674 priv->qemuCaps)))
2675 goto cleanup;
2676
2677 if (!(devprops = qemuBuildSCSIHostdevDevProps(vm->def, hostdev, backendalias)))
2678 goto cleanup;
2679
2680 VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1);
2681
2682 qemuDomainObjEnterMonitor(driver, vm);
2683
2684 if (qemuBlockStorageSourceAttachApply(priv->mon, data) < 0)
2685 goto exit_monitor;
2686
2687 if (qemuMonitorAddDeviceProps(priv->mon, &devprops) < 0)
2688 goto exit_monitor;
2689
2690 if (qemuDomainObjExitMonitor(driver, vm) < 0)
2691 goto cleanup;
2692
2693 virDomainAuditHostdev(vm, hostdev, "attach", true);
2694
2695 vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
2696
2697 ret = 0;
2698
2699 cleanup:
2700 if (ret < 0) {
2701 qemuHostdevReAttachSCSIDevices(driver, vm->def->name, &hostdev, 1);
2702 if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
2703 VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
2704 if (teardownlabel &&
2705 qemuSecurityRestoreHostdevLabel(driver, vm, hostdev) < 0)
2706 VIR_WARN("Unable to restore host device labelling on hotplug fail");
2707 if (teardowndevice &&
2708 qemuDomainNamespaceTeardownHostdev(vm, hostdev) < 0)
2709 VIR_WARN("Unable to remove host device from /dev");
2710 }
2711 qemuDomainSecretHostdevDestroy(hostdev);
2712 return ret;
2713
2714 exit_monitor:
2715 virErrorPreserveLast(&orig_err);
2716 qemuBlockStorageSourceAttachRollback(priv->mon, data);
2717 ignore_value(qemuDomainObjExitMonitor(driver, vm));
2718 virErrorRestore(&orig_err);
2719
2720 virDomainAuditHostdev(vm, hostdev, "attach", false);
2721
2722 goto cleanup;
2723 }
2724
2725 static int
qemuDomainAttachSCSIVHostDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainHostdevDef * hostdev)2726 qemuDomainAttachSCSIVHostDevice(virQEMUDriver *driver,
2727 virDomainObj *vm,
2728 virDomainHostdevDef *hostdev)
2729 {
2730 int ret = -1;
2731 qemuDomainObjPrivate *priv = vm->privateData;
2732 virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_HOSTDEV,
2733 { .hostdev = hostdev } };
2734 virDomainCCWAddressSet *ccwaddrs = NULL;
2735 g_autofree char *vhostfdName = NULL;
2736 int vhostfd = -1;
2737 g_autoptr(virJSONValue) devprops = NULL;
2738 bool removeextension = false;
2739 bool removehandle = false;
2740 bool teardowncgroup = false;
2741 bool teardownlabel = false;
2742 bool teardowndevice = false;
2743 bool releaseaddr = false;
2744
2745 if (qemuHostdevPrepareSCSIVHostDevices(driver, vm->def->name, &hostdev, 1) < 0)
2746 return -1;
2747
2748 if (qemuDomainNamespaceSetupHostdev(vm, hostdev, &teardowndevice) < 0)
2749 goto cleanup;
2750
2751 if (qemuSetupHostdevCgroup(vm, hostdev) < 0)
2752 goto cleanup;
2753 teardowncgroup = true;
2754
2755 if (qemuSecuritySetHostdevLabel(driver, vm, hostdev) < 0)
2756 goto cleanup;
2757 teardownlabel = true;
2758
2759 if (virSCSIVHostOpenVhostSCSI(&vhostfd) < 0)
2760 goto cleanup;
2761
2762 vhostfdName = g_strdup_printf("vhostfd-%d", vhostfd);
2763
2764 if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
2765 if (qemuDomainIsS390CCW(vm->def) &&
2766 virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_CCW))
2767 hostdev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW;
2768 }
2769
2770 if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE ||
2771 hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
2772 if (qemuDomainEnsurePCIAddress(vm, &dev) < 0)
2773 goto cleanup;
2774 } else if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
2775 if (!(ccwaddrs = virDomainCCWAddressSetCreateFromDomain(vm->def)))
2776 goto cleanup;
2777 if (virDomainCCWAddressAssign(hostdev->info, ccwaddrs,
2778 !hostdev->info->addr.ccw.assigned) < 0)
2779 goto cleanup;
2780 }
2781 releaseaddr = true;
2782
2783 qemuAssignDeviceHostdevAlias(vm->def, &hostdev->info->alias, -1);
2784
2785 if (!(devprops = qemuBuildSCSIVHostHostdevDevProps(vm->def,
2786 hostdev,
2787 priv->qemuCaps,
2788 vhostfdName)))
2789 goto cleanup;
2790
2791 VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1);
2792
2793 qemuDomainObjEnterMonitor(driver, vm);
2794
2795 if ((ret = qemuDomainAttachExtensionDevice(priv->mon, hostdev->info)) < 0)
2796 goto exit_monitor;
2797
2798 removeextension = true;
2799
2800 if ((ret = qemuMonitorSendFileHandle(priv->mon, vhostfdName, vhostfd)))
2801 goto exit_monitor;
2802
2803 removehandle = true;
2804
2805 if ((ret = qemuMonitorAddDeviceProps(priv->mon, &devprops)) < 0)
2806 goto exit_monitor;
2807
2808 removeextension = false;
2809 removehandle = false;
2810
2811 exit_monitor:
2812 if (removehandle)
2813 ignore_value(qemuMonitorCloseFileHandle(priv->mon, vhostfdName));
2814 if (removeextension)
2815 ignore_value(qemuDomainDetachExtensionDevice(priv->mon, hostdev->info));
2816 if (qemuDomainObjExitMonitor(driver, vm) < 0 || ret < 0)
2817 goto audit;
2818
2819 vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
2820 ret = 0;
2821
2822 audit:
2823 virDomainAuditHostdev(vm, hostdev, "attach", (ret == 0));
2824
2825 cleanup:
2826 if (ret < 0) {
2827 if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
2828 VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
2829 if (teardownlabel &&
2830 qemuSecurityRestoreHostdevLabel(driver, vm, hostdev) < 0)
2831 VIR_WARN("Unable to restore host device labelling on hotplug fail");
2832 if (teardowndevice &&
2833 qemuDomainNamespaceTeardownHostdev(vm, hostdev) < 0)
2834 VIR_WARN("Unable to remove host device from /dev");
2835 if (releaseaddr)
2836 qemuDomainReleaseDeviceAddress(vm, hostdev->info);
2837 }
2838
2839 virDomainCCWAddressSetFree(ccwaddrs);
2840
2841 VIR_FORCE_CLOSE(vhostfd);
2842 return ret;
2843 }
2844
2845
2846 static int
qemuDomainAttachMediatedDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainHostdevDef * hostdev)2847 qemuDomainAttachMediatedDevice(virQEMUDriver *driver,
2848 virDomainObj *vm,
2849 virDomainHostdevDef *hostdev)
2850 {
2851 int ret = -1;
2852 g_autoptr(virJSONValue) devprops = NULL;
2853 bool added = false;
2854 bool teardowncgroup = false;
2855 bool teardownlabel = false;
2856 bool teardowndevice = false;
2857 bool teardownmemlock = false;
2858 qemuDomainObjPrivate *priv = vm->privateData;
2859 virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_HOSTDEV,
2860 { .hostdev = hostdev } };
2861
2862 switch (hostdev->source.subsys.u.mdev.model) {
2863 case VIR_MDEV_MODEL_TYPE_VFIO_PCI:
2864 if (qemuDomainEnsurePCIAddress(vm, &dev) < 0)
2865 return -1;
2866 break;
2867 case VIR_MDEV_MODEL_TYPE_VFIO_CCW: {
2868 bool releaseaddr = false;
2869
2870 if (qemuDomainEnsureVirtioAddress(&releaseaddr, vm, &dev) < 0)
2871 return -1;
2872 } break;
2873 case VIR_MDEV_MODEL_TYPE_LAST:
2874 break;
2875 }
2876
2877 if (qemuHostdevPrepareMediatedDevices(driver,
2878 vm->def->name,
2879 &hostdev,
2880 1) < 0)
2881 goto cleanup;
2882 added = true;
2883
2884 if (qemuDomainNamespaceSetupHostdev(vm, hostdev, &teardowndevice) < 0)
2885 goto cleanup;
2886
2887 if (qemuSetupHostdevCgroup(vm, hostdev) < 0)
2888 goto cleanup;
2889 teardowncgroup = true;
2890
2891 if (qemuSecuritySetHostdevLabel(driver, vm, hostdev) < 0)
2892 goto cleanup;
2893 teardownlabel = true;
2894
2895 qemuAssignDeviceHostdevAlias(vm->def, &hostdev->info->alias, -1);
2896
2897 if (!(devprops = qemuBuildHostdevMediatedDevProps(vm->def, hostdev)))
2898 goto cleanup;
2899
2900 VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1);
2901
2902 if (qemuDomainAdjustMaxMemLockHostdev(vm, hostdev) < 0)
2903 goto cleanup;
2904 teardownmemlock = true;
2905
2906 qemuDomainObjEnterMonitor(driver, vm);
2907 ret = qemuMonitorAddDeviceProps(priv->mon, &devprops);
2908 if (qemuDomainObjExitMonitor(driver, vm) < 0) {
2909 ret = -1;
2910 goto cleanup;
2911 }
2912
2913 virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
2914 if (ret < 0)
2915 goto cleanup;
2916
2917 VIR_APPEND_ELEMENT_INPLACE(vm->def->hostdevs, vm->def->nhostdevs, hostdev);
2918 ret = 0;
2919 cleanup:
2920 if (ret < 0) {
2921 if (teardownmemlock && qemuDomainAdjustMaxMemLock(vm, false) < 0)
2922 VIR_WARN("Unable to reset maximum locked memory on hotplug fail");
2923 if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
2924 VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
2925 if (teardownlabel &&
2926 qemuSecurityRestoreHostdevLabel(driver, vm, hostdev) < 0)
2927 VIR_WARN("Unable to restore host device labelling on hotplug fail");
2928 if (teardowndevice &&
2929 qemuDomainNamespaceTeardownHostdev(vm, hostdev) < 0)
2930 VIR_WARN("Unable to remove host device from /dev");
2931 if (added)
2932 qemuHostdevReAttachMediatedDevices(driver,
2933 vm->def->name,
2934 &hostdev,
2935 1);
2936 qemuDomainReleaseDeviceAddress(vm, hostdev->info);
2937 }
2938 return ret;
2939 }
2940
2941
2942 int
qemuDomainAttachHostDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainHostdevDef * hostdev)2943 qemuDomainAttachHostDevice(virQEMUDriver *driver,
2944 virDomainObj *vm,
2945 virDomainHostdevDef *hostdev)
2946 {
2947 if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
2948 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
2949 _("hotplug is not supported for hostdev mode '%s'"),
2950 virDomainHostdevModeTypeToString(hostdev->mode));
2951 return -1;
2952 }
2953
2954 switch (hostdev->source.subsys.type) {
2955 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
2956 if (qemuDomainAttachHostPCIDevice(driver, vm,
2957 hostdev) < 0)
2958 return -1;
2959 break;
2960
2961 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
2962 if (qemuDomainAttachHostUSBDevice(driver, vm,
2963 hostdev) < 0)
2964 return -1;
2965 break;
2966
2967 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
2968 if (qemuDomainAttachHostSCSIDevice(driver, vm,
2969 hostdev) < 0)
2970 return -1;
2971 break;
2972
2973 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
2974 if (qemuDomainAttachSCSIVHostDevice(driver, vm, hostdev) < 0)
2975 return -1;
2976 break;
2977 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
2978 if (qemuDomainAttachMediatedDevice(driver, vm, hostdev) < 0)
2979 return -1;
2980 break;
2981
2982 default:
2983 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
2984 _("hotplug is not supported for hostdev subsys type '%s'"),
2985 virDomainHostdevSubsysTypeToString(hostdev->source.subsys.type));
2986 return -1;
2987 }
2988
2989 return 0;
2990 }
2991
2992
2993 int
qemuDomainAttachShmemDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainShmemDef * shmem)2994 qemuDomainAttachShmemDevice(virQEMUDriver *driver,
2995 virDomainObj *vm,
2996 virDomainShmemDef *shmem)
2997 {
2998 int ret = -1;
2999 g_autoptr(virJSONValue) devProps = NULL;
3000 g_autofree char *charAlias = NULL;
3001 g_autofree char *memAlias = NULL;
3002 bool release_backing = false;
3003 bool release_address = true;
3004 virErrorPtr orig_err = NULL;
3005 virJSONValue *props = NULL;
3006 qemuDomainObjPrivate *priv = vm->privateData;
3007 virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_SHMEM, { .shmem = shmem } };
3008
3009 switch (shmem->model) {
3010 case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_PLAIN:
3011 case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_DOORBELL:
3012 break;
3013
3014 case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM:
3015 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
3016 _("live attach of shmem model '%s' is not supported"),
3017 virDomainShmemModelTypeToString(shmem->model));
3018 G_GNUC_FALLTHROUGH;
3019 case VIR_DOMAIN_SHMEM_MODEL_LAST:
3020 return -1;
3021 }
3022
3023 qemuAssignDeviceShmemAlias(vm->def, shmem, -1);
3024
3025 qemuDomainPrepareShmemChardev(shmem);
3026
3027 VIR_REALLOC_N(vm->def->shmems, vm->def->nshmems + 1);
3028
3029 if ((shmem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE ||
3030 shmem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
3031 (qemuDomainEnsurePCIAddress(vm, &dev) < 0))
3032 return -1;
3033
3034 if (!(devProps = qemuBuildShmemDevProps(vm->def, shmem)))
3035 goto cleanup;
3036
3037 if (shmem->server.enabled) {
3038 charAlias = g_strdup_printf("char%s", shmem->info.alias);
3039 } else {
3040 if (!(props = qemuBuildShmemBackendMemProps(shmem)))
3041 goto cleanup;
3042
3043 }
3044
3045 qemuDomainObjEnterMonitor(driver, vm);
3046
3047 if (shmem->server.enabled) {
3048 if (qemuHotplugChardevAttach(priv->mon, charAlias, shmem->server.chr) < 0)
3049 goto exit_monitor;
3050 } else {
3051 if (qemuMonitorAddObject(priv->mon, &props, &memAlias) < 0)
3052 goto exit_monitor;
3053 }
3054
3055 release_backing = true;
3056
3057 if (qemuDomainAttachExtensionDevice(priv->mon, &shmem->info) < 0)
3058 goto exit_monitor;
3059
3060 if (qemuMonitorAddDeviceProps(priv->mon, &devProps) < 0) {
3061 ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &shmem->info));
3062 goto exit_monitor;
3063 }
3064
3065 if (qemuDomainObjExitMonitor(driver, vm) < 0) {
3066 release_address = false;
3067 goto cleanup;
3068 }
3069
3070 /* Doing a copy here just so the pointer doesn't get nullified
3071 * because we need it in the audit function */
3072 VIR_APPEND_ELEMENT_COPY_INPLACE(vm->def->shmems, vm->def->nshmems, shmem);
3073
3074 ret = 0;
3075 release_address = false;
3076
3077 audit:
3078 virDomainAuditShmem(vm, shmem, "attach", ret == 0);
3079
3080 cleanup:
3081 if (release_address)
3082 qemuDomainReleaseDeviceAddress(vm, &shmem->info);
3083
3084 virJSONValueFree(props);
3085
3086 return ret;
3087
3088 exit_monitor:
3089 virErrorPreserveLast(&orig_err);
3090 if (release_backing) {
3091 if (shmem->server.enabled)
3092 ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
3093 else
3094 ignore_value(qemuMonitorDelObject(priv->mon, memAlias, false));
3095 }
3096
3097 if (qemuDomainObjExitMonitor(driver, vm) < 0)
3098 release_address = false;
3099
3100 virErrorRestore(&orig_err);
3101
3102 goto audit;
3103 }
3104
3105
3106 int
qemuDomainAttachWatchdog(virQEMUDriver * driver,virDomainObj * vm,virDomainWatchdogDef * watchdog)3107 qemuDomainAttachWatchdog(virQEMUDriver *driver,
3108 virDomainObj *vm,
3109 virDomainWatchdogDef *watchdog)
3110 {
3111 int ret = -1;
3112 qemuDomainObjPrivate *priv = vm->privateData;
3113 virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_WATCHDOG, { .watchdog = watchdog } };
3114 g_autoptr(virJSONValue) props = NULL;
3115 bool releaseAddress = false;
3116 int rv;
3117
3118 if (vm->def->watchdog) {
3119 virReportError(VIR_ERR_OPERATION_INVALID, "%s",
3120 _("domain already has a watchdog"));
3121 return -1;
3122 }
3123
3124 qemuAssignDeviceWatchdogAlias(watchdog);
3125
3126 if (watchdog->model == VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB) {
3127 if (qemuDomainEnsurePCIAddress(vm, &dev) < 0)
3128 goto cleanup;
3129 releaseAddress = true;
3130 } else {
3131 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
3132 _("hotplug of watchdog of model %s is not supported"),
3133 virDomainWatchdogModelTypeToString(watchdog->model));
3134 goto cleanup;
3135 }
3136
3137 if (!(props = qemuBuildWatchdogDevProps(vm->def, watchdog)))
3138 goto cleanup;
3139
3140 qemuDomainObjEnterMonitor(driver, vm);
3141
3142 /* QEMU doesn't have a 'dump' action; we tell qemu to 'pause', then
3143 libvirt listens for the watchdog event, and we perform the dump
3144 ourselves. so convert 'dump' to 'pause' for the qemu cli */
3145 if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SET_ACTION)) {
3146 qemuMonitorActionWatchdog watchdogaction = QEMU_MONITOR_ACTION_WATCHDOG_KEEP;
3147
3148 switch (watchdog->action) {
3149 case VIR_DOMAIN_WATCHDOG_ACTION_RESET:
3150 watchdogaction = QEMU_MONITOR_ACTION_WATCHDOG_RESET;
3151 break;
3152
3153 case VIR_DOMAIN_WATCHDOG_ACTION_SHUTDOWN:
3154 watchdogaction = QEMU_MONITOR_ACTION_WATCHDOG_SHUTDOWN;
3155 break;
3156
3157 case VIR_DOMAIN_WATCHDOG_ACTION_POWEROFF:
3158 watchdogaction = QEMU_MONITOR_ACTION_WATCHDOG_POWEROFF;
3159 break;
3160
3161 case VIR_DOMAIN_WATCHDOG_ACTION_PAUSE:
3162 case VIR_DOMAIN_WATCHDOG_ACTION_DUMP:
3163 watchdogaction = QEMU_MONITOR_ACTION_WATCHDOG_PAUSE;
3164 break;
3165
3166 case VIR_DOMAIN_WATCHDOG_ACTION_NONE:
3167 watchdogaction = QEMU_MONITOR_ACTION_WATCHDOG_NONE;
3168 break;
3169
3170 case VIR_DOMAIN_WATCHDOG_ACTION_INJECTNMI:
3171 watchdogaction = QEMU_MONITOR_ACTION_WATCHDOG_INJECT_NMI;
3172 break;
3173
3174 case VIR_DOMAIN_WATCHDOG_ACTION_LAST:
3175 default:
3176 break;
3177 };
3178
3179 rv = qemuMonitorSetAction(priv->mon,
3180 QEMU_MONITOR_ACTION_SHUTDOWN_KEEP,
3181 QEMU_MONITOR_ACTION_REBOOT_KEEP,
3182 watchdogaction,
3183 QEMU_MONITOR_ACTION_PANIC_KEEP);
3184 } else {
3185 virDomainWatchdogAction actualAction = watchdog->action;
3186
3187 if (actualAction == VIR_DOMAIN_WATCHDOG_ACTION_DUMP)
3188 actualAction = VIR_DOMAIN_WATCHDOG_ACTION_PAUSE;
3189
3190 rv = qemuMonitorSetWatchdogAction(priv->mon,
3191 virDomainWatchdogActionTypeToString(actualAction));
3192 }
3193
3194 if (rv >= 0)
3195 rv = qemuMonitorAddDeviceProps(priv->mon, &props);
3196
3197 if (qemuDomainObjExitMonitor(driver, vm) < 0) {
3198 releaseAddress = false;
3199 goto cleanup;
3200 }
3201
3202 if (rv < 0)
3203 goto cleanup;
3204
3205 releaseAddress = false;
3206 vm->def->watchdog = watchdog;
3207 ret = 0;
3208
3209 cleanup:
3210 if (releaseAddress)
3211 qemuDomainReleaseDeviceAddress(vm, &watchdog->info);
3212 return ret;
3213 }
3214
3215
3216 int
qemuDomainAttachInputDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainInputDef * input)3217 qemuDomainAttachInputDevice(virQEMUDriver *driver,
3218 virDomainObj *vm,
3219 virDomainInputDef *input)
3220 {
3221 int ret = -1;
3222 g_autoptr(virJSONValue) devprops = NULL;
3223 qemuDomainObjPrivate *priv = vm->privateData;
3224 virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_INPUT,
3225 { .input = input } };
3226 virErrorPtr originalError = NULL;
3227 bool releaseaddr = false;
3228 bool teardowndevice = false;
3229 bool teardownlabel = false;
3230 bool teardowncgroup = false;
3231
3232 qemuAssignDeviceInputAlias(vm->def, input, -1);
3233
3234 switch ((virDomainInputBus) input->bus) {
3235 case VIR_DOMAIN_INPUT_BUS_USB:
3236 if (virDomainUSBAddressEnsure(priv->usbaddrs, &input->info) < 0)
3237 return -1;
3238
3239 releaseaddr = true;
3240
3241 if (!(devprops = qemuBuildInputUSBDevProps(vm->def, input)))
3242 goto cleanup;
3243 break;
3244
3245 case VIR_DOMAIN_INPUT_BUS_VIRTIO:
3246 if (qemuDomainEnsureVirtioAddress(&releaseaddr, vm, &dev) < 0)
3247 goto cleanup;
3248
3249 if (!(devprops = qemuBuildInputVirtioDevProps(vm->def, input, priv->qemuCaps)))
3250 goto cleanup;
3251 break;
3252
3253 case VIR_DOMAIN_INPUT_BUS_PS2:
3254 case VIR_DOMAIN_INPUT_BUS_XEN:
3255 case VIR_DOMAIN_INPUT_BUS_PARALLELS:
3256 case VIR_DOMAIN_INPUT_BUS_NONE:
3257 case VIR_DOMAIN_INPUT_BUS_LAST:
3258 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
3259 _("input device on bus '%s' cannot be hot plugged."),
3260 virDomainInputBusTypeToString(input->bus));
3261 return -1;
3262 }
3263
3264 if (qemuDomainNamespaceSetupInput(vm, input, &teardowndevice) < 0)
3265 goto cleanup;
3266
3267 if (qemuSetupInputCgroup(vm, input) < 0)
3268 goto cleanup;
3269 teardowncgroup = true;
3270
3271 if (qemuSecuritySetInputLabel(vm, input) < 0)
3272 goto cleanup;
3273 teardownlabel = true;
3274
3275 VIR_REALLOC_N(vm->def->inputs, vm->def->ninputs + 1);
3276
3277 qemuDomainObjEnterMonitor(driver, vm);
3278
3279 if (qemuDomainAttachExtensionDevice(priv->mon, &input->info) < 0)
3280 goto exit_monitor;
3281
3282 if (qemuMonitorAddDeviceProps(priv->mon, &devprops) < 0) {
3283 ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &input->info));
3284 goto exit_monitor;
3285 }
3286
3287 if (qemuDomainObjExitMonitor(driver, vm) < 0) {
3288 releaseaddr = false;
3289 goto cleanup;
3290 }
3291
3292 VIR_APPEND_ELEMENT_COPY_INPLACE(vm->def->inputs, vm->def->ninputs, input);
3293
3294 ret = 0;
3295
3296 audit:
3297 virDomainAuditInput(vm, input, "attach", ret == 0);
3298
3299 cleanup:
3300 if (ret < 0) {
3301 virErrorPreserveLast(&originalError);
3302 if (teardownlabel)
3303 qemuSecurityRestoreInputLabel(vm, input);
3304 if (teardowncgroup)
3305 qemuTeardownInputCgroup(vm, input);
3306 if (teardowndevice)
3307 qemuDomainNamespaceTeardownInput(vm, input);
3308 if (releaseaddr)
3309 qemuDomainReleaseDeviceAddress(vm, &input->info);
3310 virErrorRestore(&originalError);
3311 }
3312
3313 return ret;
3314
3315 exit_monitor:
3316 if (qemuDomainObjExitMonitor(driver, vm) < 0) {
3317 releaseaddr = false;
3318 goto cleanup;
3319 }
3320 goto audit;
3321 }
3322
3323
3324 int
qemuDomainAttachVsockDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainVsockDef * vsock)3325 qemuDomainAttachVsockDevice(virQEMUDriver *driver,
3326 virDomainObj *vm,
3327 virDomainVsockDef *vsock)
3328 {
3329 qemuDomainVsockPrivate *vsockPriv = (qemuDomainVsockPrivate *)vsock->privateData;
3330 qemuDomainObjPrivate *priv = vm->privateData;
3331 virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_VSOCK,
3332 { .vsock = vsock } };
3333 virErrorPtr originalError = NULL;
3334 const char *fdprefix = "vsockfd";
3335 bool releaseaddr = false;
3336 g_autofree char *fdname = NULL;
3337 g_autoptr(virJSONValue) devprops = NULL;
3338 bool removeextension = false;
3339 bool removehandle = false;
3340 int ret = -1;
3341
3342 if (vm->def->vsock) {
3343 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
3344 _("the domain already has a vsock device"));
3345 return -1;
3346 }
3347
3348 if (qemuDomainEnsureVirtioAddress(&releaseaddr, vm, &dev) < 0)
3349 return -1;
3350
3351 qemuAssignDeviceVsockAlias(vsock);
3352
3353 if (qemuProcessOpenVhostVsock(vsock) < 0)
3354 goto cleanup;
3355
3356 fdname = g_strdup_printf("%s%u", fdprefix, vsockPriv->vhostfd);
3357
3358 if (!(devprops = qemuBuildVsockDevProps(vm->def, vsock, priv->qemuCaps, fdprefix)))
3359 goto cleanup;
3360
3361 qemuDomainObjEnterMonitor(driver, vm);
3362
3363 if (qemuDomainAttachExtensionDevice(priv->mon, &vsock->info) < 0)
3364 goto exit_monitor;
3365
3366 removeextension = true;
3367
3368 if ((ret = qemuMonitorSendFileHandle(priv->mon, fdname, vsockPriv->vhostfd)) < 0)
3369 goto exit_monitor;
3370
3371 removehandle = true;
3372
3373 if ((ret = qemuMonitorAddDeviceProps(priv->mon, &devprops)) < 0)
3374 goto exit_monitor;
3375
3376 if (qemuDomainObjExitMonitor(driver, vm) < 0) {
3377 releaseaddr = false;
3378 goto cleanup;
3379 }
3380
3381 vm->def->vsock = g_steal_pointer(&vsock);
3382
3383 ret = 0;
3384
3385 cleanup:
3386 if (ret < 0) {
3387 virErrorPreserveLast(&originalError);
3388 if (releaseaddr)
3389 qemuDomainReleaseDeviceAddress(vm, &vsock->info);
3390 virErrorRestore(&originalError);
3391 }
3392
3393 return ret;
3394
3395 exit_monitor:
3396 if (removehandle)
3397 ignore_value(qemuMonitorCloseFileHandle(priv->mon, fdname));
3398 if (removeextension)
3399 ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &vsock->info));
3400 if (qemuDomainObjExitMonitor(driver, vm) < 0)
3401 releaseaddr = false;
3402 goto cleanup;
3403 }
3404
3405
3406 int
qemuDomainAttachFSDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainFSDef * fs)3407 qemuDomainAttachFSDevice(virQEMUDriver *driver,
3408 virDomainObj *vm,
3409 virDomainFSDef *fs)
3410 {
3411 qemuDomainObjPrivate *priv = vm->privateData;
3412 virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_FS,
3413 { .fs = fs } };
3414 g_autoptr(virDomainChrSourceDef) chardev = NULL;
3415 g_autoptr(virJSONValue) devprops = NULL;
3416 virErrorPtr origErr = NULL;
3417 bool releaseaddr = false;
3418 bool chardevAdded = false;
3419 bool started = false;
3420 g_autofree char *charAlias = NULL;
3421 int ret = -1;
3422
3423 if (fs->fsdriver != VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) {
3424 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
3425 _("only virtiofs filesystems can be hotplugged"));
3426 return -1;
3427 }
3428
3429 if (qemuDomainEnsureVirtioAddress(&releaseaddr, vm, &dev) < 0)
3430 return -1;
3431
3432 qemuAssignDeviceFSAlias(vm->def, fs);
3433
3434 chardev = virDomainChrSourceDefNew(priv->driver->xmlopt);
3435 chardev->type = VIR_DOMAIN_CHR_TYPE_UNIX;
3436 chardev->data.nix.path = qemuDomainGetVHostUserFSSocketPath(priv, fs);
3437
3438 charAlias = qemuDomainGetVhostUserChrAlias(fs->info.alias);
3439
3440 if (!(devprops = qemuBuildVHostUserFsDevProps(fs, vm->def, charAlias, priv)))
3441 goto cleanup;
3442
3443 if (!fs->sock) {
3444 if (qemuVirtioFSPrepareDomain(driver, fs) < 0)
3445 goto cleanup;
3446
3447 if (qemuVirtioFSStart(driver, vm, fs) < 0)
3448 goto cleanup;
3449 started = true;
3450
3451 if (qemuVirtioFSSetupCgroup(vm, fs, priv->cgroup) < 0)
3452 goto cleanup;
3453 }
3454
3455 qemuDomainObjEnterMonitor(driver, vm);
3456
3457 if (qemuHotplugChardevAttach(priv->mon, charAlias, chardev) < 0)
3458 goto exit_monitor;
3459 chardevAdded = true;
3460
3461 if (qemuDomainAttachExtensionDevice(priv->mon, &fs->info) < 0)
3462 goto exit_monitor;
3463
3464 if (qemuMonitorAddDeviceProps(priv->mon, &devprops) < 0) {
3465 ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &fs->info));
3466 goto exit_monitor;
3467 }
3468
3469 if (qemuDomainObjExitMonitor(driver, vm) < 0) {
3470 releaseaddr = false;
3471 goto cleanup;
3472 }
3473
3474 VIR_APPEND_ELEMENT_COPY(vm->def->fss, vm->def->nfss, fs);
3475
3476 ret = 0;
3477
3478 audit:
3479 virDomainAuditFS(vm, NULL, fs, "attach", ret == 0);
3480 cleanup:
3481 if (ret < 0) {
3482 virErrorPreserveLast(&origErr);
3483 if (releaseaddr)
3484 qemuDomainReleaseDeviceAddress(vm, &fs->info);
3485 if (started)
3486 qemuVirtioFSStop(driver, vm, fs);
3487 virErrorRestore(&origErr);
3488 }
3489
3490 return ret;
3491
3492 exit_monitor:
3493 virErrorPreserveLast(&origErr);
3494 if (chardevAdded)
3495 ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
3496 if (qemuDomainObjExitMonitor(driver, vm) < 0)
3497 releaseaddr = false;
3498 virErrorRestore(&origErr);
3499 goto audit;
3500 }
3501
3502
3503 int
qemuDomainAttachLease(virQEMUDriver * driver,virDomainObj * vm,virDomainLeaseDef * lease)3504 qemuDomainAttachLease(virQEMUDriver *driver,
3505 virDomainObj *vm,
3506 virDomainLeaseDef *lease)
3507 {
3508 g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
3509
3510 virDomainLeaseInsertPreAlloc(vm->def);
3511
3512 if (virDomainLockLeaseAttach(driver->lockManager, cfg->uri,
3513 vm, lease) < 0) {
3514 virDomainLeaseInsertPreAlloced(vm->def, NULL);
3515 return -1;
3516 }
3517
3518 virDomainLeaseInsertPreAlloced(vm->def, lease);
3519 return 0;
3520 }
3521
3522
3523 static int
qemuDomainChangeNetBridge(virDomainObj * vm,virDomainNetDef * olddev,virDomainNetDef * newdev)3524 qemuDomainChangeNetBridge(virDomainObj *vm,
3525 virDomainNetDef *olddev,
3526 virDomainNetDef *newdev)
3527 {
3528 int ret = -1;
3529 const char *oldbridge = virDomainNetGetActualBridgeName(olddev);
3530 const char *newbridge = virDomainNetGetActualBridgeName(newdev);
3531
3532 if (!oldbridge || !newbridge) {
3533 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing bridge name"));
3534 return -1;
3535 }
3536
3537 VIR_DEBUG("Change bridge for interface %s: %s -> %s",
3538 olddev->ifname, oldbridge, newbridge);
3539
3540 if (virNetDevExists(newbridge) != 1) {
3541 virReportError(VIR_ERR_OPERATION_FAILED,
3542 _("bridge %s doesn't exist"), newbridge);
3543 return -1;
3544 }
3545
3546 ret = virNetDevBridgeRemovePort(oldbridge, olddev->ifname);
3547 virDomainAuditNet(vm, olddev, NULL, "detach", ret == 0);
3548 if (ret < 0) {
3549 /* warn but continue - possibly the old network
3550 * had been destroyed and reconstructed, leaving the
3551 * tap device orphaned.
3552 */
3553 VIR_WARN("Unable to detach device %s from bridge %s",
3554 olddev->ifname, oldbridge);
3555 }
3556
3557 ret = virNetDevBridgeAddPort(newbridge, olddev->ifname);
3558 if (ret == 0 &&
3559 virDomainNetGetActualPortOptionsIsolated(newdev) == VIR_TRISTATE_BOOL_YES) {
3560
3561 ret = virNetDevBridgePortSetIsolated(newbridge, olddev->ifname, true);
3562 if (ret < 0) {
3563 virErrorPtr err;
3564
3565 virErrorPreserveLast(&err);
3566 ignore_value(virNetDevBridgeRemovePort(newbridge, olddev->ifname));
3567 virErrorRestore(&err);
3568 }
3569 }
3570 virDomainAuditNet(vm, NULL, newdev, "attach", ret == 0);
3571 if (ret < 0) {
3572 virErrorPtr err;
3573
3574 virErrorPreserveLast(&err);
3575 ret = virNetDevBridgeAddPort(oldbridge, olddev->ifname);
3576 if (ret == 0 &&
3577 virDomainNetGetActualPortOptionsIsolated(olddev) == VIR_TRISTATE_BOOL_YES) {
3578 ignore_value(virNetDevBridgePortSetIsolated(newbridge, olddev->ifname, true));
3579 }
3580 virDomainAuditNet(vm, NULL, olddev, "attach", ret == 0);
3581 virErrorRestore(&err);
3582 return -1;
3583 }
3584 /* caller will replace entire olddev with newdev in domain nets list */
3585 return 0;
3586 }
3587
3588 static int
qemuDomainChangeNetFilter(virDomainObj * vm,virDomainNetDef * olddev,virDomainNetDef * newdev)3589 qemuDomainChangeNetFilter(virDomainObj *vm,
3590 virDomainNetDef *olddev,
3591 virDomainNetDef *newdev)
3592 {
3593 /* make sure this type of device supports filters. */
3594 switch (virDomainNetGetActualType(newdev)) {
3595 case VIR_DOMAIN_NET_TYPE_ETHERNET:
3596 case VIR_DOMAIN_NET_TYPE_BRIDGE:
3597 case VIR_DOMAIN_NET_TYPE_NETWORK:
3598 break;
3599 case VIR_DOMAIN_NET_TYPE_USER:
3600 case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
3601 case VIR_DOMAIN_NET_TYPE_SERVER:
3602 case VIR_DOMAIN_NET_TYPE_CLIENT:
3603 case VIR_DOMAIN_NET_TYPE_MCAST:
3604 case VIR_DOMAIN_NET_TYPE_INTERNAL:
3605 case VIR_DOMAIN_NET_TYPE_DIRECT:
3606 case VIR_DOMAIN_NET_TYPE_HOSTDEV:
3607 case VIR_DOMAIN_NET_TYPE_UDP:
3608 case VIR_DOMAIN_NET_TYPE_VDPA:
3609 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
3610 _("filters not supported on interfaces of type %s"),
3611 virDomainNetTypeToString(virDomainNetGetActualType(newdev)));
3612 return -1;
3613 case VIR_DOMAIN_NET_TYPE_LAST:
3614 default:
3615 virReportEnumRangeError(virDomainNetType,
3616 virDomainNetGetActualType(newdev));
3617 return -1;
3618 }
3619
3620 virDomainConfNWFilterTeardown(olddev);
3621
3622 if (newdev->filter &&
3623 virDomainConfNWFilterInstantiate(vm->def->name,
3624 vm->def->uuid, newdev, false) < 0) {
3625 virErrorPtr errobj;
3626
3627 virReportError(VIR_ERR_OPERATION_FAILED,
3628 _("failed to add new filter rules to '%s' "
3629 "- attempting to restore old rules"),
3630 olddev->ifname);
3631 virErrorPreserveLast(&errobj);
3632 ignore_value(virDomainConfNWFilterInstantiate(vm->def->name,
3633 vm->def->uuid, olddev, false));
3634 virErrorRestore(&errobj);
3635 return -1;
3636 }
3637 return 0;
3638 }
3639
qemuDomainChangeNetLinkState(virQEMUDriver * driver,virDomainObj * vm,virDomainNetDef * dev,int linkstate)3640 int qemuDomainChangeNetLinkState(virQEMUDriver *driver,
3641 virDomainObj *vm,
3642 virDomainNetDef *dev,
3643 int linkstate)
3644 {
3645 int ret = -1;
3646 qemuDomainObjPrivate *priv = vm->privateData;
3647
3648 if (!dev->info.alias) {
3649 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
3650 _("can't change link state: device alias not found"));
3651 return -1;
3652 }
3653
3654 VIR_DEBUG("dev: %s, state: %d", dev->info.alias, linkstate);
3655
3656 qemuDomainObjEnterMonitor(driver, vm);
3657
3658 ret = qemuMonitorSetLink(priv->mon, dev->info.alias, linkstate);
3659 if (ret < 0)
3660 goto cleanup;
3661
3662 /* modify the device configuration */
3663 dev->linkstate = linkstate;
3664
3665 cleanup:
3666 if (qemuDomainObjExitMonitor(driver, vm) < 0)
3667 return -1;
3668
3669 return ret;
3670 }
3671
3672 int
qemuDomainChangeNet(virQEMUDriver * driver,virDomainObj * vm,virDomainDeviceDef * dev)3673 qemuDomainChangeNet(virQEMUDriver *driver,
3674 virDomainObj *vm,
3675 virDomainDeviceDef *dev)
3676 {
3677 qemuDomainObjPrivate *priv = vm->privateData;
3678 virDomainNetDef *newdev = dev->data.net;
3679 virDomainNetDef **devslot = NULL;
3680 virDomainNetDef *olddev;
3681 virDomainNetType oldType, newType;
3682 bool needReconnect = false;
3683 bool needBridgeChange = false;
3684 bool needFilterChange = false;
3685 bool needLinkStateChange = false;
3686 bool needReplaceDevDef = false;
3687 bool needBandwidthSet = false;
3688 bool needCoalesceChange = false;
3689 bool needVlanUpdate = false;
3690 bool needIsolatedPortChange = false;
3691 int ret = -1;
3692 int changeidx = -1;
3693 g_autoptr(virConnect) conn = NULL;
3694 virErrorPtr save_err = NULL;
3695
3696 if ((changeidx = virDomainNetFindIdx(vm->def, newdev)) < 0)
3697 goto cleanup;
3698 devslot = &vm->def->nets[changeidx];
3699 olddev = *devslot;
3700
3701 oldType = virDomainNetGetActualType(olddev);
3702 if (oldType == VIR_DOMAIN_NET_TYPE_HOSTDEV ||
3703 oldType == VIR_DOMAIN_NET_TYPE_VDPA) {
3704 /* no changes are possible to a type='hostdev' or type='vdpa' interface */
3705 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
3706 _("cannot change config of '%s' network interface type"),
3707 virDomainNetTypeToString(oldType));
3708 goto cleanup;
3709 }
3710
3711 /* Check individual attributes for changes that can't be done to a
3712 * live netdev. These checks *mostly* go in order of the
3713 * declarations in virDomainNetDef in order to assure nothing is
3714 * omitted. (exceptiong where noted in comments - in particular,
3715 * some things require that a new "actual device" be allocated
3716 * from the network driver first, but we delay doing that until
3717 * after we've made as many other checks as possible)
3718 */
3719
3720 /* type: this can change (with some restrictions), but the actual
3721 * type of the new device connection isn't known until after we
3722 * allocate the "actual" device.
3723 */
3724
3725 if (virMacAddrCmp(&olddev->mac, &newdev->mac)) {
3726 char oldmac[VIR_MAC_STRING_BUFLEN], newmac[VIR_MAC_STRING_BUFLEN];
3727
3728 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
3729 _("cannot change network interface mac address "
3730 "from %s to %s"),
3731 virMacAddrFormat(&olddev->mac, oldmac),
3732 virMacAddrFormat(&newdev->mac, newmac));
3733 goto cleanup;
3734 }
3735
3736 if (STRNEQ_NULLABLE(virDomainNetGetModelString(olddev),
3737 virDomainNetGetModelString(newdev))) {
3738 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
3739 _("cannot modify network device model from %s to %s"),
3740 NULLSTR(virDomainNetGetModelString(olddev)),
3741 NULLSTR(virDomainNetGetModelString(newdev)));
3742 goto cleanup;
3743 }
3744
3745 if (olddev->model != newdev->model) {
3746 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
3747 _("cannot modify network device model from %s to %s"),
3748 virDomainNetModelTypeToString(olddev->model),
3749 virDomainNetModelTypeToString(newdev->model));
3750 goto cleanup;
3751 }
3752
3753 if (virDomainNetIsVirtioModel(olddev) &&
3754 (olddev->driver.virtio.name != newdev->driver.virtio.name ||
3755 olddev->driver.virtio.txmode != newdev->driver.virtio.txmode ||
3756 olddev->driver.virtio.ioeventfd != newdev->driver.virtio.ioeventfd ||
3757 olddev->driver.virtio.event_idx != newdev->driver.virtio.event_idx ||
3758 olddev->driver.virtio.queues != newdev->driver.virtio.queues ||
3759 olddev->driver.virtio.rx_queue_size != newdev->driver.virtio.rx_queue_size ||
3760 olddev->driver.virtio.tx_queue_size != newdev->driver.virtio.tx_queue_size ||
3761 olddev->driver.virtio.host.csum != newdev->driver.virtio.host.csum ||
3762 olddev->driver.virtio.host.gso != newdev->driver.virtio.host.gso ||
3763 olddev->driver.virtio.host.tso4 != newdev->driver.virtio.host.tso4 ||
3764 olddev->driver.virtio.host.tso6 != newdev->driver.virtio.host.tso6 ||
3765 olddev->driver.virtio.host.ecn != newdev->driver.virtio.host.ecn ||
3766 olddev->driver.virtio.host.ufo != newdev->driver.virtio.host.ufo ||
3767 olddev->driver.virtio.host.mrg_rxbuf != newdev->driver.virtio.host.mrg_rxbuf ||
3768 olddev->driver.virtio.guest.csum != newdev->driver.virtio.guest.csum ||
3769 olddev->driver.virtio.guest.tso4 != newdev->driver.virtio.guest.tso4 ||
3770 olddev->driver.virtio.guest.tso6 != newdev->driver.virtio.guest.tso6 ||
3771 olddev->driver.virtio.guest.ecn != newdev->driver.virtio.guest.ecn ||
3772 olddev->driver.virtio.guest.ufo != newdev->driver.virtio.guest.ufo)) {
3773 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
3774 _("cannot modify virtio network device driver attributes"));
3775 goto cleanup;
3776 }
3777
3778 if (!!olddev->virtio != !!newdev->virtio ||
3779 (olddev->virtio && newdev->virtio &&
3780 (olddev->virtio->iommu != newdev->virtio->iommu ||
3781 olddev->virtio->ats != newdev->virtio->ats ||
3782 olddev->virtio->packed != newdev->virtio->packed ||
3783 olddev->virtio->page_per_vq != newdev->virtio->page_per_vq))) {
3784 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
3785 _("cannot modify virtio network device driver options"));
3786 goto cleanup;
3787 }
3788
3789 /* data: this union will be examined later, after allocating new actualdev */
3790 /* virtPortProfile: will be examined later, after allocating new actualdev */
3791
3792 if (olddev->tune.sndbuf_specified != newdev->tune.sndbuf_specified ||
3793 olddev->tune.sndbuf != newdev->tune.sndbuf) {
3794 needReconnect = true;
3795 }
3796
3797 if (STRNEQ_NULLABLE(olddev->script, newdev->script)) {
3798 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
3799 _("cannot modify network device script attribute"));
3800 goto cleanup;
3801 }
3802
3803 /* ifname: check if it's set in newdev. If not, retain the autogenerated one */
3804 if (!newdev->ifname)
3805 newdev->ifname = g_strdup(olddev->ifname);
3806 if (STRNEQ_NULLABLE(olddev->ifname, newdev->ifname)) {
3807 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
3808 _("cannot modify network device tap name"));
3809 goto cleanup;
3810 }
3811
3812 /* info: Nothing is allowed to change. First fill the missing newdev->info
3813 * from olddev and then check for changes.
3814 */
3815 /* if pci addr is missing or is invalid we overwrite it from olddev */
3816 if (newdev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE ||
3817 !virDomainDeviceAddressIsValid(&newdev->info,
3818 newdev->info.type)) {
3819 newdev->info.type = olddev->info.type;
3820 newdev->info.addr = olddev->info.addr;
3821 }
3822 if (olddev->info.type != newdev->info.type) {
3823 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
3824 _("cannot modify network device address type"));
3825 }
3826 if (!virPCIDeviceAddressEqual(&olddev->info.addr.pci,
3827 &newdev->info.addr.pci)) {
3828 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
3829 _("cannot modify network device guest PCI address"));
3830 goto cleanup;
3831 }
3832 /* grab alias from olddev if not set in newdev */
3833 if (!newdev->info.alias)
3834 newdev->info.alias = g_strdup(olddev->info.alias);
3835
3836 /* device alias is checked already in virDomainDefCompatibleDevice */
3837
3838 if (newdev->info.rombar == VIR_TRISTATE_SWITCH_ABSENT)
3839 newdev->info.rombar = olddev->info.rombar;
3840 if (olddev->info.rombar != newdev->info.rombar) {
3841 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
3842 _("cannot modify network device rom bar setting"));
3843 goto cleanup;
3844 }
3845
3846 if (!newdev->info.romfile)
3847 newdev->info.romfile = g_strdup(olddev->info.romfile);
3848 if (STRNEQ_NULLABLE(olddev->info.romfile, newdev->info.romfile)) {
3849 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
3850 _("cannot modify network rom file"));
3851 goto cleanup;
3852 }
3853
3854 if (newdev->info.bootIndex == 0)
3855 newdev->info.bootIndex = olddev->info.bootIndex;
3856 if (olddev->info.bootIndex != newdev->info.bootIndex) {
3857 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
3858 _("cannot modify network device boot index setting"));
3859 goto cleanup;
3860 }
3861
3862 if (newdev->info.romenabled == VIR_TRISTATE_BOOL_ABSENT)
3863 newdev->info.romenabled = olddev->info.romenabled;
3864 if (olddev->info.romenabled != newdev->info.romenabled) {
3865 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
3866 _("cannot modify network device rom enabled setting"));
3867 goto cleanup;
3868 }
3869 /* (end of device info checks) */
3870
3871 if (STRNEQ_NULLABLE(olddev->filter, newdev->filter) ||
3872 !virNWFilterHashTableEqual(olddev->filterparams, newdev->filterparams)) {
3873 needFilterChange = true;
3874 }
3875
3876 /* bandwidth can be modified, and will be checked later */
3877 /* vlan can be modified, and will be checked later */
3878 /* linkstate can be modified */
3879
3880 if (olddev->mtu != newdev->mtu) {
3881 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
3882 _("cannot modify MTU"));
3883 goto cleanup;
3884 }
3885
3886 /* allocate new actual device to compare to old - we will need to
3887 * free it if we fail for any reason
3888 */
3889 if (newdev->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
3890 if (!(conn = virGetConnectNetwork()))
3891 goto cleanup;
3892 if (virDomainNetAllocateActualDevice(conn, vm->def, newdev) < 0)
3893 goto cleanup;
3894 }
3895
3896 /* final validation now that we have full info on the type */
3897 if (qemuDomainValidateActualNetDef(newdev, priv->qemuCaps) < 0)
3898 goto cleanup;
3899
3900 newType = virDomainNetGetActualType(newdev);
3901
3902 if (newType == VIR_DOMAIN_NET_TYPE_HOSTDEV ||
3903 newType == VIR_DOMAIN_NET_TYPE_VDPA) {
3904 /* can't turn it into a type='hostdev' or type='vdpa' interface */
3905 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
3906 _("cannot change network interface type to '%s'"),
3907 virDomainNetTypeToString(newType));
3908 goto cleanup;
3909 }
3910
3911 if (olddev->type == newdev->type && oldType == newType) {
3912
3913 /* if type hasn't changed, check the relevant fields for the type */
3914 switch (newdev->type) {
3915 case VIR_DOMAIN_NET_TYPE_USER:
3916 break;
3917
3918 case VIR_DOMAIN_NET_TYPE_ETHERNET:
3919 break;
3920
3921 case VIR_DOMAIN_NET_TYPE_SERVER:
3922 case VIR_DOMAIN_NET_TYPE_CLIENT:
3923 case VIR_DOMAIN_NET_TYPE_MCAST:
3924 case VIR_DOMAIN_NET_TYPE_UDP:
3925 if (STRNEQ_NULLABLE(olddev->data.socket.address,
3926 newdev->data.socket.address) ||
3927 olddev->data.socket.port != newdev->data.socket.port) {
3928 needReconnect = true;
3929 }
3930 break;
3931
3932 case VIR_DOMAIN_NET_TYPE_NETWORK:
3933 if (STRNEQ(olddev->data.network.name, newdev->data.network.name)) {
3934 if (virDomainNetGetActualVirtPortProfile(newdev))
3935 needReconnect = true;
3936 else
3937 needBridgeChange = true;
3938 }
3939 /* other things handled in common code directly below this switch */
3940 break;
3941
3942 case VIR_DOMAIN_NET_TYPE_BRIDGE:
3943 /* all handled in bridge name checked in common code below */
3944 break;
3945
3946 case VIR_DOMAIN_NET_TYPE_INTERNAL:
3947 if (STRNEQ_NULLABLE(olddev->data.internal.name,
3948 newdev->data.internal.name)) {
3949 needReconnect = true;
3950 }
3951 break;
3952
3953 case VIR_DOMAIN_NET_TYPE_DIRECT:
3954 /* all handled in common code directly below this switch */
3955 break;
3956
3957 case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
3958 case VIR_DOMAIN_NET_TYPE_HOSTDEV:
3959 case VIR_DOMAIN_NET_TYPE_VDPA:
3960 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
3961 _("unable to change config on '%s' network type"),
3962 virDomainNetTypeToString(newdev->type));
3963 goto cleanup;
3964 case VIR_DOMAIN_NET_TYPE_LAST:
3965 default:
3966 virReportEnumRangeError(virDomainNetType, newdev->type);
3967 goto cleanup;
3968 }
3969 } else {
3970 /* interface type has changed. There are a few special cases
3971 * where this can only require a minor (or even no) change,
3972 * but in most cases we need to do a full reconnection.
3973 *
3974 * As long as both the new and old types use a tap device
3975 * connected to a host bridge (ie VIR_DOMAIN_NET_TYPE_NETWORK
3976 * or VIR_DOMAIN_NET_TYPE_BRIDGE), we just need to connect to
3977 * the new bridge.
3978 */
3979 if ((oldType == VIR_DOMAIN_NET_TYPE_NETWORK ||
3980 oldType == VIR_DOMAIN_NET_TYPE_BRIDGE) &&
3981 (newType == VIR_DOMAIN_NET_TYPE_NETWORK ||
3982 newType == VIR_DOMAIN_NET_TYPE_BRIDGE)) {
3983
3984 needBridgeChange = true;
3985
3986 } else if (oldType == VIR_DOMAIN_NET_TYPE_DIRECT &&
3987 newType == VIR_DOMAIN_NET_TYPE_DIRECT) {
3988
3989 /* this is the case of switching from type='direct' to
3990 * type='network' for a network that itself uses direct
3991 * (macvtap) devices. If the physical device and mode are
3992 * the same, this doesn't require any actual setup
3993 * change. If the physical device or mode *does* change,
3994 * that will be caught in the common section below */
3995
3996 } else {
3997
3998 /* for all other combinations, we'll need a full reconnect */
3999 needReconnect = true;
4000
4001 }
4002 }
4003
4004 /* now several things that are in multiple (but not all)
4005 * different types, and can be safely compared even for those
4006 * cases where they don't apply to a particular type.
4007 */
4008 if (STRNEQ_NULLABLE(virDomainNetGetActualBridgeName(olddev),
4009 virDomainNetGetActualBridgeName(newdev))) {
4010 if (virDomainNetGetActualVirtPortProfile(newdev))
4011 needReconnect = true;
4012 else
4013 needBridgeChange = true;
4014 }
4015
4016 if (STRNEQ_NULLABLE(virDomainNetGetActualDirectDev(olddev),
4017 virDomainNetGetActualDirectDev(newdev)) ||
4018 virDomainNetGetActualDirectMode(olddev) != virDomainNetGetActualDirectMode(newdev) ||
4019 !virNetDevVPortProfileEqual(virDomainNetGetActualVirtPortProfile(olddev),
4020 virDomainNetGetActualVirtPortProfile(newdev))) {
4021 needReconnect = true;
4022 }
4023
4024 if (!virNetDevVlanEqual(virDomainNetGetActualVlan(olddev),
4025 virDomainNetGetActualVlan(newdev))) {
4026 needVlanUpdate = true;
4027 }
4028
4029 if (virDomainNetGetActualPortOptionsIsolated(olddev) !=
4030 virDomainNetGetActualPortOptionsIsolated(newdev)) {
4031 needIsolatedPortChange = true;
4032 }
4033
4034 if (olddev->linkstate != newdev->linkstate)
4035 needLinkStateChange = true;
4036
4037 if (!virNetDevBandwidthEqual(virDomainNetGetActualBandwidth(olddev),
4038 virDomainNetGetActualBandwidth(newdev)))
4039 needBandwidthSet = true;
4040
4041 if (!!olddev->coalesce != !!newdev->coalesce ||
4042 (olddev->coalesce && newdev->coalesce &&
4043 memcmp(olddev->coalesce, newdev->coalesce,
4044 sizeof(*olddev->coalesce))))
4045 needCoalesceChange = true;
4046
4047 /* FINALLY - actually perform the required actions */
4048
4049 if (needReconnect) {
4050 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
4051 _("unable to change config on '%s' network type"),
4052 virDomainNetTypeToString(newdev->type));
4053 goto cleanup;
4054 }
4055
4056 if (needBandwidthSet) {
4057 const virNetDevBandwidth *newb = virDomainNetGetActualBandwidth(newdev);
4058
4059 if (newb) {
4060 if (virDomainNetDefIsOvsport(newdev)) {
4061 if (virNetDevOpenvswitchInterfaceSetQos(newdev->ifname, newb,
4062 vm->def->uuid,
4063 !virDomainNetTypeSharesHostView(newdev)) < 0)
4064 goto cleanup;
4065 } else if (virNetDevBandwidthSet(newdev->ifname, newb, false,
4066 !virDomainNetTypeSharesHostView(newdev)) < 0) {
4067 goto cleanup;
4068 }
4069 } else {
4070 /*
4071 * virNetDevBandwidthSet() doesn't clear any existing
4072 * setting unless something new is being set.
4073 */
4074 virNetDevBandwidthClear(newdev->ifname);
4075 }
4076
4077 /* If the old bandwidth was cleared out, restore qdisc. */
4078 if (virDomainNetTypeSharesHostView(newdev)) {
4079 if (!newb || !newb->out || newb->out->average == 0)
4080 qemuDomainInterfaceSetDefaultQDisc(driver, newdev);
4081 } else {
4082 if (!newb || !newb->in || newb->in->average == 0)
4083 qemuDomainInterfaceSetDefaultQDisc(driver, newdev);
4084 }
4085 needReplaceDevDef = true;
4086 }
4087
4088 if (needBridgeChange) {
4089 if (qemuDomainChangeNetBridge(vm, olddev, newdev) < 0)
4090 goto cleanup;
4091 /* we successfully switched to the new bridge, and we've
4092 * determined that the rest of newdev is equivalent to olddev,
4093 * so move newdev into place */
4094 needReplaceDevDef = true;
4095
4096 /* this is already updated as a part of reconnecting the bridge */
4097 needIsolatedPortChange = false;
4098 }
4099
4100 if (needIsolatedPortChange) {
4101 const char *bridge = virDomainNetGetActualBridgeName(newdev);
4102 bool isolatedOn = (virDomainNetGetActualPortOptionsIsolated(newdev) ==
4103 VIR_TRISTATE_BOOL_YES);
4104
4105 if (virNetDevBridgePortSetIsolated(bridge, newdev->ifname, isolatedOn) < 0)
4106 goto cleanup;
4107
4108 needReplaceDevDef = true;
4109 }
4110
4111 if (needFilterChange) {
4112 if (qemuDomainChangeNetFilter(vm, olddev, newdev) < 0)
4113 goto cleanup;
4114 /* we successfully switched to the new filter, and we've
4115 * determined that the rest of newdev is equivalent to olddev,
4116 * so move newdev into place */
4117 needReplaceDevDef = true;
4118 }
4119
4120 if (needCoalesceChange) {
4121 if (virNetDevSetCoalesce(newdev->ifname, newdev->coalesce, true) < 0)
4122 goto cleanup;
4123 needReplaceDevDef = true;
4124 }
4125
4126 if (needLinkStateChange &&
4127 qemuDomainChangeNetLinkState(driver, vm, olddev, newdev->linkstate) < 0) {
4128 goto cleanup;
4129 }
4130
4131 if (needVlanUpdate) {
4132 if (virNetDevOpenvswitchUpdateVlan(newdev->ifname, &newdev->vlan) < 0)
4133 goto cleanup;
4134 needReplaceDevDef = true;
4135 }
4136
4137 if (needReplaceDevDef) {
4138 /* the changes above warrant replacing olddev with newdev in
4139 * the domain's nets list.
4140 */
4141
4142 /* this function doesn't work with HOSTDEV networks yet, thus
4143 * no need to change the pointer in the hostdev structure */
4144 if (olddev->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
4145 if (conn || (conn = virGetConnectNetwork()))
4146 virDomainNetReleaseActualDevice(conn, vm->def, olddev);
4147 else
4148 VIR_WARN("Unable to release network device '%s'", NULLSTR(olddev->ifname));
4149 }
4150 virDomainNetDefFree(olddev);
4151 /* move newdev into the nets list, and NULL it out from the
4152 * virDomainDeviceDef that we were given so that the caller
4153 * won't delete it on return.
4154 */
4155 *devslot = newdev;
4156 newdev = dev->data.net = NULL;
4157 dev->type = VIR_DOMAIN_DEVICE_NONE;
4158 }
4159
4160 ret = 0;
4161 cleanup:
4162 virErrorPreserveLast(&save_err);
4163 /* When we get here, we will be in one of these two states:
4164 *
4165 * 1) newdev has been moved into the domain's list of nets and
4166 * newdev set to NULL, and dev->data.net will be NULL (and
4167 * dev->type is NONE). olddev will have been completely
4168 * released and freed. (aka success) In this case no extra
4169 * cleanup is needed.
4170 *
4171 * 2) newdev has *not* been moved into the domain's list of nets,
4172 * and dev->data.net == newdev (and dev->type == NET). In this *
4173 * case, we need to at least release the "actual device" from *
4174 * newdev (the caller will free dev->data.net a.k.a. newdev, and
4175 * the original olddev is still in used)
4176 *
4177 * Note that case (2) isn't necessarily a failure. It may just be
4178 * that the changes were minor enough that we didn't need to
4179 * replace the entire device object.
4180 */
4181 if (newdev && newdev->type == VIR_DOMAIN_NET_TYPE_NETWORK && conn)
4182 virDomainNetReleaseActualDevice(conn, vm->def, newdev);
4183 virErrorRestore(&save_err);
4184
4185 return ret;
4186 }
4187
4188 static virDomainGraphicsDef *
qemuDomainFindGraphics(virDomainObj * vm,virDomainGraphicsDef * dev)4189 qemuDomainFindGraphics(virDomainObj *vm,
4190 virDomainGraphicsDef *dev)
4191 {
4192 size_t i;
4193
4194 for (i = 0; i < vm->def->ngraphics; i++) {
4195 if (vm->def->graphics[i]->type == dev->type)
4196 return vm->def->graphics[i];
4197 }
4198
4199 return NULL;
4200 }
4201
4202 int
qemuDomainFindGraphicsIndex(virDomainDef * def,virDomainGraphicsDef * dev)4203 qemuDomainFindGraphicsIndex(virDomainDef *def,
4204 virDomainGraphicsDef *dev)
4205 {
4206 size_t i;
4207
4208 for (i = 0; i < def->ngraphics; i++) {
4209 if (def->graphics[i]->type == dev->type)
4210 return i;
4211 }
4212
4213 return -1;
4214 }
4215
4216
4217 int
qemuDomainChangeGraphicsPasswords(virQEMUDriver * driver,virDomainObj * vm,int type,virDomainGraphicsAuthDef * auth,const char * defaultPasswd,int asyncJob)4218 qemuDomainChangeGraphicsPasswords(virQEMUDriver *driver,
4219 virDomainObj *vm,
4220 int type,
4221 virDomainGraphicsAuthDef *auth,
4222 const char *defaultPasswd,
4223 int asyncJob)
4224 {
4225 qemuDomainObjPrivate *priv = vm->privateData;
4226 time_t now = time(NULL);
4227 const char *expire;
4228 g_autofree char *validTo = NULL;
4229 const char *connected = NULL;
4230 const char *password;
4231 int ret = -1;
4232
4233 if (!auth->passwd && !defaultPasswd)
4234 return 0;
4235
4236 password = auth->passwd ? auth->passwd : defaultPasswd;
4237
4238 if (auth->connected)
4239 connected = virDomainGraphicsAuthConnectedTypeToString(auth->connected);
4240
4241 if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
4242 return ret;
4243 ret = qemuMonitorSetPassword(priv->mon, type, password, connected);
4244
4245 if (ret != 0)
4246 goto end_job;
4247
4248 if (password[0] == '\0' ||
4249 (auth->expires && auth->validTo <= now)) {
4250 expire = "now";
4251 } else if (auth->expires) {
4252 validTo = g_strdup_printf("%lu", (unsigned long)auth->validTo);
4253 expire = validTo;
4254 } else {
4255 expire = "never";
4256 }
4257
4258 ret = qemuMonitorExpirePassword(priv->mon, type, expire);
4259
4260 end_job:
4261 if (qemuDomainObjExitMonitor(driver, vm) < 0)
4262 ret = -1;
4263
4264 return ret;
4265 }
4266
4267
4268 int
qemuDomainChangeGraphics(virQEMUDriver * driver,virDomainObj * vm,virDomainGraphicsDef * dev)4269 qemuDomainChangeGraphics(virQEMUDriver *driver,
4270 virDomainObj *vm,
4271 virDomainGraphicsDef *dev)
4272 {
4273 virDomainGraphicsDef *olddev = qemuDomainFindGraphics(vm, dev);
4274 g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
4275 const char *type = virDomainGraphicsTypeToString(dev->type);
4276 size_t i;
4277
4278 if (!olddev) {
4279 virReportError(VIR_ERR_DEVICE_MISSING,
4280 _("cannot find existing graphics device to modify of "
4281 "type '%s'"), type);
4282 return -1;
4283 }
4284
4285 if (dev->nListens != olddev->nListens) {
4286 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
4287 _("cannot change the number of listen addresses "
4288 "on '%s' graphics"), type);
4289 return -1;
4290 }
4291
4292 for (i = 0; i < dev->nListens; i++) {
4293 virDomainGraphicsListenDef *newlisten = &dev->listens[i];
4294 virDomainGraphicsListenDef *oldlisten = &olddev->listens[i];
4295
4296 if (newlisten->type != oldlisten->type) {
4297 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
4298 _("cannot change the type of listen address "
4299 "on '%s' graphics"), type);
4300 return -1;
4301 }
4302
4303 switch (newlisten->type) {
4304 case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
4305 if (STRNEQ_NULLABLE(newlisten->address, oldlisten->address)) {
4306 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
4307 _("cannot change listen address setting "
4308 "on '%s' graphics"), type);
4309 return -1;
4310 }
4311
4312 break;
4313
4314 case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK:
4315 if (STRNEQ_NULLABLE(newlisten->network, oldlisten->network)) {
4316 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
4317 _("cannot change listen address setting "
4318 "on '%s' graphics"), type);
4319 return -1;
4320 }
4321
4322 break;
4323
4324 case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET:
4325 if (STRNEQ_NULLABLE(newlisten->socket, oldlisten->socket)) {
4326 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
4327 _("cannot change listen socket setting "
4328 "on '%s' graphics"), type);
4329 return -1;
4330 }
4331 break;
4332
4333 case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
4334 case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
4335 /* nada */
4336 break;
4337 }
4338 }
4339
4340 switch (dev->type) {
4341 case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
4342 if ((olddev->data.vnc.autoport != dev->data.vnc.autoport) ||
4343 (!dev->data.vnc.autoport &&
4344 (olddev->data.vnc.port != dev->data.vnc.port))) {
4345 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
4346 _("cannot change port settings on vnc graphics"));
4347 return -1;
4348 }
4349 if (STRNEQ_NULLABLE(olddev->data.vnc.keymap, dev->data.vnc.keymap)) {
4350 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
4351 _("cannot change keymap setting on vnc graphics"));
4352 return -1;
4353 }
4354
4355 /* If a password lifetime was, or is set, or action if connected has
4356 * changed, then we must always run, even if new password matches
4357 * old password */
4358 if (olddev->data.vnc.auth.expires ||
4359 dev->data.vnc.auth.expires ||
4360 olddev->data.vnc.auth.connected != dev->data.vnc.auth.connected ||
4361 STRNEQ_NULLABLE(olddev->data.vnc.auth.passwd,
4362 dev->data.vnc.auth.passwd)) {
4363 VIR_DEBUG("Updating password on VNC server %p %p",
4364 dev->data.vnc.auth.passwd, cfg->vncPassword);
4365 if (qemuDomainChangeGraphicsPasswords(driver, vm,
4366 VIR_DOMAIN_GRAPHICS_TYPE_VNC,
4367 &dev->data.vnc.auth,
4368 cfg->vncPassword,
4369 QEMU_ASYNC_JOB_NONE) < 0)
4370 return -1;
4371
4372 /* Steal the new dev's char * reference */
4373 VIR_FREE(olddev->data.vnc.auth.passwd);
4374 olddev->data.vnc.auth.passwd = dev->data.vnc.auth.passwd;
4375 dev->data.vnc.auth.passwd = NULL;
4376 olddev->data.vnc.auth.validTo = dev->data.vnc.auth.validTo;
4377 olddev->data.vnc.auth.expires = dev->data.vnc.auth.expires;
4378 olddev->data.vnc.auth.connected = dev->data.vnc.auth.connected;
4379 }
4380 break;
4381
4382 case VIR_DOMAIN_GRAPHICS_TYPE_SPICE:
4383 if ((olddev->data.spice.autoport != dev->data.spice.autoport) ||
4384 (!dev->data.spice.autoport &&
4385 (olddev->data.spice.port != dev->data.spice.port)) ||
4386 (!dev->data.spice.autoport &&
4387 (olddev->data.spice.tlsPort != dev->data.spice.tlsPort))) {
4388 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
4389 _("cannot change port settings on spice graphics"));
4390 return -1;
4391 }
4392 if (STRNEQ_NULLABLE(olddev->data.spice.keymap,
4393 dev->data.spice.keymap)) {
4394 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
4395 _("cannot change keymap setting on spice graphics"));
4396 return -1;
4397 }
4398
4399 /* We must reset the password if it has changed but also if:
4400 * - password lifetime is or was set
4401 * - the requested action has changed
4402 * - the action is "disconnect"
4403 */
4404 if (olddev->data.spice.auth.expires ||
4405 dev->data.spice.auth.expires ||
4406 olddev->data.spice.auth.connected != dev->data.spice.auth.connected ||
4407 dev->data.spice.auth.connected ==
4408 VIR_DOMAIN_GRAPHICS_AUTH_CONNECTED_DISCONNECT ||
4409 STRNEQ_NULLABLE(olddev->data.spice.auth.passwd,
4410 dev->data.spice.auth.passwd)) {
4411 VIR_DEBUG("Updating password on SPICE server %p %p",
4412 dev->data.spice.auth.passwd, cfg->spicePassword);
4413 if (qemuDomainChangeGraphicsPasswords(driver, vm,
4414 VIR_DOMAIN_GRAPHICS_TYPE_SPICE,
4415 &dev->data.spice.auth,
4416 cfg->spicePassword,
4417 QEMU_ASYNC_JOB_NONE) < 0)
4418 return -1;
4419
4420 /* Steal the new dev's char * reference */
4421 VIR_FREE(olddev->data.spice.auth.passwd);
4422 olddev->data.spice.auth.passwd = dev->data.spice.auth.passwd;
4423 dev->data.spice.auth.passwd = NULL;
4424 olddev->data.spice.auth.validTo = dev->data.spice.auth.validTo;
4425 olddev->data.spice.auth.expires = dev->data.spice.auth.expires;
4426 olddev->data.spice.auth.connected = dev->data.spice.auth.connected;
4427 } else {
4428 VIR_DEBUG("Not updating since password didn't change");
4429 }
4430 break;
4431
4432 case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
4433 case VIR_DOMAIN_GRAPHICS_TYPE_RDP:
4434 case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP:
4435 case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS:
4436 virReportError(VIR_ERR_INTERNAL_ERROR,
4437 _("unable to change config on '%s' graphics type"), type);
4438 break;
4439 case VIR_DOMAIN_GRAPHICS_TYPE_LAST:
4440 default:
4441 virReportEnumRangeError(virDomainGraphicsType, dev->type);
4442 break;
4443 }
4444
4445 return 0;
4446 }
4447
4448
qemuComparePCIDevice(virDomainDef * def G_GNUC_UNUSED,virDomainDeviceDef * device G_GNUC_UNUSED,virDomainDeviceInfo * info1,void * opaque)4449 static int qemuComparePCIDevice(virDomainDef *def G_GNUC_UNUSED,
4450 virDomainDeviceDef *device G_GNUC_UNUSED,
4451 virDomainDeviceInfo *info1,
4452 void *opaque)
4453 {
4454 virDomainDeviceInfo *info2 = opaque;
4455
4456 if (info1->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI ||
4457 info2->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
4458 return 0;
4459
4460 if (info1->addr.pci.domain == info2->addr.pci.domain &&
4461 info1->addr.pci.bus == info2->addr.pci.bus &&
4462 info1->addr.pci.slot == info2->addr.pci.slot &&
4463 info1->addr.pci.function != info2->addr.pci.function)
4464 return -1;
4465 return 0;
4466 }
4467
qemuIsMultiFunctionDevice(virDomainDef * def,virDomainDeviceInfo * info)4468 static bool qemuIsMultiFunctionDevice(virDomainDef *def,
4469 virDomainDeviceInfo *info)
4470 {
4471 if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
4472 return false;
4473
4474 if (virDomainDeviceInfoIterate(def, qemuComparePCIDevice, info) < 0)
4475 return true;
4476 return false;
4477 }
4478
4479
4480 static int
qemuDomainRemoveDiskDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainDiskDef * disk)4481 qemuDomainRemoveDiskDevice(virQEMUDriver *driver,
4482 virDomainObj *vm,
4483 virDomainDiskDef *disk)
4484 {
4485 qemuDomainDiskPrivate *diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
4486 g_autoptr(qemuBlockStorageSourceChainData) diskBackend = NULL;
4487 virDomainDeviceDef dev;
4488 size_t i;
4489 qemuDomainObjPrivate *priv = vm->privateData;
4490 bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);
4491 int ret = -1;
4492
4493 VIR_DEBUG("Removing disk %s from domain %p %s",
4494 disk->info.alias, vm, vm->def->name);
4495
4496
4497 if (virStorageSourceGetActualType(disk->src) == VIR_STORAGE_TYPE_VHOST_USER) {
4498 char *chardevAlias = qemuDomainGetVhostUserChrAlias(disk->info.alias);
4499
4500 if (!(diskBackend = qemuBlockStorageSourceChainDetachPrepareChardev(chardevAlias)))
4501 goto cleanup;
4502 } else if (blockdev && !qemuDiskBusIsSD(disk->bus)) {
4503 if (diskPriv->blockjob) {
4504 /* the block job keeps reference to the disk chain */
4505 diskPriv->blockjob->disk = NULL;
4506 virObjectUnref(diskPriv->blockjob);
4507 diskPriv->blockjob = NULL;
4508 } else {
4509 if (!(diskBackend = qemuBlockStorageSourceChainDetachPrepareBlockdev(disk->src)))
4510 goto cleanup;
4511 }
4512
4513 if (diskPriv->nodeCopyOnRead) {
4514 if (!diskBackend)
4515 diskBackend = g_new0(qemuBlockStorageSourceChainData, 1);
4516 diskBackend->copyOnReadNodename = g_strdup(diskPriv->nodeCopyOnRead);
4517 diskBackend->copyOnReadAttached = true;
4518 }
4519 } else {
4520 char *driveAlias;
4521
4522 if (!(driveAlias = qemuAliasDiskDriveFromDisk(disk)))
4523 goto cleanup;
4524
4525 if (!(diskBackend = qemuBlockStorageSourceChainDetachPrepareDrive(disk->src, driveAlias)))
4526 goto cleanup;
4527 }
4528
4529 for (i = 0; i < vm->def->ndisks; i++) {
4530 if (vm->def->disks[i] == disk) {
4531 virDomainDiskRemove(vm->def, i);
4532 break;
4533 }
4534 }
4535
4536 qemuDomainObjEnterMonitor(driver, vm);
4537
4538 if (diskBackend)
4539 qemuBlockStorageSourceChainDetach(priv->mon, diskBackend);
4540
4541 if (qemuDomainObjExitMonitor(driver, vm) < 0)
4542 goto cleanup;
4543
4544 virDomainAuditDisk(vm, disk->src, NULL, "detach", true);
4545
4546 qemuDomainReleaseDeviceAddress(vm, &disk->info);
4547
4548 /* tear down disk security access */
4549 if (diskBackend)
4550 qemuDomainStorageSourceChainAccessRevoke(driver, vm, disk->src);
4551
4552 dev.type = VIR_DOMAIN_DEVICE_DISK;
4553 dev.data.disk = disk;
4554 ignore_value(qemuRemoveSharedDevice(driver, &dev, vm->def->name));
4555
4556 if (virStorageSourceChainHasManagedPR(disk->src) &&
4557 qemuHotplugRemoveManagedPR(driver, vm, QEMU_ASYNC_JOB_NONE) < 0)
4558 goto cleanup;
4559
4560 if (disk->transient) {
4561 VIR_DEBUG("Removing transient overlay '%s' of disk '%s'",
4562 disk->src->path, disk->dst);
4563 if (qemuDomainStorageFileInit(driver, vm, disk->src, NULL) >= 0) {
4564 virStorageSourceUnlink(disk->src);
4565 virStorageSourceDeinit(disk->src);
4566 }
4567 }
4568
4569 ret = 0;
4570
4571 cleanup:
4572 virDomainDiskDefFree(disk);
4573 return ret;
4574 }
4575
4576
4577 static int
qemuDomainRemoveControllerDevice(virDomainObj * vm,virDomainControllerDef * controller)4578 qemuDomainRemoveControllerDevice(virDomainObj *vm,
4579 virDomainControllerDef *controller)
4580 {
4581 size_t i;
4582
4583 VIR_DEBUG("Removing controller %s from domain %p %s",
4584 controller->info.alias, vm, vm->def->name);
4585
4586 for (i = 0; i < vm->def->ncontrollers; i++) {
4587 if (vm->def->controllers[i] == controller) {
4588 virDomainControllerRemove(vm->def, i);
4589 break;
4590 }
4591 }
4592
4593 qemuDomainReleaseDeviceAddress(vm, &controller->info);
4594 virDomainControllerDefFree(controller);
4595 return 0;
4596 }
4597
4598
4599 static int
qemuDomainRemoveMemoryDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainMemoryDef * mem)4600 qemuDomainRemoveMemoryDevice(virQEMUDriver *driver,
4601 virDomainObj *vm,
4602 virDomainMemoryDef *mem)
4603 {
4604 qemuDomainObjPrivate *priv = vm->privateData;
4605 unsigned long long oldmem = virDomainDefGetMemoryTotal(vm->def);
4606 unsigned long long newmem = oldmem - mem->size;
4607 g_autofree char *backendAlias = NULL;
4608 int rc;
4609 int idx;
4610
4611 VIR_DEBUG("Removing memory device %s from domain %p %s",
4612 mem->info.alias, vm, vm->def->name);
4613
4614 backendAlias = g_strdup_printf("mem%s", mem->info.alias);
4615
4616 qemuDomainObjEnterMonitor(driver, vm);
4617 rc = qemuMonitorDelObject(priv->mon, backendAlias, true);
4618 if (qemuDomainObjExitMonitor(driver, vm) < 0)
4619 rc = -1;
4620
4621 virDomainAuditMemory(vm, oldmem, newmem, "update", rc == 0);
4622 if (rc < 0)
4623 return -1;
4624
4625 if ((idx = virDomainMemoryFindByDef(vm->def, mem)) >= 0)
4626 virDomainMemoryRemove(vm->def, idx);
4627
4628 if (qemuSecurityRestoreMemoryLabel(driver, vm, mem) < 0)
4629 VIR_WARN("Unable to restore security label on memdev");
4630
4631 if (qemuTeardownMemoryDevicesCgroup(vm, mem) < 0)
4632 VIR_WARN("Unable to remove memory device cgroup ACL");
4633
4634 if (qemuDomainNamespaceTeardownMemory(vm, mem) < 0)
4635 VIR_WARN("Unable to remove memory device from /dev");
4636
4637 if (qemuProcessDestroyMemoryBackingPath(driver, vm, mem) < 0)
4638 VIR_WARN("Unable to destroy memory backing path");
4639
4640 qemuDomainReleaseMemoryDeviceSlot(vm, mem);
4641
4642 virDomainMemoryDefFree(mem);
4643
4644 /* fix the balloon size */
4645 ignore_value(qemuProcessRefreshBalloonState(driver, vm, QEMU_ASYNC_JOB_NONE));
4646
4647 /* decrease the mlock limit after memory unplug if necessary */
4648 ignore_value(qemuDomainAdjustMaxMemLock(vm, false));
4649
4650 return 0;
4651 }
4652
4653
4654 static void
qemuDomainRemovePCIHostDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainHostdevDef * hostdev)4655 qemuDomainRemovePCIHostDevice(virQEMUDriver *driver,
4656 virDomainObj *vm,
4657 virDomainHostdevDef *hostdev)
4658 {
4659 qemuHostdevReAttachPCIDevices(driver, vm->def->name, &hostdev, 1);
4660 qemuDomainReleaseDeviceAddress(vm, hostdev->info);
4661 }
4662
4663 static void
qemuDomainRemoveUSBHostDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainHostdevDef * hostdev)4664 qemuDomainRemoveUSBHostDevice(virQEMUDriver *driver,
4665 virDomainObj *vm,
4666 virDomainHostdevDef *hostdev)
4667 {
4668 qemuHostdevReAttachUSBDevices(driver, vm->def->name, &hostdev, 1);
4669 qemuDomainReleaseDeviceAddress(vm, hostdev->info);
4670 }
4671
4672 static void
qemuDomainRemoveSCSIHostDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainHostdevDef * hostdev)4673 qemuDomainRemoveSCSIHostDevice(virQEMUDriver *driver,
4674 virDomainObj *vm,
4675 virDomainHostdevDef *hostdev)
4676 {
4677 qemuHostdevReAttachSCSIDevices(driver, vm->def->name, &hostdev, 1);
4678 }
4679
4680 static void
qemuDomainRemoveSCSIVHostDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainHostdevDef * hostdev)4681 qemuDomainRemoveSCSIVHostDevice(virQEMUDriver *driver,
4682 virDomainObj *vm,
4683 virDomainHostdevDef *hostdev)
4684 {
4685 qemuHostdevReAttachSCSIVHostDevices(driver, vm->def->name, &hostdev, 1);
4686 }
4687
4688
4689 static void
qemuDomainRemoveMediatedDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainHostdevDef * hostdev)4690 qemuDomainRemoveMediatedDevice(virQEMUDriver *driver,
4691 virDomainObj *vm,
4692 virDomainHostdevDef *hostdev)
4693 {
4694 qemuHostdevReAttachMediatedDevices(driver, vm->def->name, &hostdev, 1);
4695 qemuDomainReleaseDeviceAddress(vm, hostdev->info);
4696 }
4697
4698
4699 static int
qemuDomainRemoveHostDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainHostdevDef * hostdev)4700 qemuDomainRemoveHostDevice(virQEMUDriver *driver,
4701 virDomainObj *vm,
4702 virDomainHostdevDef *hostdev)
4703 {
4704 virDomainNetDef *net = NULL;
4705 size_t i;
4706 qemuDomainObjPrivate *priv = vm->privateData;
4707
4708 VIR_DEBUG("Removing host device %s from domain %p %s",
4709 hostdev->info->alias, vm, vm->def->name);
4710
4711 if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {
4712 g_autoptr(qemuBlockStorageSourceAttachData) detachscsi = NULL;
4713
4714 detachscsi = qemuBuildHostdevSCSIDetachPrepare(hostdev, priv->qemuCaps);
4715
4716 qemuDomainObjEnterMonitor(driver, vm);
4717 qemuBlockStorageSourceAttachRollback(priv->mon, detachscsi);
4718 if (qemuDomainObjExitMonitor(driver, vm) < 0)
4719 return -1;
4720 }
4721
4722 if (hostdev->parentnet) {
4723 net = hostdev->parentnet;
4724 for (i = 0; i < vm->def->nnets; i++) {
4725 if (vm->def->nets[i] == hostdev->parentnet) {
4726 virDomainNetRemove(vm->def, i);
4727 break;
4728 }
4729 }
4730 }
4731
4732 for (i = 0; i < vm->def->nhostdevs; i++) {
4733 if (vm->def->hostdevs[i] == hostdev) {
4734 virDomainHostdevRemove(vm->def, i);
4735 break;
4736 }
4737 }
4738
4739 virDomainAuditHostdev(vm, hostdev, "detach", true);
4740
4741 if (!virHostdevIsVFIODevice(hostdev) &&
4742 qemuSecurityRestoreHostdevLabel(driver, vm, hostdev) < 0)
4743 VIR_WARN("Failed to restore host device labelling");
4744
4745 if (qemuTeardownHostdevCgroup(vm, hostdev) < 0)
4746 VIR_WARN("Failed to remove host device cgroup ACL");
4747
4748 if (qemuDomainNamespaceTeardownHostdev(vm, hostdev) < 0)
4749 VIR_WARN("Unable to remove host device from /dev");
4750
4751 switch ((virDomainHostdevSubsysType)hostdev->source.subsys.type) {
4752 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
4753 qemuDomainRemovePCIHostDevice(driver, vm, hostdev);
4754 /* QEMU might no longer need to lock as much memory, eg. we just
4755 * detached the last VFIO device, so adjust the limit here */
4756 if (qemuDomainAdjustMaxMemLock(vm, false) < 0)
4757 VIR_WARN("Failed to adjust locked memory limit");
4758 break;
4759 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
4760 qemuDomainRemoveUSBHostDevice(driver, vm, hostdev);
4761 break;
4762 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
4763 qemuDomainRemoveSCSIHostDevice(driver, vm, hostdev);
4764 break;
4765 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
4766 qemuDomainRemoveSCSIVHostDevice(driver, vm, hostdev);
4767 break;
4768 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
4769 qemuDomainRemoveMediatedDevice(driver, vm, hostdev);
4770 break;
4771 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
4772 break;
4773 }
4774
4775 virDomainHostdevDefFree(hostdev);
4776
4777 if (net) {
4778 if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
4779 g_autoptr(virConnect) conn = virGetConnectNetwork();
4780 if (conn)
4781 virDomainNetReleaseActualDevice(conn, vm->def, net);
4782 else
4783 VIR_WARN("Unable to release network device '%s'", NULLSTR(net->ifname));
4784 }
4785 virDomainNetDefFree(net);
4786 }
4787
4788 return 0;
4789 }
4790
4791
4792 static int
qemuDomainRemoveNetDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainNetDef * net)4793 qemuDomainRemoveNetDevice(virQEMUDriver *driver,
4794 virDomainObj *vm,
4795 virDomainNetDef *net)
4796 {
4797 g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
4798 qemuDomainObjPrivate *priv = vm->privateData;
4799 g_autofree char *hostnet_name = NULL;
4800 g_autofree char *charDevAlias = NULL;
4801 size_t i;
4802 int actualType = virDomainNetGetActualType(net);
4803
4804 if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
4805 /* this function handles all hostdev and netdev cleanup */
4806 return qemuDomainRemoveHostDevice(driver, vm,
4807 virDomainNetGetActualHostdev(net));
4808 }
4809
4810 VIR_DEBUG("Removing network interface %s from domain %p %s",
4811 net->info.alias, vm, vm->def->name);
4812
4813 hostnet_name = g_strdup_printf("host%s", net->info.alias);
4814 if (!(charDevAlias = qemuAliasChardevFromDevAlias(net->info.alias)))
4815 return -1;
4816
4817 if (virNetDevSupportsBandwidth(virDomainNetGetActualType(net))) {
4818 if (virDomainNetDefIsOvsport(net)) {
4819 if (virNetDevOpenvswitchInterfaceClearQos(net->ifname, vm->def->uuid) < 0)
4820 VIR_WARN("cannot clear bandwidth setting for ovs device : %s",
4821 net->ifname);
4822 } else if (virNetDevBandwidthClear(net->ifname) < 0) {
4823 VIR_WARN("cannot clear bandwidth setting for device : %s",
4824 net->ifname);
4825 }
4826 }
4827
4828 /* deactivate the tap/macvtap device on the host, which could also
4829 * affect the parent device (e.g. macvtap passthrough mode sets
4830 * the parent device offline)
4831 */
4832 ignore_value(qemuInterfaceStopDevice(net));
4833
4834 qemuDomainObjEnterMonitor(driver, vm);
4835 if (qemuMonitorRemoveNetdev(priv->mon, hostnet_name) < 0) {
4836 if (qemuDomainObjExitMonitor(driver, vm) < 0)
4837 return -1;
4838 virDomainAuditNet(vm, net, NULL, "detach", false);
4839 return -1;
4840 }
4841
4842 if (actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
4843 /* vhostuser has a chardev too */
4844 if (qemuMonitorDetachCharDev(priv->mon, charDevAlias) < 0) {
4845 /* well, this is a messy situation. Guest visible PCI device has
4846 * been removed, netdev too but chardev not. The best seems to be
4847 * to just ignore the error and carry on.
4848 */
4849 }
4850 } else if (actualType == VIR_DOMAIN_NET_TYPE_VDPA) {
4851 int vdpafdset = -1;
4852 g_autoptr(qemuMonitorFdsets) fdsets = NULL;
4853
4854 /* query qemu for which fdset is associated with the fd that we passed
4855 * to qemu via 'add-fd' for this vdpa device. If we don't remove the
4856 * fd, qemu will keep it open */
4857 if (qemuMonitorQueryFdsets(priv->mon, &fdsets) == 0) {
4858 for (i = 0; i < fdsets->nfdsets && vdpafdset < 0; i++) {
4859 size_t j;
4860 qemuMonitorFdsetInfo *set = &fdsets->fdsets[i];
4861
4862 for (j = 0; j < set->nfds; j++) {
4863 qemuMonitorFdsetFdInfo *fdinfo = &set->fds[j];
4864 if (STREQ_NULLABLE(fdinfo->opaque, net->data.vdpa.devicepath)) {
4865 vdpafdset = set->id;
4866 break;
4867 }
4868 }
4869 }
4870 }
4871
4872 if (vdpafdset < 0) {
4873 VIR_WARN("Cannot determine fdset for vdpa device");
4874 } else {
4875 if (qemuMonitorRemoveFdset(priv->mon, vdpafdset) < 0) {
4876 /* if it fails, there's not much we can do... just carry on */
4877 VIR_WARN("failed to close vdpa device");
4878 }
4879 }
4880 }
4881
4882
4883 if (qemuDomainObjExitMonitor(driver, vm) < 0)
4884 return -1;
4885
4886 if (QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp)
4887 qemuSlirpStop(QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp, vm, driver, net);
4888
4889 virDomainAuditNet(vm, net, NULL, "detach", true);
4890
4891 for (i = 0; i < vm->def->nnets; i++) {
4892 if (vm->def->nets[i] == net) {
4893 virDomainNetRemove(vm->def, i);
4894 break;
4895 }
4896 }
4897
4898 qemuDomainReleaseDeviceAddress(vm, &net->info);
4899 virDomainConfNWFilterTeardown(net);
4900
4901 if (cfg->macFilter && (net->ifname != NULL)) {
4902 ignore_value(ebtablesRemoveForwardAllowIn(driver->ebtables,
4903 net->ifname,
4904 &net->mac));
4905 }
4906
4907 if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
4908 ignore_value(virNetDevMacVLanDeleteWithVPortProfile(
4909 net->ifname, &net->mac,
4910 virDomainNetGetActualDirectDev(net),
4911 virDomainNetGetActualDirectMode(net),
4912 virDomainNetGetActualVirtPortProfile(net),
4913 cfg->stateDir));
4914 }
4915
4916 if (actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
4917 if (qemuSecurityRestoreNetdevLabel(driver, vm, net) < 0)
4918 VIR_WARN("Unable to restore security label on vhostuser char device");
4919 }
4920
4921 qemuDomainNetDeviceVportRemove(net);
4922
4923 if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
4924 g_autoptr(virConnect) conn = virGetConnectNetwork();
4925 if (conn)
4926 virDomainNetReleaseActualDevice(conn, vm->def, net);
4927 else
4928 VIR_WARN("Unable to release network device '%s'", NULLSTR(net->ifname));
4929 } else if (net->type == VIR_DOMAIN_NET_TYPE_ETHERNET) {
4930 if (net->downscript)
4931 virNetDevRunEthernetScript(net->ifname, net->downscript);
4932 }
4933 virDomainNetDefFree(net);
4934 return 0;
4935 }
4936
4937
4938 static int
qemuDomainRemoveChrDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainChrDef * chr,bool monitor)4939 qemuDomainRemoveChrDevice(virQEMUDriver *driver,
4940 virDomainObj *vm,
4941 virDomainChrDef *chr,
4942 bool monitor)
4943 {
4944 virObjectEvent *event;
4945 g_autofree char *charAlias = NULL;
4946 qemuDomainObjPrivate *priv = vm->privateData;
4947 int rc = 0;
4948
4949 VIR_DEBUG("Removing character device %s from domain %p %s",
4950 chr->info.alias, vm, vm->def->name);
4951
4952 if (!(charAlias = qemuAliasChardevFromDevAlias(chr->info.alias)))
4953 return -1;
4954
4955 if (monitor) {
4956 qemuDomainObjEnterMonitor(driver, vm);
4957 rc = qemuMonitorDetachCharDev(priv->mon, charAlias);
4958 if (qemuDomainObjExitMonitor(driver, vm) < 0)
4959 return -1;
4960 }
4961
4962 if (rc == 0 &&
4963 qemuDomainDelChardevTLSObjects(driver, vm, chr->source, charAlias) < 0)
4964 return -1;
4965
4966 virDomainAuditChardev(vm, chr, NULL, "detach", rc == 0);
4967
4968 if (rc < 0)
4969 return -1;
4970
4971 if (qemuTeardownChardevCgroup(vm, chr) < 0)
4972 VIR_WARN("Failed to remove chr device cgroup ACL");
4973
4974 if (qemuSecurityRestoreChardevLabel(driver, vm, chr) < 0)
4975 VIR_WARN("Unable to restore security label on char device");
4976
4977 if (qemuDomainNamespaceTeardownChardev(vm, chr) < 0)
4978 VIR_WARN("Unable to remove chr device from /dev");
4979
4980 qemuDomainReleaseDeviceAddress(vm, &chr->info);
4981 qemuDomainChrRemove(vm->def, chr);
4982
4983 /* The caller does not emit the event, so we must do it here. Note
4984 * that the event should be reported only after all backend
4985 * teardown is completed.
4986 */
4987 event = virDomainEventDeviceRemovedNewFromObj(vm, chr->info.alias);
4988 virObjectEventStateQueue(driver->domainEventState, event);
4989
4990 virDomainChrDefFree(chr);
4991 return 0;
4992 }
4993
4994
4995 static int
qemuDomainRemoveRNGDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainRNGDef * rng)4996 qemuDomainRemoveRNGDevice(virQEMUDriver *driver,
4997 virDomainObj *vm,
4998 virDomainRNGDef *rng)
4999 {
5000 g_autofree char *charAlias = NULL;
5001 g_autofree char *objAlias = NULL;
5002 qemuDomainObjPrivate *priv = vm->privateData;
5003 ssize_t idx;
5004 int rc = 0;
5005
5006 VIR_DEBUG("Removing RNG device %s from domain %p %s",
5007 rng->info.alias, vm, vm->def->name);
5008
5009
5010 objAlias = g_strdup_printf("obj%s", rng->info.alias);
5011
5012 if (!(charAlias = qemuAliasChardevFromDevAlias(rng->info.alias)))
5013 return -1;
5014
5015 qemuDomainObjEnterMonitor(driver, vm);
5016
5017 if (qemuMonitorDelObject(priv->mon, objAlias, true) < 0)
5018 rc = -1;
5019
5020 if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD &&
5021 rc == 0 &&
5022 qemuMonitorDetachCharDev(priv->mon, charAlias) < 0)
5023 rc = -1;
5024
5025 if (qemuDomainObjExitMonitor(driver, vm) < 0)
5026 return -1;
5027
5028 if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD &&
5029 rc == 0 &&
5030 qemuDomainDelChardevTLSObjects(driver, vm, rng->source.chardev,
5031 charAlias) < 0)
5032 rc = -1;
5033
5034 virDomainAuditRNG(vm, rng, NULL, "detach", rc == 0);
5035
5036 if (rc < 0)
5037 return -1;
5038
5039 if (qemuTeardownRNGCgroup(vm, rng) < 0)
5040 VIR_WARN("Failed to remove RNG device cgroup ACL");
5041
5042 if (qemuDomainNamespaceTeardownRNG(vm, rng) < 0)
5043 VIR_WARN("Unable to remove RNG device from /dev");
5044
5045 if ((idx = virDomainRNGFind(vm->def, rng)) >= 0)
5046 virDomainRNGRemove(vm->def, idx);
5047 qemuDomainReleaseDeviceAddress(vm, &rng->info);
5048 virDomainRNGDefFree(rng);
5049 return 0;
5050 }
5051
5052
5053 static int
qemuDomainRemoveShmemDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainShmemDef * shmem)5054 qemuDomainRemoveShmemDevice(virQEMUDriver *driver,
5055 virDomainObj *vm,
5056 virDomainShmemDef *shmem)
5057 {
5058 int rc;
5059 ssize_t idx = -1;
5060 g_autofree char *charAlias = NULL;
5061 g_autofree char *memAlias = NULL;
5062 qemuDomainObjPrivate *priv = vm->privateData;
5063
5064 VIR_DEBUG("Removing shmem device %s from domain %p %s",
5065 shmem->info.alias, vm, vm->def->name);
5066
5067 if (shmem->server.enabled) {
5068 charAlias = g_strdup_printf("char%s", shmem->info.alias);
5069 } else {
5070 memAlias = g_strdup_printf("shmmem-%s", shmem->info.alias);
5071 }
5072
5073 qemuDomainObjEnterMonitor(driver, vm);
5074
5075 if (shmem->server.enabled)
5076 rc = qemuMonitorDetachCharDev(priv->mon, charAlias);
5077 else
5078 rc = qemuMonitorDelObject(priv->mon, memAlias, true);
5079
5080 if (qemuDomainObjExitMonitor(driver, vm) < 0)
5081 return -1;
5082
5083 virDomainAuditShmem(vm, shmem, "detach", rc == 0);
5084
5085 if (rc < 0)
5086 return -1;
5087
5088 if ((idx = virDomainShmemDefFind(vm->def, shmem)) >= 0)
5089 virDomainShmemDefRemove(vm->def, idx);
5090 qemuDomainReleaseDeviceAddress(vm, &shmem->info);
5091 virDomainShmemDefFree(shmem);
5092
5093 return 0;
5094 }
5095
5096
5097 static int
qemuDomainRemoveWatchdog(virDomainObj * vm,virDomainWatchdogDef * watchdog)5098 qemuDomainRemoveWatchdog(virDomainObj *vm,
5099 virDomainWatchdogDef *watchdog)
5100 {
5101 VIR_DEBUG("Removing watchdog %s from domain %p %s",
5102 watchdog->info.alias, vm, vm->def->name);
5103
5104 qemuDomainReleaseDeviceAddress(vm, &watchdog->info);
5105 virDomainWatchdogDefFree(vm->def->watchdog);
5106 vm->def->watchdog = NULL;
5107 return 0;
5108 }
5109
5110
5111 static int
qemuDomainRemoveInputDevice(virDomainObj * vm,virDomainInputDef * dev)5112 qemuDomainRemoveInputDevice(virDomainObj *vm,
5113 virDomainInputDef *dev)
5114 {
5115 size_t i;
5116
5117 VIR_DEBUG("Removing input device %s from domain %p %s",
5118 dev->info.alias, vm, vm->def->name);
5119
5120 for (i = 0; i < vm->def->ninputs; i++) {
5121 if (vm->def->inputs[i] == dev)
5122 break;
5123 }
5124 qemuDomainReleaseDeviceAddress(vm, &dev->info);
5125 if (qemuSecurityRestoreInputLabel(vm, dev) < 0)
5126 VIR_WARN("Unable to restore security label on input device");
5127
5128 if (qemuTeardownInputCgroup(vm, dev) < 0)
5129 VIR_WARN("Unable to remove input device cgroup ACL");
5130
5131 if (qemuDomainNamespaceTeardownInput(vm, dev) < 0)
5132 VIR_WARN("Unable to remove input device from /dev");
5133
5134 virDomainInputDefFree(vm->def->inputs[i]);
5135 VIR_DELETE_ELEMENT(vm->def->inputs, i, vm->def->ninputs);
5136 return 0;
5137 }
5138
5139
5140 static int
qemuDomainRemoveVsockDevice(virDomainObj * vm,virDomainVsockDef * dev)5141 qemuDomainRemoveVsockDevice(virDomainObj *vm,
5142 virDomainVsockDef *dev)
5143 {
5144 VIR_DEBUG("Removing vsock device %s from domain %p %s",
5145 dev->info.alias, vm, vm->def->name);
5146
5147 qemuDomainReleaseDeviceAddress(vm, &dev->info);
5148 virDomainVsockDefFree(vm->def->vsock);
5149 vm->def->vsock = NULL;
5150 return 0;
5151 }
5152
5153
5154 static int
qemuDomainRemoveRedirdevDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainRedirdevDef * dev)5155 qemuDomainRemoveRedirdevDevice(virQEMUDriver *driver,
5156 virDomainObj *vm,
5157 virDomainRedirdevDef *dev)
5158 {
5159 qemuDomainObjPrivate *priv = vm->privateData;
5160 g_autofree char *charAlias = NULL;
5161 ssize_t idx;
5162
5163 VIR_DEBUG("Removing redirdev device %s from domain %p %s",
5164 dev->info.alias, vm, vm->def->name);
5165
5166 if (!(charAlias = qemuAliasChardevFromDevAlias(dev->info.alias)))
5167 return -1;
5168
5169 qemuDomainObjEnterMonitor(driver, vm);
5170 /* DeviceDel from Detach may remove chardev,
5171 * so we cannot rely on return status to delete TLS chardevs.
5172 */
5173 ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
5174
5175 if (qemuDomainObjExitMonitor(driver, vm) < 0)
5176 return -1;
5177
5178 if (qemuDomainDelChardevTLSObjects(driver, vm, dev->source, charAlias) < 0)
5179 return -1;
5180
5181 virDomainAuditRedirdev(vm, dev, "detach", true);
5182
5183 if ((idx = virDomainRedirdevDefFind(vm->def, dev)) >= 0)
5184 virDomainRedirdevDefRemove(vm->def, idx);
5185 qemuDomainReleaseDeviceAddress(vm, &dev->info);
5186 virDomainRedirdevDefFree(dev);
5187
5188 return 0;
5189 }
5190
5191
5192 static int
qemuDomainRemoveFSDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainFSDef * fs)5193 qemuDomainRemoveFSDevice(virQEMUDriver *driver,
5194 virDomainObj *vm,
5195 virDomainFSDef *fs)
5196 {
5197 g_autofree char *charAlias = NULL;
5198 qemuDomainObjPrivate *priv = vm->privateData;
5199 ssize_t idx;
5200 int rc = 0;
5201
5202 VIR_DEBUG("Removing FS device %s from domain %p %s",
5203 fs->info.alias, vm, vm->def->name);
5204
5205 if (fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) {
5206 charAlias = qemuDomainGetVhostUserChrAlias(fs->info.alias);
5207
5208 qemuDomainObjEnterMonitor(driver, vm);
5209
5210 if (qemuMonitorDetachCharDev(priv->mon, charAlias) < 0)
5211 rc = -1;
5212
5213 if (qemuDomainObjExitMonitor(driver, vm) < 0)
5214 return -1;
5215 }
5216
5217 virDomainAuditFS(vm, fs, NULL, "detach", rc == 0);
5218
5219 if (rc < 0)
5220 return -1;
5221
5222 if (!fs->sock && fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS)
5223 qemuVirtioFSStop(driver, vm, fs);
5224
5225 if ((idx = virDomainFSDefFind(vm->def, fs)) >= 0)
5226 virDomainFSRemove(vm->def, idx);
5227 qemuDomainReleaseDeviceAddress(vm, &fs->info);
5228 virDomainFSDefFree(fs);
5229 return 0;
5230 }
5231
5232
5233 static void
qemuDomainRemoveAuditDevice(virDomainObj * vm,virDomainDeviceDef * detach,bool success)5234 qemuDomainRemoveAuditDevice(virDomainObj *vm,
5235 virDomainDeviceDef *detach,
5236 bool success)
5237 {
5238 switch ((virDomainDeviceType)detach->type) {
5239 case VIR_DOMAIN_DEVICE_DISK:
5240 virDomainAuditDisk(vm, detach->data.disk->src, NULL, "detach", success);
5241 break;
5242 case VIR_DOMAIN_DEVICE_NET:
5243 virDomainAuditNet(vm, detach->data.net, NULL, "detach", success);
5244 break;
5245 case VIR_DOMAIN_DEVICE_HOSTDEV:
5246 virDomainAuditHostdev(vm, detach->data.hostdev, "detach", success);
5247 break;
5248 case VIR_DOMAIN_DEVICE_INPUT:
5249 virDomainAuditInput(vm, detach->data.input, "detach", success);
5250 break;
5251 case VIR_DOMAIN_DEVICE_CHR:
5252 virDomainAuditChardev(vm, detach->data.chr, NULL, "detach", success);
5253 break;
5254 case VIR_DOMAIN_DEVICE_RNG:
5255 virDomainAuditRNG(vm, detach->data.rng, NULL, "detach", success);
5256 break;
5257 case VIR_DOMAIN_DEVICE_MEMORY: {
5258 unsigned long long oldmem = virDomainDefGetMemoryTotal(vm->def);
5259 unsigned long long newmem = oldmem - detach->data.memory->size;
5260
5261 virDomainAuditMemory(vm, oldmem, newmem, "update", success);
5262 break;
5263 }
5264 case VIR_DOMAIN_DEVICE_SHMEM:
5265 virDomainAuditShmem(vm, detach->data.shmem, "detach", success);
5266 break;
5267 case VIR_DOMAIN_DEVICE_REDIRDEV:
5268 virDomainAuditRedirdev(vm, detach->data.redirdev, "detach", success);
5269 break;
5270
5271 case VIR_DOMAIN_DEVICE_FS:
5272 virDomainAuditFS(vm, detach->data.fs, NULL, "detach", success);
5273 break;
5274
5275 case VIR_DOMAIN_DEVICE_LEASE:
5276 case VIR_DOMAIN_DEVICE_CONTROLLER:
5277 case VIR_DOMAIN_DEVICE_WATCHDOG:
5278 case VIR_DOMAIN_DEVICE_VSOCK:
5279 /* These devices don't have associated audit logs */
5280 break;
5281
5282 case VIR_DOMAIN_DEVICE_SOUND:
5283 case VIR_DOMAIN_DEVICE_VIDEO:
5284 case VIR_DOMAIN_DEVICE_GRAPHICS:
5285 case VIR_DOMAIN_DEVICE_HUB:
5286 case VIR_DOMAIN_DEVICE_SMARTCARD:
5287 case VIR_DOMAIN_DEVICE_MEMBALLOON:
5288 case VIR_DOMAIN_DEVICE_NVRAM:
5289 case VIR_DOMAIN_DEVICE_NONE:
5290 case VIR_DOMAIN_DEVICE_TPM:
5291 case VIR_DOMAIN_DEVICE_PANIC:
5292 case VIR_DOMAIN_DEVICE_IOMMU:
5293 case VIR_DOMAIN_DEVICE_AUDIO:
5294 case VIR_DOMAIN_DEVICE_LAST:
5295 /* libvirt doesn't yet support detaching these devices */
5296 break;
5297 }
5298 }
5299
5300
5301 int
qemuDomainRemoveDevice(virQEMUDriver * driver,virDomainObj * vm,virDomainDeviceDef * dev)5302 qemuDomainRemoveDevice(virQEMUDriver *driver,
5303 virDomainObj *vm,
5304 virDomainDeviceDef *dev)
5305 {
5306 virDomainDeviceInfo *info;
5307 virObjectEvent *event;
5308 g_autofree char *alias = NULL;
5309
5310 /*
5311 * save the alias to use when sending a DEVICE_REMOVED event after
5312 * all other teardown is complete
5313 */
5314 if ((info = virDomainDeviceGetInfo(dev)))
5315 alias = g_strdup(info->alias);
5316 info = NULL;
5317
5318 switch ((virDomainDeviceType)dev->type) {
5319 case VIR_DOMAIN_DEVICE_CHR:
5320 /* We must return directly after calling
5321 * qemuDomainRemoveChrDevice because it is called directly
5322 * from other places, so it must be completely self-contained
5323 * and can't take advantage of any common code at the end of
5324 * qemuDomainRemoveDevice().
5325 */
5326 return qemuDomainRemoveChrDevice(driver, vm, dev->data.chr, true);
5327
5328 /*
5329 * all of the following qemuDomainRemove*Device() functions
5330 * are (and must be) only called from this function, so any
5331 * code that is common to them all can be pulled out and put
5332 * into this function.
5333 */
5334 case VIR_DOMAIN_DEVICE_DISK:
5335 if (qemuDomainRemoveDiskDevice(driver, vm, dev->data.disk) < 0)
5336 return -1;
5337 break;
5338 case VIR_DOMAIN_DEVICE_CONTROLLER:
5339 if (qemuDomainRemoveControllerDevice(vm, dev->data.controller) < 0)
5340 return -1;
5341 break;
5342 case VIR_DOMAIN_DEVICE_NET:
5343 if (qemuDomainRemoveNetDevice(driver, vm, dev->data.net) < 0)
5344 return -1;
5345 break;
5346 case VIR_DOMAIN_DEVICE_HOSTDEV:
5347 if (qemuDomainRemoveHostDevice(driver, vm, dev->data.hostdev) < 0)
5348 return -1;
5349 break;
5350 case VIR_DOMAIN_DEVICE_RNG:
5351 if (qemuDomainRemoveRNGDevice(driver, vm, dev->data.rng) < 0)
5352 return -1;
5353 break;
5354 case VIR_DOMAIN_DEVICE_MEMORY:
5355 if (qemuDomainRemoveMemoryDevice(driver, vm, dev->data.memory) < 0)
5356 return -1;
5357 break;
5358 case VIR_DOMAIN_DEVICE_SHMEM:
5359 if (qemuDomainRemoveShmemDevice(driver, vm, dev->data.shmem) < 0)
5360 return -1;
5361 break;
5362 case VIR_DOMAIN_DEVICE_INPUT:
5363 if (qemuDomainRemoveInputDevice(vm, dev->data.input) < 0)
5364 return -1;
5365 break;
5366 case VIR_DOMAIN_DEVICE_REDIRDEV:
5367 if (qemuDomainRemoveRedirdevDevice(driver, vm, dev->data.redirdev) < 0)
5368 return -1;
5369 break;
5370 case VIR_DOMAIN_DEVICE_WATCHDOG:
5371 if (qemuDomainRemoveWatchdog(vm, dev->data.watchdog) < 0)
5372 return -1;
5373 break;
5374 case VIR_DOMAIN_DEVICE_VSOCK:
5375 if (qemuDomainRemoveVsockDevice(vm, dev->data.vsock) < 0)
5376 return -1;
5377 break;
5378
5379 case VIR_DOMAIN_DEVICE_FS:
5380 if (qemuDomainRemoveFSDevice(driver, vm, dev->data.fs) < 0)
5381 return -1;
5382 break;
5383
5384 case VIR_DOMAIN_DEVICE_NONE:
5385 case VIR_DOMAIN_DEVICE_LEASE:
5386 case VIR_DOMAIN_DEVICE_SOUND:
5387 case VIR_DOMAIN_DEVICE_VIDEO:
5388 case VIR_DOMAIN_DEVICE_GRAPHICS:
5389 case VIR_DOMAIN_DEVICE_HUB:
5390 case VIR_DOMAIN_DEVICE_SMARTCARD:
5391 case VIR_DOMAIN_DEVICE_MEMBALLOON:
5392 case VIR_DOMAIN_DEVICE_NVRAM:
5393 case VIR_DOMAIN_DEVICE_TPM:
5394 case VIR_DOMAIN_DEVICE_PANIC:
5395 case VIR_DOMAIN_DEVICE_IOMMU:
5396 case VIR_DOMAIN_DEVICE_AUDIO:
5397 case VIR_DOMAIN_DEVICE_LAST:
5398 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
5399 _("don't know how to remove a %s device"),
5400 virDomainDeviceTypeToString(dev->type));
5401 break;
5402 }
5403
5404 event = virDomainEventDeviceRemovedNewFromObj(vm, alias);
5405 virObjectEventStateQueue(driver->domainEventState, event);
5406
5407 return 0;
5408 }
5409
5410
5411 static void
qemuDomainMarkDeviceAliasForRemoval(virDomainObj * vm,const char * alias)5412 qemuDomainMarkDeviceAliasForRemoval(virDomainObj *vm,
5413 const char *alias)
5414 {
5415 qemuDomainObjPrivate *priv = vm->privateData;
5416
5417 memset(&priv->unplug, 0, sizeof(priv->unplug));
5418
5419 priv->unplug.alias = alias;
5420 }
5421
5422
5423 static void
qemuDomainMarkDeviceForRemoval(virDomainObj * vm,virDomainDeviceInfo * info)5424 qemuDomainMarkDeviceForRemoval(virDomainObj *vm,
5425 virDomainDeviceInfo *info)
5426
5427 {
5428 qemuDomainMarkDeviceAliasForRemoval(vm, info->alias);
5429 }
5430
5431
5432 static void
qemuDomainResetDeviceRemoval(virDomainObj * vm)5433 qemuDomainResetDeviceRemoval(virDomainObj *vm)
5434 {
5435 qemuDomainObjPrivate *priv = vm->privateData;
5436 priv->unplug.alias = NULL;
5437 priv->unplug.eventSeen = false;
5438 }
5439
5440
5441 unsigned long long G_GNUC_NO_INLINE
qemuDomainGetUnplugTimeout(virDomainObj * vm)5442 qemuDomainGetUnplugTimeout(virDomainObj *vm)
5443 {
5444 if (qemuDomainIsPSeries(vm->def))
5445 return QEMU_UNPLUG_TIMEOUT_PPC64;
5446
5447 return QEMU_UNPLUG_TIMEOUT;
5448 }
5449
5450
5451 /* Returns:
5452 * -1 Unplug of the device failed
5453 *
5454 * 0 removal of the device did not finish in qemuDomainRemoveDeviceWaitTime
5455 *
5456 * 1 when the caller is responsible for finishing the device removal:
5457 * - DEVICE_DELETED event arrived before the timeout time
5458 * - we failed to reliably wait for the event and thus use fallback behavior
5459 */
5460 static int
qemuDomainWaitForDeviceRemoval(virDomainObj * vm)5461 qemuDomainWaitForDeviceRemoval(virDomainObj *vm)
5462 {
5463 qemuDomainObjPrivate *priv = vm->privateData;
5464 unsigned long long until;
5465 int rc;
5466
5467 if (virTimeMillisNow(&until) < 0)
5468 return 1;
5469 until += qemuDomainGetUnplugTimeout(vm);
5470
5471 while (priv->unplug.alias) {
5472 if ((rc = virDomainObjWaitUntil(vm, until)) == 1)
5473 return 0;
5474
5475 if (rc < 0) {
5476 VIR_WARN("Failed to wait on unplug condition for domain '%s' "
5477 "device '%s'", vm->def->name, priv->unplug.alias);
5478 return 1;
5479 }
5480 }
5481
5482 if (priv->unplug.status == QEMU_DOMAIN_UNPLUGGING_DEVICE_STATUS_GUEST_REJECTED) {
5483 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
5484 _("unplug of device was rejected by the guest"));
5485 return -1;
5486 }
5487
5488 return 1;
5489 }
5490
5491 /* Returns:
5492 * true there was a thread waiting for devAlias to be removed and this
5493 * thread will take care of finishing the removal
5494 * false the thread that started the removal is already gone and delegate
5495 * finishing the removal to a new thread
5496 */
5497 bool
qemuDomainSignalDeviceRemoval(virDomainObj * vm,const char * devAlias,qemuDomainUnpluggingDeviceStatus status)5498 qemuDomainSignalDeviceRemoval(virDomainObj *vm,
5499 const char *devAlias,
5500 qemuDomainUnpluggingDeviceStatus status)
5501 {
5502 qemuDomainObjPrivate *priv = vm->privateData;
5503
5504 if (STREQ_NULLABLE(priv->unplug.alias, devAlias)) {
5505 VIR_DEBUG("Removal of device '%s' continues in waiting thread", devAlias);
5506 qemuDomainResetDeviceRemoval(vm);
5507 priv->unplug.status = status;
5508 priv->unplug.eventSeen = true;
5509 virDomainObjBroadcast(vm);
5510 return true;
5511 }
5512 return false;
5513 }
5514
5515
5516 static int
qemuFindDisk(virDomainDef * def,const char * dst)5517 qemuFindDisk(virDomainDef *def, const char *dst)
5518 {
5519 size_t i;
5520
5521 for (i = 0; i < def->ndisks; i++) {
5522 if (STREQ(def->disks[i]->dst, dst))
5523 return i;
5524 }
5525
5526 return -1;
5527 }
5528
5529 static int
qemuDomainDetachPrepDisk(virDomainObj * vm,virDomainDiskDef * match,virDomainDiskDef ** detach)5530 qemuDomainDetachPrepDisk(virDomainObj *vm,
5531 virDomainDiskDef *match,
5532 virDomainDiskDef **detach)
5533 {
5534 virDomainDiskDef *disk;
5535 int idx;
5536
5537 if ((idx = qemuFindDisk(vm->def, match->dst)) < 0) {
5538 virReportError(VIR_ERR_DEVICE_MISSING,
5539 _("disk %s not found"), match->dst);
5540 return -1;
5541 }
5542 *detach = disk = vm->def->disks[idx];
5543
5544 switch ((virDomainDiskDevice) disk->device) {
5545 case VIR_DOMAIN_DISK_DEVICE_DISK:
5546 case VIR_DOMAIN_DISK_DEVICE_LUN:
5547
5548 switch ((virDomainDiskBus) disk->bus) {
5549 case VIR_DOMAIN_DISK_BUS_VIRTIO:
5550 case VIR_DOMAIN_DISK_BUS_USB:
5551 case VIR_DOMAIN_DISK_BUS_SCSI:
5552 break;
5553
5554 case VIR_DOMAIN_DISK_BUS_IDE:
5555 case VIR_DOMAIN_DISK_BUS_FDC:
5556 case VIR_DOMAIN_DISK_BUS_XEN:
5557 case VIR_DOMAIN_DISK_BUS_UML:
5558 case VIR_DOMAIN_DISK_BUS_SATA:
5559 case VIR_DOMAIN_DISK_BUS_SD:
5560 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
5561 _("This type of disk cannot be hot unplugged"));
5562 return -1;
5563
5564 case VIR_DOMAIN_DISK_BUS_NONE:
5565 case VIR_DOMAIN_DISK_BUS_LAST:
5566 default:
5567 virReportEnumRangeError(virDomainDiskBus, disk->bus);
5568 return -1;
5569 }
5570 break;
5571
5572 case VIR_DOMAIN_DISK_DEVICE_CDROM:
5573 case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
5574 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
5575 _("disk device type '%s' cannot be detached"),
5576 virDomainDiskDeviceTypeToString(disk->device));
5577 return -1;
5578
5579 case VIR_DOMAIN_DISK_DEVICE_LAST:
5580 default:
5581 virReportEnumRangeError(virDomainDiskDevice, disk->device);
5582 return -1;
5583 }
5584
5585 if (qemuDomainDiskBlockJobIsActive(disk))
5586 return -1;
5587
5588 return 0;
5589 }
5590
5591
5592 static bool
qemuDomainDiskControllerIsBusy(virDomainObj * vm,virDomainControllerDef * detach)5593 qemuDomainDiskControllerIsBusy(virDomainObj *vm,
5594 virDomainControllerDef *detach)
5595 {
5596 size_t i;
5597 virDomainDiskDef *disk;
5598 virDomainHostdevDef *hostdev;
5599
5600 for (i = 0; i < vm->def->ndisks; i++) {
5601 disk = vm->def->disks[i];
5602 if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE)
5603 /* the disk does not use disk controller */
5604 continue;
5605
5606 /* check whether the disk uses this type controller */
5607 switch ((virDomainControllerType) detach->type) {
5608 case VIR_DOMAIN_CONTROLLER_TYPE_IDE:
5609 if (disk->bus != VIR_DOMAIN_DISK_BUS_IDE)
5610 continue;
5611 break;
5612
5613 case VIR_DOMAIN_CONTROLLER_TYPE_FDC:
5614 if (disk->bus != VIR_DOMAIN_DISK_BUS_FDC)
5615 continue;
5616 break;
5617
5618 case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
5619 if (disk->bus != VIR_DOMAIN_DISK_BUS_SCSI)
5620 continue;
5621 break;
5622
5623 case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
5624 if (disk->bus != VIR_DOMAIN_DISK_BUS_SATA)
5625 continue;
5626 break;
5627
5628 case VIR_DOMAIN_CONTROLLER_TYPE_XENBUS:
5629 /* xenbus is not supported by the qemu driver */
5630 continue;
5631
5632 case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
5633 /* virtio-serial does not host any disks */
5634 continue;
5635
5636 case VIR_DOMAIN_CONTROLLER_TYPE_CCID:
5637 case VIR_DOMAIN_CONTROLLER_TYPE_USB:
5638 case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
5639 case VIR_DOMAIN_CONTROLLER_TYPE_ISA:
5640 /* These buses have (also) other device types too so they need to
5641 * be checked elsewhere */
5642 continue;
5643
5644 case VIR_DOMAIN_CONTROLLER_TYPE_LAST:
5645 default:
5646 continue;
5647 }
5648
5649 if (disk->info.addr.drive.controller == detach->idx)
5650 return true;
5651 }
5652
5653 if (detach->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
5654 for (i = 0; i < vm->def->nhostdevs; i++) {
5655 hostdev = vm->def->hostdevs[i];
5656 if (!virHostdevIsSCSIDevice(hostdev))
5657 continue;
5658
5659 if (hostdev->info->addr.drive.controller == detach->idx)
5660 return true;
5661 }
5662 }
5663
5664 return false;
5665 }
5666
5667
5668 static bool
qemuDomainControllerIsBusy(virDomainObj * vm,virDomainControllerDef * detach)5669 qemuDomainControllerIsBusy(virDomainObj *vm,
5670 virDomainControllerDef *detach)
5671 {
5672 switch ((virDomainControllerType) detach->type) {
5673 case VIR_DOMAIN_CONTROLLER_TYPE_IDE:
5674 case VIR_DOMAIN_CONTROLLER_TYPE_FDC:
5675 case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
5676 case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
5677 return qemuDomainDiskControllerIsBusy(vm, detach);
5678
5679 case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
5680 case VIR_DOMAIN_CONTROLLER_TYPE_CCID:
5681 case VIR_DOMAIN_CONTROLLER_TYPE_USB:
5682 case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
5683 case VIR_DOMAIN_CONTROLLER_TYPE_ISA:
5684 /* detach of the controller types above is not yet supported */
5685 return false;
5686
5687 case VIR_DOMAIN_CONTROLLER_TYPE_XENBUS:
5688 /* qemu driver doesn't support xenbus */
5689 return false;
5690
5691 case VIR_DOMAIN_CONTROLLER_TYPE_LAST:
5692 default:
5693 return false;
5694 }
5695 }
5696
5697
5698 static int
qemuDomainDetachPrepController(virDomainObj * vm,virDomainControllerDef * match,virDomainControllerDef ** detach)5699 qemuDomainDetachPrepController(virDomainObj *vm,
5700 virDomainControllerDef *match,
5701 virDomainControllerDef **detach)
5702 {
5703 int idx;
5704 virDomainControllerDef *controller = NULL;
5705
5706 if (match->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
5707 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
5708 _("'%s' controller cannot be hot unplugged."),
5709 virDomainControllerTypeToString(match->type));
5710 return -1;
5711 }
5712
5713 if ((idx = virDomainControllerFind(vm->def, match->type, match->idx)) < 0) {
5714 virReportError(VIR_ERR_DEVICE_MISSING,
5715 _("controller %s:%d not found"),
5716 virDomainControllerTypeToString(match->type),
5717 match->idx);
5718 return -1;
5719 }
5720
5721 *detach = controller = vm->def->controllers[idx];
5722
5723 if (qemuDomainControllerIsBusy(vm, controller)) {
5724 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
5725 _("device cannot be detached: device is busy"));
5726 return -1;
5727 }
5728
5729 return 0;
5730 }
5731
5732
5733 /* search for a hostdev matching dev and detach it */
5734 static int
qemuDomainDetachPrepHostdev(virDomainObj * vm,virDomainHostdevDef * match,virDomainHostdevDef ** detach)5735 qemuDomainDetachPrepHostdev(virDomainObj *vm,
5736 virDomainHostdevDef *match,
5737 virDomainHostdevDef **detach)
5738 {
5739 virDomainHostdevSubsys *subsys = &match->source.subsys;
5740 virDomainHostdevSubsysUSB *usbsrc = &subsys->u.usb;
5741 virDomainHostdevSubsysPCI *pcisrc = &subsys->u.pci;
5742 virDomainHostdevSubsysSCSI *scsisrc = &subsys->u.scsi;
5743 virDomainHostdevSubsysMediatedDev *mdevsrc = &subsys->u.mdev;
5744 virDomainHostdevDef *hostdev = NULL;
5745 int idx;
5746
5747 if (match->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
5748 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
5749 _("hot unplug is not supported for hostdev mode '%s'"),
5750 virDomainHostdevModeTypeToString(match->mode));
5751 return -1;
5752 }
5753
5754 idx = virDomainHostdevFind(vm->def, match, &hostdev);
5755 *detach = hostdev;
5756
5757 if (idx < 0) {
5758 switch (subsys->type) {
5759 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
5760 virReportError(VIR_ERR_DEVICE_MISSING,
5761 _("host pci device " VIR_PCI_DEVICE_ADDRESS_FMT
5762 " not found"),
5763 pcisrc->addr.domain, pcisrc->addr.bus,
5764 pcisrc->addr.slot, pcisrc->addr.function);
5765 break;
5766 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
5767 if (usbsrc->bus && usbsrc->device) {
5768 virReportError(VIR_ERR_DEVICE_MISSING,
5769 _("host usb device %03d.%03d not found"),
5770 usbsrc->bus, usbsrc->device);
5771 } else {
5772 virReportError(VIR_ERR_DEVICE_MISSING,
5773 _("host usb device vendor=0x%.4x product=0x%.4x not found"),
5774 usbsrc->vendor, usbsrc->product);
5775 }
5776 break;
5777 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
5778 if (scsisrc->protocol ==
5779 VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
5780 virDomainHostdevSubsysSCSIiSCSI *iscsisrc = &scsisrc->u.iscsi;
5781 virReportError(VIR_ERR_DEVICE_MISSING,
5782 _("host scsi iSCSI path %s not found"),
5783 iscsisrc->src->path);
5784 } else {
5785 virDomainHostdevSubsysSCSIHost *scsihostsrc =
5786 &scsisrc->u.host;
5787 virReportError(VIR_ERR_DEVICE_MISSING,
5788 _("host scsi device %s:%u:%u.%llu not found"),
5789 scsihostsrc->adapter, scsihostsrc->bus,
5790 scsihostsrc->target, scsihostsrc->unit);
5791 }
5792 break;
5793 }
5794 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
5795 virReportError(VIR_ERR_DEVICE_MISSING,
5796 _("mediated device '%s' not found"),
5797 mdevsrc->uuidstr);
5798 break;
5799 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
5800 break;
5801 default:
5802 virReportError(VIR_ERR_INTERNAL_ERROR,
5803 _("unexpected hostdev type %d"), subsys->type);
5804 break;
5805 }
5806 return -1;
5807 }
5808
5809 return 0;
5810 }
5811
5812
5813 static int
qemuDomainDetachPrepShmem(virDomainObj * vm,virDomainShmemDef * match,virDomainShmemDef ** detach)5814 qemuDomainDetachPrepShmem(virDomainObj *vm,
5815 virDomainShmemDef *match,
5816 virDomainShmemDef **detach)
5817 {
5818 ssize_t idx = -1;
5819 virDomainShmemDef *shmem = NULL;
5820
5821 if ((idx = virDomainShmemDefFind(vm->def, match)) < 0) {
5822 virReportError(VIR_ERR_DEVICE_MISSING,
5823 _("model '%s' shmem device not present "
5824 "in domain configuration"),
5825 virDomainShmemModelTypeToString(match->model));
5826 return -1;
5827 }
5828
5829 *detach = shmem = vm->def->shmems[idx];
5830
5831 switch (shmem->model) {
5832 case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_PLAIN:
5833 case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_DOORBELL:
5834 break;
5835
5836 case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM:
5837 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
5838 _("live detach of shmem model '%s' is not supported"),
5839 virDomainShmemModelTypeToString(shmem->model));
5840 G_GNUC_FALLTHROUGH;
5841 case VIR_DOMAIN_SHMEM_MODEL_LAST:
5842 return -1;
5843 }
5844
5845 return 0;
5846 }
5847
5848
5849 static int
qemuDomainDetachPrepWatchdog(virDomainObj * vm,virDomainWatchdogDef * match,virDomainWatchdogDef ** detach)5850 qemuDomainDetachPrepWatchdog(virDomainObj *vm,
5851 virDomainWatchdogDef *match,
5852 virDomainWatchdogDef **detach)
5853 {
5854 virDomainWatchdogDef *watchdog;
5855
5856 *detach = watchdog = vm->def->watchdog;
5857
5858 if (!watchdog) {
5859 virReportError(VIR_ERR_DEVICE_MISSING, "%s",
5860 _("watchdog device not present in domain configuration"));
5861 return -1;
5862 }
5863
5864 /* While domains can have up to one watchdog, the one supplied by the user
5865 * doesn't necessarily match the one domain has. Refuse to detach in such
5866 * case. */
5867 if (!(watchdog->model == match->model &&
5868 watchdog->action == match->action &&
5869 virDomainDeviceInfoAddressIsEqual(&match->info, &watchdog->info))) {
5870 virReportError(VIR_ERR_DEVICE_MISSING,
5871 _("model '%s' watchdog device not present "
5872 "in domain configuration"),
5873 virDomainWatchdogModelTypeToString(watchdog->model));
5874 return -1;
5875 }
5876
5877 if (watchdog->model != VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB) {
5878 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
5879 _("hot unplug of watchdog of model %s is not supported"),
5880 virDomainWatchdogModelTypeToString(watchdog->model));
5881 return -1;
5882 }
5883
5884 return 0;
5885 }
5886
5887
5888 static int
qemuDomainDetachPrepRedirdev(virDomainObj * vm,virDomainRedirdevDef * match,virDomainRedirdevDef ** detach)5889 qemuDomainDetachPrepRedirdev(virDomainObj *vm,
5890 virDomainRedirdevDef *match,
5891 virDomainRedirdevDef **detach)
5892 {
5893 ssize_t idx;
5894
5895 if ((idx = virDomainRedirdevDefFind(vm->def, match)) < 0) {
5896 virReportError(VIR_ERR_OPERATION_INVALID, "%s",
5897 _("no matching redirdev was not found"));
5898 return -1;
5899 }
5900
5901 *detach = vm->def->redirdevs[idx];
5902
5903 return 0;
5904 }
5905
5906
5907 static int
qemuDomainDetachPrepNet(virDomainObj * vm,virDomainNetDef * match,virDomainNetDef ** detach)5908 qemuDomainDetachPrepNet(virDomainObj *vm,
5909 virDomainNetDef *match,
5910 virDomainNetDef **detach)
5911 {
5912 int detachidx;
5913
5914 if ((detachidx = virDomainNetFindIdx(vm->def, match)) < 0)
5915 return -1;
5916
5917 *detach = vm->def->nets[detachidx];
5918
5919 return 0;
5920 }
5921
5922
5923 static int
qemuDomainDetachDeviceChr(virQEMUDriver * driver,virDomainObj * vm,virDomainChrDef * chr,bool async)5924 qemuDomainDetachDeviceChr(virQEMUDriver *driver,
5925 virDomainObj *vm,
5926 virDomainChrDef *chr,
5927 bool async)
5928 {
5929 int ret = -1;
5930 qemuDomainObjPrivate *priv = vm->privateData;
5931 virDomainDef *vmdef = vm->def;
5932 virDomainChrDef *tmpChr;
5933 bool guestfwd = false;
5934
5935 if (!(tmpChr = virDomainChrFind(vmdef, chr))) {
5936 virReportError(VIR_ERR_DEVICE_MISSING,
5937 _("chr type '%s' device not present "
5938 "in domain configuration"),
5939 virDomainChrDeviceTypeToString(chr->deviceType));
5940 goto cleanup;
5941 }
5942
5943 /* guestfwd channels are not really -device rather than
5944 * -netdev. We need to treat them slightly differently. */
5945 guestfwd = tmpChr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
5946 tmpChr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD;
5947
5948 if (!async && !guestfwd)
5949 qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info);
5950
5951 if (guestfwd) {
5952 int rc;
5953 qemuDomainObjEnterMonitor(driver, vm);
5954 rc = qemuMonitorRemoveNetdev(priv->mon, tmpChr->info.alias);
5955 if (qemuDomainObjExitMonitor(driver, vm) < 0)
5956 rc = -1;
5957
5958 if (rc < 0)
5959 goto cleanup;
5960 } else {
5961 if (qemuDomainDeleteDevice(vm, tmpChr->info.alias) < 0)
5962 goto cleanup;
5963 }
5964
5965 if (guestfwd) {
5966 ret = qemuDomainRemoveChrDevice(driver, vm, tmpChr, false);
5967 } else if (async) {
5968 ret = 0;
5969 } else {
5970 if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
5971 ret = qemuDomainRemoveChrDevice(driver, vm, tmpChr, true);
5972 }
5973
5974 cleanup:
5975 if (!async)
5976 qemuDomainResetDeviceRemoval(vm);
5977 return ret;
5978 }
5979
5980
5981 static int
qemuDomainDetachPrepRNG(virDomainObj * vm,virDomainRNGDef * match,virDomainRNGDef ** detach)5982 qemuDomainDetachPrepRNG(virDomainObj *vm,
5983 virDomainRNGDef *match,
5984 virDomainRNGDef **detach)
5985 {
5986 ssize_t idx;
5987
5988 if ((idx = virDomainRNGFind(vm->def, match)) < 0) {
5989 virReportError(VIR_ERR_DEVICE_MISSING,
5990 _("model '%s' RNG device not present "
5991 "in domain configuration"),
5992 virDomainRNGBackendTypeToString(match->model));
5993 return -1;
5994 }
5995
5996 *detach = vm->def->rngs[idx];
5997
5998 return 0;
5999 }
6000
6001
6002 static int
qemuDomainDetachPrepMemory(virDomainObj * vm,virDomainMemoryDef * match,virDomainMemoryDef ** detach)6003 qemuDomainDetachPrepMemory(virDomainObj *vm,
6004 virDomainMemoryDef *match,
6005 virDomainMemoryDef **detach)
6006 {
6007 int idx;
6008
6009 if (qemuDomainMemoryDeviceAlignSize(vm->def, match) < 0)
6010 return -1;
6011
6012 if ((idx = virDomainMemoryFindByDef(vm->def, match)) < 0) {
6013 virReportError(VIR_ERR_DEVICE_MISSING,
6014 _("model '%s' memory device not present "
6015 "in the domain configuration"),
6016 virDomainMemoryModelTypeToString(match->model));
6017 return -1;
6018 }
6019
6020 *detach = vm->def->mems[idx];
6021
6022 return 0;
6023 }
6024
6025
6026 static int
qemuDomainDetachPrepInput(virDomainObj * vm,virDomainInputDef * match,virDomainInputDef ** detach)6027 qemuDomainDetachPrepInput(virDomainObj *vm,
6028 virDomainInputDef *match,
6029 virDomainInputDef **detach)
6030 {
6031 virDomainInputDef *input;
6032 int idx;
6033
6034 if ((idx = virDomainInputDefFind(vm->def, match)) < 0) {
6035 virReportError(VIR_ERR_DEVICE_MISSING, "%s",
6036 _("matching input device not found"));
6037 return -1;
6038 }
6039 *detach = input = vm->def->inputs[idx];
6040
6041 switch ((virDomainInputBus) input->bus) {
6042 case VIR_DOMAIN_INPUT_BUS_PS2:
6043 case VIR_DOMAIN_INPUT_BUS_XEN:
6044 case VIR_DOMAIN_INPUT_BUS_PARALLELS:
6045 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
6046 _("input device on bus '%s' cannot be detached"),
6047 virDomainInputBusTypeToString(input->bus));
6048 return -1;
6049
6050 case VIR_DOMAIN_INPUT_BUS_LAST:
6051 case VIR_DOMAIN_INPUT_BUS_USB:
6052 case VIR_DOMAIN_INPUT_BUS_VIRTIO:
6053 case VIR_DOMAIN_INPUT_BUS_NONE:
6054 break;
6055 }
6056
6057 return 0;
6058 }
6059
6060
6061 static int
qemuDomainDetachPrepVsock(virDomainObj * vm,virDomainVsockDef * match,virDomainVsockDef ** detach)6062 qemuDomainDetachPrepVsock(virDomainObj *vm,
6063 virDomainVsockDef *match,
6064 virDomainVsockDef **detach)
6065 {
6066 virDomainVsockDef *vsock;
6067
6068 *detach = vsock = vm->def->vsock;
6069 if (!vsock ||
6070 !virDomainVsockDefEquals(match, vsock)) {
6071 virReportError(VIR_ERR_DEVICE_MISSING, "%s",
6072 _("matching vsock device not found"));
6073 return -1;
6074 }
6075
6076 return 0;
6077 }
6078
6079
6080 static int
qemuDomainDetachPrepFS(virDomainObj * vm,virDomainFSDef * match,virDomainFSDef ** detach)6081 qemuDomainDetachPrepFS(virDomainObj *vm,
6082 virDomainFSDef *match,
6083 virDomainFSDef **detach)
6084 {
6085 ssize_t idx;
6086
6087 if ((idx = virDomainFSDefFind(vm->def, match)) < 0) {
6088 virReportError(VIR_ERR_DEVICE_MISSING, "%s",
6089 _("matching filesystem not found"));
6090 return -1;
6091 }
6092
6093 if (vm->def->fss[idx]->fsdriver != VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) {
6094 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
6095 _("only virtiofs filesystems can be hotplugged"));
6096 return -1;
6097 }
6098
6099 *detach = vm->def->fss[idx];
6100
6101 return 0;
6102 }
6103
6104
6105 static int
qemuDomainDetachDeviceLease(virQEMUDriver * driver,virDomainObj * vm,virDomainLeaseDef * lease)6106 qemuDomainDetachDeviceLease(virQEMUDriver *driver,
6107 virDomainObj *vm,
6108 virDomainLeaseDef *lease)
6109 {
6110 virDomainLeaseDef *det_lease;
6111 int idx;
6112
6113 if ((idx = virDomainLeaseIndex(vm->def, lease)) < 0) {
6114 virReportError(VIR_ERR_INVALID_ARG,
6115 _("Lease %s in lockspace %s does not exist"),
6116 lease->key, NULLSTR(lease->lockspace));
6117 return -1;
6118 }
6119
6120 if (virDomainLockLeaseDetach(driver->lockManager, vm, lease) < 0)
6121 return -1;
6122
6123 det_lease = virDomainLeaseRemoveAt(vm->def, idx);
6124 virDomainLeaseDefFree(det_lease);
6125 return 0;
6126 }
6127
6128
6129 int
qemuDomainDetachDeviceLive(virDomainObj * vm,virDomainDeviceDef * match,virQEMUDriver * driver,bool async)6130 qemuDomainDetachDeviceLive(virDomainObj *vm,
6131 virDomainDeviceDef *match,
6132 virQEMUDriver *driver,
6133 bool async)
6134 {
6135 virDomainDeviceDef detach = { .type = match->type };
6136 virDomainDeviceInfo *info = NULL;
6137 int ret = -1;
6138
6139 switch ((virDomainDeviceType)match->type) {
6140 /*
6141 * lease and chr devices don't follow the standard pattern of
6142 * the others, so they must have their own self-contained
6143 * Detach functions.
6144 */
6145 case VIR_DOMAIN_DEVICE_LEASE:
6146 return qemuDomainDetachDeviceLease(driver, vm, match->data.lease);
6147
6148 case VIR_DOMAIN_DEVICE_CHR:
6149 return qemuDomainDetachDeviceChr(driver, vm, match->data.chr, async);
6150
6151 /*
6152 * All the other device types follow a very similar pattern -
6153 * First we call type-specific functions to 1) locate the
6154 * device we want to detach (based on the prototype device in
6155 * match) and 2) do any device-type-specific validation to
6156 * assure it is okay to detach the device.
6157 */
6158 case VIR_DOMAIN_DEVICE_DISK:
6159 if (qemuDomainDetachPrepDisk(vm, match->data.disk,
6160 &detach.data.disk) < 0) {
6161 return -1;
6162 }
6163 break;
6164 case VIR_DOMAIN_DEVICE_CONTROLLER:
6165 if (qemuDomainDetachPrepController(vm, match->data.controller,
6166 &detach.data.controller) < 0) {
6167 return -1;
6168 }
6169 break;
6170 case VIR_DOMAIN_DEVICE_NET:
6171 if (qemuDomainDetachPrepNet(vm, match->data.net,
6172 &detach.data.net) < 0) {
6173 return -1;
6174 }
6175 break;
6176 case VIR_DOMAIN_DEVICE_HOSTDEV:
6177 if (qemuDomainDetachPrepHostdev(vm, match->data.hostdev,
6178 &detach.data.hostdev) < 0) {
6179 return -1;
6180 }
6181 break;
6182 case VIR_DOMAIN_DEVICE_RNG:
6183 if (qemuDomainDetachPrepRNG(vm, match->data.rng,
6184 &detach.data.rng) < 0) {
6185 return -1;
6186 }
6187 break;
6188 case VIR_DOMAIN_DEVICE_MEMORY:
6189 if (qemuDomainDetachPrepMemory(vm, match->data.memory,
6190 &detach.data.memory) < 0) {
6191 return -1;
6192 }
6193 break;
6194 case VIR_DOMAIN_DEVICE_SHMEM:
6195 if (qemuDomainDetachPrepShmem(vm, match->data.shmem,
6196 &detach.data.shmem) < 0) {
6197 return -1;
6198 }
6199 break;
6200 case VIR_DOMAIN_DEVICE_WATCHDOG:
6201 if (qemuDomainDetachPrepWatchdog(vm, match->data.watchdog,
6202 &detach.data.watchdog) < 0) {
6203 return -1;
6204 }
6205 break;
6206 case VIR_DOMAIN_DEVICE_INPUT:
6207 if (qemuDomainDetachPrepInput(vm, match->data.input,
6208 &detach.data.input) < 0) {
6209 return -1;
6210 }
6211 break;
6212 case VIR_DOMAIN_DEVICE_REDIRDEV:
6213 if (qemuDomainDetachPrepRedirdev(vm, match->data.redirdev,
6214 &detach.data.redirdev) < 0) {
6215 return -1;
6216 }
6217 break;
6218 case VIR_DOMAIN_DEVICE_VSOCK:
6219 if (qemuDomainDetachPrepVsock(vm, match->data.vsock,
6220 &detach.data.vsock) < 0) {
6221 return -1;
6222 }
6223 break;
6224
6225 case VIR_DOMAIN_DEVICE_FS:
6226 if (qemuDomainDetachPrepFS(vm, match->data.fs,
6227 &detach.data.fs) < 0) {
6228 return -1;
6229 }
6230 break;
6231
6232 case VIR_DOMAIN_DEVICE_SOUND:
6233 case VIR_DOMAIN_DEVICE_VIDEO:
6234 case VIR_DOMAIN_DEVICE_GRAPHICS:
6235 case VIR_DOMAIN_DEVICE_HUB:
6236 case VIR_DOMAIN_DEVICE_SMARTCARD:
6237 case VIR_DOMAIN_DEVICE_MEMBALLOON:
6238 case VIR_DOMAIN_DEVICE_NVRAM:
6239 case VIR_DOMAIN_DEVICE_NONE:
6240 case VIR_DOMAIN_DEVICE_TPM:
6241 case VIR_DOMAIN_DEVICE_PANIC:
6242 case VIR_DOMAIN_DEVICE_IOMMU:
6243 case VIR_DOMAIN_DEVICE_AUDIO:
6244 case VIR_DOMAIN_DEVICE_LAST:
6245 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
6246 _("live detach of device '%s' is not supported"),
6247 virDomainDeviceTypeToString(match->type));
6248 return -1;
6249 }
6250
6251 /* "detach" now points to the actual device we want to detach */
6252
6253 if (!(info = virDomainDeviceGetInfo(&detach))) {
6254 /*
6255 * This should never happen, since all of the device types in
6256 * the switch cases that end with a "break" instead of a
6257 * return have a virDeviceInfo in them.
6258 */
6259 virReportError(VIR_ERR_INTERNAL_ERROR,
6260 _("device of type '%s' has no device info"),
6261 virDomainDeviceTypeToString(detach.type));
6262 return -1;
6263 }
6264
6265
6266 /* Make generic validation checks common to all device types */
6267
6268 if (!info->alias) {
6269 virReportError(VIR_ERR_INTERNAL_ERROR,
6270 _("Cannot detach %s device with no alias"),
6271 virDomainDeviceTypeToString(detach.type));
6272 return -1;
6273 }
6274
6275 if (qemuIsMultiFunctionDevice(vm->def, info)) {
6276 virReportError(VIR_ERR_OPERATION_FAILED,
6277 _("cannot hot unplug %s device with multifunction PCI guest address: "
6278 VIR_PCI_DEVICE_ADDRESS_FMT),
6279 virDomainDeviceTypeToString(detach.type),
6280 info->addr.pci.domain, info->addr.pci.bus,
6281 info->addr.pci.slot, info->addr.pci.function);
6282 return -1;
6283 }
6284
6285 if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
6286
6287 virDomainControllerDef *controller;
6288 int controllerIdx = virDomainControllerFind(vm->def,
6289 VIR_DOMAIN_CONTROLLER_TYPE_PCI,
6290 info->addr.pci.bus);
6291 if (controllerIdx < 0) {
6292 virReportError(VIR_ERR_OPERATION_FAILED,
6293 _("cannot hot unplug %s device with PCI guest address: "
6294 VIR_PCI_DEVICE_ADDRESS_FMT
6295 " - controller not found"),
6296 virDomainDeviceTypeToString(detach.type),
6297 info->addr.pci.domain, info->addr.pci.bus,
6298 info->addr.pci.slot, info->addr.pci.function);
6299 return -1;
6300 }
6301
6302 controller = vm->def->controllers[controllerIdx];
6303 if (controller->opts.pciopts.hotplug == VIR_TRISTATE_SWITCH_OFF) {
6304 virReportError(VIR_ERR_OPERATION_FAILED,
6305 _("cannot hot unplug %s device with PCI guest address: "
6306 VIR_PCI_DEVICE_ADDRESS_FMT
6307 " - not allowed by controller"),
6308 virDomainDeviceTypeToString(detach.type),
6309 info->addr.pci.domain, info->addr.pci.bus,
6310 info->addr.pci.slot, info->addr.pci.function);
6311 return -1;
6312 }
6313 }
6314
6315 /*
6316 * Issue the qemu monitor command to delete the device (based on
6317 * its alias), and optionally wait a short time in case the
6318 * DEVICE_DELETED event arrives from qemu right away.
6319 */
6320 if (!async)
6321 qemuDomainMarkDeviceForRemoval(vm, info);
6322
6323 if (qemuDomainDeleteDevice(vm, info->alias) < 0) {
6324 if (virDomainObjIsActive(vm))
6325 qemuDomainRemoveAuditDevice(vm, &detach, false);
6326 goto cleanup;
6327 }
6328
6329 if (async) {
6330 ret = 0;
6331 } else {
6332 if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
6333 ret = qemuDomainRemoveDevice(driver, vm, &detach);
6334 }
6335
6336 cleanup:
6337 if (!async)
6338 qemuDomainResetDeviceRemoval(vm);
6339
6340 return ret;
6341 }
6342
6343
6344 static int
qemuDomainRemoveVcpu(virQEMUDriver * driver,virDomainObj * vm,unsigned int vcpu)6345 qemuDomainRemoveVcpu(virQEMUDriver *driver,
6346 virDomainObj *vm,
6347 unsigned int vcpu)
6348 {
6349 qemuDomainObjPrivate *priv = vm->privateData;
6350 virDomainVcpuDef *vcpuinfo = virDomainDefGetVcpu(vm->def, vcpu);
6351 qemuDomainVcpuPrivate *vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpuinfo);
6352 int oldvcpus = virDomainDefGetVcpus(vm->def);
6353 unsigned int nvcpus = vcpupriv->vcpus;
6354 virErrorPtr save_error = NULL;
6355 size_t i;
6356
6357 if (qemuDomainRefreshVcpuInfo(driver, vm, QEMU_ASYNC_JOB_NONE, false) < 0)
6358 return -1;
6359
6360 /* validation requires us to set the expected state prior to calling it */
6361 for (i = vcpu; i < vcpu + nvcpus; i++) {
6362 vcpuinfo = virDomainDefGetVcpu(vm->def, i);
6363 vcpuinfo->online = false;
6364 }
6365
6366 if (qemuDomainValidateVcpuInfo(vm) < 0) {
6367 /* rollback vcpu count if the setting has failed */
6368 virDomainAuditVcpu(vm, oldvcpus, oldvcpus - nvcpus, "update", false);
6369
6370 for (i = vcpu; i < vcpu + nvcpus; i++) {
6371 vcpuinfo = virDomainDefGetVcpu(vm->def, i);
6372 vcpuinfo->online = true;
6373 }
6374 return -1;
6375 }
6376
6377 virDomainAuditVcpu(vm, oldvcpus, oldvcpus - nvcpus, "update", true);
6378
6379 virErrorPreserveLast(&save_error);
6380
6381 for (i = vcpu; i < vcpu + nvcpus; i++)
6382 ignore_value(virCgroupDelThread(priv->cgroup, VIR_CGROUP_THREAD_VCPU, i));
6383
6384 virErrorRestore(&save_error);
6385
6386 return 0;
6387 }
6388
6389
6390 void
qemuDomainRemoveVcpuAlias(virQEMUDriver * driver,virDomainObj * vm,const char * alias)6391 qemuDomainRemoveVcpuAlias(virQEMUDriver *driver,
6392 virDomainObj *vm,
6393 const char *alias)
6394 {
6395 virDomainVcpuDef *vcpu;
6396 qemuDomainVcpuPrivate *vcpupriv;
6397 size_t i;
6398
6399 for (i = 0; i < virDomainDefGetVcpusMax(vm->def); i++) {
6400 vcpu = virDomainDefGetVcpu(vm->def, i);
6401 vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpu);
6402
6403 if (STREQ_NULLABLE(alias, vcpupriv->alias)) {
6404 qemuDomainRemoveVcpu(driver, vm, i);
6405 return;
6406 }
6407 }
6408 }
6409
6410
6411 static int
qemuDomainHotplugDelVcpu(virQEMUDriver * driver,virQEMUDriverConfig * cfg,virDomainObj * vm,unsigned int vcpu)6412 qemuDomainHotplugDelVcpu(virQEMUDriver *driver,
6413 virQEMUDriverConfig *cfg,
6414 virDomainObj *vm,
6415 unsigned int vcpu)
6416 {
6417 virDomainVcpuDef *vcpuinfo = virDomainDefGetVcpu(vm->def, vcpu);
6418 qemuDomainVcpuPrivate *vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpuinfo);
6419 int oldvcpus = virDomainDefGetVcpus(vm->def);
6420 unsigned int nvcpus = vcpupriv->vcpus;
6421 int rc;
6422 int ret = -1;
6423
6424 if (!vcpupriv->alias) {
6425 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
6426 _("vcpu '%u' can't be unplugged"), vcpu);
6427 return -1;
6428 }
6429
6430 qemuDomainMarkDeviceAliasForRemoval(vm, vcpupriv->alias);
6431
6432 if (qemuDomainDeleteDevice(vm, vcpupriv->alias) < 0) {
6433 if (virDomainObjIsActive(vm))
6434 virDomainAuditVcpu(vm, oldvcpus, oldvcpus - nvcpus, "update", false);
6435 goto cleanup;
6436 }
6437
6438 if ((rc = qemuDomainWaitForDeviceRemoval(vm)) <= 0) {
6439 if (rc == 0)
6440 virReportError(VIR_ERR_OPERATION_TIMEOUT, "%s",
6441 _("vcpu unplug request timed out. Unplug result "
6442 "must be manually inspected in the domain"));
6443
6444 goto cleanup;
6445 }
6446
6447 if (qemuDomainRemoveVcpu(driver, vm, vcpu) < 0)
6448 goto cleanup;
6449
6450 qemuDomainVcpuPersistOrder(vm->def);
6451
6452 if (virDomainObjSave(vm, driver->xmlopt, cfg->stateDir) < 0)
6453 goto cleanup;
6454
6455 ret = 0;
6456
6457 cleanup:
6458 qemuDomainResetDeviceRemoval(vm);
6459 return ret;
6460 }
6461
6462
6463 static int
qemuDomainHotplugAddVcpu(virQEMUDriver * driver,virQEMUDriverConfig * cfg,virDomainObj * vm,unsigned int vcpu)6464 qemuDomainHotplugAddVcpu(virQEMUDriver *driver,
6465 virQEMUDriverConfig *cfg,
6466 virDomainObj *vm,
6467 unsigned int vcpu)
6468 {
6469 g_autoptr(virJSONValue) vcpuprops = NULL;
6470 virDomainVcpuDef *vcpuinfo = virDomainDefGetVcpu(vm->def, vcpu);
6471 qemuDomainVcpuPrivate *vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpuinfo);
6472 unsigned int nvcpus = vcpupriv->vcpus;
6473 int rc;
6474 int oldvcpus = virDomainDefGetVcpus(vm->def);
6475 size_t i;
6476
6477 if (!qemuDomainSupportsNewVcpuHotplug(vm)) {
6478 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
6479 _("cpu hotplug is not supported"));
6480 return -1;
6481 }
6482
6483 vcpupriv->alias = g_strdup_printf("vcpu%u", vcpu);
6484
6485 if (!(vcpuprops = qemuBuildHotpluggableCPUProps(vcpuinfo)))
6486 return -1;
6487
6488 qemuDomainObjEnterMonitor(driver, vm);
6489
6490 rc = qemuMonitorAddDeviceProps(qemuDomainGetMonitor(vm), &vcpuprops);
6491
6492 if (qemuDomainObjExitMonitor(driver, vm) < 0)
6493 return -1;
6494
6495 virDomainAuditVcpu(vm, oldvcpus, oldvcpus + nvcpus, "update", rc == 0);
6496
6497 if (rc < 0)
6498 return -1;
6499
6500 /* start outputting of the new XML element to allow keeping unpluggability */
6501 vm->def->individualvcpus = true;
6502
6503 if (qemuDomainRefreshVcpuInfo(driver, vm, QEMU_ASYNC_JOB_NONE, false) < 0)
6504 return -1;
6505
6506 /* validation requires us to set the expected state prior to calling it */
6507 for (i = vcpu; i < vcpu + nvcpus; i++) {
6508 vcpuinfo = virDomainDefGetVcpu(vm->def, i);
6509 vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpuinfo);
6510
6511 vcpuinfo->online = true;
6512
6513 if (vcpupriv->tid > 0 &&
6514 qemuProcessSetupVcpu(vm, i) < 0)
6515 return -1;
6516 }
6517
6518 if (qemuDomainValidateVcpuInfo(vm) < 0)
6519 return -1;
6520
6521 qemuDomainVcpuPersistOrder(vm->def);
6522
6523 if (virDomainObjSave(vm, driver->xmlopt, cfg->stateDir) < 0)
6524 return -1;
6525
6526 return 0;
6527 }
6528
6529
6530 /**
6531 * qemuDomainSelectHotplugVcpuEntities:
6532 *
6533 * @def: domain definition
6534 * @nvcpus: target vcpu count
6535 * @enable: set to true if vcpus should be enabled
6536 *
6537 * Tries to find which vcpu entities need to be enabled or disabled to reach
6538 * @nvcpus. This function works in order of the legacy hotplug but is able to
6539 * skip over entries that are added out of order.
6540 *
6541 * Returns the bitmap of vcpus to modify on success, NULL on error.
6542 */
6543 static virBitmap *
qemuDomainSelectHotplugVcpuEntities(virDomainDef * def,unsigned int nvcpus,bool * enable)6544 qemuDomainSelectHotplugVcpuEntities(virDomainDef *def,
6545 unsigned int nvcpus,
6546 bool *enable)
6547 {
6548 virBitmap *ret = NULL;
6549 virDomainVcpuDef *vcpu;
6550 qemuDomainVcpuPrivate *vcpupriv;
6551 unsigned int maxvcpus = virDomainDefGetVcpusMax(def);
6552 unsigned int curvcpus = virDomainDefGetVcpus(def);
6553 ssize_t i;
6554
6555 ret = virBitmapNew(maxvcpus);
6556
6557 if (nvcpus > curvcpus) {
6558 *enable = true;
6559
6560 for (i = 0; i < maxvcpus && curvcpus < nvcpus; i++) {
6561 vcpu = virDomainDefGetVcpu(def, i);
6562 vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpu);
6563
6564 if (vcpu->online)
6565 continue;
6566
6567 if (vcpupriv->vcpus == 0)
6568 continue;
6569
6570 curvcpus += vcpupriv->vcpus;
6571
6572 if (curvcpus > nvcpus) {
6573 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6574 _("target vm vcpu granularity does not allow the "
6575 "desired vcpu count"));
6576 goto error;
6577 }
6578
6579 ignore_value(virBitmapSetBit(ret, i));
6580 }
6581 } else {
6582 *enable = false;
6583
6584 for (i = maxvcpus - 1; i >= 0 && curvcpus > nvcpus; i--) {
6585 vcpu = virDomainDefGetVcpu(def, i);
6586 vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpu);
6587
6588 if (!vcpu->online)
6589 continue;
6590
6591 if (vcpupriv->vcpus == 0)
6592 continue;
6593
6594 if (!vcpupriv->alias)
6595 continue;
6596
6597 curvcpus -= vcpupriv->vcpus;
6598
6599 if (curvcpus < nvcpus) {
6600 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6601 _("target vm vcpu granularity does not allow the "
6602 "desired vcpu count"));
6603 goto error;
6604 }
6605
6606 ignore_value(virBitmapSetBit(ret, i));
6607 }
6608 }
6609
6610 if (curvcpus != nvcpus) {
6611 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6612 _("failed to find appropriate hotpluggable vcpus to "
6613 "reach the desired target vcpu count"));
6614 goto error;
6615 }
6616
6617 return ret;
6618
6619 error:
6620 virBitmapFree(ret);
6621 return NULL;
6622 }
6623
6624
6625 static int
qemuDomainSetVcpusLive(virQEMUDriver * driver,virQEMUDriverConfig * cfg,virDomainObj * vm,virBitmap * vcpumap,bool enable)6626 qemuDomainSetVcpusLive(virQEMUDriver *driver,
6627 virQEMUDriverConfig *cfg,
6628 virDomainObj *vm,
6629 virBitmap *vcpumap,
6630 bool enable)
6631 {
6632 qemuDomainObjPrivate *priv = vm->privateData;
6633 qemuCgroupEmulatorAllNodesData *emulatorCgroup = NULL;
6634 ssize_t nextvcpu = -1;
6635 int ret = -1;
6636
6637 if (qemuCgroupEmulatorAllNodesAllow(priv->cgroup, &emulatorCgroup) < 0)
6638 goto cleanup;
6639
6640 if (enable) {
6641 while ((nextvcpu = virBitmapNextSetBit(vcpumap, nextvcpu)) != -1) {
6642 if (qemuDomainHotplugAddVcpu(driver, cfg, vm, nextvcpu) < 0)
6643 goto cleanup;
6644 }
6645 } else {
6646 for (nextvcpu = virDomainDefGetVcpusMax(vm->def) - 1; nextvcpu >= 0; nextvcpu--) {
6647 if (!virBitmapIsBitSet(vcpumap, nextvcpu))
6648 continue;
6649
6650 if (qemuDomainHotplugDelVcpu(driver, cfg, vm, nextvcpu) < 0)
6651 goto cleanup;
6652 }
6653 }
6654
6655 ret = 0;
6656
6657 cleanup:
6658 qemuCgroupEmulatorAllNodesRestore(emulatorCgroup);
6659
6660 return ret;
6661 }
6662
6663
6664 /**
6665 * qemuDomainSetVcpusConfig:
6666 * @def: config/offline definition of a domain
6667 * @nvcpus: target vcpu count
6668 *
6669 * Properly handle cold(un)plug of vcpus:
6670 * - plug in inactive vcpus/uplug active rather than rewriting state
6671 * - fix hotpluggable state
6672 */
6673 static void
qemuDomainSetVcpusConfig(virDomainDef * def,unsigned int nvcpus,bool hotpluggable)6674 qemuDomainSetVcpusConfig(virDomainDef *def,
6675 unsigned int nvcpus,
6676 bool hotpluggable)
6677 {
6678 virDomainVcpuDef *vcpu;
6679 size_t curvcpus = virDomainDefGetVcpus(def);
6680 size_t maxvcpus = virDomainDefGetVcpusMax(def);
6681 size_t i;
6682
6683 /* ordering information may become invalid, thus clear it */
6684 virDomainDefVcpuOrderClear(def);
6685
6686 if (curvcpus == nvcpus)
6687 return;
6688
6689 if (curvcpus < nvcpus) {
6690 for (i = 0; i < maxvcpus; i++) {
6691 vcpu = virDomainDefGetVcpu(def, i);
6692
6693 if (!vcpu)
6694 continue;
6695
6696 if (vcpu->online) {
6697 /* non-hotpluggable vcpus need to be clustered at the beginning,
6698 * thus we need to force vcpus to be hotpluggable when we find
6699 * vcpus that are hotpluggable and online prior to the ones
6700 * we are going to add */
6701 if (vcpu->hotpluggable == VIR_TRISTATE_BOOL_YES)
6702 hotpluggable = true;
6703
6704 continue;
6705 }
6706
6707 vcpu->online = true;
6708 if (hotpluggable) {
6709 vcpu->hotpluggable = VIR_TRISTATE_BOOL_YES;
6710 def->individualvcpus = true;
6711 } else {
6712 vcpu->hotpluggable = VIR_TRISTATE_BOOL_NO;
6713 }
6714
6715 if (++curvcpus == nvcpus)
6716 break;
6717 }
6718 } else {
6719 for (i = maxvcpus; i != 0; i--) {
6720 vcpu = virDomainDefGetVcpu(def, i - 1);
6721
6722 if (!vcpu || !vcpu->online)
6723 continue;
6724
6725 vcpu->online = false;
6726 vcpu->hotpluggable = VIR_TRISTATE_BOOL_YES;
6727
6728 if (--curvcpus == nvcpus)
6729 break;
6730 }
6731 }
6732 }
6733
6734
6735 int
qemuDomainSetVcpusInternal(virQEMUDriver * driver,virDomainObj * vm,virDomainDef * def,virDomainDef * persistentDef,unsigned int nvcpus,bool hotpluggable)6736 qemuDomainSetVcpusInternal(virQEMUDriver *driver,
6737 virDomainObj *vm,
6738 virDomainDef *def,
6739 virDomainDef *persistentDef,
6740 unsigned int nvcpus,
6741 bool hotpluggable)
6742 {
6743 g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
6744 virBitmap *vcpumap = NULL;
6745 bool enable;
6746 int ret = -1;
6747
6748 if (def && nvcpus > virDomainDefGetVcpusMax(def)) {
6749 virReportError(VIR_ERR_INVALID_ARG,
6750 _("requested vcpus is greater than max allowable"
6751 " vcpus for the live domain: %u > %u"),
6752 nvcpus, virDomainDefGetVcpusMax(def));
6753 goto cleanup;
6754 }
6755
6756 if (persistentDef && nvcpus > virDomainDefGetVcpusMax(persistentDef)) {
6757 virReportError(VIR_ERR_INVALID_ARG,
6758 _("requested vcpus is greater than max allowable"
6759 " vcpus for the persistent domain: %u > %u"),
6760 nvcpus, virDomainDefGetVcpusMax(persistentDef));
6761 goto cleanup;
6762 }
6763
6764 if (def) {
6765 if (!(vcpumap = qemuDomainSelectHotplugVcpuEntities(vm->def, nvcpus,
6766 &enable)))
6767 goto cleanup;
6768
6769 if (qemuDomainSetVcpusLive(driver, cfg, vm, vcpumap, enable) < 0)
6770 goto cleanup;
6771 }
6772
6773 if (persistentDef) {
6774 qemuDomainSetVcpusConfig(persistentDef, nvcpus, hotpluggable);
6775
6776 if (virDomainDefSave(persistentDef, driver->xmlopt, cfg->configDir) < 0)
6777 goto cleanup;
6778 }
6779
6780 ret = 0;
6781
6782 cleanup:
6783 virBitmapFree(vcpumap);
6784 return ret;
6785 }
6786
6787
6788 static void
qemuDomainSetVcpuConfig(virDomainDef * def,virBitmap * map,bool state)6789 qemuDomainSetVcpuConfig(virDomainDef *def,
6790 virBitmap *map,
6791 bool state)
6792 {
6793 virDomainVcpuDef *vcpu;
6794 ssize_t next = -1;
6795
6796 def->individualvcpus = true;
6797
6798 /* ordering information may become invalid, thus clear it */
6799 virDomainDefVcpuOrderClear(def);
6800
6801 while ((next = virBitmapNextSetBit(map, next)) >= 0) {
6802 if (!(vcpu = virDomainDefGetVcpu(def, next)))
6803 continue;
6804
6805 vcpu->online = state;
6806 vcpu->hotpluggable = VIR_TRISTATE_BOOL_YES;
6807 }
6808 }
6809
6810
6811 /**
6812 * qemuDomainFilterHotplugVcpuEntities:
6813 *
6814 * Returns a bitmap of hotpluggable vcpu entities that correspond to the logical
6815 * vcpus requested in @vcpus.
6816 */
6817 static virBitmap *
qemuDomainFilterHotplugVcpuEntities(virDomainDef * def,virBitmap * vcpus,bool state)6818 qemuDomainFilterHotplugVcpuEntities(virDomainDef *def,
6819 virBitmap *vcpus,
6820 bool state)
6821 {
6822 qemuDomainVcpuPrivate *vcpupriv;
6823 virDomainVcpuDef *vcpu;
6824 g_autoptr(virBitmap) map = virBitmapNewCopy(vcpus);
6825 ssize_t next = -1;
6826 size_t i;
6827
6828 /* make sure that all selected vcpus are in the correct state */
6829 while ((next = virBitmapNextSetBit(map, next)) >= 0) {
6830 if (!(vcpu = virDomainDefGetVcpu(def, next)))
6831 continue;
6832
6833 if (vcpu->online == state) {
6834 virReportError(VIR_ERR_INVALID_ARG,
6835 _("vcpu '%zd' is already in requested state"), next);
6836 return NULL;
6837 }
6838
6839 if (vcpu->online && !vcpu->hotpluggable) {
6840 virReportError(VIR_ERR_INVALID_ARG,
6841 _("vcpu '%zd' can't be hotunplugged"), next);
6842 return NULL;
6843 }
6844 }
6845
6846 /* Make sure that all vCPUs belonging to a single hotpluggable entity were
6847 * selected and then de-select any sub-threads of it. */
6848 next = -1;
6849 while ((next = virBitmapNextSetBit(map, next)) >= 0) {
6850 if (!(vcpu = virDomainDefGetVcpu(def, next)))
6851 continue;
6852
6853 vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpu);
6854
6855 if (vcpupriv->vcpus == 0) {
6856 virReportError(VIR_ERR_INVALID_ARG,
6857 _("vcpu '%zd' belongs to a larger hotpluggable entity, "
6858 "but siblings were not selected"), next);
6859 return NULL;
6860 }
6861
6862 for (i = next + 1; i < next + vcpupriv->vcpus; i++) {
6863 if (!virBitmapIsBitSet(map, i)) {
6864 virReportError(VIR_ERR_INVALID_ARG,
6865 _("vcpu '%zu' was not selected but it belongs to "
6866 "hotpluggable entity '%zd-%zd' which was "
6867 "partially selected"),
6868 i, next, next + vcpupriv->vcpus - 1);
6869 return NULL;
6870 }
6871
6872 /* clear the subthreads */
6873 ignore_value(virBitmapClearBit(map, i));
6874 }
6875 }
6876
6877 return g_steal_pointer(&map);
6878 }
6879
6880
6881 static int
qemuDomainVcpuValidateConfig(virDomainDef * def,virBitmap * map)6882 qemuDomainVcpuValidateConfig(virDomainDef *def,
6883 virBitmap *map)
6884 {
6885 virDomainVcpuDef *vcpu;
6886 size_t maxvcpus = virDomainDefGetVcpusMax(def);
6887 ssize_t next;
6888 ssize_t firstvcpu = -1;
6889
6890 /* vcpu 0 can't be modified */
6891 if (virBitmapIsBitSet(map, 0)) {
6892 virReportError(VIR_ERR_INVALID_ARG, "%s",
6893 _("vCPU '0' can't be modified"));
6894 return -1;
6895 }
6896
6897 firstvcpu = virBitmapNextSetBit(map, -1);
6898
6899 /* non-hotpluggable vcpus need to stay clustered starting from vcpu 0 */
6900 for (next = firstvcpu + 1; next < maxvcpus; next++) {
6901 if (!(vcpu = virDomainDefGetVcpu(def, next)))
6902 continue;
6903
6904 /* skip vcpus being modified */
6905 if (virBitmapIsBitSet(map, next))
6906 continue;
6907
6908 if (vcpu->online && vcpu->hotpluggable == VIR_TRISTATE_BOOL_NO) {
6909 virReportError(VIR_ERR_INVALID_ARG,
6910 _("vcpu '%zd' can't be modified as it is followed "
6911 "by non-hotpluggable online vcpus"), firstvcpu);
6912 return -1;
6913 }
6914 }
6915
6916 return 0;
6917 }
6918
6919
6920 int
qemuDomainSetVcpuInternal(virQEMUDriver * driver,virDomainObj * vm,virDomainDef * def,virDomainDef * persistentDef,virBitmap * map,bool state)6921 qemuDomainSetVcpuInternal(virQEMUDriver *driver,
6922 virDomainObj *vm,
6923 virDomainDef *def,
6924 virDomainDef *persistentDef,
6925 virBitmap *map,
6926 bool state)
6927 {
6928 g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
6929 virBitmap *livevcpus = NULL;
6930 int ret = -1;
6931
6932 if (def) {
6933 if (!qemuDomainSupportsNewVcpuHotplug(vm)) {
6934 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
6935 _("this qemu version does not support specific "
6936 "vCPU hotplug"));
6937 goto cleanup;
6938 }
6939
6940 if (!(livevcpus = qemuDomainFilterHotplugVcpuEntities(def, map, state)))
6941 goto cleanup;
6942
6943 /* Make sure that only one hotpluggable entity is selected.
6944 * qemuDomainSetVcpusLive allows setting more at once but error
6945 * resolution in case of a partial failure is hard, so don't let users
6946 * do so */
6947 if (virBitmapCountBits(livevcpus) != 1) {
6948 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
6949 _("only one hotpluggable entity can be selected"));
6950 goto cleanup;
6951 }
6952 }
6953
6954 if (persistentDef) {
6955 if (qemuDomainVcpuValidateConfig(persistentDef, map) < 0)
6956 goto cleanup;
6957 }
6958
6959 if (livevcpus &&
6960 qemuDomainSetVcpusLive(driver, cfg, vm, livevcpus, state) < 0)
6961 goto cleanup;
6962
6963 if (persistentDef) {
6964 qemuDomainSetVcpuConfig(persistentDef, map, state);
6965
6966 if (virDomainDefSave(persistentDef, driver->xmlopt, cfg->configDir) < 0)
6967 goto cleanup;
6968 }
6969
6970 ret = 0;
6971
6972 cleanup:
6973 virBitmapFree(livevcpus);
6974 return ret;
6975 }
6976
6977
6978 int
qemuDomainChangeMemoryRequestedSize(virQEMUDriver * driver,virDomainObj * vm,const char * alias,unsigned long long requestedsize)6979 qemuDomainChangeMemoryRequestedSize(virQEMUDriver *driver,
6980 virDomainObj *vm,
6981 const char *alias,
6982 unsigned long long requestedsize)
6983 {
6984 qemuDomainObjPrivate *priv = vm->privateData;
6985 int rc;
6986
6987 qemuDomainObjEnterMonitor(driver, vm);
6988 rc = qemuMonitorChangeMemoryRequestedSize(priv->mon, alias, requestedsize);
6989 if (qemuDomainObjExitMonitor(driver, vm) < 0)
6990 return -1;
6991
6992 return rc;
6993 }
6994