static virNetworkPtr vboxNetworkLookupByUUID(virConnectPtr conn, const unsigned char *uuid) { vboxDriverPtr data = conn->privateData; PRUint32 interfaceType = 0; char *nameUtf8 = NULL; PRUnichar *nameUtf16 = NULL; IHostNetworkInterface *networkInterface = NULL; vboxIIDUnion iid; IHost *host = NULL; virNetworkPtr ret = NULL; if (!data->vboxObj) return ret; gVBoxAPI.UIVirtualBox.GetHost(data->vboxObj, &host); if (!host) return ret; VBOX_IID_INITIALIZE(&iid); vboxIIDFromUUID(&iid, uuid); /* TODO: "internal" networks are just strings and * thus can't do much with them */ gVBoxAPI.UIHost.FindHostNetworkInterfaceById(host, &iid, &networkInterface); if (!networkInterface) goto cleanup; gVBoxAPI.UIHNInterface.GetInterfaceType(networkInterface, &interfaceType); if (interfaceType != HostNetworkInterfaceType_HostOnly) goto cleanup; gVBoxAPI.UIHNInterface.GetName(networkInterface, &nameUtf16); VBOX_UTF16_TO_UTF8(nameUtf16, &nameUtf8); ret = virGetNetwork(conn, nameUtf8, uuid); VIR_DEBUG("Network Name: %s", nameUtf8); DEBUGIID("Network UUID", &iid); VBOX_UTF8_FREE(nameUtf8); VBOX_UTF16_FREE(nameUtf16); cleanup: VBOX_RELEASE(networkInterface); VBOX_RELEASE(host); vboxIIDUnalloc(&iid); return ret; }
static virNetworkPtr vboxNetworkLookupByName(virConnectPtr conn, const char *name) { vboxDriverPtr data = conn->privateData; PRUnichar *nameUtf16 = NULL; IHostNetworkInterface *networkInterface = NULL; PRUint32 interfaceType = 0; unsigned char uuid[VIR_UUID_BUFLEN]; vboxIIDUnion iid; IHost *host = NULL; virNetworkPtr ret = NULL; nsresult rc; if (!data->vboxObj) return ret; gVBoxAPI.UIVirtualBox.GetHost(data->vboxObj, &host); if (!host) return ret; VBOX_IID_INITIALIZE(&iid); VBOX_UTF8_TO_UTF16(name, &nameUtf16); gVBoxAPI.UIHost.FindHostNetworkInterfaceByName(host, nameUtf16, &networkInterface); if (!networkInterface) goto cleanup; gVBoxAPI.UIHNInterface.GetInterfaceType(networkInterface, &interfaceType); if (interfaceType != HostNetworkInterfaceType_HostOnly) goto cleanup; rc = gVBoxAPI.UIHNInterface.GetId(networkInterface, &iid); if (NS_FAILED(rc)) goto cleanup; vboxIIDToUUID(&iid, uuid); ret = virGetNetwork(conn, name, uuid); VIR_DEBUG("Network Name: %s", name); DEBUGIID("Network UUID", &iid); vboxIIDUnalloc(&iid); cleanup: VBOX_RELEASE(networkInterface); VBOX_UTF16_FREE(nameUtf16); VBOX_RELEASE(host); return ret; }
static int vboxStorageVolDelete(virStorageVolPtr vol, unsigned int flags) { vboxDriverPtr data = vol->conn->privateData; unsigned char uuid[VIR_UUID_BUFLEN]; IMedium *hardDisk = NULL; int deregister = 0; PRUint32 hddstate = 0; size_t i = 0; size_t j = 0; PRUint32 machineIdsSize = 0; vboxArray machineIds = VBOX_ARRAY_INITIALIZER; vboxIID hddIID; int ret = -1; if (!data->vboxObj) return ret; VBOX_IID_INITIALIZE(&hddIID); virCheckFlags(0, -1); if (virUUIDParse(vol->key, uuid) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("Could not parse UUID from '%s'"), vol->key); return -1; } vboxIIDFromUUID(&hddIID, uuid); if (NS_FAILED(gVBoxAPI.UIVirtualBox.GetHardDiskByIID(data->vboxObj, &hddIID, &hardDisk))) goto cleanup; gVBoxAPI.UIMedium.GetState(hardDisk, &hddstate); if (hddstate == MediaState_Inaccessible) goto cleanup; gVBoxAPI.UArray.vboxArrayGet(&machineIds, hardDisk, gVBoxAPI.UArray.handleMediumGetMachineIds(hardDisk)); #if defined WIN32 /* VirtualBox 2.2 on Windows represents IIDs as GUIDs and the * machineIds array contains direct instances of the GUID struct * instead of pointers to the actual struct instances. But there * is no 128bit width simple item type for a SafeArray to fit a * GUID in. The largest simple type it 64bit width and VirtualBox * uses two of this 64bit items to represents one GUID. Therefore, * we divide the size of the SafeArray by two, to compensate for * this workaround in VirtualBox */ if (gVBoxAPI.uVersion >= 2001052 && gVBoxAPI.uVersion < 2002051) machineIds.count /= 2; #endif /* !defined WIN32 */ machineIdsSize = machineIds.count; for (i = 0; i < machineIds.count; i++) { IMachine *machine = NULL; vboxIID machineId; vboxArray hddAttachments = VBOX_ARRAY_INITIALIZER; VBOX_IID_INITIALIZE(&machineId); vboxIIDFromArrayItem(&machineId, &machineIds, i); if (NS_FAILED(gVBoxAPI.UIVirtualBox.GetMachine(data->vboxObj, &machineId, &machine))) { virReportError(VIR_ERR_NO_DOMAIN, "%s", _("no domain with matching uuid")); break; } if (NS_FAILED(gVBoxAPI.UISession.Open(data, &machineId, machine))) { vboxIIDUnalloc(&machineId); continue; } if (NS_FAILED(gVBoxAPI.UISession.GetMachine(data->vboxSession, &machine))) goto cleanupLoop; gVBoxAPI.UArray.vboxArrayGet(&hddAttachments, machine, gVBoxAPI.UArray.handleMachineGetMediumAttachments(machine)); for (j = 0; j < hddAttachments.count; j++) { IMediumAttachment *hddAttachment = hddAttachments.items[j]; IMedium *hdd = NULL; vboxIID iid; if (!hddAttachment) continue; if (NS_FAILED(gVBoxAPI.UIMediumAttachment.GetMedium(hddAttachment, &hdd)) || !hdd) continue; VBOX_IID_INITIALIZE(&iid); if (NS_FAILED(gVBoxAPI.UIMedium.GetId(hdd, &iid))) { VBOX_MEDIUM_RELEASE(hdd); continue; } DEBUGIID("HardDisk (to delete) UUID", &hddIID); DEBUGIID("HardDisk (currently processing) UUID", &iid); if (vboxIIDIsEqual(&hddIID, &iid)) { PRUnichar *controller = NULL; PRInt32 port = 0; PRInt32 device = 0; DEBUGIID("Found HardDisk to delete, UUID", &hddIID); gVBoxAPI.UIMediumAttachment.GetController(hddAttachment, &controller); gVBoxAPI.UIMediumAttachment.GetPort(hddAttachment, &port); gVBoxAPI.UIMediumAttachment.GetDevice(hddAttachment, &device); if (NS_SUCCEEDED(gVBoxAPI.UIMachine.DetachDevice(machine, controller, port, device))) { ignore_value(gVBoxAPI.UIMachine.SaveSettings(machine)); VIR_DEBUG("saving machine settings"); deregister++; VIR_DEBUG("deregistering hdd:%d", deregister); } VBOX_UTF16_FREE(controller); } vboxIIDUnalloc(&iid); VBOX_MEDIUM_RELEASE(hdd); } cleanupLoop: gVBoxAPI.UArray.vboxArrayRelease(&hddAttachments); VBOX_RELEASE(machine); gVBoxAPI.UISession.Close(data->vboxSession); vboxIIDUnalloc(&machineId); } gVBoxAPI.UArray.vboxArrayUnalloc(&machineIds); if (machineIdsSize == 0 || machineIdsSize == deregister) { IProgress *progress = NULL; if (NS_SUCCEEDED(gVBoxAPI.UIMedium.DeleteStorage(hardDisk, &progress)) && progress) { gVBoxAPI.UIProgress.WaitForCompletion(progress, -1); VBOX_RELEASE(progress); DEBUGIID("HardDisk deleted, UUID", &hddIID); ret = 0; } } cleanup: VBOX_MEDIUM_RELEASE(hardDisk); vboxIIDUnalloc(&hddIID); return ret; }
static char *vboxNetworkGetXMLDesc(virNetworkPtr network, unsigned int flags) { vboxDriverPtr data = network->conn->privateData; virNetworkDefPtr def = NULL; virNetworkIPDefPtr ipdef = NULL; char *networkNameUtf8 = NULL; PRUnichar *networkInterfaceNameUtf16 = NULL; IHostNetworkInterface *networkInterface = NULL; PRUint32 interfaceType = 0; PRUnichar *networkNameUtf16 = NULL; IDHCPServer *dhcpServer = NULL; vboxIIDUnion vboxnet0IID; IHost *host = NULL; char *ret = NULL; nsresult rc; if (!data->vboxObj) return ret; gVBoxAPI.UIVirtualBox.GetHost(data->vboxObj, &host); if (!host) return ret; VBOX_IID_INITIALIZE(&vboxnet0IID); virCheckFlags(0, NULL); if (VIR_ALLOC(def) < 0) goto cleanup; if (VIR_ALLOC(ipdef) < 0) goto cleanup; def->ips = ipdef; def->nips = 1; if (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", network->name) < 0) goto cleanup; VBOX_UTF8_TO_UTF16(network->name, &networkInterfaceNameUtf16); gVBoxAPI.UIHost.FindHostNetworkInterfaceByName(host, networkInterfaceNameUtf16, &networkInterface); if (!networkInterface) goto cleanup; gVBoxAPI.UIHNInterface.GetInterfaceType(networkInterface, &interfaceType); if (interfaceType != HostNetworkInterfaceType_HostOnly) goto cleanup; if (VIR_STRDUP(def->name, network->name) < 0) goto cleanup; rc = gVBoxAPI.UIHNInterface.GetId(networkInterface, &vboxnet0IID); if (NS_FAILED(rc)) goto cleanup; vboxIIDToUUID(&vboxnet0IID, def->uuid); VBOX_UTF8_TO_UTF16(networkNameUtf8, &networkNameUtf16); def->forward.type = VIR_NETWORK_FORWARD_NONE; gVBoxAPI.UIVirtualBox.FindDHCPServerByNetworkName(data->vboxObj, networkNameUtf16, &dhcpServer); if (dhcpServer) { ipdef->nranges = 1; if (VIR_ALLOC_N(ipdef->ranges, ipdef->nranges) >= 0) { PRUnichar *ipAddressUtf16 = NULL; PRUnichar *networkMaskUtf16 = NULL; PRUnichar *fromIPAddressUtf16 = NULL; PRUnichar *toIPAddressUtf16 = NULL; bool errorOccurred = false; gVBoxAPI.UIDHCPServer.GetIPAddress(dhcpServer, &ipAddressUtf16); gVBoxAPI.UIDHCPServer.GetNetworkMask(dhcpServer, &networkMaskUtf16); gVBoxAPI.UIDHCPServer.GetLowerIP(dhcpServer, &fromIPAddressUtf16); gVBoxAPI.UIDHCPServer.GetUpperIP(dhcpServer, &toIPAddressUtf16); /* Currently virtualbox supports only one dhcp server per network * with contigious address space from start to end */ if (vboxSocketParseAddrUtf16(data, ipAddressUtf16, &ipdef->address) < 0 || vboxSocketParseAddrUtf16(data, networkMaskUtf16, &ipdef->netmask) < 0 || vboxSocketParseAddrUtf16(data, fromIPAddressUtf16, &ipdef->ranges[0].start) < 0 || vboxSocketParseAddrUtf16(data, toIPAddressUtf16, &ipdef->ranges[0].end) < 0) { errorOccurred = true; } VBOX_UTF16_FREE(ipAddressUtf16); VBOX_UTF16_FREE(networkMaskUtf16); VBOX_UTF16_FREE(fromIPAddressUtf16); VBOX_UTF16_FREE(toIPAddressUtf16); if (errorOccurred) goto cleanup; } else { ipdef->nranges = 0; } ipdef->nhosts = 1; if (VIR_ALLOC_N(ipdef->hosts, ipdef->nhosts) >= 0) { if (VIR_STRDUP(ipdef->hosts[0].name, network->name) < 0) { VIR_FREE(ipdef->hosts); ipdef->nhosts = 0; } else { PRUnichar *macAddressUtf16 = NULL; PRUnichar *ipAddressUtf16 = NULL; bool errorOccurred = false; gVBoxAPI.UIHNInterface.GetHardwareAddress(networkInterface, &macAddressUtf16); gVBoxAPI.UIHNInterface.GetIPAddress(networkInterface, &ipAddressUtf16); VBOX_UTF16_TO_UTF8(macAddressUtf16, &ipdef->hosts[0].mac); if (vboxSocketParseAddrUtf16(data, ipAddressUtf16, &ipdef->hosts[0].ip) < 0) { errorOccurred = true; } VBOX_UTF16_FREE(macAddressUtf16); VBOX_UTF16_FREE(ipAddressUtf16); if (errorOccurred) goto cleanup; } } else { ipdef->nhosts = 0; } } else { PRUnichar *networkMaskUtf16 = NULL; PRUnichar *ipAddressUtf16 = NULL; bool errorOccurred = false; gVBoxAPI.UIHNInterface.GetNetworkMask(networkInterface, &networkMaskUtf16); gVBoxAPI.UIHNInterface.GetIPAddress(networkInterface, &ipAddressUtf16); if (vboxSocketParseAddrUtf16(data, networkMaskUtf16, &ipdef->netmask) < 0 || vboxSocketParseAddrUtf16(data, ipAddressUtf16, &ipdef->address) < 0) { errorOccurred = true; } VBOX_UTF16_FREE(networkMaskUtf16); VBOX_UTF16_FREE(ipAddressUtf16); if (errorOccurred) goto cleanup; } DEBUGIID("Network UUID", &vboxnet0IID); ret = virNetworkDefFormat(def, 0); cleanup: vboxIIDUnalloc(&vboxnet0IID); VBOX_UTF16_FREE(networkNameUtf16); VBOX_RELEASE(networkInterface); VBOX_UTF16_FREE(networkInterfaceNameUtf16); VBOX_RELEASE(host); virNetworkDefFree(def); VIR_FREE(networkNameUtf8); VBOX_RELEASE(dhcpServer); return ret; }
static virNetworkPtr vboxNetworkDefineCreateXML(virConnectPtr conn, const char *xml, bool start) { vboxDriverPtr data = conn->privateData; PRUnichar *networkInterfaceNameUtf16 = NULL; char *networkInterfaceNameUtf8 = NULL; PRUnichar *networkNameUtf16 = NULL; char *networkNameUtf8 = NULL; IHostNetworkInterface *networkInterface = NULL; virNetworkDefPtr def = virNetworkDefParseString(xml); virNetworkIPDefPtr ipdef = NULL; unsigned char uuid[VIR_UUID_BUFLEN]; vboxIIDUnion vboxnetiid; virSocketAddr netmask; IHost *host = NULL; virNetworkPtr ret = NULL; nsresult rc; if (!data->vboxObj) return ret; gVBoxAPI.UIVirtualBox.GetHost(data->vboxObj, &host); if (!host) return ret; VBOX_IID_INITIALIZE(&vboxnetiid); if ((!def) || (def->forward.type != VIR_NETWORK_FORWARD_NONE) || (def->nips == 0 || !def->ips)) goto cleanup; /* Look for the first IPv4 IP address definition and use that. * If there weren't any IPv4 addresses, ignore the network (since it's * required below to have an IPv4 address) */ ipdef = virNetworkDefGetIPByIndex(def, AF_INET, 0); if (!ipdef) goto cleanup; if (virNetworkIPDefNetmask(ipdef, &netmask) < 0) goto cleanup; /* 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 ignored here for now. * * If the vbox is in 2.x and the def->name not equal to vboxnet0, * the function call will fail and the networkInterface set to * NULL. (We can't assign a new name to hostonly network, only * take the given name, say vboxnet0) */ gVBoxAPI.UIHost.CreateHostOnlyNetworkInterface(data, host, def->name, &networkInterface); if (!networkInterface) goto cleanup; gVBoxAPI.UIHNInterface.GetName(networkInterface, &networkInterfaceNameUtf16); if (!networkInterfaceNameUtf16) goto cleanup; VBOX_UTF16_TO_UTF8(networkInterfaceNameUtf16, &networkInterfaceNameUtf8); if (virAsprintf(&networkNameUtf8, "HostInterfaceNetworking-%s", networkInterfaceNameUtf8) < 0) goto cleanup; VBOX_UTF8_TO_UTF16(networkNameUtf8, &networkNameUtf16); /* Currently support only one dhcp server per network * with contigious address space from start to end */ if ((ipdef->nranges >= 1) && VIR_SOCKET_ADDR_VALID(&ipdef->ranges[0].start) && VIR_SOCKET_ADDR_VALID(&ipdef->ranges[0].end)) { IDHCPServer *dhcpServer = NULL; gVBoxAPI.UIVirtualBox.FindDHCPServerByNetworkName(data->vboxObj, networkNameUtf16, &dhcpServer); if (!dhcpServer) { /* create a dhcp server */ gVBoxAPI.UIVirtualBox.CreateDHCPServer(data->vboxObj, networkNameUtf16, &dhcpServer); VIR_DEBUG("couldn't find dhcp server so creating one"); } if (dhcpServer) { PRUnichar *ipAddressUtf16 = NULL; PRUnichar *networkMaskUtf16 = NULL; PRUnichar *fromIPAddressUtf16 = NULL; PRUnichar *toIPAddressUtf16 = NULL; PRUnichar *trunkTypeUtf16 = NULL; ipAddressUtf16 = vboxSocketFormatAddrUtf16(data, &ipdef->address); networkMaskUtf16 = vboxSocketFormatAddrUtf16(data, &netmask); fromIPAddressUtf16 = vboxSocketFormatAddrUtf16(data, &ipdef->ranges[0].start); toIPAddressUtf16 = vboxSocketFormatAddrUtf16(data, &ipdef->ranges[0].end); if (ipAddressUtf16 == NULL || networkMaskUtf16 == NULL || fromIPAddressUtf16 == NULL || toIPAddressUtf16 == NULL) { VBOX_UTF16_FREE(ipAddressUtf16); VBOX_UTF16_FREE(networkMaskUtf16); VBOX_UTF16_FREE(fromIPAddressUtf16); VBOX_UTF16_FREE(toIPAddressUtf16); VBOX_RELEASE(dhcpServer); goto cleanup; } VBOX_UTF8_TO_UTF16("netflt", &trunkTypeUtf16); gVBoxAPI.UIDHCPServer.SetEnabled(dhcpServer, PR_TRUE); gVBoxAPI.UIDHCPServer.SetConfiguration(dhcpServer, ipAddressUtf16, networkMaskUtf16, fromIPAddressUtf16, toIPAddressUtf16); if (start) gVBoxAPI.UIDHCPServer.Start(dhcpServer, networkNameUtf16, networkInterfaceNameUtf16, trunkTypeUtf16); VBOX_UTF16_FREE(ipAddressUtf16); VBOX_UTF16_FREE(networkMaskUtf16); VBOX_UTF16_FREE(fromIPAddressUtf16); VBOX_UTF16_FREE(toIPAddressUtf16); VBOX_UTF16_FREE(trunkTypeUtf16); VBOX_RELEASE(dhcpServer); } } if ((ipdef->nhosts >= 1) && VIR_SOCKET_ADDR_VALID(&ipdef->hosts[0].ip)) { PRUnichar *ipAddressUtf16 = NULL; PRUnichar *networkMaskUtf16 = NULL; ipAddressUtf16 = vboxSocketFormatAddrUtf16(data, &ipdef->hosts[0].ip); networkMaskUtf16 = vboxSocketFormatAddrUtf16(data, &netmask); if (ipAddressUtf16 == NULL || networkMaskUtf16 == NULL) { VBOX_UTF16_FREE(ipAddressUtf16); VBOX_UTF16_FREE(networkMaskUtf16); goto cleanup; } /* Current drawback is that since EnableStaticIpConfig() sets * IP and enables the interface so even if the dhcpserver is not * started the interface is still up and running */ gVBoxAPI.UIHNInterface.EnableStaticIPConfig(networkInterface, ipAddressUtf16, networkMaskUtf16); VBOX_UTF16_FREE(ipAddressUtf16); VBOX_UTF16_FREE(networkMaskUtf16); } else { gVBoxAPI.UIHNInterface.EnableDynamicIPConfig(networkInterface); gVBoxAPI.UIHNInterface.DHCPRediscover(networkInterface); } rc = gVBoxAPI.UIHNInterface.GetId(networkInterface, &vboxnetiid); if (NS_FAILED(rc)) goto cleanup; vboxIIDToUUID(&vboxnetiid, uuid); DEBUGIID("Real Network UUID", &vboxnetiid); vboxIIDUnalloc(&vboxnetiid); ret = virGetNetwork(conn, networkInterfaceNameUtf8, uuid); cleanup: VIR_FREE(networkNameUtf8); VBOX_UTF16_FREE(networkNameUtf16); VBOX_RELEASE(networkInterface); VBOX_UTF8_FREE(networkInterfaceNameUtf8); VBOX_UTF16_FREE(networkInterfaceNameUtf16); VBOX_RELEASE(host); virNetworkDefFree(def); return ret; }