[libvirt] [PATCH] parallels: implement attach/detach network.

2015-06-11 Thread Mikhail Feoktistov
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.

2015-06-04 Thread Mikhail Feoktistov
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)) {
+
+