Refactored driver reg to avoid type-punning

This commit is contained in:
Daniel P. Berrange 2007-03-08 14:53:41 +00:00
parent 89de0c87ae
commit f30b84f901
2 changed files with 51 additions and 52 deletions

View File

@ -1,3 +1,9 @@
Thu Mar 8 09:47:24 EST 2007 Daniel P. Berrange <berrange@redhat.com>
* src/libvirt.c: Refactored driver registration to avoid
type-punning problems by casting different structs. Also
fix network driver opening to open read-only when needed.
Thu Mar 8 15:10:12 CET 2007 Daniel Veillard <veillard@redhat.com> Thu Mar 8 15:10:12 CET 2007 Daniel Veillard <veillard@redhat.com>
* src/internal.h src/xend_internal.c src/xm_internal.c src/xml.c: * src/internal.h src/xend_internal.c src/xm_internal.c src/xml.c:
@ -5,7 +11,7 @@ Thu Mar 8 15:10:12 CET 2007 Daniel Veillard <veillard@redhat.com>
had arbitrary minimal memory requirement and use a predefined had arbitrary minimal memory requirement and use a predefined
macro to clean this up. macro to clean this up.
Thu Mar 8 08:45:46 EST 2007 Daniel P., Berrange <berrange@redhat.com> Thu Mar 8 08:45:46 EST 2007 Daniel P. Berrange <berrange@redhat.com>
* src/virsh.c: Added an explicit --readonly option to virsh * src/virsh.c: Added an explicit --readonly option to virsh
to override the simple Xen-specific heuristic when running to override the simple Xen-specific heuristic when running

View File

