mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-24 14:45:24 +00:00
vz: implementation of attach/detach network devices
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.
This commit is contained in:
parent
366e31a6ef
commit
6de12b026b
@ -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"),
|
||||
|
127
src/vz/vz_sdk.c
127
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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user