[libvirt] [PATCH 2/2] vz: add tcp and udp serial device support

Nikolay Shirokovskiy nshirokovskiy at virtuozzo.com
Tue May 31 09:38:33 UTC 2016


vz supports only a subset of tcp and udp parameters.

1. tcp type supports only 'raw' protocol.
2. udp type supports only same parameters of 'host' and 'service'
for 'bind' and 'connect'.

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy at virtuozzo.com>
---
 src/vz/vz_sdk.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 92 insertions(+), 16 deletions(-)

diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c
index d5e0746..232df52 100644
--- a/src/vz/vz_sdk.c
+++ b/src/vz/vz_sdk.c
@@ -889,48 +889,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;
 }
 
 
@@ -2552,7 +2589,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",
@@ -2575,6 +2614,27 @@ 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;
 }
 
@@ -2776,6 +2836,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)
@@ -2796,11 +2857,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 "
@@ -2817,10 +2894,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);
@@ -2831,6 +2906,7 @@ static int prlsdkAddSerial(PRL_HANDLE sdkdom, virDomainChrDefPtr chr)
     ret = 0;
  cleanup:
     PrlHandle_Free(sdkchr);
+    VIR_FREE(url);
     return ret;
 }
 
-- 
1.8.3.1




More information about the libvir-list mailing list