return virDomainLeaseRemoveAt(def, idx);
}
-static bool
+bool
virDomainChrEquals(virDomainChrDefPtr src,
virDomainChrDefPtr tgt)
{
case VIR_DOMAIN_DEVICE_RNG:
rc = virDomainRNGDefFormat(&buf, src->data.rng, flags);
break;
+ case VIR_DOMAIN_DEVICE_CHR:
+ rc = virDomainChrDefFormat(&buf, src->data.chr, flags);
+ break;
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_SMARTCARD:
- case VIR_DOMAIN_DEVICE_CHR:
case VIR_DOMAIN_DEVICE_MEMBALLOON:
case VIR_DOMAIN_DEVICE_NVRAM:
case VIR_DOMAIN_DEVICE_LAST:
return -1;
break;
+ case VIR_DOMAIN_DEVICE_CHR:
+ if (qemuDomainChrInsert(vmdef, dev->data.chr) < 0)
+ return -1;
+ dev->data.chr = NULL;
+ break;
+
default:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("persistent attach of device '%s' is not supported"),
virDomainHostdevDefPtr hostdev, det_hostdev;
virDomainLeaseDefPtr lease, det_lease;
virDomainControllerDefPtr cont, det_cont;
+ virDomainChrDefPtr chr;
int idx;
char mac[VIR_MAC_STRING_BUFLEN];
break;
+ case VIR_DOMAIN_DEVICE_CHR:
+ if (!(chr = qemuDomainChrRemove(vmdef, dev->data.chr)))
+ return -1;
+
+ virDomainChrDefFree(chr);
+ virDomainChrDefFree(dev->data.chr);
+ dev->data.chr = NULL;
+ break;
+
default:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("persistent detach of device '%s' is not supported"),
}
+int
+qemuDomainChrInsert(virDomainDefPtr vmdef,
+ virDomainChrDefPtr chr)
+{
+ if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
+ chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("attaching serial console is not supported"));
+ return -1;
+ }
+
+ if (virDomainChrFind(vmdef, chr)) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("chardev already exists"));
+ return -1;
+ }
+
+ if (virDomainChrInsert(vmdef, chr) < 0)
+ return -1;
+
+ /* Due to some crazy backcompat stuff, the first serial device is an alias
+ * to the first console too. If this is the case, the definition must be
+ * duplicated as first console device. */
+ if (vmdef->nserials == 1 && vmdef->nconsoles == 0) {
+ if ((!vmdef->consoles && VIR_ALLOC(vmdef->consoles) < 0) ||
+ VIR_ALLOC(vmdef->consoles[0]) < 0) {
+ virDomainChrRemove(vmdef, chr);
+ return -1;
+ }
+ vmdef->nconsoles = 1;
+
+ /* Create an console alias for the serial port */
+ vmdef->consoles[0]->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE;
+ vmdef->consoles[0]->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
+ }
+
+ return 0;
+}
+
+virDomainChrDefPtr
+qemuDomainChrRemove(virDomainDefPtr vmdef,
+ virDomainChrDefPtr chr)
+{
+ virDomainChrDefPtr ret;
+ bool removeCompat;
+
+ if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
+ chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("detaching serial console is not supported"));
+ return NULL;
+ }
+
+ /* Due to some crazy backcompat stuff, the first serial device is an alias
+ * to the first console too. If this is the case, the definition must be
+ * duplicated as first console device. */
+ removeCompat = vmdef->nserials && vmdef->nconsoles &&
+ vmdef->consoles[0]->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
+ vmdef->consoles[0]->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL &&
+ virDomainChrEquals(vmdef->serials[0], chr);
+
+ if (!(ret = virDomainChrRemove(vmdef, chr))) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("device not present in domain configuration"));
+ return NULL;
+ }
+
+ if (removeCompat)
+ VIR_DELETE_ELEMENT(vmdef->consoles, 0, vmdef->nconsoles);
+
+ return ret;
+}
int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainHostdevDefPtr hostdev)