PRL_UINT32 emulatedType;
char *friendlyName = NULL;
PRL_SERIAL_PORT_SOCKET_OPERATION_MODE socket_mode;
+ char *uristr = NULL;
+ virURIPtr uri = NULL;
+ int ret = -1;
chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
chr->targetTypeAttr = false;
pret = PrlVmDev_GetIndex(serialPort, &serialPortIndex);
- prlsdkCheckRetGoto(pret, error);
+ prlsdkCheckRetGoto(pret, cleanup);
chr->target.port = serialPortIndex;
pret = PrlVmDev_GetEmulatedType(serialPort, &emulatedType);
- prlsdkCheckRetGoto(pret, error);
+ prlsdkCheckRetGoto(pret, cleanup);
if (!(friendlyName = prlsdkGetStringParamVar(PrlVmDev_GetFriendlyName,
serialPort)))
- goto error;
+ goto cleanup;
pret = PrlVmDevSerial_GetSocketMode(serialPort, &socket_mode);
- prlsdkCheckRetGoto(pret, error);
+ prlsdkCheckRetGoto(pret, cleanup);
switch (emulatedType) {
case PDT_USE_OUTPUT_FILE:
chr->source.type = VIR_DOMAIN_CHR_TYPE_FILE;
chr->source.data.file.path = friendlyName;
+ friendlyName = NULL;
break;
case PDT_USE_SERIAL_PORT_SOCKET_MODE:
chr->source.type = VIR_DOMAIN_CHR_TYPE_UNIX;
chr->source.data.nix.path = friendlyName;
chr->source.data.nix.listen = socket_mode == PSP_SERIAL_SOCKET_SERVER;
+ friendlyName = NULL;
break;
case PDT_USE_REAL_DEVICE:
chr->source.type = VIR_DOMAIN_CHR_TYPE_DEV;
chr->source.data.file.path = friendlyName;
+ friendlyName = NULL;
+ break;
+ case PDT_USE_TCP:
+ chr->source.type = VIR_DOMAIN_CHR_TYPE_TCP;
+ if (virAsprintf(&uristr, "tcp://%s", friendlyName) < 0)
+ goto cleanup;
+ if (!(uri = virURIParse(uristr)))
+ goto cleanup;
+ if (VIR_STRDUP(chr->source.data.tcp.host, uri->server) < 0)
+ goto cleanup;
+ if (virAsprintf(&chr->source.data.tcp.service, "%d", uri->port) < 0)
+ goto cleanup;
+ chr->source.data.tcp.listen = socket_mode == PSP_SERIAL_SOCKET_SERVER;
+ break;
+ case PDT_USE_UDP:
+ chr->source.type = VIR_DOMAIN_CHR_TYPE_UDP;
+ if (virAsprintf(&uristr, "udp://%s", friendlyName) < 0)
+ goto cleanup;
+ if (!(uri = virURIParse(uristr)))
+ goto cleanup;
+ if (VIR_STRDUP(chr->source.data.udp.bindHost, uri->server) < 0)
+ goto cleanup;
+ if (virAsprintf(&chr->source.data.udp.bindService, "%d", uri->port) < 0)
+ goto cleanup;
+ if (VIR_STRDUP(chr->source.data.udp.connectHost, uri->server) < 0)
+ goto cleanup;
+ if (virAsprintf(&chr->source.data.udp.connectService, "%d", uri->port) < 0)
+ goto cleanup;
break;
default:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unknown serial type: %X"), emulatedType);
- goto error;
+ goto cleanup;
break;
}
- return 0;
- error:
+ ret = 0;
+
+ cleanup:
VIR_FREE(friendlyName);
- return -1;
+ VIR_FREE(uristr);
+ virURIFree(uri);
+
+ return ret;
}
if (chr->source.type != VIR_DOMAIN_CHR_TYPE_DEV &&
chr->source.type != VIR_DOMAIN_CHR_TYPE_FILE &&
- chr->source.type != VIR_DOMAIN_CHR_TYPE_UNIX) {
+ chr->source.type != VIR_DOMAIN_CHR_TYPE_UNIX &&
+ chr->source.type != VIR_DOMAIN_CHR_TYPE_TCP &&
+ chr->source.type != VIR_DOMAIN_CHR_TYPE_UDP) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
return -1;
}
+ if (chr->source.type == VIR_DOMAIN_CHR_TYPE_TCP &&
+ chr->source.data.tcp.protocol != VIR_DOMAIN_CHR_TCP_PROTOCOL_RAW) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Protocol '%s' is not supported for "
+ "tcp character device."),
+ virDomainChrTcpProtocolTypeToString(chr->source.data.tcp.protocol));
+ return -1;
+ }
+
+ if (chr->source.type == VIR_DOMAIN_CHR_TYPE_UDP &&
+ (STRNEQ(chr->source.data.udp.bindHost,
+ chr->source.data.udp.connectHost) ||
+ STRNEQ(chr->source.data.udp.bindService,
+ chr->source.data.udp.connectService))) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Different bind and connect parameters for "
+ "udp character device is not supported."));
+ return -1;
+ }
+
return 0;
}
PRL_VM_DEV_EMULATION_TYPE emutype;
PRL_SERIAL_PORT_SOCKET_OPERATION_MODE socket_mode = PSP_SERIAL_SOCKET_SERVER;
char *path;
+ char *url = NULL;
int ret = -1;
if (prlsdkCheckSerialUnsupportedParams(chr) < 0)
case VIR_DOMAIN_CHR_TYPE_UNIX:
emutype = PDT_USE_SERIAL_PORT_SOCKET_MODE;
path = chr->source.data.nix.path;
- if (chr->source.data.nix.listen)
- socket_mode = PSP_SERIAL_SOCKET_SERVER;
- else
+ if (!chr->source.data.nix.listen)
+ socket_mode = PSP_SERIAL_SOCKET_CLIENT;
+ break;
+ case VIR_DOMAIN_CHR_TYPE_TCP:
+ emutype = PDT_USE_TCP;
+ if (virAsprintf(&url, "%s:%s",
+ chr->source.data.tcp.host,
+ chr->source.data.tcp.service) < 0)
+ goto cleanup;
+ if (!chr->source.data.tcp.listen)
socket_mode = PSP_SERIAL_SOCKET_CLIENT;
+ path = url;
+ break;
+ case VIR_DOMAIN_CHR_TYPE_UDP:
+ emutype = PDT_USE_UDP;
+ if (virAsprintf(&url, "%s:%s",
+ chr->source.data.udp.bindHost,
+ chr->source.data.udp.bindService) < 0)
+ goto cleanup;
+ path = url;
break;
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
pret = PrlVmDev_SetFriendlyName(sdkchr, path);
prlsdkCheckRetGoto(pret, cleanup);
- if (chr->source.type == VIR_DOMAIN_CHR_TYPE_UNIX) {
- pret = PrlVmDevSerial_SetSocketMode(sdkchr, socket_mode);
- prlsdkCheckRetGoto(pret, cleanup);
- }
+ pret = PrlVmDevSerial_SetSocketMode(sdkchr, socket_mode);
+ prlsdkCheckRetGoto(pret, cleanup);
pret = PrlVmDev_SetEnabled(sdkchr, 1);
prlsdkCheckRetGoto(pret, cleanup);
ret = 0;
cleanup:
PrlHandle_Free(sdkchr);
+ VIR_FREE(url);
return ret;
}