You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ra...@apache.org on 2014/05/05 09:35:40 UTC

[2/2] git commit: updated refs/heads/4.4-forward to cf41cca

CLOUDSTACK-6518 [Hyper-V] Efficient way of finding the empty nic in VR/VpcVR to configure VPC entities


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/cf41ccaa
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/cf41ccaa
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/cf41ccaa

Branch: refs/heads/4.4-forward
Commit: cf41ccaa5b6475dace0bddbe6681c98cc5149189
Parents: 6cd1c7a
Author: Rajesh Battala <ra...@citrix.com>
Authored: Mon May 5 12:55:59 2014 +0530
Committer: Rajesh Battala <ra...@citrix.com>
Committed: Mon May 5 12:59:24 2014 +0530

----------------------------------------------------------------------
 .../com/cloud/agent/api/GetVmConfigAnswer.java  |   7 +-
 .../agent/api/ModifyVmNicConfigCommand.java     |  17 ++
 .../HypervResource/CloudStackTypes.cs           |  13 +-
 .../HypervResource/HypervResourceController.cs  |  66 +++--
 .../HypervResource/IWmiCallsV2.cs               |   6 +-
 .../ServerResource/HypervResource/WmiCallsV2.cs | 291 ++++++++++++++++---
 .../resource/HypervDirectConnectResource.java   |  51 +++-
 7 files changed, 364 insertions(+), 87 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cf41ccaa/core/src/com/cloud/agent/api/GetVmConfigAnswer.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/GetVmConfigAnswer.java b/core/src/com/cloud/agent/api/GetVmConfigAnswer.java