@ -42,7 +42,9 @@
*/ */
static virDriverPtr virDriverTab[MAX_DRIVERS]; static virDriverPtr virDriverTab[MAX_DRIVERS];
static int virDriverTabCount = 0;
static virNetworkDriverPtr virNetworkDriverTab[MAX_DRIVERS]; static virNetworkDriverPtr virNetworkDriverTab[MAX_DRIVERS];
static int virNetworkDriverTabCount = 0;
static int initialized = 0; static int initialized = 0;
/** /**
@ -57,8 +59,6 @@ static int initialized = 0;
int int
virInitialize(void) virInitialize(void)
{ {
int i;
if (initialized) if (initialized)
return(0); return(0);
initialized = 1; initialized = 1;
@ -66,14 +66,6 @@ virInitialize(void)
if (!bindtextdomain(GETTEXT_PACKAGE, LOCALEBASEDIR)) if (!bindtextdomain(GETTEXT_PACKAGE, LOCALEBASEDIR))
return (-1); return (-1);
/*
* should not be needed but...
*/
for (i = 0;i < MAX_DRIVERS;i++) {
virDriverTab[i] = NULL;
virNetworkDriverTab[i] = NULL;
}
/* /*
* Note that the order is important the first ones have a higher priority * Note that the order is important the first ones have a higher priority
*/ */
@ -163,35 +155,6 @@ virLibNetworkError(virNetworkPtr network, virErrorNumber error,
errmsg, info, NULL, 0, 0, errmsg, info); errmsg, info, NULL, 0, 0, errmsg, info);
} }
static int
_virRegisterDriver(void *driver, int isNetwork)
{
void **drivers;
int i;
if (!initialized)
if (virInitialize() < 0)
return -1;
if (driver == NULL) {
virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
drivers = isNetwork ? (void **) virNetworkDriverTab : (void **) virDriverTab;
for (i = 0;i < MAX_DRIVERS;i++) {
if (drivers[i] == driver)
return(i);
}
for (i = 0;i < MAX_DRIVERS;i++) {
if (drivers[i] == NULL) {
drivers[i] = driver;
return(i);
}
}
virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
/** /**
* virRegisterNetworkDriver: * virRegisterNetworkDriver:
* @driver: pointer to a network driver block * @driver: pointer to a network driver block
@ -203,7 +166,21 @@ _virRegisterDriver(void *driver, int isNetwork)
int int
virRegisterNetworkDriver(virNetworkDriverPtr driver) virRegisterNetworkDriver(virNetworkDriverPtr driver)
{ {
return _virRegisterDriver(driver, 1); if (virInitialize() < 0)
return -1;
if (driver == NULL) {
virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
if (virNetworkDriverTabCount >= MAX_DRIVERS) {
virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
virNetworkDriverTab[virNetworkDriverTabCount] = driver;
return virNetworkDriverTabCount++;
} }
/** /**
@ -217,7 +194,21 @@ virRegisterNetworkDriver(virNetworkDriverPtr driver)
int int
virRegisterDriver(virDriverPtr driver) virRegisterDriver(virDriverPtr driver)
{ {
return _virRegisterDriver(driver, 0); if (virInitialize() < 0)
return -1;
if (driver == NULL) {
virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
if (virDriverTabCount >= MAX_DRIVERS) {
virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(-1);
}
virDriverTab[virDriverTabCount] = driver;
return virDriverTabCount++;
} }
/** /**
@ -252,14 +243,14 @@ virGetVersion(unsigned long *libVer, const char *type,
if (typeVer != NULL) { if (typeVer != NULL) {
if (type == NULL) if (type == NULL)
type = "Xen"; type = "Xen";
for (i = 0;i < MAX_DRIVERS;i++) { for (i = 0;i < virDriverTabCount;i++) {
if ((virDriverTab[i] != NULL) && if ((virDriverTab[i] != NULL) &&
(!strcmp(virDriverTab[i]->name, type))) { (!strcmp(virDriverTab[i]->name, type))) {
*typeVer = virDriverTab[i]->ver; *typeVer = virDriverTab[i]->ver;
break; break;
} }
} }
if (i >= MAX_DRIVERS) { if (i >= virDriverTabCount) {
*typeVer = 0; *typeVer = 0;
virLibConnError(NULL, VIR_ERR_NO_SUPPORT, type); virLibConnError(NULL, VIR_ERR_NO_SUPPORT, type);
return (-1); return (-1);
@ -300,8 +291,8 @@ virConnectOpen(const char *name)
goto failed; goto failed;
} }
for (i = 0;i < MAX_DRIVERS;i++) { for (i = 0;i < virDriverTabCount;i++) {
if ((virDriverTab[i] != NULL) && (virDriverTab[i]->open != NULL)) { if ((virDriverTab[i]->open != NULL)) {
res = virDriverTab[i]->open(ret, name, VIR_DRV_OPEN_QUIET); res = virDriverTab[i]->open(ret, name, VIR_DRV_OPEN_QUIET);
/* /*
* For a default connect to Xen make sure we manage to contact * For a default connect to Xen make sure we manage to contact
@ -316,8 +307,8 @@ virConnectOpen(const char *name)
} }
} }
for (i = 0;i < MAX_DRIVERS;i++) { for (i = 0;i < virNetworkDriverTabCount;i++) {
if ((virNetworkDriverTab[i] != NULL) && (virNetworkDriverTab[i]->open != NULL) && if ((virNetworkDriverTab[i]->open != NULL) &&
(res = virNetworkDriverTab[i]->open(ret, name, VIR_DRV_OPEN_QUIET)) == 0) { (res = virNetworkDriverTab[i]->open(ret, name, VIR_DRV_OPEN_QUIET)) == 0) {
ret->networkDrivers[ret->nb_network_drivers++] = virNetworkDriverTab[i]; ret->networkDrivers[ret->nb_network_drivers++] = virNetworkDriverTab[i];
} }
@ -375,16 +366,18 @@ virConnectOpenReadOnly(const char *name)
goto failed; goto failed;
} }
for (i = 0;i < MAX_DRIVERS;i++) { for (i = 0;i < virDriverTabCount;i++) {
if ((virDriverTab[i] != NULL) && (virDriverTab[i]->open != NULL)) { if ((virDriverTab[i]->open != NULL)) {
res = virDriverTab[i]->open(ret, name, res = virDriverTab[i]->open(ret, name,
VIR_DRV_OPEN_QUIET | VIR_DRV_OPEN_RO); VIR_DRV_OPEN_QUIET | VIR_DRV_OPEN_RO);
if (res == 0) if (res == 0)
ret->drivers[ret->nb_drivers++] = virDriverTab[i]; ret->drivers[ret->nb_drivers++] = virDriverTab[i];
} }
if ((virNetworkDriverTab[i] != NULL) && (virNetworkDriverTab[i]->open != NULL) && }
(res = virNetworkDriverTab[i]->open(ret, name, VIR_DRV_OPEN_QUIET)) == 0) { for (i = 0;i < virNetworkDriverTabCount;i++) {
if ((virNetworkDriverTab[i]->open != NULL) &&
(res = virNetworkDriverTab[i]->open(ret, name, VIR_DRV_OPEN_QUIET|VIR_DRV_OPEN_RO)) == 0) {
ret->networkDrivers[ret->nb_network_drivers++] = virNetworkDriverTab[i]; ret->networkDrivers[ret->nb_network_drivers++] = virNetworkDriverTab[i];
} }
} }