Einrichten eines Storage-Pools (Windows Server 2012 Storage Spaces)

Für die Storage Spaces habe ich zusammenhängend nur sehr wenig und verstreute Informationen gefunden. Hauptsächlich für mich selbst habe nachfolgend zusammengestellt, wie man einen Storage-Space (Pool) mit PowerShell-Commandlets einrichtet.

Alle PowerShell-Befehle, die für die nachfolgend beschriebenen Aktionen benötigt werden, sind im Module Storage zu finden.

Get-Command -Module storage

Hilfe zu jedem PowerShell-Befehl bekommt man mit Get-Help <Commendlet> z.B:

Clear-Disk

Zunächst muss man feststellen, welche physikalischen Laufwerke (also Festplatten) man in seinem System zur Verfügung hat. Mit PowerShell geht es wie folgt:

Get-PhysicalDisk

Beispiel einer Ausgabe:


FriendlyName        CanPool     OperationalStatus   HealthStatus        Usage                  Size
------------        -------     -----------------   ------------        -----                  ----
PhysicalDisk11      False       OK                  Healthy             Auto-Select       465.76 GB
PhysicalDisk12      False       OK                  Healthy             Auto-Select       465.76 GB
PhysicalDisk13      False       OK                  Healthy             Auto-Select       465.76 GB
PhysicalDisk14      False       OK                  Healthy             Auto-Select       465.76 GB
PhysicalDisk9       False       OK                  Healthy             Auto-Select       931.51 GB
PhysicalDisk0       False       OK                  Healthy             Auto-Select         1.82 TB
PhysicalDisk2       False       OK                  Healthy             Auto-Select       930.75 GB
PhysicalDisk3       False       OK                  Healthy             Auto-Select       930.75 GB
PhysicalDisk4       False       OK                  Healthy             Auto-Select       930.75 GB
PhysicalDisk5       False       OK                  Healthy             Auto-Select       930.75 GB
PhysicalDisk6       False       OK                  Healthy             Auto-Select         1.82 TB
PhysicalDisk1       False       OK                  Healthy             Auto-Select       465.76 GB
PhysicalDisk10      False       OK                  Healthy             Auto-Select       931.51 GB

Wie man unschwer erkennen kann, sind die Einträge nicht besonders geschickt sortiert. Hier schafft Sort-Object nach FriendlyName Abhilfe:

Get-PhysicalDisk | Sort-Object FriendlyName


FriendlyName        CanPool     OperationalStatus   HealthStatus        Usage                  Size
------------        -------     -----------------   ------------        -----                  ----
PhysicalDisk0       False       OK                  Healthy             Auto-Select         1.82 TB
PhysicalDisk1       False       OK                  Healthy             Auto-Select       465.76 GB
PhysicalDisk10      False       OK                  Healthy             Auto-Select       931.51 GB
PhysicalDisk11      False       OK                  Healthy             Auto-Select       465.76 GB
PhysicalDisk12      False       OK                  Healthy             Auto-Select       465.76 GB
PhysicalDisk13      False       OK                  Healthy             Auto-Select       465.76 GB
PhysicalDisk14      False       OK                  Healthy             Auto-Select       465.76 GB
PhysicalDisk2       False       OK                  Healthy             Auto-Select       930.75 GB
PhysicalDisk3       False       OK                  Healthy             Auto-Select       930.75 GB
PhysicalDisk4       False       OK                  Healthy             Auto-Select       930.75 GB
PhysicalDisk5       False       OK                  Healthy             Auto-Select       930.75 GB
PhysicalDisk6       False       OK                  Healthy             Auto-Select         1.82 TB
PhysicalDisk9       False       OK                  Healthy             Auto-Select       931.51 GB	

Aus der Ansicht kann man erkennen, welche Festplatten für einen Storage-Pool geeignet sind. Leider sind nur Festplatten geeignet, die leer sind. Wie man hier sieht, ist zunächst keine der Festplatten für einen Storage-Pool geeignet (CanPool ist False). Wenn man genau weiß, dass die Festplatten gelöscht werden können, (dabei gehen Daten und Partitionen unwiederbringlich verloren!) kann man die Festplatten mit den folgenden Anweisungen “poolfähig” machen. Nachfolgend werden 4 physikalische Disks PhysicalDisk11, PhysicalDisk12, PhysicalDisk13 und PhysicalDisk14 zu einem Storage-Pool vorbereitet. Dazu muss man die Festplatten-Nummer wissen. Diese erhält man mit dem Befehl:

Get-Disk


Number Friendly Name                            OperationalStatus                    Total Size Partition Style
------ -------------                            -----------------                    ---------- ---------------
1      Hitachi HDP725050GLA360 ATA Device       Online                                465.76 GB MBR
10     WD My Book USB Device                    Offline                               931.51 GB MBR
7      Microsoft Storage Space Device           Offline                                   10 TB GPT
8      Microsoft Storage Space Device           Offline                                   10 TB GPT
9      WD My Book USB Device                    Offline                               931.51 GB MBR
13     Hitachi HDP725050GLA SCSI Disk Device    Offline                               465.76 GB RAW
12     Hitachi HDP725050GLA SCSI Disk Device    Offline                               465.76 GB RAW
11     Hitachi HDP725050GLA SCSI Disk Device    Offline                               465.76 GB RAW
14     Hitachi HDP725050GLA SCSI Disk Device    Offline                               465.76 GB RAW