index 46e003e..e0d1536 100644
--- a/core/src/com/cloud/agent/api/GetVmConfigAnswer.java
+++ b/core/src/com/cloud/agent/api/GetVmConfigAnswer.java
@@ -42,13 +42,15 @@ public class GetVmConfigAnswer extends Answer {
     public class NicDetails {
         String macAddress;
         int vlanid;
+        boolean state;
 
         public NicDetails() {
         }
 
-        public NicDetails(String macAddress, int vlanid) {
+        public NicDetails(String macAddress, int vlanid, boolean state) {
             this.macAddress = macAddress;
             this.vlanid = vlanid;
+            this.state = state;
         }
 
         public String getMacAddress() {
@@ -59,6 +61,9 @@ public class GetVmConfigAnswer extends Answer {
             return vlanid;
         }
 
+        public boolean getState() {
+            return state;
+        }
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cf41ccaa/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java b/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java
index 5f4f0e1..54c0eb0 100644
--- a/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java
+++ b/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java
@@ -22,6 +22,9 @@ public class ModifyVmNicConfigCommand extends Command {
     int vlan;
     String macAddress;
     int index;
+    boolean enable;
+    String switchLableName;
+
     protected ModifyVmNicConfigCommand() {
     }
 
@@ -37,10 +40,24 @@ public class ModifyVmNicConfigCommand extends Command {
         this.index = position;
     }
 
+    public ModifyVmNicConfigCommand(String vmName, int vlan, int position, boolean enable) {
+        this.vmName = vmName;
+        this.vlan = vlan;
+        this.index = position;
+        this.enable = enable;
+    }
+
     public String getVmName() {
         return vmName;
     }
 
+    public String getSwitchLableName() {
+        return switchLableName;
+    }
+
+    public void setSwitchLableName(String switchlableName) {
+        this.switchLableName = switchlableName;
+    }
 
     @Override
     public boolean executeInSequence() {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cf41ccaa/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
index f7bed71..4516191 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
@@ -717,11 +717,22 @@ namespace HypervResource
         public string macaddress;
         [JsonProperty("vlanid")]
         public int vlanid;
+        [JsonProperty("state")]
+        public bool state;
         public NicDetails() { }
-        public NicDetails(String macaddress, int vlanid)
+        public NicDetails(String macaddress, int vlanid, int enabledState)
         {
             this.macaddress = macaddress;
             this.vlanid = vlanid;
+            if (enabledState == 2)
+            {
+                this.state = true;
+            }
+            else
+            {
+                this.state = false;
+            }
+
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cf41ccaa/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
index c28cb66..37f5f53 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
@@ -1077,11 +1077,10 @@ namespace HypervResource
             using (log4net.NDC.Push(Guid.NewGuid().ToString()))
             {
                 logger.Info(CloudStackTypes.PlugNicCommand + Utils.CleanString(cmd.ToString()));
-
                 object ansContent = new
                 {
                     result = true,
-                    details = "instead of plug, change he network settings",
+                    details = "Hot Nic plug not supported, change any empty virtual network adapter network settings",
                     contextMap = contextMap
                 };
                 return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.PlugNicAnswer);
@@ -1394,18 +1393,21 @@ namespace HypervResource
                 logger.Info(CloudStackTypes.ModifyVmNicConfigCommand + Utils.CleanString(cmd.ToString()));
                 bool result = false;
                 String vmName = cmd.vmName;
-                uint vlan = (uint)cmd.vlan;
+                String vlan = cmd.vlan;
                 string macAddress = cmd.macAddress;
-                uint pos = cmd.index;
+                uint pos = cmd.index;
+                bool enable = cmd.enable;
+                string switchLableName = cmd.switchLableName;
                 if (macAddress != null)
                 {
-                    wmiCallsV2.ModifyVmVLan(vmName, vlan, macAddress);
-                }
-                else if (pos > 1)
-                {
-                    wmiCallsV2.ModifyVmVLan(vmName, vlan, pos);
+                    wmiCallsV2.ModifyVmVLan(vmName, vlan, macAddress);
+                    result = true;
                 }
+                else if (pos >= 1)
+                {
+                    wmiCallsV2.ModifyVmVLan(vmName, vlan, pos, enable, switchLableName);
                     result = true;
+                }
 
                 object ansContent = new
                 {
@@ -1432,31 +1434,37 @@ namespace HypervResource
                 List<NicDetails> nicDetails = new List<NicDetails>();
                 var nicSettingsViaVm = wmiCallsV2.GetEthernetPortSettings(vm);
                 NicDetails nic = null;
-                String[] macAddress = new String[nicSettingsViaVm.Length];
-                int index = 0;
-                foreach (SyntheticEthernetPortSettingData item in nicSettingsViaVm)
-                {
-                    macAddress[index++] = item.Address;
-                }
-
+                int index = 0;
+                int[] nicStates = new int[8];
+                int[] nicVlan = new int[8];
+                int vlanid = 1;
+
+                var ethernetConnections = wmiCallsV2.GetEthernetConnections(vm);
+                foreach (EthernetPortAllocationSettingData item in ethernetConnections)
+                {
+                    EthernetSwitchPortVlanSettingData vlanSettings = wmiCallsV2.GetVlanSettings(item);
+                    if (vlanSettings == null)
+                    {
+                        vlanid = -1;
+                    }
+                    else
+                    {
+                        vlanid = vlanSettings.AccessVlanId;
+                    }
+                    nicStates[index] = (Int32)(item.EnabledState);
+                    nicVlan[index] = vlanid;
+                    index++;
+                }
+
                 index = 0;
-                var ethernetConnections = wmiCallsV2.GetEthernetConnections(vm);
-                int vlanid = 1;
-                foreach (EthernetPortAllocationSettingData item in ethernetConnections)
+                foreach (SyntheticEthernetPortSettingData item in nicSettingsViaVm)
                 {
-                    EthernetSwitchPortVlanSettingData vlanSettings = wmiCallsV2.GetVlanSettings(item);
-                    if (vlanSettings == null)
-                    {
-                        vlanid = -1;
-                    }
-                    else
-                    {
-                        vlanid = vlanSettings.AccessVlanId;
-                    }
-                    nic = new NicDetails(macAddress[index++], vlanid);
+                    nic = new NicDetails(item.Address, nicVlan[index], nicStates[index]);
+                    index++;
                     nicDetails.Add(nic);
                 }
 
+
                 result = true;
 
                 object ansContent = new

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cf41ccaa/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs
index c5e5bf3..6873198 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs
@@ -70,7 +70,9 @@ namespace HypervResource
         void SetState(ComputerSystem vm, ushort requiredState);
         Dictionary<String, VmState> GetVmSync(String privateIpAddress);
         string GetVmNote(System.Management.ManagementPath sysPath);
-        void ModifyVmVLan(string vmName, uint vlanid, string mac);
-        void ModifyVmVLan(string vmName, uint vlanid, uint pos);
+        void ModifyVmVLan(string vmName, String vlanid, string mac);
+        void ModifyVmVLan(string vmName, String vlanid, uint pos, bool enable, string switchLabelName);
+        void DisableVmNics();
+        void DisableNicVlan(String mac, String vmName);
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cf41ccaa/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
index 71d8cbd..fb14a0f 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
@@ -229,7 +229,6 @@ namespace HypervResource
             string errMsg = vmName;
             var diskDrives = vmInfo.disks;
             var bootArgs = vmInfo.bootArgs;
-            string defaultvlan = "4094"; 
 
             // assert
             errMsg = vmName + ": missing disk information, array empty or missing, agent expects *at least* one disk for a VM";
@@ -380,6 +379,8 @@ namespace HypervResource
             }
 
             int nicCount = 0;
+            int enableState = 2;
+
             // Add the Nics to the VM in the deviceId order.
             foreach (var nc in nicInfo)
             {
@@ -418,13 +419,17 @@ namespace HypervResource
                             throw ex;
                         }
                     }
-                    if(nicIp.Equals("0.0.0.0") && nicNetmask.Equals("255.255.255.255") ) {
-                        // this is the extra nic added to VR.
-                        vlan = defaultvlan;
-                    }
-
+
+
                     if (nicid == nicCount)
                     {
+                        if (nicIp.Equals("0.0.0.0") && nicNetmask.Equals("255.255.255.255"))
+                        {
+                            // this is the extra nic added to VR.
+                            vlan = null;
+                            enableState = 3;
+                        }
+
                         // Create network adapter
                         var newAdapter = CreateNICforVm(newVm, mac);
                         String switchName ="";
@@ -432,10 +437,11 @@ namespace HypervResource
                         {
                             switchName =  nic.name;
                         }
-
+                        EthernetPortAllocationSettingData portSettings = null;
                         // connection to vswitch
-                        var portSettings = AttachNicToPort(newVm, newAdapter, switchName);
-
+                        portSettings = AttachNicToPort(newVm, newAdapter, switchName, enableState);
+                        //reset the flag for other nics
+                        enableState = 2;
                         // set vlan
                         if (vlan != null)
                         {
@@ -449,6 +455,8 @@ namespace HypervResource
 
                         logger.DebugFormat("Created adapter {0} on port {1}, {2}", 
                             newAdapter.Path, portSettings.Path, (vlan == null ? "No VLAN" : "VLAN " + vlan));
+                     //   logger.DebugFormat("Created adapter {0} on port {1}, {2}", 
+                    //       newAdapter.Path, portSettings.Path, (vlan == null ? "No VLAN" : "VLAN " + vlan));
                     }
                 }
                 nicCount++;
@@ -464,14 +472,8 @@ namespace HypervResource
                
                 String bootargs = bootArgs;
                 AddUserData(vm, bootargs);
-
-                // Verify key added to subsystem
-                //kvpInfo = GetKvpSettings(vmSettings);
-
-                // HostExchangesItems are embedded objects in the sense that the object value is stored and not a reference to the object.
-                //kvpProps = kvpInfo.HostExchangeItems;
-
             }
+
             // call patch systemvm iso only for systemvms
             if (vmName.StartsWith("r-") || vmName.StartsWith("s-") || vmName.StartsWith("v-"))
             {
@@ -524,7 +526,7 @@ namespace HypervResource
             return false;
         }
 
-        private EthernetPortAllocationSettingData AttachNicToPort(ComputerSystem newVm, SyntheticEthernetPortSettingData newAdapter, String vSwitchName)
+        private EthernetPortAllocationSettingData AttachNicToPort(ComputerSystem newVm, SyntheticEthernetPortSettingData newAdapter, String vSwitchName, int enableState)
         {
             // Get the virtual switch
             VirtualEthernetSwitch vSwitch = GetExternalVirtSwitch(vSwitchName);
@@ -553,7 +555,7 @@ namespace HypervResource
             var newEthernetPortSettings = new EthernetPortAllocationSettingData((ManagementBaseObject)defaultEthernetPortSettingsObj.LateBoundObject.Clone());
             newEthernetPortSettings.LateBoundObject["Parent"] = newAdapter.Path.Path;
             newEthernetPortSettings.LateBoundObject["HostResource"] = new string[] { vSwitch.Path.Path };
-
+            newEthernetPortSettings.LateBoundObject["EnabledState"] = enableState; //3 disabled 2 Enabled
             // Insert NIC into vm
             string[] newResources = new string[] { newEthernetPortSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20) };
             ManagementPath[] newResourcePaths = AddVirtualResource(newResources, newVm);
@@ -913,13 +915,16 @@ namespace HypervResource
             return new ResourceAllocationSettingData((ManagementBaseObject)defaultDiskDriveSettings.LateBoundObject.Clone());
         }
 
-        // Modify the systemvm nic's VLAN id
-        public void ModifyVmVLan(string vmName, uint vlanid, String mac)
-        {
+        // Modify the systemvm nic's VLAN id
+        public void ModifyVmVLan(string vmName, String vlanid, String mac)
+        {
+            int enableState = 2;
+            bool enable = true;
             ComputerSystem vm = GetComputerSystem(vmName);
             SyntheticEthernetPortSettingData[] nicSettingsViaVm = GetEthernetPortSettings(vm);
             // Obtain controller for Hyper-V virtualisation subsystem
-            VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService();
+            VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService();
+            EthernetPortAllocationSettingData networkAdapter = null;
             string normalisedMAC = string.Join("", (mac.Split(new char[] { ':' })));
             int index = 0;
             foreach (SyntheticEthernetPortSettingData item in nicSettingsViaVm)
@@ -929,35 +934,229 @@ namespace HypervResource
                     break;
                 }
                 index++;
-            }
-
-            //TODO: make sure the index wont be out of range.
-
-            EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm);
-            EthernetSwitchPortVlanSettingData vlanSettings = GetVlanSettings(ethernetConnections[index]);
+            }
+            String vSwitchName = "";
+            VirtualEthernetSwitch vSwitch = GetExternalVirtSwitch(vSwitchName);
+            EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm);
+            networkAdapter = ethernetConnections[index];
+            networkAdapter.LateBoundObject["EnabledState"] = enableState; //3 disabled 2 Enabled
+            networkAdapter.LateBoundObject["HostResource"] = new string[] { vSwitch.Path.Path };
+
+            ModifyVmResources(vmMgmtSvc, vm, new String[] {
+                networkAdapter.LateBoundObject.GetText(TextFormat.CimDtd20)
+                });
 
-            //Assign configuration to new NIC
-            vlanSettings.LateBoundObject["AccessVlanId"] = vlanid;
-            vlanSettings.LateBoundObject["OperationMode"] = 1;
-            ModifyFeatureVmResources(vmMgmtSvc, vm, new String[] {
-                vlanSettings.LateBoundObject.GetText(TextFormat.CimDtd20)});
+            EthernetSwitchPortVlanSettingData vlanSettings = GetVlanSettings(ethernetConnections[index]);
+
+            if (vlanSettings == null)
+            {
+                // when modifying  nic to not connected dont create vlan
+                if (enable)
+                {
+                    if (vlanid != null)
+                    {
+                        SetPortVlan(vlanid, networkAdapter);
+                    }
+                }
+            }
+            else
+            {
+                if (enable)
+                {
+                    if (vlanid != null)
+                    {
+                        //Assign vlan configuration to nic
+                        vlanSettings.LateBoundObject["AccessVlanId"] = vlanid;
+                        vlanSettings.LateBoundObject["OperationMode"] = 1;
+                        ModifyFeatureVmResources(vmMgmtSvc, vm, new String[] {
+                            vlanSettings.LateBoundObject.GetText(TextFormat.CimDtd20)});
+                    }
+                }
+                else
+                {
+                    var virtSysMgmtSvc = GetVirtualisationSystemManagementService();
+
+                    // This method will remove the vlan settings present on the Nic
+                    ManagementPath jobPath;
+                    var ret_val = virtSysMgmtSvc.RemoveFeatureSettings(new ManagementPath[] { vlanSettings.Path },
+                        out jobPath);
+
+                    // If the Job is done asynchronously
+                    if (ret_val == ReturnCode.Started)
+                    {
+                        JobCompleted(jobPath);
+                    }
+                    else if (ret_val != ReturnCode.Completed)
+                    {
+                        var errMsg = string.Format(
+                            "Failed to remove vlan resource {0} from VM {1} (GUID {2}) due to {3}",
+                            vlanSettings.Path,
+                            vm.ElementName,
+                            vm.Name,
+                            ReturnCode.ToString(ret_val));
+                        var ex = new WmiException(errMsg);
+                        logger.Error(errMsg, ex);
+                    }
+                }
+            }
+        }
+
+        // This is disabling the VLAN settings on the specified nic. It works Awesome.
+        public void DisableNicVlan(String mac, String vmName)
+        {
+            ComputerSystem vm = GetComputerSystem(vmName);
+            SyntheticEthernetPortSettingData[] nicSettingsViaVm = GetEthernetPortSettings(vm);
+            // Obtain controller for Hyper-V virtualisation subsystem
+            VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService();
+            string normalisedMAC = string.Join("", (mac.Split(new char[] { ':' })));
+            int index = 0;
+            foreach (SyntheticEthernetPortSettingData item in nicSettingsViaVm)
+            {
+                if (normalisedMAC.ToLower().Equals(item.Address.ToLower()))
+                {
+                    break;
+                }
+                index++;
+            }
+
+            //TODO: make sure the index wont be out of range.
+
+            EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm);
+            EthernetSwitchPortVlanSettingData vlanSettings = GetVlanSettings(ethernetConnections[index]);
+
+            var virtSysMgmtSvc = GetVirtualisationSystemManagementService();
+
+            // This method will remove the vlan settings present on the Nic
+            ManagementPath jobPath;
+            var ret_val = virtSysMgmtSvc.RemoveFeatureSettings(new ManagementPath[]{ vlanSettings.Path},
+                out jobPath);
+
+            // If the Job is done asynchronously
+            if (ret_val == ReturnCode.Started)
+            {
+                JobCompleted(jobPath);
+            }
+            else if (ret_val != ReturnCode.Completed)
+            {
+                var errMsg = string.Format(
+                    "Failed to remove vlan resource {0} from VM {1} (GUID {2}) due to {3}",
+                    vlanSettings.Path,
+                    vm.ElementName,
+                    vm.Name,
+                    ReturnCode.ToString(ret_val));
+                var ex = new WmiException(errMsg);
+                logger.Error(errMsg, ex);
+                throw ex;
+            }
         }
 
