diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c index 3563b577bd..5e36a8b1e8 100644 --- a/src/vz/vz_sdk.c +++ b/src/vz/vz_sdk.c @@ -1078,48 +1078,85 @@ prlsdkGetSerialInfo(PRL_HANDLE serialPort, virDomainChrDefPtr chr) 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; } @@ -2627,7 +2664,9 @@ static int prlsdkCheckSerialUnsupportedParams(virDomainChrDefPtr chr) 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", @@ -2650,6 +2689,26 @@ static int prlsdkCheckSerialUnsupportedParams(virDomainChrDefPtr chr) 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; } @@ -2851,6 +2910,7 @@ static int prlsdkAddSerial(PRL_HANDLE sdkdom, virDomainChrDefPtr chr) 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) @@ -2871,11 +2931,27 @@ static int prlsdkAddSerial(PRL_HANDLE sdkdom, virDomainChrDefPtr chr) 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", _("vz driver doesn't support " @@ -2892,10 +2968,8 @@ static int prlsdkAddSerial(PRL_HANDLE sdkdom, virDomainChrDefPtr chr) 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); @@ -2906,6 +2980,7 @@ static int prlsdkAddSerial(PRL_HANDLE sdkdom, virDomainChrDefPtr chr) ret = 0; cleanup: PrlHandle_Free(sdkchr); + VIR_FREE(url); return ret; }