Diese Ausgabe zeigt an, dass die Nummer in PhysikalDisk-FriendlyName z.B. 11 mit der Nummer aus Get-Disk übereinstimmt. Ob das immer zutrifft, weiß ich leider nicht. Die Nummer benötigen wir, um die Platte löschen zu können. Das erledigen wir mit:

Clear-Disk -Number 11 -RemoveData -RemoveOEM


Confirm
Are you sure you want to perform this action?
This will erase all data on disk 11 "Hitachi HDP725050GLA SCSI Disk Device".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"):

Den Befehl mit Return bzw. “y” bestätigen. Im obigen Beispiel werden wir durch die folgende Fehlermeldung auf den Umstand hingewiesen, dass die Platte Offline und ReadOnly ist.

Set-Disk -Number 11 -IsOffline $false


Clear-Disk : The disk is offline.
    At line:1 char:1
    + Clear-Disk -Number 11 -RemoveData -RemoveOEM
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (StorageWMI:ROOT/Microsoft/Windows/Storage/MSFT_Disk) [Clear-Disk], CimExc
    eption
    + FullyQualifiedErrorId : StorageWMI 41003,Clear-Disk

Also den Schreibschutz der Platte  aufheben und die Platte Online nehmen:

Set-Disk -Number 11 -IsReadOnly $false
Set-Disk -Number 11 -IsOffline $false
Clear-Disk -Number 11 -RemoveData -RemoveOEM

Wir können uns davon überzeugen, dass die Festplatte nun “poolfähig” ist:

Get-PhysicalDisk -FriendlyName PhysicalDisk11


FriendlyName        CanPool   OperationalStatus   HealthStatus        Usage                    Size
------------        -------   -----------------   ------------        -----                    ----
PhysicalDisk11      True      OK                  Healthy             Auto-Select         465.76 GB

Mit den Disknummern 12, 13, und 14 verfahren wir wie oben. Jetzt müssen wir nur noch wissen, ob wir über mehrere StorageSubSystems verfügen. Das geht mit:

Get-StorageSubSystem

Da ich nur ein StorageSubSystem habe, brauche ich die Festplatten nicht nach dem StorageSubSystem zu filtern. Für den StoragePool müssen wir wissen, welche Platten da rein sollen. Die merken wir uns in einer Variable:

$disks = Get-PhysicalDisk -CanPool $true

mit

$disks

FriendlyName        CanPool    OperationalStatus   HealthStatus        Usage                   Size
------------        -------    -----------------   ------------        -----                   ----
PhysicalDisk11      True       OK                  Healthy             Auto-Select        465.76 GB
PhysicalDisk12      True       OK                  Healthy             Auto-Select        465.76 GB
PhysicalDisk13      True       OK                  Healthy             Auto-Select        465.76 GB
PhysicalDisk14      True       OK                  Healthy             Auto-Select        465.76 GB

überzeugen wir uns, dass wir die richtige Platten selektiert haben. Um den StoragePool zu erstellen, wird der FriendlyName des StorageSubSystem benötigt. Den merken wir uns mit:

$sssName = $(Get-StorageSubSystem).FriendlyName

Endlich ist es soweit, mit:

New-StoragePool -FriendlyName VmExploration -StorageSubsystemFriendlyName $sssName -PhysicalDisks $disks


FriendlyName            OperationalStatus       HealthStatus            IsPrimordial     IsReadOnly
------------            -----------------       ------------            ------------     ----------
VmExploration           OK                      Healthy                 False            False	

erstellen wir einen StoragePool mit dem FriendlyName “VmExploration”. Jetzt noch eine VirtualDisk mit dem FriendlyName “Exploration”:

New-VirtualDisk -StoragePoolFriendlyName VmExploration -FriendlyName Exploration -ResiliencySettingName Parity -Size 5TB -ProvisioningType Thin


FriendlyName        ResiliencySettingNa OperationalStatus   HealthStatus        IsManualAttach     Size
------------        ------------------- -----------------   ------------        --------------     ----
Exploration         Parity              OK                  Healthy             False              5 TB	

Die VirtualDisk ist größer (5TB) als der tatsächliche Plattenplatz im StoragePool (ca. 2TB). Wir haben mit “-ResiliencySettingName Parity” eine Redundanz vergleichbar mit einem RAID 5 geschaffen. Sollte der pyhsikalische Platz knapp werden, stecken wir einfach eine Platte zum Pool dazu und schon können wir weiterarbeiten, ohne Partitionen vergrößern zu müssen und Filesysteme ändern zu müssen. Einfach eine klasse Sache, diese “Storage Spaces”. Ersetzen Software-RAID und Logical Volume Manager (LVM). Sind einfacher zu konfigurieren und wesentlich flexibler.