-        // Modify the systemvm nic's VLAN id
-        public void ModifyVmVLan(string vmName, uint vlanid, uint pos)
-        {
-            ComputerSystem vm = GetComputerSystem(vmName);
-            // Obtain controller for Hyper-V virtualisation subsystem
-            VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService();
+        // Modify All VM Nics to disable
+        public void DisableVmNics()
+        {
+            ComputerSystem vm = GetComputerSystem("test");
+            EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm);
+            // Get the virtual switch
+            VirtualEthernetSwitch vSwitch = GetExternalVirtSwitch("vswitch2");
+
+            foreach (EthernetPortAllocationSettingData epasd in ethernetConnections)
+            {
+                epasd.LateBoundObject["EnabledState"] = 2; //3 disabled 2 Enabled
+                epasd.LateBoundObject["HostResource"] = new string[] { vSwitch.Path.Path };
+
+                VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService();
+                ModifyVmResources(vmMgmtSvc, vm, new String[] {
+                epasd.LateBoundObject.GetText(TextFormat.CimDtd20)
+                });
+            }
+        }
 
-            EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm);
-            EthernetSwitchPortVlanSettingData vlanSettings = GetVlanSettings(ethernetConnections[pos]);
+        // Modify the systemvm nic's VLAN id
+        public void ModifyVmVLan(string vmName, String vlanid, uint pos, bool enable, string switchLabelName)
+        {
+            // This if to modify the VPC VR nics
+            // 1. Enable the network adapter and connect to a switch
+            // 2. modify the vlan id
+            int enableState = 2;
+            ComputerSystem vm = GetComputerSystem(vmName);
+                EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm);
+            // Obtain controller for Hyper-V virtualisation subsystem
+            EthernetPortAllocationSettingData networkAdapter = null;
+            VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService();
+
+            String vSwitchName = "";
+            if (switchLabelName != null)
+                vSwitchName = switchLabelName;
+            VirtualEthernetSwitch vSwitch = GetExternalVirtSwitch(vSwitchName);
+            if (pos <= ethernetConnections.Length)
+            {
+                if (enable == false)
+                {
+                    enableState = 3;
+                }
+
+                networkAdapter = ethernetConnections[pos];
+                networkAdapter.LateBoundObject["EnabledState"] = enableState; //3 disabled 2 Enabled
+                networkAdapter.LateBoundObject["HostResource"] = new string[] { vSwitch.Path.Path };
+                ModifyVmResources(vmMgmtSvc, vm, new String[] {
+                networkAdapter.LateBoundObject.GetText(TextFormat.CimDtd20)
+                });
+            }
 
