提交 32ad6aef 编写于 作者: P Pritesh Kothari 提交者: Daniel Veillard

VBox cleanup and update of networking XML functions

* src/vbox/vbox_tmpl.c: merged vboxNetworkCreateXML() and
  vboxNetworkDefineXML() and added code to handle multiple hostonly
  interfaces.
上级 85d15b51
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <sys/utsname.h> #include <sys/utsname.h>
#include <stdbool.h>
#include "internal.h" #include "internal.h"
...@@ -5046,50 +5047,72 @@ static virNetworkPtr vboxNetworkLookupByName(virConnectPtr conn, const char *nam ...@@ -5046,50 +5047,72 @@ static virNetworkPtr vboxNetworkLookupByName(virConnectPtr conn, const char *nam
return ret; return ret;
} }
static virNetworkPtr vboxNetworkCreateXML(virConnectPtr conn, const char *xml) { static virNetworkPtr vboxNetworkDefineCreateXML(virConnectPtr conn, const char *xml, bool start) {
vboxGlobalData *data = conn->privateData; vboxGlobalData *data = conn->privateData;
virNetworkDefPtr def = NULL; virNetworkDefPtr def = NULL;
virNetworkPtr ret = NULL; virNetworkPtr ret = NULL;
char *networkNameUtf8 = NULL;
if ((def = virNetworkDefParseString(conn, xml)) == NULL) if ((def = virNetworkDefParseString(conn, xml)) == NULL)
goto cleanup; goto cleanup;
if (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", def->name) < 0) {
virReportOOMError(conn);
goto cleanup;
}
if ((data->vboxObj) && (def->forwardType == VIR_NETWORK_FORWARD_NONE)) { if ((data->vboxObj) && (def->forwardType == VIR_NETWORK_FORWARD_NONE)) {
/* VirtualBox version 2.2.* has only one "hostonly"
* network called "vboxnet0" for linux
*/
if (STREQ(def->name, "vboxnet0")) {
IHost *host = NULL; IHost *host = NULL;
/* the current limitation of hostonly network is that you can't
* assign a name to it and it defaults to vboxnet*, for e.g:
* vboxnet0, vboxnet1, etc. Also the UUID is assigned to it
* automatically depending on the mac address and thus both
* these paramters are ignore here for now.
*/
data->vboxObj->vtbl->GetHost(data->vboxObj, &host); data->vboxObj->vtbl->GetHost(data->vboxObj, &host);
if (host) { if (host) {
PRUnichar *networkInterfaceNameUtf16 = NULL; PRUnichar *networkInterfaceNameUtf16 = NULL;
char *networkInterfaceNameUtf8 = NULL;
IHostNetworkInterface *networkInterface = NULL; IHostNetworkInterface *networkInterface = NULL;
data->pFuncs->pfnUtf8ToUtf16(def->name, &networkInterfaceNameUtf16); #if VBOX_API_VERSION == 2002
if STREQ(def->name, "vboxnet0") {
PRUint32 interfaceType = 0;
data->pFuncs->pfnUtf8ToUtf16(def->name, &networkInterfaceNameUtf16);
host->vtbl->FindHostNetworkInterfaceByName(host, networkInterfaceNameUtf16, &networkInterface); host->vtbl->FindHostNetworkInterfaceByName(host, networkInterfaceNameUtf16, &networkInterface);
if (networkInterface) {
PRUint32 interfaceType = 0;
networkInterface->vtbl->GetInterfaceType(networkInterface, &interfaceType); networkInterface->vtbl->GetInterfaceType(networkInterface, &interfaceType);
if (interfaceType != HostNetworkInterfaceType_HostOnly) {
networkInterface->vtbl->nsisupports.Release((nsISupports *) networkInterface);
networkInterface = NULL;
}
}
#else /* VBOX_API_VERSION != 2002 */
IProgress *progress = NULL;
host->vtbl->CreateHostOnlyNetworkInterface(host, &networkInterface, &progress);
if (interfaceType == HostNetworkInterfaceType_HostOnly) { if (progress) {
progress->vtbl->WaitForCompletion(progress, -1);
progress->vtbl->nsisupports.Release((nsISupports *)progress);
}
#endif /* VBOX_API_VERSION != 2002 */
if (networkInterface) {
unsigned char uuid[VIR_UUID_BUFLEN]; unsigned char uuid[VIR_UUID_BUFLEN];
char *networkNameUtf8 = NULL;
PRUnichar *networkNameUtf16 = NULL; PRUnichar *networkNameUtf16 = NULL;
vboxIID *vboxnet0IID = NULL; vboxIID *vboxnetiid = NULL;
networkInterface->vtbl->GetId(networkInterface, &vboxnet0IID); networkInterface->vtbl->GetName(networkInterface, &networkInterfaceNameUtf16);
vboxIIDToUUID(uuid, vboxnet0IID); if (networkInterfaceNameUtf16) {
data->pFuncs->pfnUtf8ToUtf16(networkNameUtf8 , &networkNameUtf16); data->pFuncs->pfnUtf16ToUtf8(networkInterfaceNameUtf16, &networkInterfaceNameUtf8);
if (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", networkInterfaceNameUtf8) < 0) {
host->vtbl->nsisupports.Release((nsISupports *)host);
networkInterface->vtbl->nsisupports.Release((nsISupports *)networkInterface);
virReportOOMError(conn);
goto cleanup;
}
}
data->pFuncs->pfnUtf8ToUtf16(networkNameUtf8 , &networkNameUtf16);
/* Currently support only one dhcp server per network /* Currently support only one dhcp server per network
* with contigious address space from start to end * with contigious address space from start to end
...@@ -5131,6 +5154,7 @@ static virNetworkPtr vboxNetworkCreateXML(virConnectPtr conn, const char *xml) { ...@@ -5131,6 +5154,7 @@ static virNetworkPtr vboxNetworkCreateXML(virConnectPtr conn, const char *xml) {
fromIPAddressUtf16, fromIPAddressUtf16,
toIPAddressUtf16); toIPAddressUtf16);
if (start)
dhcpServer->vtbl->Start(dhcpServer, dhcpServer->vtbl->Start(dhcpServer,
networkNameUtf16, networkNameUtf16,
networkInterfaceNameUtf16, networkInterfaceNameUtf16,
...@@ -5145,154 +5169,66 @@ static virNetworkPtr vboxNetworkCreateXML(virConnectPtr conn, const char *xml) { ...@@ -5145,154 +5169,66 @@ static virNetworkPtr vboxNetworkCreateXML(virConnectPtr conn, const char *xml) {
} }
} }
ret = virGetNetwork(conn, def->name, uuid); if ((def->nhosts >= 1) &&
(def->hosts[0].ip)) {
#if VBOX_API_VERSION == 2002
DEBUGUUID("Real Network UUID", vboxnet0IID);
vboxIIDUnalloc(vboxnet0IID);
#else
DEBUGPRUnichar("Real Network UUID", vboxnet0IID);
vboxIIDFree(vboxnet0IID);
#endif
data->pFuncs->pfnUtf16Free(networkNameUtf16);
}
networkInterface->vtbl->nsisupports.Release((nsISupports *) networkInterface);
}
data->pFuncs->pfnUtf16Free(networkInterfaceNameUtf16);
host->vtbl->nsisupports.Release((nsISupports *) host);
}
}
}
cleanup:
VIR_FREE(networkNameUtf8);
virNetworkDefFree(def);
return ret;
}
static virNetworkPtr vboxNetworkDefineXML(virConnectPtr conn, const char *xml) {
vboxGlobalData *data = conn->privateData;
virNetworkDefPtr def = NULL;
virNetworkPtr ret = NULL;
char *networkNameUtf8 = NULL;
/* vboxNetworkDefineXML() is not exactly "network definition"
* as the network is up and running, only the DHCP server is off,
* so you can always assign static IP and get the network running.
*/
if ((def = virNetworkDefParseString(conn, xml)) == NULL)
goto cleanup;
if (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", def->name) < 0) {
virReportOOMError(conn);
goto cleanup;
}
if ((data->vboxObj) && (def->forwardType == VIR_NETWORK_FORWARD_NONE)) {
/* VirtualBox version 2.2.* has only one "hostonly"
* network called "vboxnet0" for linux
*/
if (STREQ(def->name, "vboxnet0")) {
IHost *host = NULL;
data->vboxObj->vtbl->GetHost(data->vboxObj, &host);
if (host) {
PRUnichar *networkInterfaceNameUtf16 = NULL;
IHostNetworkInterface *networkInterface = NULL;
data->pFuncs->pfnUtf8ToUtf16(def->name, &networkInterfaceNameUtf16);
host->vtbl->FindHostNetworkInterfaceByName(host, networkInterfaceNameUtf16, &networkInterface);
if (networkInterface) {
PRUint32 interfaceType = 0;
networkInterface->vtbl->GetInterfaceType(networkInterface, &interfaceType);
if (interfaceType == HostNetworkInterfaceType_HostOnly) {
unsigned char uuid[VIR_UUID_BUFLEN];
PRUnichar *networkNameUtf16 = NULL;
vboxIID *vboxnet0IID = NULL;
networkInterface->vtbl->GetId(networkInterface, &vboxnet0IID);
vboxIIDToUUID(uuid, vboxnet0IID);
data->pFuncs->pfnUtf8ToUtf16(networkNameUtf8 , &networkNameUtf16);
/* Currently support only one dhcp server per network
* with contigious address space from start to end
*/
if ((def->nranges >= 1) &&
(def->ranges[0].start) &&
(def->ranges[0].end)) {
IDHCPServer *dhcpServer = NULL;
data->vboxObj->vtbl->FindDHCPServerByNetworkName(data->vboxObj,
networkNameUtf16,
&dhcpServer);
if (!dhcpServer) {
/* create a dhcp server */
data->vboxObj->vtbl->CreateDHCPServer(data->vboxObj,
networkNameUtf16,
&dhcpServer);
DEBUG0("couldn't find dhcp server so creating one");
}
if (dhcpServer) {
PRUnichar *ipAddressUtf16 = NULL; PRUnichar *ipAddressUtf16 = NULL;
PRUnichar *networkMaskUtf16 = NULL; PRUnichar *networkMaskUtf16 = NULL;
PRUnichar *fromIPAddressUtf16 = NULL;
PRUnichar *toIPAddressUtf16 = NULL;
data->pFuncs->pfnUtf8ToUtf16(def->ipAddress, &ipAddressUtf16);
data->pFuncs->pfnUtf8ToUtf16(def->netmask, &networkMaskUtf16); data->pFuncs->pfnUtf8ToUtf16(def->netmask, &networkMaskUtf16);
data->pFuncs->pfnUtf8ToUtf16(def->ranges[0].start, &fromIPAddressUtf16); data->pFuncs->pfnUtf8ToUtf16(def->hosts[0].ip, &ipAddressUtf16);
data->pFuncs->pfnUtf8ToUtf16(def->ranges[0].end, &toIPAddressUtf16);
dhcpServer->vtbl->SetEnabled(dhcpServer, PR_FALSE); /* Current drawback is that since EnableStaticIpConfig() sets
* IP and enables the interface so even if the dhcpserver is not
dhcpServer->vtbl->SetConfiguration(dhcpServer, * started the interface is still up and running
*/
networkInterface->vtbl->EnableStaticIpConfig(networkInterface,
ipAddressUtf16, ipAddressUtf16,
networkMaskUtf16, networkMaskUtf16);
fromIPAddressUtf16,
toIPAddressUtf16);
data->pFuncs->pfnUtf16Free(ipAddressUtf16); data->pFuncs->pfnUtf16Free(ipAddressUtf16);
data->pFuncs->pfnUtf16Free(networkMaskUtf16); data->pFuncs->pfnUtf16Free(networkMaskUtf16);
data->pFuncs->pfnUtf16Free(fromIPAddressUtf16); } else {
data->pFuncs->pfnUtf16Free(toIPAddressUtf16); networkInterface->vtbl->EnableDynamicIpConfig(networkInterface);
dhcpServer->vtbl->nsisupports.Release((nsISupports *) dhcpServer); networkInterface->vtbl->DhcpRediscover(networkInterface);
}
} }
ret = virGetNetwork(conn, def->name, uuid); networkInterface->vtbl->GetId(networkInterface, &vboxnetiid);
if (vboxnetiid) {
vboxIIDToUUID(uuid, vboxnetiid);
#if VBOX_API_VERSION == 2002 #if VBOX_API_VERSION == 2002
DEBUGUUID("Real Network UUID", vboxnet0IID); DEBUGUUID("Real Network UUID", vboxnetiid);
vboxIIDUnalloc(vboxnet0IID); vboxIIDUnalloc(vboxnetiid);
#else #else /* VBOX_API_VERSION != 2002 */
DEBUGPRUnichar("Real Network UUID", vboxnet0IID); DEBUGPRUnichar("Real Network UUID", vboxnetiid);
vboxIIDFree(vboxnet0IID); vboxIIDFree(vboxnetiid);
#endif #endif /* VBOX_API_VERSION != 2002 */
data->pFuncs->pfnUtf16Free(networkNameUtf16); ret = virGetNetwork(conn, networkInterfaceNameUtf8, uuid);
} }
VIR_FREE(networkNameUtf8);
data->pFuncs->pfnUtf16Free(networkNameUtf16);
networkInterface->vtbl->nsisupports.Release((nsISupports *) networkInterface); networkInterface->vtbl->nsisupports.Release((nsISupports *) networkInterface);
} }
data->pFuncs->pfnUtf8Free(networkInterfaceNameUtf8);
data->pFuncs->pfnUtf16Free(networkInterfaceNameUtf16); data->pFuncs->pfnUtf16Free(networkInterfaceNameUtf16);
host->vtbl->nsisupports.Release((nsISupports *) host); host->vtbl->nsisupports.Release((nsISupports *) host);
} }
} }
}
cleanup: cleanup:
VIR_FREE(networkNameUtf8);
virNetworkDefFree(def); virNetworkDefFree(def);
return ret; return ret;
} }
static virNetworkPtr vboxNetworkCreateXML(virConnectPtr conn, const char *xml) {
return vboxNetworkDefineCreateXML(conn, xml, true);
}
static virNetworkPtr vboxNetworkDefineXML(virConnectPtr conn, const char *xml) {
return vboxNetworkDefineCreateXML(conn, xml, false);
}
static int vboxNetworkUndefine(virNetworkPtr network) { static int vboxNetworkUndefine(virNetworkPtr network) {
vboxGlobalData *data = network->conn->privateData; vboxGlobalData *data = network->conn->privateData;
char *networkNameUtf8 = NULL; char *networkNameUtf8 = NULL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册