You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by de...@apache.org on 2013/12/17 12:11:50 UTC

git commit: updated refs/heads/master to 3604f87

Updated Branches:
  refs/heads/master 025335a3a -> 3604f87c8


CLOUDSTACK-5217: Attach volume fails with NPE. Made changes to make sure
the hypervisor product version is reported on startup. Also made changes
to fix attach and detach volume on scsi controller.


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

Branch: refs/heads/master
Commit: 3604f87c8d4a55a11d103b3b040bb3c36af33657
Parents: 025335a
Author: Devdeep Singh <de...@gmail.com>
Authored: Tue Dec 17 22:53:12 2013 +0530
Committer: Devdeep Singh <de...@gmail.com>
Committed: Tue Dec 17 16:28:08 2013 +0530

----------------------------------------------------------------------
 .../HypervResource/CloudStackTypes.cs           |   4 +
 .../HypervResource/HypervResourceController.cs  |  53 +++++--
 .../HypervResource/IWmiCallsV2.cs               |   3 +-
 .../ServerResource/HypervResource/WmiCallsV2.cs | 137 +++++++++++++++----
 4 files changed, 158 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3604f87c/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 f4d25ec..eb20d7f 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
@@ -406,7 +406,9 @@ namespace HypervResource
     public class DiskTO
     {
         public string type;
+        public string diskSequence = null;
         public TemplateObjectTO templateObjectTO = null;
+        public VolumeObjectTO volumeObjectTO = null;
 
         public static DiskTO ParseJson(dynamic json)
         {
@@ -416,7 +418,9 @@ namespace HypervResource
                 result = new DiskTO()
                 {
                     templateObjectTO = TemplateObjectTO.ParseJson(json.data),
+                    volumeObjectTO = VolumeObjectTO.ParseJson(json.data),
                     type = (string)json.type,
+                    diskSequence = json.diskSeq
                 };
             }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3604f87c/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 b283d97..51a27bf 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
@@ -215,18 +215,29 @@ namespace HypervResource
                 {
                     string vmName = (string)cmd.vmName;
                     DiskTO disk = DiskTO.ParseJson(cmd.disk);
-                    TemplateObjectTO dataStore = disk.templateObjectTO;
 
-                    if (dataStore.nfsDataStoreTO != null)
+                    if (disk.type.Equals("ISO"))
                     {
+                        TemplateObjectTO dataStore = disk.templateObjectTO;
                         NFSTO share = dataStore.nfsDataStoreTO;
                         Utils.ConnectToRemote(share.UncPath, share.Domain, share.User, share.Password);
-
-                        // The share is mapped, now attach the iso
-                        string isoPath = Utils.NormalizePath(Path.Combine(share.UncPath, dataStore.path));
-                        wmiCallsV2.AttachIso(vmName, isoPath);
+                        string diskPath = Utils.NormalizePath(Path.Combine(share.UncPath, dataStore.path));
+                        wmiCallsV2.AttachIso(vmName, diskPath);
+                        result = true;
+                    }
+                    else if (disk.type.Equals("DATADISK"))
+                    {
+                        VolumeObjectTO volume = disk.volumeObjectTO;
+                        PrimaryDataStoreTO primary = volume.primaryDataStore;
+                        Utils.ConnectToRemote(primary.UncPath, primary.Domain, primary.User, primary.Password);
+                        string diskPath = Utils.NormalizePath(volume.FullFileName);
+                        wmiCallsV2.AttachDisk(vmName, diskPath, disk.diskSequence);
                         result = true;
                     }
+                    else
+                    {
+                        details = "Invalid disk type to be attached to vm " + vmName;
+                    }
                 }
                 catch (Exception sysEx)
                 {
@@ -238,6 +249,7 @@ namespace HypervResource
                 {
                     result = result,
                     details = details,
+                    disk = cmd.disk,
                     contextMap = contextMap
                 };
 
@@ -261,16 +273,27 @@ namespace HypervResource
                 {
                     string vmName = (string)cmd.vmName;
                     DiskTO disk = DiskTO.ParseJson(cmd.disk);
-                    TemplateObjectTO dataStore = disk.templateObjectTO;
 
-                    if (dataStore.nfsDataStoreTO != null)
+                    if (disk.type.Equals("ISO"))
                     {
+                        TemplateObjectTO dataStore = disk.templateObjectTO;
                         NFSTO share = dataStore.nfsDataStoreTO;
-                        // The share is mapped, now attach the iso
-                        string isoPath = Utils.NormalizePath(Path.Combine(share.UncPath, dataStore.path));
-                        wmiCallsV2.DetachDisk(vmName, isoPath);
+                        string diskPath = Utils.NormalizePath(Path.Combine(share.UncPath, dataStore.path));
+                        wmiCallsV2.DetachDisk(vmName, diskPath);
                         result = true;
                     }
+                    else if (disk.type.Equals("DATADISK"))
+                    {
+                        VolumeObjectTO volume = disk.volumeObjectTO;
+                        PrimaryDataStoreTO primary = volume.primaryDataStore;
+                        string diskPath = Utils.NormalizePath(volume.FullFileName);
+                        wmiCallsV2.DetachDisk(vmName, diskPath);
+                        result = true;
+                    }
+                    else
+                    {
+                        details = "Invalid disk type to be dettached from vm " + vmName;
+                    }
                 }
                 catch (Exception sysEx)
                 {
@@ -1649,6 +1672,14 @@ namespace HypervResource
                 strtRouteCmd.hypervisorVersion = System.Environment.OSVersion.Version.ToString();
                 strtRouteCmd.caps = "hvm";
 
+                dynamic details = strtRouteCmd.hostDetails;
+                if (details != null)
+                {
+                    string productVersion = System.Environment.OSVersion.Version.Major.ToString() + "." +
+                        System.Environment.OSVersion.Version.Minor.ToString();
+                    details.Add("product_version", productVersion);
+                }
+
                 // Detect CPUs, speed, memory
                 uint cores;
                 uint mhz;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3604f87c/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 99ce352..35cdec0 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs
@@ -27,9 +27,10 @@ namespace HypervResource
 {
     public interface IWmiCallsV2
     {
-        System.Management.ManagementPath AddDiskDriveToVm(ComputerSystem vm, string vhdfile, string cntrllerAddr, string driveResourceType);
+        System.Management.ManagementPath AddDiskDriveToIdeController(ComputerSystem vm, string vhdfile, string cntrllerAddr, string driveResourceType);
         ComputerSystem AddUserData(ComputerSystem vm, string userData);
         void AttachIso(string displayName, string iso);
+        void AttachDisk(string vmName, string diskPath, string addressOnController);
         void CreateDynamicVirtualHardDisk(ulong MaxInternalSize, string Path);
         SyntheticEthernetPortSettingData CreateNICforVm(ComputerSystem vm, string mac);
         ComputerSystem CreateVM(string name, long memory_mb, int vcpus);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3604f87c/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 c89f837..b7ae665 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
@@ -207,14 +207,14 @@ namespace HypervResource
             return new SyntheticEthernetPortSettingData(newResourcePaths[0]);
         }
 
-        public const string IDE_HARDDISK_CONTROLLER = "Microsoft:Hyper-V:Emulated IDE Controller";
+        public const string IDE_CONTROLLER = "Microsoft:Hyper-V:Emulated IDE Controller";
         public const string SCSI_CONTROLLER = "Microsoft:Hyper-V:Synthetic SCSI Controller";
-        public const string IDE_HARDDISK_DRIVE = "Microsoft:Hyper-V:Synthetic Disk Drive";
-        public const string IDE_ISO_DRIVE = "Microsoft:Hyper-V:Synthetic DVD Drive";
+        public const string HARDDISK_DRIVE = "Microsoft:Hyper-V:Synthetic Disk Drive";
+        public const string ISO_DRIVE = "Microsoft:Hyper-V:Synthetic DVD Drive";
 
         // TODO: names harvested from Msvm_ResourcePool, not clear how to create new instances
-        public const string IDE_ISO_DISK = "Microsoft:Hyper-V:Virtual CD/DVD Disk"; // For IDE_ISO_DRIVE
-        public const string IDE_HARDDISK_DISK = "Microsoft:Hyper-V:Virtual Hard Disk"; // For IDE_HARDDISK_DRIVE
+        public const string ISO_DISK = "Microsoft:Hyper-V:Virtual CD/DVD Disk"; // For IDE_ISO_DRIVE
+        public const string HARDDISK_DISK = "Microsoft:Hyper-V:Virtual Hard Disk"; // For IDE_HARDDISK_DRIVE
 
         /// <summary>
         /// Create new VM.  By default we start it. 
@@ -280,7 +280,7 @@ namespace HypervResource
             var newVm = CreateVM(vmName, memSize, vcpus);
 
             // Add a SCSI controller for attaching/detaching data volumes.
-            AddScsiControllerToVm(newVm);
+            AddScsiController(newVm);
 
             foreach (var diskDrive in diskDrives)
             {
@@ -345,11 +345,11 @@ namespace HypervResource
                 switch (driveType) {
                     case "ROOT":
                         ideCtrllr = "0";
-                        driveResourceType = IDE_HARDDISK_DRIVE;
+                        driveResourceType = HARDDISK_DRIVE;
                         break;
                     case "ISO":
                         ideCtrllr = "1";
-                        driveResourceType = IDE_ISO_DRIVE;
+                        driveResourceType = ISO_DRIVE;
                         break;
                     default: 
                         // TODO: double check exception type
@@ -362,7 +362,7 @@ namespace HypervResource
                 }
                 logger.DebugFormat("Create disk type {1} (Named: {0}), on vm {2} {3}", diskName, driveResourceType, vmName, 
                                         string.IsNullOrEmpty(vhdFile) ? " no disk to insert" : ", inserting disk" +vhdFile );
-                AddDiskDriveToVm(newVm, vhdFile, ideCtrllr, driveResourceType);
+                AddDiskDriveToIdeController(newVm, vhdFile, ideCtrllr, driveResourceType);
                 if (isoPath != null)
                 {
                     AttachIso(vmName, isoPath);
@@ -566,16 +566,32 @@ namespace HypervResource
         public void patchSystemVmIso(String vmName, String systemVmIso)
         {
             ComputerSystem vmObject = GetComputerSystem(vmName);
-            AddDiskDriveToVm(vmObject, "", "1", IDE_ISO_DRIVE);
+            AddDiskDriveToIdeController(vmObject, "", "1", ISO_DRIVE);
             AttachIso(vmName, systemVmIso);
         }
 
+        public void AttachDisk(string vmName, string diskPath, string addressOnController)
+        {
+            logger.DebugFormat("Got request to attach disk {0} to vm {1}", diskPath, vmName);
+
+            ComputerSystem vm = GetComputerSystem(vmName);
+            if (vm == null)
+            {
+                logger.DebugFormat("VM {0} not found", vmName);
+                return;
+            }
+            else
+            {
+                ManagementPath newDrivePath = AttachDiskDriveToScsiController(vm, addressOnController);
+                InsertDiskImage(vm, diskPath, HARDDISK_DISK, newDrivePath);
+            }
+        }
 
         /// </summary>
         /// <param name="vm"></param>
         /// <param name="cntrllerAddr"></param>
         /// <param name="driveResourceType">IDE_HARDDISK_DRIVE or IDE_ISO_DRIVE</param>
-        public ManagementPath AddDiskDriveToVm(ComputerSystem vm, string vhdfile, string cntrllerAddr, string driveResourceType)
+        public ManagementPath AddDiskDriveToIdeController(ComputerSystem vm, string vhdfile, string cntrllerAddr, string driveResourceType)
         {
             logger.DebugFormat("Creating DISK for VM {0} (GUID {1}) by attaching {2}", 
                         vm.ElementName,
@@ -585,11 +601,11 @@ namespace HypervResource
             // Determine disk type for drive and assert drive type valid
             string diskResourceSubType = null;
             switch(driveResourceType) {
-                case IDE_HARDDISK_DRIVE:
-                    diskResourceSubType = IDE_HARDDISK_DISK;
+                case HARDDISK_DRIVE:
+                    diskResourceSubType = HARDDISK_DISK;
                     break;
-                case IDE_ISO_DRIVE: 
-                    diskResourceSubType = IDE_ISO_DISK;
+                case ISO_DRIVE: 
+                    diskResourceSubType = ISO_DISK;
                     break;
                 default:
                     var errMsg = string.Format(
@@ -602,7 +618,7 @@ namespace HypervResource
                     throw ex;
             }
 
-            ManagementPath newDrivePath = AttachNewDriveToVm(vm, cntrllerAddr, driveResourceType);
+            ManagementPath newDrivePath = AttachNewDrive(vm, cntrllerAddr, driveResourceType);
 
             // If there's not disk to insert, we are done.
             if (String.IsNullOrEmpty(vhdfile))
@@ -629,7 +645,7 @@ namespace HypervResource
             }
             else
             {
-                RemoveStorageImageFromVm(vm, diskFileName);
+                RemoveStorageImage(vm, diskFileName);
             }
         }
 
@@ -638,7 +654,7 @@ namespace HypervResource
         /// </summary>
         /// <param name="vm"></param>
         /// <param name="diskFileName"></param>
-        private void RemoveStorageImageFromVm(ComputerSystem vm, string diskFileName)
+        private void RemoveStorageImage(ComputerSystem vm, string diskFileName)
         {
             // Obtain StorageAllocationSettingData for disk
             StorageAllocationSettingData.StorageAllocationSettingDataCollection storageSettingsObjs = StorageAllocationSettingData.GetInstances();
@@ -674,13 +690,13 @@ namespace HypervResource
 
             RemoveStorageResource(imageToRemove.Path, vm);
 
-            logger.InfoFormat("REmoved disk image {0} from VM {1} (GUID {2}): the disk image is not attached.",
+            logger.InfoFormat("Removed disk image {0} from VM {1} (GUID {2}): the disk image is not attached.",
                     diskFileName,
                     vm.ElementName,
                     vm.Name);
         }
 
-        private ManagementPath AttachNewDriveToVm(ComputerSystem vm, string cntrllerAddr, string driveType)
+        private ManagementPath AttachNewDrive(ComputerSystem vm, string cntrllerAddr, string driveType)
         {
             // Disk drives are attached to a 'Parent' IDE controller.  We IDE Controller's settings for the 'Path', which our new Disk drive will use to reference it.
             VirtualSystemSettingData vmSettings = GetVmSettings(vm);
@@ -722,7 +738,7 @@ namespace HypervResource
             return newDrivePaths[0];
         }
 
-        private ManagementPath AddScsiControllerToVm(ComputerSystem vm)
+        private ManagementPath AddScsiController(ComputerSystem vm)
         {
             // A description of the controller is created by modifying a clone of the default ResourceAllocationSettingData for scsi controller
             string scsiQuery = String.Format("ResourceSubType LIKE \"{0}\" AND InstanceID LIKE \"%Default\"", SCSI_CONTROLLER);
@@ -754,6 +770,55 @@ namespace HypervResource
             return newResourcePaths[0];
         }
 
+        private ManagementPath GetDiskDriveToScsiController(ComputerSystem vm, string addrOnController)
+        {
+            VirtualSystemSettingData vmSettings = GetVmSettings(vm);
+            var ctrller = GetScsiControllerSettings(vmSettings);
+            return null;
+        }
+
+        private ManagementPath AttachDiskDriveToScsiController(ComputerSystem vm, string addrOnController)
+        {
+            // Disk drives are attached to a 'Parent' Scsi controller.
+            VirtualSystemSettingData vmSettings = GetVmSettings(vm);
+            var ctrller = GetScsiControllerSettings(vmSettings);
+
+            // A description of the drive is created by modifying a clone of the default ResourceAllocationSettingData for that drive type
+            string defaultDriveQuery = String.Format("ResourceSubType LIKE \"{0}\" AND InstanceID LIKE \"%Default\"", HARDDISK_DRIVE);
+            var newDiskDriveSettings = CloneResourceAllocationSetting(defaultDriveQuery);
+
+            // Set IDE controller and address on the controller for the new drive
+            newDiskDriveSettings.LateBoundObject["Parent"] = ctrller.Path.ToString();
+            newDiskDriveSettings.LateBoundObject["AddressOnParent"] = addrOnController;
+            newDiskDriveSettings.CommitObject();
+
+            // Add this new disk drive to the VM
+            logger.DebugFormat("Creating disk drive type {0}, parent IDE controller is {1} and address on controller is {2}",
+                newDiskDriveSettings.ResourceSubType,
+                newDiskDriveSettings.Parent,
+                newDiskDriveSettings.AddressOnParent);
+            string[] newDriveResource = new string[] { newDiskDriveSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20) };
+            ManagementPath[] newDrivePaths = AddVirtualResource(newDriveResource, vm);
+
+            // assert
+            if (newDrivePaths.Length != 1)
+            {
+                var errMsg = string.Format(
+                    "Failed to add disk drive type {3} to VM {0} (GUID {1}): number of resource created {2}",
+                    vm.ElementName,
+                    vm.Name,
+                    newDrivePaths.Length,
+                    HARDDISK_DRIVE);
+                var ex = new WmiException(errMsg);
+                logger.Error(errMsg, ex);
+                throw ex;
+            }
+            logger.DebugFormat("New disk drive type {0} WMI path is {1}s",
+                newDiskDriveSettings.ResourceSubType,
+                newDrivePaths[0].Path);
+            return newDrivePaths[0];
+        }
+
 
         private void InsertDiskImage(ComputerSystem vm, string diskImagePath, string diskResourceSubType, ManagementPath drivePath)
         {
@@ -795,16 +860,14 @@ namespace HypervResource
         /// Create Msvm_StorageAllocationSettingData corresponding to the ISO image, and 
         /// associate this with the VM's DVD drive.
         /// </summary>
-        private void AttachIsoToVm(ComputerSystem vm, string isoPath)
+        private void AttachIso(ComputerSystem vm, string isoPath)
         {
             // Disk drives are attached to a 'Parent' IDE controller.  We IDE Controller's settings for the 'Path', which our new Disk drive will use to reference it.
             VirtualSystemSettingData vmSettings = GetVmSettings(vm);
             var driveWmiObj = GetDvdDriveSettings(vmSettings);
-            InsertDiskImage(vm, isoPath, IDE_ISO_DISK, driveWmiObj.Path);
+            InsertDiskImage(vm, isoPath, ISO_DISK, driveWmiObj.Path);
         }
 
-
-
         private static ResourceAllocationSettingData CloneResourceAllocationSetting(string wmiQuery)
         {
             var defaultDiskDriveSettingsObjs = ResourceAllocationSettingData.GetInstances(wmiQuery);
@@ -834,7 +897,7 @@ namespace HypervResource
             }
             else
             {
-                AttachIsoToVm(vm, iso);
+                AttachIso(vm, iso);
             }
         }
 
@@ -1827,7 +1890,7 @@ namespace HypervResource
 
             foreach (ResourceAllocationSettingData wmiObj in wmiObjCollection)
             {
-                if (wmiObj.ResourceSubType == IDE_HARDDISK_CONTROLLER && wmiObj.Address == cntrllerAddr)
+                if (wmiObj.ResourceSubType == IDE_CONTROLLER && wmiObj.Address == cntrllerAddr)
                 {
                     return wmiObj;
                 }
@@ -1842,6 +1905,26 @@ namespace HypervResource
             throw ex;
         }
 
+        public ResourceAllocationSettingData GetScsiControllerSettings(VirtualSystemSettingData vmSettings)
+        {
+            var wmiObjCollection = GetResourceAllocationSettings(vmSettings);
+
+            foreach (ResourceAllocationSettingData wmiObj in wmiObjCollection)
+            {
+                if (wmiObj.ResourceSubType == SCSI_CONTROLLER)
+                {
+                    return wmiObj;
+                }
+            }
+
+            var errMsg = string.Format(
+                                "Cannot find the Microsoft Synthetic SCSI Controller in VirtualSystemSettingData {1}",
+                                vmSettings.Path.Path);
+            var ex = new WmiException(errMsg);
+            logger.Error(errMsg, ex);
+            throw ex;
+        }
+
         /// <summary>
         /// VM resources, typically hardware a described by a generic MSVM_ResourceAllocationSettingData object.  The hardware type being 
         /// described is identified in two ways:  in general terms using an enum in the ResourceType field, and in terms of the implementation