Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
static int vboxConnectListNetworks(virConnectPtr conn, char **const names, int nnames)
{
    vboxDriverPtr data = conn->privateData;
    vboxArray networkInterfaces = VBOX_ARRAY_INITIALIZER;
    IHost *host = NULL;
    size_t i = 0;
    int ret = -1;

    if (!data->vboxObj)
        return ret;

    gVBoxAPI.UIVirtualBox.GetHost(data->vboxObj, &host);
    if (!host)
        return ret;

    gVBoxAPI.UArray.vboxArrayGet(&networkInterfaces, host,
                                 gVBoxAPI.UArray.handleHostGetNetworkInterfaces(host));

    ret = 0;
    for (i = 0; (ret < nnames) && (i < networkInterfaces.count); i++) {
        IHostNetworkInterface *networkInterface = networkInterfaces.items[i];
        char *nameUtf8 = NULL;
        PRUnichar *nameUtf16 = NULL;
        PRUint32 interfaceType = 0;
        PRUint32 status = HostNetworkInterfaceStatus_Unknown;

        if (!networkInterface)
            continue;

        gVBoxAPI.UIHNInterface.GetInterfaceType(networkInterface, &interfaceType);

        if (interfaceType != HostNetworkInterfaceType_HostOnly)
            continue;

        gVBoxAPI.UIHNInterface.GetStatus(networkInterface, &status);

        if (status != HostNetworkInterfaceStatus_Up)
            continue;

        gVBoxAPI.UIHNInterface.GetName(networkInterface, &nameUtf16);
        VBOX_UTF16_TO_UTF8(nameUtf16, &nameUtf8);

        VIR_DEBUG("nnames[%d]: %s", ret, nameUtf8);
        if (VIR_STRDUP(names[ret], nameUtf8) >= 0)
            ret++;

        VBOX_UTF8_FREE(nameUtf8);
        VBOX_UTF16_FREE(nameUtf16);
    }

    gVBoxAPI.UArray.vboxArrayRelease(&networkInterfaces);

    VBOX_RELEASE(host);

    return ret;
}
Пример #4
0
static int vboxConnectNumOfNetworks(virConnectPtr conn)
{
    vboxDriverPtr data = conn->privateData;
    vboxArray networkInterfaces = VBOX_ARRAY_INITIALIZER;
    IHost *host = NULL;
    size_t i = 0;
    int ret = -1;

    if (!data->vboxObj)
        return ret;

    gVBoxAPI.UIVirtualBox.GetHost(data->vboxObj, &host);
    if (!host)
        return ret;

    gVBoxAPI.UArray.vboxArrayGet(&networkInterfaces, host,
                                 gVBoxAPI.UArray.handleHostGetNetworkInterfaces(host));

    ret = 0;
    for (i = 0; i < networkInterfaces.count; i++) {
        IHostNetworkInterface *networkInterface = networkInterfaces.items[i];
        PRUint32 status = HostNetworkInterfaceStatus_Unknown;
        PRUint32 interfaceType = 0;

        if (!networkInterface)
            continue;

        gVBoxAPI.UIHNInterface.GetInterfaceType(networkInterface, &interfaceType);
        if (interfaceType != HostNetworkInterfaceType_HostOnly)
            continue;

        gVBoxAPI.UIHNInterface.GetStatus(networkInterface, &status);

        if (status == HostNetworkInterfaceStatus_Up)
            ret++;
    }

    gVBoxAPI.UArray.vboxArrayRelease(&networkInterfaces);

    VBOX_RELEASE(host);

    VIR_DEBUG("numActive: %d", ret);
    return ret;
}
Пример #5
0
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;
}
Пример #6
0
static virStorageVolPtr
vboxStorageVolCreateXML(virStoragePoolPtr pool,
                        const char *xml, unsigned int flags)
{
    vboxDriverPtr data = pool->conn->privateData;
    virStorageVolDefPtr def = NULL;
    PRUnichar *hddFormatUtf16 = NULL;
    PRUnichar *hddNameUtf16 = NULL;
    virStoragePoolDef poolDef;
    nsresult rc;
    vboxIID hddIID;
    unsigned char uuid[VIR_UUID_BUFLEN];
    char key[VIR_UUID_STRING_BUFLEN] = "";
    IMedium *hardDisk = NULL;
    IProgress *progress = NULL;
    PRUint64 logicalSize = 0;
    PRUint32 variant = HardDiskVariant_Standard;
    resultCodeUnion resultCode;
    virStorageVolPtr ret = NULL;

    if (!data->vboxObj)
        return ret;

    virCheckFlags(0, NULL);

    /* since there is currently one default pool now
     * and virStorageVolDefFormat() just checks it type
     * so just assign it for now, change the behaviour
     * when vbox supports pools.
     */
    memset(&poolDef, 0, sizeof(poolDef));
    poolDef.type = VIR_STORAGE_POOL_DIR;

    if ((def = virStorageVolDefParseString(&poolDef, xml, 0)) == NULL)
        goto cleanup;

    if (!def->name ||
        (def->type != VIR_STORAGE_VOL_FILE))
        goto cleanup;

    /* For now only the vmdk, vpc and vdi type harddisk
     * variants can be created.  For historical reason, we default to vdi */
    if (def->target.format == VIR_STORAGE_FILE_VMDK) {
        VBOX_UTF8_TO_UTF16("VMDK", &hddFormatUtf16);
    } else if (def->target.format == VIR_STORAGE_FILE_VPC) {
        VBOX_UTF8_TO_UTF16("VHD", &hddFormatUtf16);
    } else {
        VBOX_UTF8_TO_UTF16("VDI", &hddFormatUtf16);
    }

    /* If target.path isn't given, use default path ~/.VirtualBox/image_name */
    if (def->target.path == NULL &&
        virAsprintf(&def->target.path, "%s/.VirtualBox/%s", virGetUserDirectory(), def->name) < 0)
        goto cleanup;
    VBOX_UTF8_TO_UTF16(def->target.path, &hddNameUtf16);

    if (!hddFormatUtf16 || !hddNameUtf16)
        goto cleanup;

    rc = gVBoxAPI.UIVirtualBox.CreateHardDisk(data->vboxObj, hddFormatUtf16, hddNameUtf16, &hardDisk);
    if (NS_FAILED(rc)) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Could not create harddisk, rc=%08x"),
                       (unsigned)rc);
        goto cleanup;
    }

    logicalSize = VIR_DIV_UP(def->target.capacity, 1024 * 1024);

    if (def->target.capacity == def->target.allocation)
        variant = HardDiskVariant_Fixed;

    rc = gVBoxAPI.UIMedium.CreateBaseStorage(hardDisk, logicalSize, variant, &progress);
    if (NS_FAILED(rc) || !progress) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Could not create base storage, rc=%08x"),
                       (unsigned)rc);
        goto cleanup;
    }

    gVBoxAPI.UIProgress.WaitForCompletion(progress, -1);
    gVBoxAPI.UIProgress.GetResultCode(progress, &resultCode);
    if (RC_FAILED(resultCode)) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Could not create base storage, rc=%08x"),
                       (unsigned)resultCode.uResultCode);
        goto cleanup;
    }

    VBOX_IID_INITIALIZE(&hddIID);
    rc = gVBoxAPI.UIMedium.GetId(hardDisk, &hddIID);
    if (NS_FAILED(rc))
        goto cleanup;

    vboxIIDToUUID(&hddIID, uuid);
    virUUIDFormat(uuid, key);

    ret = virGetStorageVol(pool->conn, pool->name, def->name, key,
                           NULL, NULL);

 cleanup:
    vboxIIDUnalloc(&hddIID);
    VBOX_RELEASE(progress);
    VBOX_UTF16_FREE(hddFormatUtf16);
    VBOX_UTF16_FREE(hddNameUtf16);
    virStorageVolDefFree(def);
    return ret;
}
Пример #7
0
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;
}
Пример #8
0
static int vboxNetworkCreate(virNetworkPtr network)
{
    vboxDriverPtr data = network->conn->privateData;
    char *networkNameUtf8 = NULL;
    PRUnichar *networkInterfaceNameUtf16 = NULL;
    IHostNetworkInterface *networkInterface = NULL;
    PRUnichar *networkNameUtf16 = NULL;
    IDHCPServer *dhcpServer = NULL;
    PRUnichar *trunkTypeUtf16 = NULL;
    PRUint32 interfaceType = 0;
    IHost *host = NULL;
    int ret = -1;

    if (!data->vboxObj)
        return ret;

    gVBoxAPI.UIVirtualBox.GetHost(data->vboxObj, &host);
    if (!host)
        return ret;

    /* Current limitation of the function for VirtualBox 2.2.* is
     * that the default hostonly network "vboxnet0" is always active
     * and thus all this functions does is start the dhcp server,
     * but the network can still be used without starting the dhcp
     * server by giving the machine static IP
     */

    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;

    VBOX_UTF8_TO_UTF16(networkNameUtf8, &networkNameUtf16);

    gVBoxAPI.UIVirtualBox.FindDHCPServerByNetworkName(data->vboxObj,
                                                      networkNameUtf16,
                                                      &dhcpServer);
    if (!dhcpServer)
        goto cleanup;

    gVBoxAPI.UIDHCPServer.SetEnabled(dhcpServer, PR_TRUE);

    VBOX_UTF8_TO_UTF16("netflt", &trunkTypeUtf16);

    gVBoxAPI.UIDHCPServer.Start(dhcpServer,
                                networkNameUtf16,
                                networkInterfaceNameUtf16,
                                trunkTypeUtf16);

    VBOX_UTF16_FREE(trunkTypeUtf16);
    ret = 0;

 cleanup:
    VBOX_RELEASE(dhcpServer);
    VBOX_UTF16_FREE(networkNameUtf16);
    VBOX_RELEASE(networkInterface);
    VBOX_UTF16_FREE(networkInterfaceNameUtf16);
    VBOX_RELEASE(host);
    VIR_FREE(networkNameUtf8);
    return ret;
}
Пример #9
0
static int
vboxNetworkUndefineDestroy(virNetworkPtr network, bool removeinterface)
{
    vboxDriverPtr data = network->conn->privateData;
    char *networkNameUtf8 = NULL;
    PRUnichar *networkInterfaceNameUtf16 = NULL;
    IHostNetworkInterface *networkInterface = NULL;
    PRUnichar *networkNameUtf16 = NULL;
    IDHCPServer *dhcpServer = NULL;
    PRUint32 interfaceType = 0;
    IHost *host = NULL;
    int ret = -1;

    if (!data->vboxObj)
        return ret;

    gVBoxAPI.UIVirtualBox.GetHost(data->vboxObj, &host);
    if (!host)
        return ret;

    /* Current limitation of the function for VirtualBox 2.2.* is
     * that you can't delete the default hostonly adaptor namely:
     * vboxnet0 and thus all this functions does is remove the
     * dhcp server configuration, but the network can still be used
     * by giving the machine static IP and also it will still
     * show up in the net-list in virsh
     */

    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 (gVBoxAPI.networkRemoveInterface && removeinterface) {
        vboxIIDUnion iid;
        IProgress *progress = NULL;
        nsresult rc;
        resultCodeUnion resultCode;

        VBOX_IID_INITIALIZE(&iid);
        rc = gVBoxAPI.UIHNInterface.GetId(networkInterface, &iid);

        if (NS_FAILED(rc))
            goto cleanup;

        gVBoxAPI.UIHost.RemoveHostOnlyNetworkInterface(host, &iid, &progress);
        vboxIIDUnalloc(&iid);

        if (!progress)
            goto cleanup;

        gVBoxAPI.UIProgress.WaitForCompletion(progress, -1);
        gVBoxAPI.UIProgress.GetResultCode(progress, &resultCode);
        if (RC_FAILED(resultCode)) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Error while removing hostonly network interface, rc=%08x"),
                           resultCode.uResultCode);
            goto cleanup;
        }
        VBOX_RELEASE(progress);
    }

    VBOX_UTF8_TO_UTF16(networkNameUtf8, &networkNameUtf16);

    gVBoxAPI.UIVirtualBox.FindDHCPServerByNetworkName(data->vboxObj,
                                                      networkNameUtf16,
                                                      &dhcpServer);
    if (!dhcpServer)
        goto cleanup;

    gVBoxAPI.UIDHCPServer.SetEnabled(dhcpServer, PR_FALSE);
    gVBoxAPI.UIDHCPServer.Stop(dhcpServer);
    if (removeinterface)
        gVBoxAPI.UIVirtualBox.RemoveDHCPServer(data->vboxObj, dhcpServer);
    ret = 0;
    VBOX_RELEASE(dhcpServer);

 cleanup:
    VBOX_UTF16_FREE(networkNameUtf16);
    VBOX_RELEASE(networkInterface);
    VBOX_UTF16_FREE(networkInterfaceNameUtf16);
    VBOX_RELEASE(host);
    VIR_FREE(networkNameUtf8);
    return ret;
}
Пример #10
0
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;
}