-            //Assign configuration to new NIC
-            vlanSettings.LateBoundObject["AccessVlanId"] = vlanid;
-            vlanSettings.LateBoundObject["OperationMode"] = 1;
-            ModifyFeatureVmResources(vmMgmtSvc, vm, new String[] {
-                vlanSettings.LateBoundObject.GetText(TextFormat.CimDtd20)});
+            // check when nic is disabled, removing vlan is required or not.
+            EthernetPortAllocationSettingData[] vmEthernetConnections = GetEthernetConnections(vm);
+            EthernetSwitchPortVlanSettingData vlanSettings = GetVlanSettings(vmEthernetConnections[pos]);
+
+            if (vlanSettings == null)
+            {
+                // when modifying  nic to not connected dont create vlan
+                if (enable)
+                {
+                    if (vlanid != null)
+                    {
+                        SetPortVlan(vlanid, networkAdapter);
+                    }
+                }
+            }
+            else
+            {
+                if (enable)
+                {
+                    if (vlanid != null)
+                    {
+                        //Assign vlan configuration to nic
+                        vlanSettings.LateBoundObject["AccessVlanId"] = vlanid;
+                        vlanSettings.LateBoundObject["OperationMode"] = 1;
+                        ModifyFeatureVmResources(vmMgmtSvc, vm, new String[] {
+                            vlanSettings.LateBoundObject.GetText(TextFormat.CimDtd20)});
+                    }
+                }
+                else
+                {
+                    var virtSysMgmtSvc = GetVirtualisationSystemManagementService();
+
+                    // This method will remove the vlan settings present on the Nic
+                    ManagementPath jobPath;
+                    var ret_val = virtSysMgmtSvc.RemoveFeatureSettings(new ManagementPath[] { vlanSettings.Path },
+                        out jobPath);
+
+                    // If the Job is done asynchronously
+                    if (ret_val == ReturnCode.Started)
+                    {
+                        JobCompleted(jobPath);
+                    }
+                    else if (ret_val != ReturnCode.Completed)
+                    {
+                        var errMsg = string.Format(
+                            "Failed to remove vlan resource {0} from VM {1} (GUID {2}) due to {3}",
+                            vlanSettings.Path,
+                            vm.ElementName,
+                            vm.Name,
+                            ReturnCode.ToString(ret_val));
+                        var ex = new WmiException(errMsg);
+                        logger.Error(errMsg, ex);
+                    }
+                }
+            }
         }
 
         public void AttachIso(string displayName, string iso)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cf41ccaa/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
