[libvirt] [PATCH] parallels: implement attach/detach network.
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,
[libvirt] [PATCH] parallels: implement attach/detach network.
Support nova commands interface-attach and interface-detach. For containers only. --- 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 e385f3d..a49a030 100644 --- a/src/parallels/parallels_driver.c +++ b/src/parallels/parallels_driver.c @@ -1050,6 +1050,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), @@ -1133,6 +1141,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 6e293f7..a1c9131 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -2751,6 +2751,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 @@ -2821,14 +2827,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); @@ -2836,12 +2843,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)) { + +