diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c index cef3c7714e97454a23d2f870380faa2771dcf92a..d9ddd4f53552b9ae0ddcaeb88777d0ff7ff8fe89 100644 --- a/src/vz/vz_driver.c +++ b/src/vz/vz_driver.c @@ -1117,6 +1117,14 @@ static int vzDomainAttachDeviceFlags(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 vzDomainDetachDeviceFlags(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/vz/vz_sdk.c b/src/vz/vz_sdk.c index 98f7a57cefdbb12cdfa07d87fd2a1214488057c7..dea6e37990777c544fa4cbf7a270b0a3358432fd 100644 --- a/src/vz/vz_sdk.c +++ b/src/vz/vz_sdk.c @@ -2908,6 +2908,133 @@ static void prlsdkDelNet(vzConnPtr 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")); + return ret; + } + + job = PrlVm_BeginEdit(privdom->sdkdom); + if (PRL_FAILED(waitJob(job))) + return ret; + + 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))) { + return -1; + } + } + + return ret; +} + +static int +prlsdkGetNetIndex(PRL_HANDLE sdkdom, virDomainNetDefPtr net) +{ + int idx = -1; + PRL_RESULT pret; + PRL_UINT32 adaptersCount; + PRL_UINT32 i; + PRL_HANDLE adapter = PRL_INVALID_HANDLE; + PRL_UINT32 len; + char adapterMac[PRL_MAC_STRING_BUFNAME]; + char expectedMac[PRL_MAC_STRING_BUFNAME]; + + prlsdkFormatMac(&net->mac, expectedMac); + pret = PrlVmCfg_GetNetAdaptersCount(sdkdom, &adaptersCount); + prlsdkCheckRetGoto(pret, cleanup); + + for (i = 0; i < adaptersCount; ++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, expectedMac, 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")); + return ret; + } + + job = PrlVm_BeginEdit(privdom->sdkdom); + if (PRL_FAILED(waitJob(job))) + return ret; + + idx = prlsdkGetNetIndex(privdom->sdkdom, net); + if (idx < 0) + return ret; + + ret = prlsdkDelNet(privconn, net); + if (ret != 0) + return ret; + + ret = prlsdkDelNetAdapter(privdom->sdkdom, idx); + if (ret == 0) { + job = PrlVm_CommitEx(privdom->sdkdom, PVCF_DETACH_HDD_BUNDLE); + if (PRL_FAILED(waitJob(job))) { + return -1; + } + } + + return ret; +} + static int prlsdkDelDisk(PRL_HANDLE sdkdom, int idx) { int ret = -1; diff --git a/src/vz/vz_sdk.h b/src/vz/vz_sdk.h index dd4fecfef78a1a744fd7d196215fb564a82afc50..cde8904789e429cc7acab6b593a5032489d0d126 100644 --- a/src/vz/vz_sdk.h +++ b/src/vz/vz_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);