Aber wir wollen die (virtuelle) Disk auch im OS nutzen bzw. einer VM zur Verfügung stellen. Noch die Disk initialisieren mit:

Initialize-Disk -VirtualDisk (Get-VirtualDisk -FriendlyName Exploration)

Wer mitgezählt hat, wird feststellen, dass die neue Disk die Nummer 15 haben müsste. Wir zeigen uns zur Sicherheit das an:

Get-Disk


Number Friendly Name                            OperationalStatus                    Total Size Partition Style
------ -------------                            -----------------                    ---------- ---------------
1      Hitachi HDP725050GLA360 ATA Device       Online                                465.76 GB MBR
10     WD My Book USB Device                    Offline                               931.51 GB MBR
15     Microsoft Storage Space Device           Online                                     5 TB GPT
7      Microsoft Storage Space Device           Offline                                   10 TB GPT
8      Microsoft Storage Space Device           Offline                                   10 TB GPT
9      WD My Book USB Device                    Offline                               931.51 GB MBR

Es ist tatsächlich die Nummer 15 :-)

Nun können wir – wie bei einer ganz normalen Platte – eine neue Partition anlegen:

New-Partition -DiskNumber 15 -UseMaximumSize -AssignDriveLetter


Disk Number: 15
PartitionNumber  DriveLetter Offset                                        Size Type
---------------  ----------- ------                                        ---- ----
2                D           135266304                                     5 TB Basic	

Die “Reserved” Partition mit PartitionNumber 1 wird bei dieser Ausgabe nicht angezeigt.

Jetzt noch formatieren mit der Angabe des DriveLetter (in unserem Fall ist es D):

Format-Volume -DriveLetter D

mit Return bzw. “Y” bestätigen


Confirm
Are you sure you want to perform this action?
Warning, all data on the volume will be lost!
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): y

DriveLetter       FileSystemLabel  FileSystem       DriveType        HealthStatus        SizeRemaining    Size
-----------       ---------------  ----------       ---------        ------------        -------------    ----
D                                  NTFS             Fixed            Healthy                      5 TB    5 TB			

Letzte Überprüfung, ob alles korrekt funktioniert hat mit:

Get-Volume


DriveLetter       FileSystemLabel  FileSystem       DriveType        HealthStatus        SizeRemaining        Size
-----------       ---------------  ----------       ---------        ------------        -------------        ----
System Reserved  NTFS             Fixed            Healthy                  109.8 MB           350 MB
D                                  NTFS             Fixed            Healthy                      5 TB        5 TB
C                                  NTFS             Fixed            Healthy                 265.66 GB   465.42 GB
CD-ROM           Healthy                       0 B              0 B
E                 HRM_SSS_X64FR... UDF              CD-ROM           Healthy                       0 B     3.44 GB	

Festplatte “D” ist da, ist formatiert und kann benutzt werden. Falls man vor hat, die neue Festplatte einer VM zur Verfügung zu stellen, muss man sie “Offline” setzen.

Set-Disk -Number 15 -IsOffline $true

Nur dann kann man ein “Physical Drive” einer VM zuordnen.

z.B.:

Get-VMScsiController -VMName Exchange2013 -ControllerNumber 0 | Add-VMHardDiskDrive -DiskNumber 15

Bjarne Stroustrup zum Thema schlechter Code

Ich habe mehr fürchterlichen Code gesehen, als ich mir jemals hätte träumen lassen. Schlechter Code ist natürlich kein reines C++-Problem, und vielleicht war der schlechteste, den ich gesehen habe, noch nicht einmal in C++ verfasst. Allerdings fühle ich mich für C++-Code ein wenig verantwortlich. Ich vermute, dass das Problem weit über C++ herausgeht und eher mit einem Versagen in der Ausbildung zu tun hat, wo sich Grundlagen der Informatik teilweise nicht als wichtiges Thema durchsetzen konnten. Es scheint so, als würde das US-amerikanische Bildungssystem in diesem Bereich einige Wissenschaftler, Horden von angelernten “Codern” und bei weitem zu wenig Leute mit einer ausgewogenen Mischung aus zur Softwareentwicklung notwendigen Fähigkeiten (zum Beispiel ein stabiles Grundlagenwissen in den Bereichen Mathematik, Datenstrukturen, Algorithmen, Rechnerarchitektur, Design- und Programmierungstechniken, Systementwicklung, Tests, Qualitätssicherung und ein gutes Verständnis des Anwendungsbereichs) und einer professionellen Einstellung hervorbringen. Der Versuch, das alles durch das Design einer Sprache abfangen zu wollen, ist wahrscheinlich unmöglich und – was noch schlimmer ist – macht das Einführen besserer Techniken und das Aktualisieren unserer Toolchains (wozu auch Programmiersprachen zählen) schwerer.
Das gesamte Interview.