GMOインターネット株式会社 システム本部 樋口 勝一が担当するGMO最新ネット業界レポート-ソリューション編。今回はWindows Server 2012 R2のHyper-Vから新たに追加されたDefineSystemメソッドによるVMの世代の設定方法と、メモリの設定方法をご紹介します。
Windows Server 2012 R2のvirtualization名前空間
すでにWindow Server 2012 R2 の情報が出てきていますが、R2ではこれまで利用してきたroot\virtualizationという名前空間が完全に、root\virtualization\v2に置き換わることとなりました。
> root\virtualization
> root\virtualization\v2
Windows Server 2012、Windows Server 2012 R2 それぞれのサーバー内でWMI Explorerで見てみると、確かにR2の方は名前空間がvirtualizationの中に一つしかありません。
Windows Server 2012 のvirtualization名前空間
Windows Server 2012 R2のvirtualization名前空間
これはかなり大きな変更となります。Hyper-VのプロビジョニングをWMIで行ってきた場合、コードのほぼすべてを書き換える必要があるということです。メソッド名だけでなく、新しい機能に対応したクラスの追加や、新しいメソッドの使い方など、大幅に変更されています。ほとんどサンプルのないWMIを使ったHyper-Vのプロビジョニングですので、このGMO業界レポートで、より積極的にサンプルコードを紹介する必要が出てきました。ということで、引き続きお付き合いください。
まずは、追加情報となります。前回紹介した、VMの骨組みを作成するMsvm_VirtualSystemManagementServiceクラスの「DefineSystem」メソッドですが、Windows Server 2012 R2の登場にあわせて、重要な追加オプションが設定できるようになったのでご紹介します。
Windows Server 2012 R2のHyper-Vでは仮想マシンの世代を選択することができるようになりました。
第1世代はこれまでのHyper-V上でのVMと同様のものとなります。第2世代はレガシーBIOSや古いデバイス接続など、実マシンとの互換性を保つために備わっていた機能をすべて省き、仮想マシンとしてパフォーマンスを最大限発揮できる構成となっています。
これにより更なる高速化が実現されることとなりました。WMIでこの世代を設定するには「DefineSystem」メソッドで、「VirtualSystemSubType」プロパティーを設定する必要があります。
1: Imports System.Management
2:
3: Module GMOReport
4:
5: Sub Main()
6: Dim strUser As String = ""
7: Dim strPass As String = ""
8: Dim objManagementScope As ManagementScope = ConnectManagementScope("win2012.local", strUser, strPass)
9: Call DefineVM(objManagementScope, "VM01", "D:\Hyper-V\VM01", 2)
10: End Sub
11:
12: Function ConnectManagementScope(ByVal strServer As String, ByVal strAccount As String, ByVal strPassword As String) As ManagementScope
13: Dim objConnectionOptions As New ConnectionOptions()
14: objConnectionOptions.Impersonation = ImpersonationLevel.Impersonate
15: objConnectionOptions.EnablePrivileges = True
16: objConnectionOptions.Username = strAccount
17: objConnectionOptions.Password = strPassword
18: Dim objManagementScope As New ManagementScope("\\" + strServer + "\root\virtualization\v2", objConnectionOptions)
19: objManagementScope.Connect()
20: Return (objManagementScope)
21: End Function
22:
23: Function DefineVM(ByVal objManagementScope As ManagementScope, ByVal strVMName As String, ByVal strFolderPath As String, intGeneration As Integer) As Boolean
24: Dim objVirtualSystemSettingData As New ManagementClass(objManagementScope, New ManagementPath("Msvm_VirtualSystemSettingData"), Nothing)
25: Dim objVirtualSystemSettingDataInstance As ManagementObject = objVirtualSystemSettingData.CreateInstance
26: objVirtualSystemSettingDataInstance("ElementName") = strVMName
27: objVirtualSystemSettingDataInstance("ConfigurationDataRoot") = strFolderPath
28: objVirtualSystemSettingDataInstance("VirtualSystemSubType") = "Microsoft:Hyper-V:SubType:" & intGeneration
29: objVirtualSystemSettingDataInstance("VirtualNumaEnabled") = False
30: Dim strSystemsettingData As String = objVirtualSystemSettingDataInstance.GetText(TextFormat.CimDtd20)
31:
32: For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
33: Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("DefineSystem")
34: objParams("SystemSettings") = strSystemsettingData
35: objParams("ResourceSettings") = Nothing
36: objParams("ReferenceConfiguration") = Nothing
37: Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("DefineSystem", objParams, Nothing)
38: Return JobComplete(objManagementBaseObject, objManagementScope)
39: Next
40: End Function
41:
42: Function JobComplete(ByVal objManagementBaseObject As ManagementBaseObject, ByVal objManagementScope As ManagementScope) As Boolean
43: 'JobState New = 2 Starting = 3 Running = 4 Suspended = 5 ShuttingDown = 6 Completed = 7 Terminated = 8 Killed = 9 Exception = 10 Service = 11
44: If objManagementBaseObject("ReturnValue") <> 0 Then
45: Dim strJobPath As String = objManagementBaseObject("Job")
46: Dim objJob As New ManagementObject(objManagementScope, New ManagementPath(strJobPath), Nothing)
47: objJob.Get()
48: Do While objJob("JobState") = 3 Or objJob("JobState") = 4
49: System.Threading.Thread.Sleep(1000)
50: objJob.Get()
51: Loop
52: If objJob("JobState") <> 7 Then
53: Console.WriteLine("ErrorCode=" & objJob("ErrorCode") & " JobState=" & objJob("JobState"))
54: Return False
55: Else
56: Return True
57: End If
58: Else
59: Return True
60: End If
61: End Function
62:
63: End Module
12行目:
行目:引数として、引数intGenerationを追加しています。1の場合第1世代、2の場合第2世代となります。28行目:第1世代の場合、「VirtualSystemSubType」プロパティーには「Microsoft:Hyper-V:SubType:1」、第2世代の場合は「Microsoft:Hyper-V:SubType:2」という文字列を指定します。29行目:後ほどメモリの設定方法の章にて解説します。
DefineSystemメソッド実行直後のVM
第1世代
第2世代(IDE、フロッピーディスク、シリアルポートなど余計なデバイスが省略されている)
ついでに、作成したVMを削除する方法も合わせて紹介します。VMを削除するにはMsvm_VirtualSystemManagementServiceクラスの「DestroySystem」メソッドを利用します。
1: Imports System.Management
2:
3: Module GMOReport
4:
5: Sub Main()
6: Dim strUser As String = ""
7: Dim strPass As String = ""
8: Dim objManagementScope As ManagementScope = ConnectManagementScope("win2012.local", strUser, strPass)
9: Call DeleteVM(objManagementScope, "VM01")
10: End Sub
11:
12: Function ConnectManagementScope(ByVal strServer As String, ByVal strAccount As String, ByVal strPassword As String) As ManagementScope
13: Dim objConnectionOptions As New ConnectionOptions()
14: objConnectionOptions.Impersonation = ImpersonationLevel.Impersonate
15: objConnectionOptions.EnablePrivileges = True
16: objConnectionOptions.Username = strAccount
17: objConnectionOptions.Password = strPassword
18: Dim objManagementScope As New ManagementScope("\\" + strServer + "\root\virtualization\v2", objConnectionOptions)
19: objManagementScope.Connect()
20: Return (objManagementScope)
21: End Function
22:
23: Function DeleteVM(ByVal objManagementScope As ManagementScope, ByVal strVMName As String) As Boolean
24: Dim objComputerSystem As ManagementObject = Nothing
25: For Each objManagementObject As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName = '" & strVMName & "'")).Get
26: objComputerSystem = objManagementObject
27: Next
28:
29: For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
30: Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("DestroySystem")
31: objParams("AffectedSystem") = objComputerSystem.Path.Path
32: Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("DestroySystem", objParams, Nothing)
33: Return JobComplete(objManagementBaseObject, objManagementScope)
34: Next
35: End Function
36:
37: Function JobComplete(ByVal objManagementBaseObject As ManagementBaseObject, ByVal objManagementScope As ManagementScope) As Boolean
38: 'JobState New = 2 Starting = 3 Running = 4 Suspended = 5 ShuttingDown = 6 Completed = 7 Terminated = 8 Killed = 9 Exception = 10 Service = 11
39: If objManagementBaseObject("ReturnValue") <> 0 Then
40: Dim strJobPath As String = objManagementBaseObject("Job")
41: Dim objJob As New ManagementObject(objManagementScope, New ManagementPath(strJobPath), Nothing)
42: objJob.Get()
43: Do While objJob("JobState") = 3 Or objJob("JobState") = 4
44: System.Threading.Thread.Sleep(1000)
45: objJob.Get()
46: Loop
47: If objJob("JobState") <> 7 Then
48: Console.WriteLine("ErrorCode=" & objJob("ErrorCode") & " JobState=" & objJob("JobState"))
49: Return False
50: Else
51: Return True
52: End If
53: Else
54: Return True
55: End If
56: End Function
57:
58: End Module
34行目:「DestroySystem」メソッドのパラメーター「AffectedSystem」に削除するVMの情報を設定して実行します。
削除する場合は非常にシンプルな方法となっています。
メモリの設定方法
次に紹介するのはメモリの設定方法です。
>以前までのroot\virtualization名前空間の場合はこちら
Hyper-VはWindows Server 2012から「Non-Uniform Memory Access(NUMA)」という機能を使えるようになりました。NUMAは簡単に言えば、マルチプロセッサを利用する場合に効率よくメモリを使用することで、パフォーマンスをアップする技術です。このNUMAを利用する場合は、Hyper-Vではメモリ設定のオプションである「ダイナミックメモリ(動的メモリ)」を同時に利用することができない仕様となっています。
以前のroot\virtualization名前空間DefineVirtualSystemメソッドでVMを作成した場合は、初期設定としてNUMAは無効になっていましたが、root\virtualization\v2名前空間DefineSystemメソッドで作成したVMは、初期設定としてNUMAが有効に設定されています。したがって、メモリ設定時にダイナミックメモリを利用する場合は、事前にNUMAを無効に変更する必要があります。
前述のDefineSystemのサンプルコード内の29行目では、DefineSystemメソッド実行時にNUMAを無効にするプロパティー「VirtualNumaEnabled」をFalseにすることで、設定可能です。また、これとは別に、NUMAだけの設定をあとから変更することも可能です。この場合は「Msvm_VirtualSystemManagementService」クラスの「ModifySystemSettings」メソッドで、設定を変更することとなります。
1: Imports System.Management
2:
3: Module GMOReport
4:
5: Sub Main()
6: Dim strUser As String = ""
7: Dim strPass As String = ""
8: Dim objManagementScope As ManagementScope = ConnectManagementScope("win2012.local", strUser, strPass)
9: Call SetNumaNode(objManagementScope, "VM01", False)
10: End Sub
11:
12: Function ConnectManagementScope(ByVal strServer As String, ByVal strAccount As String, ByVal strPassword As String) As ManagementScope
13: Dim objConnectionOptions As New ConnectionOptions()
14: objConnectionOptions.Impersonation = ImpersonationLevel.Impersonate
15: objConnectionOptions.EnablePrivileges = True
16: objConnectionOptions.Username = strAccount
17: objConnectionOptions.Password = strPassword
18: Dim objManagementScope As New ManagementScope("\\" + strServer + "\root\virtualization\v2", objConnectionOptions)
19: objManagementScope.Connect()
20: Return (objManagementScope)
21: End Function
22:
23: Function SetNumaNode(ByVal objManagementScope As ManagementScope, ByVal strVMName As String, blnEnabled As Boolean) As Boolean
24: Dim objComputerSystem As ManagementObject = Nothing
25: For Each objManagementObject As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName = '" & strVMName & "'")).Get
26: objComputerSystem = objManagementObject
27: Next
28:
29: Dim objVirtualSystemsettingData As ManagementObject = Nothing
30: For Each objManagementObject As ManagementObject In objComputerSystem.GetRelated("Msvm_VirtualSystemSettingData")
31: objVirtualSystemsettingData = objManagementObject
32: objVirtualSystemsettingData("VirtualNumaEnabled") = blnEnabled
33: Next
34:
35: For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
36: Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("ModifySystemSettings")
37: objParams("SystemSettings") = objVirtualSystemsettingData.GetText(TextFormat.CimDtd20)
38: Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("ModifySystemSettings", objParams, Nothing)
39: Return JobComplete(objManagementBaseObject, objManagementScope)
40: Next
41: End Function
42:
43: Function JobComplete(ByVal objManagementBaseObject As ManagementBaseObject, ByVal objManagementScope As ManagementScope) As Boolean
44: 'JobState New = 2 Starting = 3 Running = 4 Suspended = 5 ShuttingDown = 6 Completed = 7 Terminated = 8 Killed = 9 Exception = 10 Service = 11
45: If objManagementBaseObject("ReturnValue") <> 0 Then
46: Dim strJobPath As String = objManagementBaseObject("Job")
47: Dim objJob As New ManagementObject(objManagementScope, New ManagementPath(strJobPath), Nothing)
48: objJob.Get()
49: Do While objJob("JobState") = 3 Or objJob("JobState") = 4
50: System.Threading.Thread.Sleep(1000)
51: objJob.Get()
52: Loop
53: If objJob("JobState") <> 7 Then
54: Console.WriteLine("ErrorCode=" & objJob("ErrorCode") & " JobState=" & objJob("JobState"))
55: Return False
56: Else
57: Return True
58: End If
59: Else
60: Return True
61: End If
62: End Function
63:
64: End Module
行目:VirtualNumaEnabledの値を設定します。NUMAを無効にするにはFalseに設定。35-40行目:ModifySystemSettingsメソッドで設定内容を変更する。
NUMAの設定方法が分かったところで、本題のメモリの設定方法です。基本的な設定項目は依然と同様となりますが、設定内容の変更はNUMAの設定変更同様「Msvm_VirtualSystemManagementService」クラスの「ModifySystemSettings」メソッドとなります。
1: Imports System.Management
2:
3: Module GMOReport
4:
5: Sub Main()
6: Dim strUser As String = ""
7: Dim strPass As String = ""
8: Dim objManagementScope As ManagementScope = ConnectManagementScope("win2012.local", strUser, strPass)
9: Call SetMemory(objManagementScope, "VM01", True, 1024, 512, 2048, 5000, 20)
10: End Sub
11:
12: Function ConnectManagementScope(ByVal strServer As String, ByVal strAccount As String, ByVal strPassword As String) As ManagementScope
13: Dim objConnectionOptions As New ConnectionOptions()
14: objConnectionOptions.Impersonation = ImpersonationLevel.Impersonate
15: objConnectionOptions.EnablePrivileges = True
16: objConnectionOptions.Username = strAccount
17: objConnectionOptions.Password = strPassword
18: Dim objManagementScope As New ManagementScope("\\" + strServer + "\root\virtualization\v2", objConnectionOptions)
19: objManagementScope.Connect()
20: Return (objManagementScope)
21: End Function
22:
23: Function SetMemory(ByVal objManagementScope As ManagementScope, ByVal strVMName As String, blnDynamicMemoryEnabled As Boolean, ByVal intVirtualQuantity As Integer, ByVal intReservation As Integer, ByVal intLimitMemory As Integer, ByVal intWeight As Integer, ByVal intTargetMemoryBuffer As Integer) As Boolean
24:
25: Dim objComputerSystem As ManagementObject = Nothing
26: For Each objManagementObject As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName = '" & strVMName & "'")).Get
27: objComputerSystem = objManagementObject
28: Next
29:
30: Dim objVirtualSystemSettingData As ManagementObject = Nothing
31: For Each objManagementObject As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemSettingData WHERE ElementName = '" & strVMName & "'")).Get
32: objVirtualSystemSettingData = objManagementObject
33: Next
34:
35: Dim objMemorySettingData As ManagementBaseObject = Nothing
36: For Each objManagementObject As ManagementObject In objVirtualSystemSettingData.GetRelated("Msvm_MemorySettingData")
37: objMemorySettingData = objManagementObject
38: objMemorySettingData("DynamicMemoryEnabled") = blnDynamicMemoryEnabled
39: objMemorySettingData("VirtualQuantity") = intVirtualQuantity
40: objMemorySettingData("Reservation") = intReservation
41: objMemorySettingData("Limit") = intLimitMemory
42: objMemorySettingData("Weight") = intWeight
43: objMemorySettingData("TargetMemoryBuffer") = intTargetMemoryBuffer
44: Next
45:
46: For Each objVirtualSystemManagementService As ManagementObject In New ManagementObjectSearcher(objManagementScope, New ObjectQuery("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
47: Dim objParams As ManagementBaseObject = objVirtualSystemManagementService.GetMethodParameters("ModifyResourceSettings")
48: objParams("ResourceSettings") = New String() {objMemorySettingData.GetText(TextFormat.CimDtd20)}
49: Dim objManagementBaseObject As ManagementBaseObject = objVirtualSystemManagementService.InvokeMethod("ModifyResourceSettings", objParams, Nothing)
50: Return JobComplete(objManagementBaseObject, objManagementScope)
51: Next
52: End Function
53:
54: Function JobComplete(ByVal objManagementBaseObject As ManagementBaseObject, ByVal objManagementScope As ManagementScope) As Boolean
55: 'JobState New = 2 Starting = 3 Running = 4 Suspended = 5 ShuttingDown = 6 Completed = 7 Terminated = 8 Killed = 9 Exception = 10 Service = 11
56: If objManagementBaseObject("ReturnValue") <> 0 Then
57: Dim strJobPath As String = objManagementBaseObject("Job")
58: Dim objJob As New ManagementObject(objManagementScope, New ManagementPath(strJobPath), Nothing)
59: objJob.Get()
60: Do While objJob("JobState") = 3 Or objJob("JobState") = 4
61: System.Threading.Thread.Sleep(1000)
62: objJob.Get()
63: Loop
64: If objJob("JobState") <> 7 Then
65: Console.WriteLine("ErrorCode=" & objJob("ErrorCode") & " JobState=" & objJob("JobState"))
66: Return False
67: Else
68: Return True
69: End If
70: Else
71: Return True
72: End If
73: End Function
74:
75: End Module
VirtualQuantityスタートアップRAMReservation最低RAMLimit最大RAMTargetMemoryBufferメモリバッファー(5~2000%)Weightメモリの優先度(0~10000)
http://msdn.microsoft.com/en-us/library/cc136856(v=vs.85).aspx
今回のサンプルでは、最大メモリを2GB、最低メモリを512KBとして設定しています。このコードによってメモリの設定が可能となります。
以上、今回はWindows Server 2012 R2のHyper-Vから新たに追加されたDefineSystemメソッドによるVMの世代の設定方法と、メモリの設定方法をご紹介しました。
次回も引き続き新しいWMIの利用方法をご紹介します。
サンプルコードをこちらからダウンロードいただけます。 → GMOReport.zip(22.6KB)
*本文中に記載されている会社名および商品名・サービス名は、各社の商標 または登録商標です。