[libvirt] [PATCH] Support for virtualbox version 3.1
pritesh
Pritesh.Kothari at Sun.COM
Fri Nov 20 10:22:07 UTC 2009
Hi Matthias,
> Well, apart from the new auto generated files for version 3.1 support
> a huge part of the patch affects vbox_tmpl.c, ~7700 lines changed.
> Most of that are pure indentation level changes, due to inverting the
> logic of some common error checks. Applying the patch and creating a
> new patch using git diff -b to ignore pure whitespace changes results
> in ~2200 lines changed. And even most of this 2200 lines are due to
> the wrapping of some common code patterns into macros; mostly
> free/release calls. The actual functional change of this patch is
> fairly small. You should have split this at least into two separate
> patches.
Wow that was really great, thanks for the efforts you put in analyzing and
reviewing the code. I really appreciate it.
Also about not splitting the patch in two separate chunks, I tried but then
some functions in 3.1 would break thus making it very dependent on second
patch, and the second reason being, i need to sync the 3.1 code with internal
svn (company policy ...) and generating patch from it is not so easy :(
> [...]
> > + return NULL;
> > + }
> > +
> > + if (storageBus == StorageBus_IDE) {
> > + name[0] = 'h';
> > + name[1] = 'd';
> > + } else if ( (storageBus == StorageBus_SATA)
> > + || (storageBus == StorageBus_SCSI)) {
> > + name[0] = 's';
> > + name[1] = 'd';
> > + } else if (storageBus == StorageBus_Floppy) {
> > + name[0] = 'f';
> > + name[1] = 'd';
> > + }
>
> You're missing an else branch here to handle the case of the storage
> bus being none of the checked values.
thanks, handled this now.
>
> > + if (len == 4) {
> > + name[2] = (char)(97 + total);
>
> If total is out-of-range len will also be 4, because 4 is the default
> value and you have no out-or-range checks to catch such a situation.
> So you're going to create a bogus name then.
handled this now as well
>
> > + } else if (len == 5) {
> > + name[2] = (char)(96 + (total / 26));
> > + name[3] = (char)(97 + (total % 26));
> > + } else if (len == 6) {
> > + name[2] = (char)(96 + (total / 26*26));
> > + name[3] = (char)(96 + ((total % (26*26)) / 26));
> > + name[4] = (char)(97 + ((total % (26*26)) % 26));
> > + }
>
> You should use virDiskNameToIndex() in vboxGetDeviceDetails() (see
> below). So you should use the matching inverse function here. I added
> esxVMX_IndexToDiskName() for the ESX driver, because libvirt doesn't
> have this function yet. Maybe I should post a patch to add it to
> src/util/util.[ch].
that would be really appreciated, will use this function once available in
util.[ch]
>
> Actually, it seems you do the correct inverse operation to
> virDiskNameToIndex() with this code.
>
> > + name[len - 1] = '\0';
> > + DEBUG("name=%s, len=%d, total=%d, storageBus=%u, deviceInst=%d, "
> > + "devicePort=%d deviceSlot=%d, maxPortPerInst=%u
> > maxSlotPerPort=%u", + name, len, total, storageBus, deviceInst,
> > devicePort, + deviceSlot, maxPortPerInst, maxSlotPerPort);
> > + return name;
> > +}
> > +
> > +/**
> > + * function to get the StorageBus, Port number
> > + * and Device number for the given devicename
> > + * e.g: hda has StorageBus = IDE, port = 0,
> > + * device = 0
> > + *
> > + * Limitation: only name till 4 chars supported
> > + * i.e from hda till hdzz
> > + *
> > + * @returns true on Success, false on failure.
> > + * @param deviceName Input device name
> > + * @param aMaxPortPerInst Input array of max port per device
> > instance + * @param aMaxSlotPerPort Input array of max slot per
> > device port + * @param storageBus Input storage bus type
> > + * @param deviceInst Output device instance number
> > + * @param devicePort Output port number
> > + * @param deviceSlot Output slot number
> > + *
> > + */
> > +static bool vboxGetDeviceDetails(const char *deviceName,
> > + PRUint32 *aMaxPortPerInst,
> > + PRUint32 *aMaxSlotPerPort,
> > + PRUint32 storageBus,
> > + PRInt32 *deviceInst,
> > + PRInt32 *devicePort,
> > + PRInt32 *deviceSlot) {
> > + int len = 0;
> > + int total = 0;
> > + PRUint32 maxPortPerInst = 0;
> > + PRUint32 maxSlotPerPort = 0;
> > +
> > + if ( !deviceName
> > + || !storageBus
> > + || !deviceInst
> > + || !devicePort
> > + || !deviceSlot
> > + || !aMaxPortPerInst
> > + || !aMaxSlotPerPort)
> > + return false;
> > +
> > + len = strlen(deviceName);
> > +
> > + /* support till hdzz only so 4 chars */
> > + if (len > 4)
> > + return false;
> > +
> > + maxPortPerInst = aMaxPortPerInst[storageBus];
> > + maxSlotPerPort = aMaxSlotPerPort[storageBus];
> > +
> > + if ( !maxPortPerInst
> > + || !maxSlotPerPort)
> > + return false;
> > +
> > + if (len == 3) {
> > + total = (deviceName[2] - 97);
> > + } else if (len == 4) {
> > + total = ((deviceName[2] - 96) * 26) + (deviceName[3] - 97);
> > + }
>
> You assume that you got sane input here. This code is going to fail
> due to char underflow if the input is 'hdA' instead of 'hda'. You
> should use the more robust virDiskNameToIndex() here.
yes will switch to virDiskNameToIndex() here.
>
> > + *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, "
> > + "devicePort=%d deviceSlot=%d, maxPortPerInst=%u
> > maxSlotPerPort=%u", + deviceName, len, total, storageBus,
> > *deviceInst, *devicePort, + *deviceSlot, maxPortPerInst,
> > maxSlotPerPort);
> > +
> > + return true;
> > +}
>
> [...]
>
> > +/**
> > + * Converts Utf-16 string to int
> > + */
> > +static int PRUnicharToInt(PRUnichar *strUtf16) {
> > + char *strUtf8 = NULL;
> > + int ret = 0;
> > +
> > + if (!strUtf16)
> > + return -1;
> > +
> > + g_pVBoxGlobalData->pFuncs->pfnUtf16ToUtf8(strUtf16, &strUtf8);
> > + if (!strUtf8)
> > + return -1;
> > +
> > + ret = atoi(strUtf8);
> > + g_pVBoxGlobalData->pFuncs->pfnUtf8Free(strUtf8);
> > +
> > + return ret;
> > +}
> > +
> > +/**
> > + * Converts int to Utf-16 string
> > + */
> > +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;
> > + }
> > +
> > + g_pVBoxGlobalData->pFuncs->pfnUtf8ToUtf16(s, &strUtf16);
> > +
> > + return strUtf16;
> > +}
>
> I don't understand why you do this in such a complex way. What about
> snprintf?
oops, this is called sincere novice mistake ;) ,, will change this
>
> PRUnichar *strUtf16 = NULL;
> char s[24];
>
> snprintf(s, sizeof(s), "%d", n);
>
> g_pVBoxGlobalData->pFuncs->pfnUtf8ToUtf16(s, &strUtf16);
>
> return strUtf16;
>
> > +#endif /* VBOX_API_VERSION >= 3001 */
> > +
> > #endif /* !(VBOX_API_VERSION == 2002) */
> >
> > static virCapsPtr vboxCapsInit(void) {
>
> ACK, apart from the minor issues in vboxGenerateMediumName() and
> vboxGetDeviceDetails().
>
> Matthias
>
once again thanks for review, will try to split the patch in two and repost it
again which changes suggested above, but before that, would like to know if
esxVMX_IndexToDiskName() goes into util.[ch] anytime soon or only after the
release?
Regards,
Pritesh
More information about the libvir-list
mailing list