// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft. All rights reserved. namespace Microsoft.Samples.HyperV.ResourcePools { using System; using System.Collections; using System.Globalization; using System.Management; using Microsoft.Samples.HyperV.Common; /// /// Utilities to allow access to the Msvm_ResourcePoolConfigurationService service, /// which allow for the creation, modication, and deletion of resource pools. /// For the ModifyPoolResource, ModifyPoolSettings, and DeletePool methods, there are /// three ways that a resource pool can be referenced: by WMI reference path, /// by a resource pool managment object (MOB), and by resource type and pool ID. /// static class MsvmResourcePoolConfigurationService { /// /// Returns the Msvm_ResourcePoolConfigurationService MOB. /// /// The ManagementScope to use to connect to WMI. /// The resource pool configuration service MOB. internal static ManagementObject GetResourcePoolConfigurationService( ManagementScope scope) { using (ManagementClass resourcePoolConfigurationServiceClass = new ManagementClass("Msvm_ResourcePoolConfigurationService")) { resourcePoolConfigurationServiceClass.Scope = scope; // // Msvm_ResourcePoolConfigurationService is a singleton object. // ManagementObject resourcePoolConfigurationService = WmiUtilities.GetFirstObjectFromCollection( resourcePoolConfigurationServiceClass.GetInstances()); return resourcePoolConfigurationService; } } /// /// Creates a resource pool and returns its associated CIM_ResourcePool MOB. /// /// The ManagementScope to use to connect to WMI. /// service management object. /// The resource pool configuration. /// The resource type to assign. /// The resource subtype to assign. /// The pool ID to assign. /// The pool name to assign. /// An array of strings that specify the parent /// pool IDs. /// An array of string arrays that represent the host /// resources. /// A Msvm_ResourcePool object. internal static ManagementObject CreatePoolHelper( ManagementScope scope, ManagementObject rPConfigurationService, string resourceType, string resourceSubType, string childPoolId, string childPoolName, string[] parentPoolIdArray, string[][] parentHostResourcesArray) { if (parentPoolIdArray.Length == 0) { throw new ManagementException(string.Format( CultureInfo.CurrentCulture, @"At least one parent pool must be specified when creating a child resource pool (PoolId ""{0}"")", childPoolId)); } if (parentPoolIdArray.Length != parentHostResourcesArray.Length) { throw new ManagementException(string.Format( CultureInfo.CurrentCulture, @"When creating a child resource pool, a host resource must be specified for each parent pool. Shared allocations are not supported (PoolId ""{0}"")", childPoolId)); } string resourcePoolSettingData = MsvmResourcePoolSettingData.GetSettingsForPool( scope, resourceType, resourceSubType, childPoolId, childPoolName); string[] parentPoolPathArray = ResourcePoolUtilities.GetParentPoolArrayFromPoolIds( scope, resourceType, resourceSubType, parentPoolIdArray); string[] resourceAllocationSettingDataArray = MsvmResourceAllocationSettingData.GetNewPoolAllocationSettingsArray( scope, resourceType, resourceSubType, parentPoolIdArray, parentHostResourcesArray); using (ManagementBaseObject inParams = rPConfigurationService.GetMethodParameters( "CreatePool")) { inParams["PoolSettings"] = resourcePoolSettingData; inParams["ParentPools"] = parentPoolPathArray; inParams["AllocationSettings"] = resourceAllocationSettingDataArray; using (ManagementBaseObject outParams = rPConfigurationService.InvokeMethod( "CreatePool", inParams, null)) { if (WmiUtilities.ValidateOutput(outParams, scope, true, true)) { string poolPath = outParams["Pool"].ToString(); return new ManagementObject( scope, new ManagementPath(poolPath), null); } else { return null; } } } } /// /// Creates a resource pool. /// /// The display name of the resource type. /// The pool ID to assign. /// The pool name to assign. /// A delimited string that specifies the parent /// pool IDs. /// A delimited string that represents the host /// resources for each parent pool. internal static void CreatePool( string resourceDisplayName, string childPoolId, string childPoolName, string parentPoolIdsString, string parentHostResourcesString) { Console.WriteLine( "Creating a resource pool:\n" + "\tPool Id: " + childPoolId + "\n\tPool Name: " + childPoolName); ResourceUtilities.DisplayResourceInformation( resourceDisplayName); ResourcePoolUtilities.DisplayPoolIdAndHostResources( parentPoolIdsString, parentHostResourcesString); string[] poolDelimter = { "[p]" }; // // Pool IDs are delimted by "[p], e.g. // "[p]Child Pool A[p][p]Child Pool B[p]" // string[] parentPoolIdArray = ResourcePoolUtilities.GetOneDimensionalArray( parentPoolIdsString, poolDelimter); string[] hostResourceDelimter = { "[h]" }; // // Parent pool host resources are specified by a 2-D array. Each pool is delimited // by a "[p]"; Each host resource is delimited by a "[h]". For example, // "[p][h]Child A, Resource 1[h][h]Child A, Resource 2[h][p][p][h]Child B, Resource 1[h][p]" // string[][] parentHostResourcesArray = ResourcePoolUtilities.GetTwoDimensionalArray( parentHostResourcesString, poolDelimter, hostResourceDelimter); ManagementScope scope = ResourcePoolUtilities.GetManagementScope(); using (ManagementObject rPConfigurationService = MsvmResourcePoolConfigurationService.GetResourcePoolConfigurationService( scope)) { CreatePoolHelper( scope, rPConfigurationService, ResourceUtilities.GetResourceType(resourceDisplayName), ResourceUtilities.GetResourceSubType(resourceDisplayName), childPoolId, childPoolName, parentPoolIdArray, parentHostResourcesArray); } } /// /// Modifies the host resources assigned to a resource pool. /// /// The ManagementScope to use to connect to WMI. /// service management object. /// The resource pool configuration /// The resource type to assign. /// The resource subtype to assign. /// The reference path to a resource pool. /// An array of strings that specify the parent /// pool IDs. /// An array of string arrays that represent the host /// resources internal static void ModifyPoolResourcesByPath( ManagementScope scope, ManagementObject rPConfigurationService, string resourceType, string resourceSubType, string poolPath, string[] parentPoolIdArray, string[][] parentHostResourcesArray) { if (parentPoolIdArray.Length == 0) { throw new ManagementException(string.Format( CultureInfo.CurrentCulture, @"At least one parent pool must be specified when modifying a resource pool's host resources (poolPath ""{0}"")", poolPath)); } if (parentPoolIdArray.Length != parentHostResourcesArray.Length) { throw new ManagementException(string.Format( CultureInfo.CurrentCulture, @"When modifying a child resource pool's host resources, a host resource must be specified for each parent pool. Shared allocations are not supported (poolPath ""{0}"")", poolPath)); } string[] parentPoolPathArray = ResourcePoolUtilities.GetParentPoolArrayFromPoolIds( scope, resourceType, resourceSubType, parentPoolIdArray); string[] resourceAllocationSettingDataArray = MsvmResourceAllocationSettingData.GetNewPoolAllocationSettingsArray( scope, resourceType, resourceSubType, parentPoolIdArray, parentHostResourcesArray); using (ManagementBaseObject inParams = rPConfigurationService.GetMethodParameters( "ModifyPoolResources")) { inParams["ChildPool"] = poolPath; inParams["ParentPools"] = parentPoolPathArray; inParams["AllocationSettings"] = resourceAllocationSettingDataArray; using (ManagementBaseObject outParams = rPConfigurationService.InvokeMethod( "ModifyPoolResources", inParams, null)) { WmiUtilities.ValidateOutput(outParams, scope, true, true); } } } /// /// Modifies the host resources assigned to a resource pool. /// /// The ManagementScope to use to connect to WMI. /// service management object. /// The resource pool configuration /// The resource type to assign. /// The resource subtype to assign. /// The pool ID of a resource pool. /// An array of strings that specify the parent /// pool IDs. /// An array of string arrays that represent the host /// resources internal static void ModifyPoolResourcesHelper( ManagementScope scope, ManagementObject rPConfigurationService, string resourceType, string resourceSubType, string poolId, string[] parentPoolIdArray, string[][] parentHostResourcesArray) { string poolPath = MsvmResourcePool.GetResourcePoolPath( scope, resourceType, resourceSubType, poolId); ModifyPoolResourcesByPath( scope, rPConfigurationService, resourceType, resourceSubType, poolPath, parentPoolIdArray, parentHostResourcesArray); } /// /// Modifies the host resources assigned to a resource pool. /// /// The display name of the resource type. /// The pool ID of the pool to modify. /// A delimited string that specifies the parent /// pool IDs. /// A delimited string that represents the host /// resources for each parent pool. internal static void ModifyPoolResources( string resourceDisplayName, string poolId, string parentPoolIdsString, string parentHostResourcesString) { Console.WriteLine( "Modifying a resource pool's host resources:\n" + "\tPool ID: " + poolId); ResourceUtilities.DisplayResourceInformation( resourceDisplayName); ResourcePoolUtilities.DisplayPoolIdAndHostResources( parentPoolIdsString, parentHostResourcesString); string[] poolDelimiter = { "[p]" }; string[] hostResourceDelimter = { "[h]" }; string[] parentPoolIdArray = ResourcePoolUtilities.GetOneDimensionalArray( parentPoolIdsString, poolDelimiter); string[][] parentHostResourcesArray = ResourcePoolUtilities.GetTwoDimensionalArray( parentHostResourcesString, poolDelimiter, hostResourceDelimter); ManagementScope scope = ResourcePoolUtilities.GetManagementScope(); using (ManagementObject rPConfigurationService = MsvmResourcePoolConfigurationService.GetResourcePoolConfigurationService( scope)) { ModifyPoolResourcesHelper( scope, rPConfigurationService, ResourceUtilities.GetResourceType(resourceDisplayName), ResourceUtilities.GetResourceSubType(resourceDisplayName), poolId, parentPoolIdArray, parentHostResourcesArray); } } /// /// Modifies the resource pool's settings. /// /// The ManagementScope to use to connect to WMI. /// service management object. /// The resource pool configuration /// The reference path to a resource pool. /// An embedded instance string of a /// Msvm_ResourcePoolSettingData object. /// A Msvm_ResourcePool object. internal static void ModifyPoolSettingsByPath( ManagementScope scope, ManagementObject rPConfigurationService, string poolPath, string resourcePoolSettingData) { using (ManagementBaseObject inParams = rPConfigurationService.GetMethodParameters( "ModifyPoolSettings")) { inParams["ChildPool"] = poolPath; inParams["PoolSettings"] = resourcePoolSettingData; using (ManagementBaseObject outParams = rPConfigurationService.InvokeMethod( "ModifyPoolSettings", inParams, null)) { WmiUtilities.ValidateOutput(outParams, scope, true, true); } } } /// /// Modifies the resource pool's settings. /// /// The ManagementScope to use to connect to WMI. /// service management object. /// The resource pool configuration /// The resource type to assign. /// The resource subtype to assign. /// The pool ID of a resource pool. /// An embedded instance string of a /// Msvm_ResourcePoolSettingData object. /// A Msvm_ResourcePool object. internal static void ModifyPoolSettingsHelper( ManagementScope scope, ManagementObject rPConfigurationService, string resourceType, string resourceSubType, string poolId, string resourcePoolSettingData) { string poolPath = MsvmResourcePool.GetResourcePoolPath( scope, resourceType, resourceSubType, poolId); ModifyPoolSettingsByPath( scope, rPConfigurationService, poolPath, resourcePoolSettingData); } /// /// Modifies the resource pool's settings. /// /// The display name of the resource type. /// The pool ID of a resource pool. /// The new pool ID of the resource pool. /// The new pool Name of the resource pool. internal static void ModifyPoolSettings( string resourceDisplayName, string poolId, string newPoolId, string newPoolName) { Console.WriteLine( "Modifying a resource pool's settings:\n" + "\tPool ID: " + poolId + " (change to " + newPoolId + ")\n" + "\tPool Name: (change to " + newPoolName + ")"); ResourceUtilities.DisplayResourceInformation( resourceDisplayName); ManagementScope scope = ResourcePoolUtilities.GetManagementScope(); using (ManagementObject rPConfigurationService = MsvmResourcePoolConfigurationService.GetResourcePoolConfigurationService( scope)) { string resourcePoolSettingData = MsvmResourcePoolSettingData.GetSettingsForPool( scope, ResourceUtilities.GetResourceType(resourceDisplayName), ResourceUtilities.GetResourceSubType(resourceDisplayName), newPoolId, newPoolName); ModifyPoolSettingsHelper( scope, rPConfigurationService, ResourceUtilities.GetResourceType(resourceDisplayName), ResourceUtilities.GetResourceSubType(resourceDisplayName), poolId, resourcePoolSettingData); } } /// /// Delete a resource pool. /// /// The ManagementScope to use to connect to WMI. /// service management object. /// The resource pool configuration. /// The resource type to assign. /// The resource subtype to assign. /// The pool ID to assign. internal static void DeletePoolHelper( ManagementScope scope, ManagementObject rPConfigurationService, string resourceType, string resourceSubType, string poolId) { string poolPath = MsvmResourcePool.GetResourcePoolPath( scope, resourceType, resourceSubType, poolId); using (ManagementBaseObject inParams = rPConfigurationService.GetMethodParameters( "DeletePool")) { inParams["Pool"] = poolPath; using (ManagementBaseObject outParams = rPConfigurationService.InvokeMethod( "DeletePool", inParams, null)) { WmiUtilities.ValidateOutput(outParams, scope, true, true); } } } /// /// Delete a resource pool. /// /// The display name of the resource type to assign. /// The pool ID to assign. internal static void DeletePool( string resourceDisplayName, string poolId) { Console.WriteLine( "Deleting a resource pool:\n" + "\tPool Id: " + poolId); ResourceUtilities.DisplayResourceInformation( resourceDisplayName); ManagementScope scope = ResourcePoolUtilities.GetManagementScope(); using (ManagementObject rPConfigurationService = MsvmResourcePoolConfigurationService.GetResourcePoolConfigurationService( scope)) { DeletePoolHelper( scope, rPConfigurationService, ResourceUtilities.GetResourceType(resourceDisplayName), ResourceUtilities.GetResourceSubType(resourceDisplayName), poolId); } } } }