[libvirt] [PATCH 0/4] parallels: Implementation of attach/detach network devices and small network fixes

Mikhail Feoktistov (4): parallels: Fix initialization of buflen variable in each loop iteration parallels: Fix false error messages in libvirt log parallels: Switch on DHCP for newly created network adapters parallels: implementation of attach/detach network devices

We need to initialize buflen every time when we get network adapter's friendly name because we call PrlVmDev_GetFriendlyName in a loop --- src/parallels/parallels_sdk.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index 104c905..d27bac9 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -3150,6 +3150,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); -- 1.7.1

There was many errors in libvirt.log caused by prlsdkDelNet function because job variable was always initialized as PRL_INVALID_HANDLE In this patch job variable gets return value of PrlSrv_DeleteVirtualNetwork function() --- src/parallels/parallels_sdk.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index d27bac9..1d982c5 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -2900,7 +2900,7 @@ 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; -- 1.7.1

Let network adapter use DHCP server to get network configuration. To do this we use PrlVmDevNet_SetConfigureWithDhcp to enable it and PrlVmDevNet_SetAutoApply to makes necessary settings within guest OS In linux case it creates network startup scripts /etc/sysconfig/network-scripts/ifcfg-ethN and fills it with necessary parameters. --- src/parallels/parallels_sdk.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index 1d982c5..4c3d1eb 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 " -- 1.7.1

In this patch we add VIR_DOMAIN_DEVICE_NET handlers implementation for domainAttachDevice and domainDetachDevice callbacks. As soon as we don't support this operation for hypervisor type domains, we implement this functionality for containers only. In detach procedure we find network device by MAC address. Because PrlVmDevNet_GetMacAddress() returns MAC as a UTF-8 encoded null-terminated string, we use memcmp() to compare it. Also we remove corresponding virtual network by prlsdkDelNetAdapter call. --- src/parallels/parallels_driver.c | 16 +++++ src/parallels/parallels_sdk.c | 127 ++++++++++++++++++++++++++++++++++++++ src/parallels/parallels_sdk.h | 4 + 3 files changed, 147 insertions(+), 0 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 4c3d1eb..8fec34c 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -2914,6 +2914,133 @@ static void prlsdkDelNet(parallelsConnPtr privconn, virDomainNetDefPtr net) PrlHandle_Free(vnet); } +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) { int ret = -1; 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
participants (1)
-
Mikhail Feoktistov