예제 #1
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;
}
예제 #2
0
static int
vboxStoragePoolListVolumes(virStoragePoolPtr pool, char **const names, int nnames)
{
    vboxDriverPtr data = pool->conn->privateData;
    vboxArray hardDisks = VBOX_ARRAY_INITIALIZER;
    PRUint32 numActive = 0;
    nsresult rc;
    size_t i;
    int ret = -1;

    if (!data->vboxObj)
        return ret;

    rc = gVBoxAPI.UArray.vboxArrayGet(&hardDisks, data->vboxObj,
                                      gVBoxAPI.UArray.handleGetHardDisks(data->vboxObj));
    if (NS_FAILED(rc)) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("could not get the volume list in the pool: %s, rc=%08x"),
                       pool->name, (unsigned)rc);
        return ret;
    }

    for (i = 0; i < hardDisks.count && numActive < nnames; ++i) {
        IMedium *hardDisk = hardDisks.items[i];
        PRUint32 hddstate;
        char *nameUtf8 = NULL;
        PRUnichar *nameUtf16 = NULL;

        if (!hardDisk)
            continue;

        gVBoxAPI.UIMedium.GetState(hardDisk, &hddstate);
        if (hddstate == MediaState_Inaccessible)
            continue;

        gVBoxAPI.UIMedium.GetName(hardDisk, &nameUtf16);

        VBOX_UTF16_TO_UTF8(nameUtf16, &nameUtf8);
        VBOX_UTF16_FREE(nameUtf16);

        if (!nameUtf8)
            continue;

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

        VBOX_UTF8_FREE(nameUtf8);
    }

    gVBoxAPI.UArray.vboxArrayRelease(&hardDisks);
    ret = numActive;

    return ret;
}
예제 #3
0
static char *vboxStorageVolGetPath(virStorageVolPtr vol)
{
    vboxDriverPtr data = vol->conn->privateData;
    IMedium *hardDisk = NULL;
    PRUnichar *hddLocationUtf16 = NULL;
    char *hddLocationUtf8 = NULL;
    unsigned char uuid[VIR_UUID_BUFLEN];
    vboxIID hddIID;
    PRUint32 hddstate;
    nsresult rc;
    char *ret = NULL;

    if (!data->vboxObj)
        return ret;

    if (virUUIDParse(vol->key, uuid) < 0) {
        virReportError(VIR_ERR_INVALID_ARG,
                       _("Could not parse UUID from '%s'"), vol->key);
        return ret;
    }

    VBOX_IID_INITIALIZE(&hddIID);
    vboxIIDFromUUID(&hddIID, uuid);
    rc = gVBoxAPI.UIVirtualBox.GetHardDiskByIID(data->vboxObj, &hddIID, &hardDisk);
    if (NS_FAILED(rc))
        goto cleanup;

    gVBoxAPI.UIMedium.GetState(hardDisk, &hddstate);
    if (hddstate == MediaState_Inaccessible)
        goto cleanup;

    gVBoxAPI.UIMedium.GetLocation(hardDisk, &hddLocationUtf16);
    if (!hddLocationUtf16)
        goto cleanup;

    VBOX_UTF16_TO_UTF8(hddLocationUtf16, &hddLocationUtf8);
    if (!hddLocationUtf8)
        goto cleanup;

    ignore_value(VIR_STRDUP(ret, hddLocationUtf8));

    VIR_DEBUG("Storage Volume Name: %s", vol->name);
    VIR_DEBUG("Storage Volume Path: %s", hddLocationUtf8);
    VIR_DEBUG("Storage Volume Pool: %s", vol->pool);

    VBOX_UTF8_FREE(hddLocationUtf8);

 cleanup:
    VBOX_UTF16_FREE(hddLocationUtf16);
    VBOX_MEDIUM_RELEASE(hardDisk);
    vboxIIDUnalloc(&hddIID);
    return ret;
}
예제 #4
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;
}
예제 #5
0
static int
vboxSocketParseAddrUtf16(vboxDriverPtr data, const PRUnichar *utf16,
                         virSocketAddrPtr addr)
{
    int result = -1;
    char *utf8 = NULL;

    VBOX_UTF16_TO_UTF8(utf16, &utf8);

    if (virSocketAddrParse(addr, utf8, AF_UNSPEC) < 0)
        goto cleanup;

    result = 0;

 cleanup:
    VBOX_UTF8_FREE(utf8);

    return result;
}
예제 #6
0
static char *vboxStorageVolGetXMLDesc(virStorageVolPtr vol, unsigned int flags)
{
    vboxDriverPtr data = vol->conn->privateData;
    IMedium *hardDisk = NULL;
    unsigned char uuid[VIR_UUID_BUFLEN];
    PRUnichar *hddFormatUtf16 = NULL;
    char *hddFormatUtf8 = NULL;
    PRUint64 hddLogicalSize = 0;
    PRUint64 hddActualSize = 0;
    virStoragePoolDef pool;
    virStorageVolDef def;
    vboxIID hddIID;
    PRUint32 hddstate;
    nsresult rc;
    char *ret = NULL;

    if (!data->vboxObj)
        return ret;

    virCheckFlags(0, NULL);

    memset(&pool, 0, sizeof(pool));
    memset(&def, 0, sizeof(def));

    if (virUUIDParse(vol->key, uuid) < 0) {
        virReportError(VIR_ERR_INVALID_ARG,
                       _("Could not parse UUID from '%s'"), vol->key);
        return ret;
    }

    VBOX_IID_INITIALIZE(&hddIID);
    vboxIIDFromUUID(&hddIID, uuid);
    rc = gVBoxAPI.UIVirtualBox.GetHardDiskByIID(data->vboxObj, &hddIID, &hardDisk);
    if (NS_FAILED(rc))
        goto cleanup;

    gVBoxAPI.UIMedium.GetState(hardDisk, &hddstate);
    if (hddstate == MediaState_Inaccessible)
        goto cleanup;

    /* 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.
     */
    pool.type = VIR_STORAGE_POOL_DIR;
    def.type = VIR_STORAGE_VOL_FILE;

    rc = gVBoxAPI.UIMedium.GetLogicalSize(hardDisk, &hddLogicalSize);
    if (NS_FAILED(rc))
        goto cleanup;

    def.target.capacity = hddLogicalSize;

    rc = gVBoxAPI.UIMedium.GetSize(hardDisk, &hddActualSize);
    if (NS_FAILED(rc))
        goto cleanup;

    if (VIR_STRDUP(def.name, vol->name) < 0)
        goto cleanup;

    if (VIR_STRDUP(def.key, vol->key) < 0)
        goto cleanup;

    rc = gVBoxAPI.UIMedium.GetFormat(hardDisk, &hddFormatUtf16);
    if (NS_FAILED(rc))
        goto cleanup;

    VBOX_UTF16_TO_UTF8(hddFormatUtf16, &hddFormatUtf8);
    if (!hddFormatUtf8)
        goto cleanup;

    VIR_DEBUG("Storage Volume Format: %s", hddFormatUtf8);

    if (STRCASEEQ("vmdk", hddFormatUtf8))
        def.target.format = VIR_STORAGE_FILE_VMDK;
    else if (STRCASEEQ("vhd", hddFormatUtf8))
        def.target.format = VIR_STORAGE_FILE_VPC;
    else if (STRCASEEQ("vdi", hddFormatUtf8))
        def.target.format = VIR_STORAGE_FILE_VDI;
    else
        def.target.format = VIR_STORAGE_FILE_RAW;
    ret = virStorageVolDefFormat(&pool, &def);

 cleanup:
    VBOX_UTF16_FREE(hddFormatUtf16);
    VBOX_UTF8_FREE(hddFormatUtf8);
    VBOX_MEDIUM_RELEASE(hardDisk);
    vboxIIDUnalloc(&hddIID);
    return ret;
}
예제 #7
0
static virStorageVolPtr
vboxStorageVolLookupByPath(virConnectPtr conn, const char *path)
{
    vboxDriverPtr data = conn->privateData;
    PRUnichar *hddPathUtf16 = NULL;
    IMedium *hardDisk = NULL;
    PRUnichar *hddNameUtf16 = NULL;
    char *hddNameUtf8 = NULL;
    unsigned char uuid[VIR_UUID_BUFLEN];
    char key[VIR_UUID_STRING_BUFLEN] = "";
    vboxIID hddIID;
    PRUint32 hddstate;
    nsresult rc;
    virStorageVolPtr ret = NULL;

    if (!data->vboxObj)
        return ret;

    VBOX_IID_INITIALIZE(&hddIID);

    if (!path)
        return ret;

    VBOX_UTF8_TO_UTF16(path, &hddPathUtf16);

    if (!hddPathUtf16)
        return ret;

    rc = gVBoxAPI.UIVirtualBox.FindHardDisk(data->vboxObj, hddPathUtf16,
                                            DeviceType_HardDisk, AccessMode_ReadWrite, &hardDisk);
    if (NS_FAILED(rc))
        goto cleanup;

    gVBoxAPI.UIMedium.GetState(hardDisk, &hddstate);
    if (hddstate == MediaState_Inaccessible)
        goto cleanup;

    gVBoxAPI.UIMedium.GetName(hardDisk, &hddNameUtf16);

    if (!hddNameUtf16)
        goto cleanup;

    VBOX_UTF16_TO_UTF8(hddNameUtf16, &hddNameUtf8);
    VBOX_UTF16_FREE(hddNameUtf16);

    if (!hddNameUtf8)
        goto cleanup;

    rc = gVBoxAPI.UIMedium.GetId(hardDisk, &hddIID);
    if (NS_FAILED(rc)) {
        VBOX_UTF8_FREE(hddNameUtf8);
        goto cleanup;
    }

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

    /* TODO: currently only one default pool and thus
     * the check below, change it when pools are supported
     */
    if (vboxConnectNumOfStoragePools(conn) == 1)
        ret = virGetStorageVol(conn, "default-pool", hddNameUtf8, key,
                               NULL, NULL);

    VIR_DEBUG("Storage Volume Pool: %s", "default-pool");
    VIR_DEBUG("Storage Volume Name: %s", hddNameUtf8);
    VIR_DEBUG("Storage Volume key : %s", key);

    vboxIIDUnalloc(&hddIID);
    VBOX_UTF8_FREE(hddNameUtf8);

 cleanup:
    VBOX_MEDIUM_RELEASE(hardDisk);
    VBOX_UTF16_FREE(hddPathUtf16);
    return ret;
}
예제 #8
0
static virStorageVolPtr
vboxStorageVolLookupByKey(virConnectPtr conn, const char *key)
{
    vboxDriverPtr data = conn->privateData;
    vboxIID hddIID;
    unsigned char uuid[VIR_UUID_BUFLEN];
    IMedium *hardDisk = NULL;
    PRUnichar *hddNameUtf16 = NULL;
    char *hddNameUtf8 = NULL;
    PRUint32 hddstate;
    nsresult rc;
    virStorageVolPtr ret = NULL;

    if (!data->vboxObj)
        return ret;

    VBOX_IID_INITIALIZE(&hddIID);
    if (!key)
        return ret;

    if (virUUIDParse(key, uuid) < 0) {
        virReportError(VIR_ERR_INVALID_ARG,
                       _("Could not parse UUID from '%s'"), key);
        return NULL;
    }

    vboxIIDFromUUID(&hddIID, uuid);
    rc = gVBoxAPI.UIVirtualBox.GetHardDiskByIID(data->vboxObj, &hddIID, &hardDisk);
    if (NS_FAILED(rc))
        goto cleanup;

    gVBoxAPI.UIMedium.GetState(hardDisk, &hddstate);
    if (hddstate == MediaState_Inaccessible)
        goto cleanup;

    gVBoxAPI.UIMedium.GetName(hardDisk, &hddNameUtf16);
    if (!hddNameUtf16)
        goto cleanup;

    VBOX_UTF16_TO_UTF8(hddNameUtf16, &hddNameUtf8);
    if (!hddNameUtf8) {
        VBOX_UTF16_FREE(hddNameUtf16);
        goto cleanup;
    }

    if (vboxConnectNumOfStoragePools(conn) == 1) {
        ret = virGetStorageVol(conn, "default-pool", hddNameUtf8, key,
                               NULL, NULL);
        VIR_DEBUG("Storage Volume Pool: %s", "default-pool");
    } else {
        /* TODO: currently only one default pool and thus
         * nothing here, change it when pools are supported
         */
    }

    VIR_DEBUG("Storage Volume Name: %s", key);
    VIR_DEBUG("Storage Volume key : %s", hddNameUtf8);

    VBOX_UTF8_FREE(hddNameUtf8);
    VBOX_UTF16_FREE(hddNameUtf16);

 cleanup:
    VBOX_MEDIUM_RELEASE(hardDisk);
    vboxIIDUnalloc(&hddIID);
    return ret;
}
예제 #9
0
static virStorageVolPtr
vboxStorageVolLookupByName(virStoragePoolPtr pool, const char *name)
{
    vboxDriverPtr data = pool->conn->privateData;
    vboxArray hardDisks = VBOX_ARRAY_INITIALIZER;
    nsresult rc;
    size_t i;
    virStorageVolPtr ret = NULL;

    if (!data->vboxObj)
        return ret;

    if (!name)
        return ret;

    rc = gVBoxAPI.UArray.vboxArrayGet(&hardDisks, data->vboxObj,
                                      gVBoxAPI.UArray.handleGetHardDisks(data->vboxObj));
    if (NS_FAILED(rc))
        return ret;

    for (i = 0; i < hardDisks.count; ++i) {
        IMedium *hardDisk = hardDisks.items[i];
        PRUint32 hddstate;
        char *nameUtf8 = NULL;
        PRUnichar *nameUtf16 = NULL;

        if (!hardDisk)
            continue;

        gVBoxAPI.UIMedium.GetState(hardDisk, &hddstate);
        if (hddstate == MediaState_Inaccessible)
            continue;

        gVBoxAPI.UIMedium.GetName(hardDisk, &nameUtf16);

        if (nameUtf16) {
            VBOX_UTF16_TO_UTF8(nameUtf16, &nameUtf8);
            VBOX_UTF16_FREE(nameUtf16);
        }

        if (nameUtf8 && STREQ(nameUtf8, name)) {
            vboxIID hddIID;
            unsigned char uuid[VIR_UUID_BUFLEN];
            char key[VIR_UUID_STRING_BUFLEN] = "";

            VBOX_IID_INITIALIZE(&hddIID);
            rc = gVBoxAPI.UIMedium.GetId(hardDisk, &hddIID);
            if (NS_SUCCEEDED(rc)) {
                vboxIIDToUUID(&hddIID, uuid);
                virUUIDFormat(uuid, key);

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

                VIR_DEBUG("virStorageVolPtr: %p", ret);
                VIR_DEBUG("Storage Volume Name: %s", name);
                VIR_DEBUG("Storage Volume key : %s", key);
                VIR_DEBUG("Storage Volume Pool: %s", pool->name);
            }

            vboxIIDUnalloc(&hddIID);
            VBOX_UTF8_FREE(nameUtf8);
            break;
        }

        VBOX_UTF8_FREE(nameUtf8);
    }

    gVBoxAPI.UArray.vboxArrayRelease(&hardDisks);

    return ret;
}
예제 #10
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;
}
예제 #11
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;
}