index 12fc39d..7888e43 100644
--- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
+++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
@@ -177,7 +177,6 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
     protected final int _retry = 24;
     protected final int _sleep = 10000;
     protected static final int DEFAULT_DOMR_SSHPORT = 3922;
-    private final int maxid = 4094;
     private String _clusterGuid;
 
     // Used by initialize to assert object configured before
@@ -535,11 +534,15 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
             }
             int vlanId = Integer.parseInt(BroadcastDomainType.getValue(broadcastUri));
             int publicNicInfo = -1;
-            publicNicInfo = getVmNics(vmName, maxid);
+            publicNicInfo = getVmFreeNicIndex(vmName);
             if (publicNicInfo > 0) {
-                modifyNicVlan(vmName, vlanId, publicNicInfo);
+                modifyNicVlan(vmName, vlanId, publicNicInfo, true, cmd.getNic().getName());
+                return new PlugNicAnswer(cmd, true, "success");
             }
-            return new PlugNicAnswer(cmd, true, "success");
+            String msg = " Plug Nic failed for the vm as it has reached max limit of NICs to be added";
+            s_logger.warn(msg);
+            return new PlugNicAnswer(cmd, false, msg);
+
         } catch (Exception e) {
             s_logger.error("Unexpected exception: ", e);
             return new PlugNicAnswer(cmd, false, "Unable to execute PlugNicCommand due to " + e.toString());
@@ -563,7 +566,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
             int publicNicInfo = -1;
             publicNicInfo = getVmNics(vmName, vlanId);
             if (publicNicInfo > 0) {
-                modifyNicVlan(vmName, maxid, publicNicInfo);
+                modifyNicVlan(vmName, 2, publicNicInfo, false, "");
             }
             return new UnPlugNicAnswer(cmd, true, "success");
         } catch (Exception e) {
@@ -1765,6 +1768,37 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
         return new IpAssocAnswer(cmd, results);
     }
 
