return 0;
}
+
+static void
+qemuBuildChrChardevReconnectStr(virBufferPtr buf,
+ const virDomainChrSourceReconnectDef *def)
+{
+ if (def->enabled == VIR_TRISTATE_BOOL_YES) {
+ virBufferAsprintf(buf, ",reconnect=%u", def->timeout);
+ } else if (def->enabled == VIR_TRISTATE_BOOL_NO) {
+ virBufferAddLit(buf, ",reconnect=0");
+ }
+}
+
+
/* This function outputs a -chardev command line option which describes only the
* host side of the character device */
static char *
if (dev->data.tcp.listen)
virBufferAdd(&buf, nowait ? ",server,nowait" : ",server", -1);
+ qemuBuildChrChardevReconnectStr(&buf, &dev->data.tcp.reconnect);
+
if (dev->data.tcp.haveTLS == VIR_TRISTATE_BOOL_YES) {
qemuDomainChrSourcePrivatePtr chrSourcePriv =
QEMU_DOMAIN_CHR_SOURCE_PRIVATE(dev);
virQEMUBuildBufferEscapeComma(&buf, dev->data.nix.path);
if (dev->data.nix.listen)
virBufferAdd(&buf, nowait ? ",server,nowait" : ",server", -1);
+
+ qemuBuildChrChardevReconnectStr(&buf, &dev->data.nix.reconnect);
break;
case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
}
+static int
+qemuDomainChrSourceReconnectDefValidate(const virDomainChrSourceReconnectDef *def)
+{
+ if (def->enabled == VIR_TRISTATE_BOOL_YES &&
+ def->timeout == 0) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("chardev reconnect source timeout cannot be '0'"));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int
+qemuDomainChrSourceDefValidate(const virDomainChrSourceDef *def)
+{
+ switch ((virDomainChrType)def->type) {
+ case VIR_DOMAIN_CHR_TYPE_TCP:
+ if (qemuDomainChrSourceReconnectDefValidate(&def->data.tcp.reconnect) < 0)
+ return -1;
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_UNIX:
+ if (qemuDomainChrSourceReconnectDefValidate(&def->data.nix.reconnect) < 0)
+ return -1;
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_NULL:
+ case VIR_DOMAIN_CHR_TYPE_VC:
+ case VIR_DOMAIN_CHR_TYPE_PTY:
+ case VIR_DOMAIN_CHR_TYPE_DEV:
+ case VIR_DOMAIN_CHR_TYPE_FILE:
+ case VIR_DOMAIN_CHR_TYPE_PIPE:
+ case VIR_DOMAIN_CHR_TYPE_STDIO:
+ case VIR_DOMAIN_CHR_TYPE_UDP:
+ case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
+ case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
+ case VIR_DOMAIN_CHR_TYPE_NMDM:
+ case VIR_DOMAIN_CHR_TYPE_LAST:
+ break;
+ }
+
+ return 0;
+}
+
+
+static int
+qemuDomainChrDefValidate(const virDomainChrDef *def)
+{
+ if (qemuDomainChrSourceDefValidate(def->source) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int
+qemuDomainSmartcardDefValidate(const virDomainSmartcardDef *def)
+{
+ if (def->type == VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH &&
+ qemuDomainChrSourceDefValidate(def->data.passthru) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int
+qemuDomainRNGDefValidate(const virDomainRNGDef *def)
+{
+ if (def->backend == VIR_DOMAIN_RNG_BACKEND_EGD &&
+ qemuDomainChrSourceDefValidate(def->source.chardev) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int
+qemuDomainRedirdevDefValidate(const virDomainRedirdevDef *def)
+{
+ if (qemuDomainChrSourceDefValidate(def->source) < 0)
+ return -1;
+
+ return 0;
+}
+
+
static int
qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev,
const virDomainDef *def ATTRIBUTE_UNUSED,
virDomainNetTypeToString(net->type));
goto cleanup;
}
+ } else if (dev->type == VIR_DOMAIN_DEVICE_CHR) {
+ if (qemuDomainChrDefValidate(dev->data.chr) < 0)
+ goto cleanup;
+ } else if (dev->type == VIR_DOMAIN_DEVICE_SMARTCARD) {
+ if (qemuDomainSmartcardDefValidate(dev->data.smartcard) < 0)
+ goto cleanup;
+ } else if (dev->type == VIR_DOMAIN_DEVICE_RNG) {
+ if (qemuDomainRNGDefValidate(dev->data.rng) < 0)
+ goto cleanup;
+ } else if (dev->type == VIR_DOMAIN_DEVICE_REDIRDEV) {
+ if (qemuDomainRedirdevDefValidate(dev->data.redirdev) < 0)
+ goto cleanup;
}
/* forbid capabilities mode hostdev in this kind of hypervisor */