>From fb161a69e90f6284466b94800067c67094131d43 Mon Sep 17 00:00:00 2001
From: pritesh <pritesh@d6844923-1013-0410-bc22-a9adef35e721>
Date: Fri, 20 Nov 2009 16:04:21 +0000
Subject: [PATCH] libvirt: fixed bugs in vboxGenerateMediumName, vboxGetDeviceDetails, PRUnicharFromInt and serial port functionality

git-svn-id: https://linserv.germany.sun.com/vbox/svn/trunk/src/libs/libvirt@55061 d6844923-1013-0410-bc22-a9adef35e721
---
 src/vbox/vbox_tmpl.c |  147 +++++++++++++++++++++++++++-----------------------
 1 files changed, 79 insertions(+), 68 deletions(-)

diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index ed4406f..10cc1ed 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -434,7 +434,7 @@ static char *vboxGenerateMediumName(virConnectPtr conn,
                                     PRUint32 *aMaxPortPerInst,
                                     PRUint32 *aMaxSlotPerPort) {
     char *name  = NULL;
-    int   len   = 4;
+    int   len   = 0;
     int   total = 0;
     PRUint32 maxPortPerInst = 0;
     PRUint32 maxSlotPerPort = 0;
@@ -443,22 +443,31 @@ static char *vboxGenerateMediumName(virConnectPtr conn,
         || !aMaxSlotPerPort)
         return NULL;
 
+    if (   (storageBus < StorageBus_IDE)
+        || (storageBus > StorageBus_Floppy))
+        return NULL;
+
     maxPortPerInst = aMaxPortPerInst[storageBus];
     maxSlotPerPort = aMaxSlotPerPort[storageBus];
     total =   (deviceInst * maxPortPerInst * maxSlotPerPort)
             + (devicePort * maxSlotPerPort)
             + deviceSlot;
 
-    if ((total >= 26) && (total < 26*26 + 26))
+    if ((total >= 0) && (total < 26))
+        len = 4;
+    else if ((total >= 26) && (total < 26*26 + 26))
         len = 5;
     else if ((total >= 26*26 + 26) && (total < 26*26*26 + 26*26 + 26))
         len = 6;
+    else
+        return NULL;
 
     if (VIR_ALLOC_N(name, len) < 0) {
         virReportOOMError(conn);
         return NULL;
     }
 
+    /* TODO: use virIndexToDiskName() here when available */
     if (storageBus == StorageBus_IDE) {
         name[0] = 'h';
         name[1] = 'd';
@@ -516,13 +525,11 @@ static bool vboxGetDeviceDetails(const char *deviceName,
                                  PRInt32    *deviceInst,
                                  PRInt32    *devicePort,
                                  PRInt32    *deviceSlot) {
-    int len   = 0;
     int total = 0;
     PRUint32 maxPortPerInst = 0;
     PRUint32 maxSlotPerPort = 0;
 
     if (   !deviceName
-        || !storageBus
         || !deviceInst
         || !devicePort
         || !deviceSlot
@@ -530,32 +537,27 @@ static bool vboxGetDeviceDetails(const char *deviceName,
         || !aMaxSlotPerPort)
         return false;
 
-    len = strlen(deviceName);
-
-    /* support till hdzz only so 4 chars */
-    if (len > 4)
+    if (   (storageBus < StorageBus_IDE)
+        || (storageBus > StorageBus_Floppy))
         return false;
 
+    total = virDiskNameToIndex(deviceName);
+
     maxPortPerInst = aMaxPortPerInst[storageBus];
     maxSlotPerPort = aMaxSlotPerPort[storageBus];
 
     if (   !maxPortPerInst
-        || !maxSlotPerPort)
+        || !maxSlotPerPort
+        || (total < 0))
         return false;
 
-    if (len == 3) {
-        total = (deviceName[2] - 97);
-    } else if (len == 4) {
-        total = ((deviceName[2] - 96) * 26) + (deviceName[3] - 97);
-    }
-
     *deviceInst = total / (maxPortPerInst * maxSlotPerPort);
     *devicePort = (total % (maxPortPerInst * maxSlotPerPort)) / maxSlotPerPort;
     *deviceSlot = (total % (maxPortPerInst * maxSlotPerPort)) % maxSlotPerPort;
 
-    DEBUG("name=%s, len=%d, total=%d, storageBus=%u, deviceInst=%d, "
+    DEBUG("name=%s, total=%d, storageBus=%u, deviceInst=%d, "
           "devicePort=%d deviceSlot=%d, maxPortPerInst=%u maxSlotPerPort=%u",
-          deviceName, len, total, storageBus, *deviceInst, *devicePort,
+          deviceName, total, storageBus, *deviceInst, *devicePort,
           *deviceSlot, maxPortPerInst, maxSlotPerPort);
 
     return true;
@@ -641,22 +643,9 @@ static int PRUnicharToInt(PRUnichar *strUtf16) {
  */
 static PRUnichar *PRUnicharFromInt(int n) {
     PRUnichar *strUtf16 = NULL;
-    char c, s[24] = {};
-    int sign, i = 0, j = 0;
-
-    if ((sign = n) < 0)
-        n = -n;
-    do {
-        s[i++] = n % 10 + '0';
-    } while ((n /= 10) > 0);
-    if (sign < 0)
-        s[i++] = '-';
-    s[i] = '\0';
-    for (j = 0; j < i; j++, i--) {
-        c = s[j];
-        s[j] = s[i];
-        s[i] = c;
-    }
+    char s[24];
+
+    snprintf(s, sizeof(s), "%d", n);
 
     g_pVBoxGlobalData->pFuncs->pfnUtf8ToUtf16(s, &strUtf16);
 
@@ -2113,18 +2102,21 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
                         PRUint32 VRAMSize          = 8 * 1024;
                         PRUint32 monitorCount      = 1;
                         PRBool accelerate3DEnabled = PR_FALSE;
+                        PRBool accelerate2DEnabled = PR_FALSE;
 
                         machine->vtbl->GetVRAMSize(machine, &VRAMSize);
                         machine->vtbl->GetMonitorCount(machine, &monitorCount);
                         machine->vtbl->GetAccelerate3DEnabled(machine, &accelerate3DEnabled);
+#if VBOX_API_VERSION >= 3001
+                        machine->vtbl->GetAccelerate2DVideoEnabled(machine, &accelerate2DEnabled);
+#endif /* VBOX_API_VERSION >= 3001 */
 
                         def->videos[0]->type            = VIR_DOMAIN_VIDEO_TYPE_VBOX;
                         def->videos[0]->vram            = VRAMSize;
                         def->videos[0]->heads           = monitorCount;
                         if (VIR_ALLOC(def->videos[0]->accel) >= 0) {
                             def->videos[0]->accel->support3d = accelerate3DEnabled;
-                            /* Not supported yet, but should be in 3.1 soon */
-                            def->videos[0]->accel->support2d = 0;
+                            def->videos[0]->accel->support2d = accelerate2DEnabled;
                         } else
                             virReportOOMError(dom->conn);
                     } else
@@ -2511,6 +2503,16 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
                                                                     deviceSlot,
                                                                     maxPortPerInst,
                                                                     maxSlotPerPort);
+                if (!def->disks[diskCount]->dst) {
+                    vboxError(dom->conn, VIR_ERR_INTERNAL_ERROR,
+                              "%s: controller instance:%u, port:%d, slot:%d",
+                              "Could not generate medium name for the disk at",
+                              deviceInst, devicePort, deviceSlot);
+                    VBOX_RELEASE(medium);
+                    VBOX_RELEASE(storageController);
+                    error = true;
+                    break;
+                }
 
                 medium->vtbl->GetReadOnly(medium, &readOnly);
                 if (readOnly == PR_TRUE)
@@ -2855,10 +2857,16 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
                             def->serials[serialPortIncCount]->type = VIR_DOMAIN_CHR_TYPE_PIPE;
                         } else if (hostMode == PortMode_HostDevice) {
                             def->serials[serialPortIncCount]->type = VIR_DOMAIN_CHR_TYPE_DEV;
+#if VBOX_API_VERSION >= 3000
+                        } else if (hostMode == PortMode_RawFile) {
+                            def->serials[serialPortIncCount]->type = VIR_DOMAIN_CHR_TYPE_FILE;
+#endif /* VBOX_API_VERSION >= 3000 */
                         } else {
                             def->serials[serialPortIncCount]->type = VIR_DOMAIN_CHR_TYPE_NULL;
                         }
 
+                        def->serials[serialPortIncCount]->targetType = VIR_DOMAIN_CHR_TARGET_TYPE_SERIAL;
+
                         serialPort->vtbl->GetIRQ(serialPort, &IRQ);
                         serialPort->vtbl->GetIOBase(serialPort, &IOBase);
                         if ((IRQ == 4) && (IOBase == 1016)) {
@@ -2869,8 +2877,10 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
 
                         serialPort->vtbl->GetPath(serialPort, &pathUtf16);
 
-                        VBOX_UTF16_TO_UTF8(pathUtf16, &path);
-                        def->serials[serialPortIncCount]->data.file.path = strdup(path);
+                        if (pathUtf16) {
+                            VBOX_UTF16_TO_UTF8(pathUtf16, &path);
+                            def->serials[serialPortIncCount]->data.file.path = strdup(path);
+                        }
 
                         serialPortIncCount++;
 
@@ -2934,6 +2944,7 @@ static char *vboxDomainDumpXML(virDomainPtr dom, int flags) {
                         }
 
                         def->parallels[parallelPortIncCount]->type = VIR_DOMAIN_CHR_TYPE_FILE;
+                        def->parallels[parallelPortIncCount]->targetType = VIR_DOMAIN_CHR_TARGET_TYPE_PARALLEL;
 
                         parallelPort->vtbl->GetPath(parallelPort, &pathUtf16);
 
@@ -4146,7 +4157,11 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
                 PRUnichar *pathUtf16 = NULL;
 
                 serialPort->vtbl->SetEnabled(serialPort, 1);
-                VBOX_UTF8_TO_UTF16(def->serials[i]->data.file.path, &pathUtf16);
+
+                if (def->serials[i]->data.file.path) {
+                    VBOX_UTF8_TO_UTF16(def->serials[i]->data.file.path, &pathUtf16);
+                    serialPort->vtbl->SetPath(serialPort, pathUtf16);
+                }
 
                 /* For now hard code the serial ports to COM1 and COM2,
                  * COM1 (Base Addr: 0x3F8 (decimal: 1016), IRQ: 4)
@@ -4157,38 +4172,27 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
                  * that def->serials[i]->target.port shows real port
                  * and not always start at 0
                  */
+                if (def->serials[i]->target.port == 0) {
+                    serialPort->vtbl->SetIRQ(serialPort, 4);
+                    serialPort->vtbl->SetIOBase(serialPort, 1016);
+                    DEBUG(" serialPort-%d irq: %d, iobase 0x%x, path: %s",
+                          i, 4, 1016, def->serials[i]->data.file.path);
+                } else if (def->serials[i]->target.port == 1) {
+                    serialPort->vtbl->SetIRQ(serialPort, 3);
+                    serialPort->vtbl->SetIOBase(serialPort, 760);
+                    DEBUG(" serialPort-%d irq: %d, iobase 0x%x, path: %s",
+                          i, 3, 760, def->serials[i]->data.file.path);
+                }
+
                 if (def->serials[i]->type == VIR_DOMAIN_CHR_TYPE_DEV) {
-                    serialPort->vtbl->SetPath(serialPort, pathUtf16);
-                    if (def->serials[i]->target.port == 0) {
-                        serialPort->vtbl->SetIRQ(serialPort, 4);
-                        serialPort->vtbl->SetIOBase(serialPort, 1016);
-                        DEBUG(" serialPort-%d irq: %d, iobase 0x%x, path: %s",
-                              i, 4, 1016, def->serials[i]->data.file.path);
-                    } else if (def->serials[i]->target.port == 1) {
-                        serialPort->vtbl->SetIRQ(serialPort, 3);
-                        serialPort->vtbl->SetIOBase(serialPort, 760);
-                        DEBUG(" serialPort-%d irq: %d, iobase 0x%x, path: %s",
-                              i, 3, 760, def->serials[i]->data.file.path);
-                    }
                     serialPort->vtbl->SetHostMode(serialPort, PortMode_HostDevice);
                 } else if (def->serials[i]->type == VIR_DOMAIN_CHR_TYPE_PIPE) {
-                    serialPort->vtbl->SetPath(serialPort, pathUtf16);
-                    if (def->serials[i]->target.port == 0) {
-                        serialPort->vtbl->SetIRQ(serialPort, 4);
-                        serialPort->vtbl->SetIOBase(serialPort, 1016);
-                        DEBUG(" serialPort-%d irq: %d, iobase 0x%x, path: %s",
-                              i, 4, 1016, def->serials[i]->data.file.path);
-                    } else if (def->serials[i]->target.port == 1) {
-                        serialPort->vtbl->SetIRQ(serialPort, 3);
-                        serialPort->vtbl->SetIOBase(serialPort, 760);
-                        DEBUG(" serialPort-%d irq: %d, iobase 0x%x, path: %s",
-                              i, 3, 760, def->serials[i]->data.file.path);
-                    }
-                    if (!virFileExists(def->serials[i]->data.file.path)) {
-                        serialPort->vtbl->SetServer(serialPort, 1);
-                    }
                     serialPort->vtbl->SetHostMode(serialPort, PortMode_HostPipe);
-                } else if (def->serials[i]->type == VIR_DOMAIN_CHR_TYPE_NULL) {
+#if VBOX_API_VERSION >= 3000
+                } else if (def->serials[i]->type == VIR_DOMAIN_CHR_TYPE_FILE) {
+                    serialPort->vtbl->SetHostMode(serialPort, PortMode_RawFile);
+#endif /* VBOX_API_VERSION >= 3000 */
+                } else {
                     serialPort->vtbl->SetHostMode(serialPort, PortMode_Disconnected);
                 }
 
@@ -4268,10 +4272,17 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
         if ((def->nvideos == 1) && (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_VBOX)) {
             machine->vtbl->SetVRAMSize(machine, def->videos[0]->vram);
             machine->vtbl->SetMonitorCount(machine, def->videos[0]->heads);
-            if (def->videos[0]->accel)
+            if (def->videos[0]->accel) {
                 machine->vtbl->SetAccelerate3DEnabled(machine, def->videos[0]->accel->support3d);
-            else
+#if VBOX_API_VERSION >= 3001
+                machine->vtbl->SetAccelerate2DVideoEnabled(machine, def->videos[0]->accel->support2d);
+#endif /* VBOX_API_VERSION >= 3001 */
+            } else {
                 machine->vtbl->SetAccelerate3DEnabled(machine, 0);
+#if VBOX_API_VERSION >= 3001
+                machine->vtbl->SetAccelerate2DVideoEnabled(machine, 0);
+#endif /* VBOX_API_VERSION >= 3001 */
+            }
         }
     }   /* Finished:Block to specify video card settings */
 
-- 
1.6.3.3