+
+    protected int getVmFreeNicIndex(String vmName) {
+        GetVmConfigCommand vmConfig = new GetVmConfigCommand(vmName);
+        URI agentUri = null;
+        int nicposition = -1;
+        try {
+            String cmdName = GetVmConfigCommand.class.getName();
+            agentUri =
+                    new URI("https", null, _agentIp, _port,
+                            "/api/HypervResource/" + cmdName, null, null);
+        } catch (URISyntaxException e) {
+            String errMsg = "Could not generate URI for Hyper-V agent";
+            s_logger.error(errMsg, e);
+        }
+        String ansStr = postHttpRequest(s_gson.toJson(vmConfig), agentUri);
+        Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
+        s_logger.debug("GetVmConfigCommand response received "
+                + s_gson.toJson(result));
+        if (result.length > 0) {
+            GetVmConfigAnswer ans = ((GetVmConfigAnswer)result[0]);
+            List<NicDetails> nics = ans.getNics();
+            for (NicDetails nic : nics) {
+                if (nic.getState() == false) {
+                    nicposition = nics.indexOf(nic);
+                    break;
+                }
+            }
+        }
+        return nicposition;
+    }
+
     protected int getVmNics(String vmName, int vlanid) {
         GetVmConfigCommand vmConfig = new GetVmConfigCommand(vmName);
         URI agentUri = null;
@@ -1816,8 +1850,9 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
         }
     }
 
-    protected void modifyNicVlan(String vmName, int vlanId, int pos) {
-        ModifyVmNicConfigCommand modifynic = new ModifyVmNicConfigCommand(vmName, vlanId, pos);
+    protected void modifyNicVlan(String vmName, int vlanId, int pos, boolean enable, String switchLabelName) {
+        ModifyVmNicConfigCommand modifyNic = new ModifyVmNicConfigCommand(vmName, vlanId, pos, enable);
+        modifyNic.setSwitchLableName(switchLabelName);
         URI agentUri = null;
         try {
             String cmdName = ModifyVmNicConfigCommand.class.getName();
@@ -1828,7 +1863,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
             String errMsg = "Could not generate URI for Hyper-V agent";
             s_logger.error(errMsg, e);
         }
-        String ansStr = postHttpRequest(s_gson.toJson(modifynic), agentUri);
+        String ansStr = postHttpRequest(s_gson.toJson(modifyNic), agentUri);
         Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
         s_logger.debug("executeRequest received response "
                 + s_gson.toJson(result));