11# ###########################################################
22# Script to query the job limits inside a process-isolated container
33# ###########################################################
4+
45<#
56 . NOTES
67 Copyright (c) Microsoft Corporation. All rights reserved.
1920 . DESCRIPTION
2021 Queries the job limits from inside a process-isolated container
2122
22- . PARAMETER Verbose
23- If passed, dump verbose output
23+ . PARAMETER LimitType
24+ Determines the type of limit to query. The following values are supported:
25+ - JobMemoryLimit: Returns the job memory limit in bytes
26+ - PeakJobMemoryUsed: Returns the peak job memory used in bytes
27+ - CpuRateControl: Returns the CPU rate control, if enabled, which is generally a cycle count out of a total of 10000
2428
2529 . EXAMPLE
2630 .\Query-JobLimits.ps1
3034[CmdletBinding (DefaultParameterSetName = " Standard" )]
3135param (
3236 [Parameter (Mandatory = $True )]
33- [ValidateSet (" JobMemoryLimit" , " PeakJobMemoryUsed" )]
37+ [ValidateSet (" JobMemoryLimit" , " PeakJobMemoryUsed" , " CpuRateControl " )]
3438 [string ]$LimitType
3539)
3640
@@ -55,6 +59,11 @@ Add-Type @"
5559 JobObjectBasicAndIoAccountingInformation,
5660 JobObjectExtendedLimitInformation,
5761 JobObjectJobSetInformation,
62+ JobObjectGroupInformation,
63+ JobObjectNotificationLimitInformation,
64+ JobObjectLimitViolationInformation,
65+ JobObjectGroupInformationEx,
66+ JobObjectCpuRateControlInformation,
5867 MaxJobObjectInfoClass,
5968 }
6069
@@ -80,6 +89,14 @@ Add-Type @"
8089 public const UInt32 JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK = 0x00001000;
8190 public const UInt32 JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x00002000;
8291
92+ //
93+ // CPU Rate Control Flags
94+ //
95+ public const UInt32 JOB_OBJECT_CPU_RATE_CONTROL_ENABLE = 0x00000001;
96+ public const UInt32 JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED = 0x00000002;
97+ public const UInt32 JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP = 0x00000004;
98+ public const UInt32 JOB_OBJECT_CPU_RATE_CONTROL_NOTIFY = 0x00000008;
99+
83100 [StructLayout(LayoutKind.Sequential)]
84101 public struct JOBOBJECT_BASIC_LIMIT_INFORMATION
85102 {
@@ -116,6 +133,13 @@ Add-Type @"
116133 public UIntPtr PeakJobMemoryUsed;
117134 }
118135
136+ [StructLayout(LayoutKind.Sequential)]
137+ public struct JOBOBJECT_CPU_RATE_CONTROL_INFORMATION
138+ {
139+ public UInt32 ControlFlags;
140+ public UInt32 Data;
141+ }
142+
119143 [DllImport("kernel32.dll", CharSet = CharSet.Auto, EntryPoint = "QueryInformationJobObject", SetLastError = true)]
120144 public static extern bool QueryInformationJobObject(
121145 IntPtr handleJob,
@@ -137,7 +161,7 @@ Add-Type @"
137161 {
138162 // Marshal.AllocHGlobal will throw on failure, so we do not need to
139163 // check for allocation failure.
140- ptrData = Marshal.AllocHGlobal( inSize );
164+ ptrData = Marshal.AllocHGlobal( inSize );
141165 UInt32 outSize = 0;
142166
143167 // Query the job object for its extended limits
@@ -168,21 +192,103 @@ Add-Type @"
168192 }
169193 }
170194 }
195+
196+ // Query the CPU rate control info for the running job
197+ // If this is run outside of an executing job, or if the CPU rates are not set,
198+ // the script will return zero.
199+ public static JOBOBJECT_CPU_RATE_CONTROL_INFORMATION QueryCPURateControlInformation()
200+ {
201+ // Allocate an JOBOBJECT_CPU_RATE_CONTROL_INFORMATION
202+ int inSize = Marshal.SizeOf(typeof(Api.JOBOBJECT_CPU_RATE_CONTROL_INFORMATION));
203+ IntPtr ptrData = IntPtr.Zero;
204+ try
205+ {
206+ // Marshal.AllocHGlobal will throw on failure, so we do not need to
207+ // check for allocation failure.
208+ ptrData = Marshal.AllocHGlobal( inSize );
209+ UInt32 outSize = 0;
210+
211+ // Query the job object for its extended limits
212+ bool result = Api.QueryInformationJobObject(IntPtr.Zero,
213+ Api.JOBOBJECTINFOCLASS.JobObjectCpuRateControlInformation,
214+ ptrData,
215+ (UInt32)inSize,
216+ ref outSize);
217+ if (result)
218+ {
219+ // Marshal the result data into a .NET structure
220+ Api.JOBOBJECT_CPU_RATE_CONTROL_INFORMATION jobinfo =
221+ (Api.JOBOBJECT_CPU_RATE_CONTROL_INFORMATION)Marshal.PtrToStructure(ptrData, typeof(Api.JOBOBJECT_CPU_RATE_CONTROL_INFORMATION));
222+
223+ // Return the extended limit information to the caller
224+ return jobinfo;
225+ }
226+ else
227+ {
228+ throw new Win32Exception(Marshal.GetLastWin32Error());
229+ }
230+ }
231+ finally
232+ {
233+ if (ptrData != IntPtr.Zero)
234+ {
235+ Marshal.FreeHGlobal( ptrData );
236+ }
237+ }
238+ }
239+
240+ public static UInt32 GetCpuLimit()
241+ {
242+ JOBOBJECT_CPU_RATE_CONTROL_INFORMATION cpuRateControl = QueryCPURateControlInformation();
243+
244+ // Is CPU rate control enabled?
245+ if ((cpuRateControl.ControlFlags & JOB_OBJECT_CPU_RATE_CONTROL_ENABLE) == 0)
246+ {
247+ Console.WriteLine("# CPU rate control is not enabled.");
248+ return 0;
249+ }
250+
251+ // Is CPU rate control weight-based?
252+ if ((cpuRateControl.ControlFlags & JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED) != 0)
253+ {
254+ Console.WriteLine("# CPU rate control is weight-based.");
255+ return cpuRateControl.Data;
256+ }
257+
258+ // Is CPU rate control hard cap?
259+ if ((cpuRateControl.ControlFlags & JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP) != 0)
260+ {
261+ Console.WriteLine("# CPU rate control is hard cap.");
262+ return cpuRateControl.Data;
263+ }
264+
265+ // Otherwise, default to zero.
266+ return 0;
267+ }
171268 }
172269
173270"@
174271
175- $result = [Api ]::QueryExtendedLimitInformation()
176-
177272switch ($LimitType ) {
273+ # Returns the job memory limit in bytes
178274 " JobMemoryLimit" {
275+ $result = [Api ]::QueryExtendedLimitInformation()
179276 $result.JobMemoryLimit
180277 }
181278
279+ # Returns the peak job memory used in bytes
182280 " PeakJobMemoryUsed" {
281+ $result = [Api ]::QueryExtendedLimitInformation()
183282 $result.PeakJobMemoryUsed
184283 }
185284
285+ # Returns the CPU rate control, if enabled,
286+ # which is generally a cycle count out of a total of 10000
287+ " CpuRateControl" {
288+ $result = [Api ]::GetCpuLimit()
289+ $result
290+ }
291+
186292 Default {
187293 Write-Error " Limit type unknown: $LimitType "
188294 }
0 commit comments