Support nova commands interface-attach and interface-detach. For containers only. I use memcmp() to compare MAC addresses, because PrlVmDevNet_GetMacAddress() returns MAC as a UTF-8 encoded, null-terminated string. --- src/parallels/parallels_driver.c | 16 ++++ src/parallels/parallels_sdk.c | 144 +++++++++++++++++++++++++++++++++++++- src/parallels/parallels_sdk.h | 4 + 3 files changed, 161 insertions(+), 3 deletions(-) diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c index 706229d..0009127 100644 --- a/src/parallels/parallels_driver.c +++ b/src/parallels/parallels_driver.c @@ -1117,6 +1117,14 @@ static int parallelsDomainAttachDeviceFlags(virDomainPtr dom, const char *xml, goto cleanup; } break; + case VIR_DOMAIN_DEVICE_NET: + ret = prlsdkAttachNet(privdom, privconn, dev->data.net); + if (ret) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("network attach failed")); + goto cleanup; + } + break; default: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("device type '%s' cannot be attached"), @@ -1186,6 +1194,14 @@ static int parallelsDomainDetachDeviceFlags(virDomainPtr dom, const char *xml, goto cleanup; } break; + case VIR_DOMAIN_DEVICE_NET: + ret = prlsdkDetachNet(privdom, privconn, dev->data.net); + if (ret) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("network detach failed")); + goto cleanup; + } + break; default: virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("device type '%s' cannot be detached"), diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index 104c905..306f5e3 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -2815,6 +2815,12 @@ static int prlsdkAddNet(PRL_HANDLE sdkdom, pret = PrlVmDevNet_SetMacAddress(sdknet, macstr); prlsdkCheckRetGoto(pret, cleanup); + pret = PrlVmDevNet_SetConfigureWithDhcp(sdknet, true); + prlsdkCheckRetGoto(pret, cleanup); + + pret = PrlVmDevNet_SetAutoApply(sdknet, true); + prlsdkCheckRetGoto(pret, cleanup); + if (isCt) { if (net->model) VIR_WARN("Setting network adapter for containers is not " @@ -2885,14 +2891,15 @@ static int prlsdkAddNet(PRL_HANDLE sdkdom, return ret; } -static void prlsdkDelNet(parallelsConnPtr privconn, virDomainNetDefPtr net) +static int prlsdkDelNet(parallelsConnPtr privconn, virDomainNetDefPtr net) { + int ret = -1; PRL_RESULT pret; PRL_HANDLE vnet = PRL_INVALID_HANDLE; PRL_HANDLE job = PRL_INVALID_HANDLE; if (net->type != VIR_DOMAIN_NET_TYPE_BRIDGE) - return; + return 0; pret = PrlVirtNet_Create(&vnet); prlsdkCheckRetGoto(pret, cleanup); @@ -2900,12 +2907,142 @@ static void prlsdkDelNet(parallelsConnPtr privconn, virDomainNetDefPtr net) pret = PrlVirtNet_SetNetworkId(vnet, net->data.network.name); prlsdkCheckRetGoto(pret, cleanup); - PrlSrv_DeleteVirtualNetwork(privconn->server, vnet, 0); + job = PrlSrv_DeleteVirtualNetwork(privconn->server, vnet, 0); if (PRL_FAILED(pret = waitJob(job))) goto cleanup; + ret = 0; + cleanup: PrlHandle_Free(vnet); + return ret; +} + +int prlsdkAttachNet(virDomainObjPtr dom, parallelsConnPtr privconn, virDomainNetDefPtr net) +{ + int ret = -1; + parallelsDomObjPtr privdom = dom->privateData; + PRL_HANDLE job = PRL_INVALID_HANDLE; + + if (!IS_CT(dom->def)) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("network device cannot be attached")); + goto cleanup; + } + + job = PrlVm_BeginEdit(privdom->sdkdom); + if (PRL_FAILED(waitJob(job))) + goto cleanup; + + ret = prlsdkAddNet(privdom->sdkdom, privconn, net, IS_CT(dom->def)); + if (ret == 0) { + job = PrlVm_CommitEx(privdom->sdkdom, PVCF_DETACH_HDD_BUNDLE); + if (PRL_FAILED(waitJob(job))) { + ret = -1; + goto cleanup; + } + } + + cleanup: + return ret; +} + +static int +prlsdkGetNetIndex(PRL_HANDLE sdkdom, virDomainNetDefPtr net) +{ + int idx = -1; + PRL_RESULT pret; + PRL_UINT32 netCount; + PRL_UINT32 i; + PRL_HANDLE adapter = PRL_INVALID_HANDLE; + PRL_UINT32 len; + char adapterMac[PRL_MAC_STRING_BUFNAME]; + char netMac[PRL_MAC_STRING_BUFNAME]; + + prlsdkFormatMac(&net->mac, netMac); + pret = PrlVmCfg_GetNetAdaptersCount(sdkdom, &netCount); + prlsdkCheckRetGoto(pret, cleanup); + + for (i = 0; i < netCount; ++i) { + + pret = PrlVmCfg_GetNetAdapter(sdkdom, i, &adapter); + prlsdkCheckRetGoto(pret, cleanup); + + len = sizeof(adapterMac); + memset(adapterMac, 0, sizeof(adapterMac)); + pret = PrlVmDevNet_GetMacAddress(adapter, adapterMac, &len); + prlsdkCheckRetGoto(pret, cleanup); + + if (memcmp(adapterMac, netMac, PRL_MAC_STRING_BUFNAME)) { + + PrlHandle_Free(adapter); + adapter = PRL_INVALID_HANDLE; + continue; + } + + idx = i; + break; + } + + cleanup: + PrlHandle_Free(adapter); + return idx; +} + +static int prlsdkDelNetAdapter(PRL_HANDLE sdkdom, int idx) +{ + int ret = -1; + PRL_RESULT pret; + PRL_HANDLE sdknet = PRL_INVALID_HANDLE; + + pret = PrlVmCfg_GetNetAdapter(sdkdom, idx, &sdknet); + prlsdkCheckRetGoto(pret, cleanup); + + pret = PrlVmDev_Remove(sdknet); + prlsdkCheckRetGoto(pret, cleanup); + + ret = 0; + + cleanup: + PrlHandle_Free(sdknet); + return ret; +} + +int prlsdkDetachNet(virDomainObjPtr dom, parallelsConnPtr privconn, virDomainNetDefPtr net) +{ + int ret = -1, idx = -1; + parallelsDomObjPtr privdom = dom->privateData; + PRL_HANDLE job = PRL_INVALID_HANDLE; + + if (!IS_CT(dom->def)) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("network device cannot be detached")); + goto cleanup; + } + + idx = prlsdkGetNetIndex(privdom->sdkdom, net); + if (idx < 0) + goto cleanup; + + job = PrlVm_BeginEdit(privdom->sdkdom); + if (PRL_FAILED(waitJob(job))) + goto cleanup; + + ret = prlsdkDelNet(privconn, net); + if (ret != 0) + goto cleanup; + + ret = prlsdkDelNetAdapter(privdom->sdkdom, idx); + if (ret == 0) { + job = PrlVm_CommitEx(privdom->sdkdom, PVCF_DETACH_HDD_BUNDLE); + if (PRL_FAILED(waitJob(job))) { + ret = -1; + goto cleanup; + } + } + + cleanup: + return ret; } static int prlsdkDelDisk(PRL_HANDLE sdkdom, int idx) @@ -3150,6 +3287,7 @@ prlsdkGetDiskIndex(PRL_HANDLE sdkdom, virDomainDiskDefPtr disk) pret = PrlVmCfg_GetHardDisk(sdkdom, i, &hdd); prlsdkCheckRetGoto(pret, cleanup); + buflen = 0; pret = PrlVmDev_GetFriendlyName(hdd, 0, &buflen); prlsdkCheckRetGoto(pret, cleanup); diff --git a/src/parallels/parallels_sdk.h b/src/parallels/parallels_sdk.h index afa6745..6708fd4 100644 --- a/src/parallels/parallels_sdk.h +++ b/src/parallels/parallels_sdk.h @@ -66,3 +66,7 @@ int prlsdkDetachVolume(virDomainObjPtr dom, virDomainDiskDefPtr disk); int prlsdkGetBlockStats(virDomainObjPtr dom, virDomainDiskDefPtr disk, virDomainBlockStatsPtr stats); +int +prlsdkAttachNet(virDomainObjPtr dom, parallelsConnPtr privconn, virDomainNetDefPtr net); +int +prlsdkDetachNet(virDomainObjPtr dom, parallelsConnPtr privconn, virDomainNetDefPtr net); -- 1.7.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list