Windows Server 2012 includes a new storage model. It follows in the footsteps of ZFS and btrfs, in that it uses a pooled disk model, and attempts to combine all of the functionality of RAID, LVM, and the file system. Now this looks like a 1.0 from the perspective of integration, however I am quite impressed by the implementation from the usability perspective. While it is not as polished and integrated the flow is consistent and when using the GUI it is very simple to actually configure your storage. That said this feels like multiple layers.
Usability Comparison to ZFS
To give you an idea of what I would expect lets look at how it works in ZFS.
In ZFS you configure a pool of disks, where we have disk0-4 and want to name the pool tank.
# zpool create tank mirror disk0 disk1 mirror disk2 disk3
Then you configure file systems on top of that, in this case fs1 on tank with a size of 10G.
# zfs create 10G tank/fs1
Regardless of which camp you are in the above commands are simple to understand and can be easily modified to suit my use case.
Interpretation of What is Being Done
Now as far as I can tell Microsoft has integrated VHD files into the solution in order to expose this functionality. I don’t have a technical problem with this, however at this point there is a lot of manual work that has to be done in order to get to the point where I have a usable file system. So you create your pool with your disks (this is no different from ZFS, however in ZFS this is where your RAID is performed. Whereas in the Storage Pool/Spaces implementation they are doing that on the file system level (I suspect with software RAID on top of VHD files). Once the pool is up and configured you create a Virtual Disk, where you will assign your resiliency (RAID level), then initialize the Virtual Disk, create a partition on the Virtual Disk, and finally format the Virtual Disk. Now I am not saying that you shouldn’t have to technically do all of these things, however for this to have the seamless experience that they are trying to go for, they will need to put a bit more polish on this.
Find Our Physical Disks
As you can see we have a 25GB disk for our OS, which has the “CanPool” as False, this is because it is the system disk, and it is already being used. We also have 2 10GB disks and 6 5GB disks. I am doing this testing on my Virtualbox Windows 2012, so the disks are simple to scale out. So the goal is to get them all in the same pool. But in order to be more thorough we will be creating the pool with ONLY the 5GB disks, and then adding the 10GB disk, just to prove that we can.
PS> Get-PhysicalDisk FriendlyName CanPool OperationalStatus HealthStatus Usage Size ------------ ------- ----------------- ------------ ----- ---- PhysicalDisk0 False OK Healthy Auto-Select 25 GB PhysicalDisk1 True OK Healthy Auto-Select 5 GB PhysicalDisk2 True OK Healthy Auto-Select 5 GB PhysicalDisk3 True OK Healthy Auto-Select 5 GB PhysicalDisk4 True OK Healthy Auto-Select 5 GB PhysicalDisk5 True OK Healthy Auto-Select 5 GB PhysicalDisk6 True OK Healthy Auto-Select 5 GB PhysicalDisk7 True OK Healthy Auto-Select 10 GB PhysicalDisk8 True OK Healthy Auto-Select 10 GB
Assign our Disks to a Variable
PS> $disk = Get-PhysicalDisk | where {$_.size -eq "5GB"}
PS> $disk FriendlyName CanPool OperationalStatus HealthStatus Usage Size ------------ ------- ----------------- ------------ ----- ---- PhysicalDisk1 True OK Healthy Auto-Select 5 GB PhysicalDisk2 True OK Healthy Auto-Select 5 GB PhysicalDisk3 True OK Healthy Auto-Select 5 GB PhysicalDisk4 True OK Healthy Auto-Select 5 GB PhysicalDisk5 True OK Healthy Auto-Select 5 GB PhysicalDisk6 True OK Healthy Auto-Select 5 GB
Check the Name of the Storage SubSystem
I am assuming that you could wildcard this to your PC name or to Storage Spaces, but I didn’t want to document it that way since I am not sure how it would behave if you have multiple pools.
PS> Get-StorageSubSystem FriendlyName HealthStatus OperationalStatus ------------ ------------ ----------------- Storage Spaces on WIN-PTP6J8CKQNG Healthy OK
Create the New Storage Pool
Here we are going to combine the variable we assigned earlier, with the name of the Storage SubSystem to create our new pool. Then we will check the pools on the machine. You might have noticed this before, but there is a Primordial pool, which holds disks which have not been assigned. Sounds like someone at Microsoft has a sense of humor. It is the goo from which your pool rises.
PS> New-StoragePool -StorageSubSystemFriendlyName "Storage Spaces on WIN-PTP6J8CKQNG" -FriendlyName pool0 -PhysicalDisks $disk FriendlyName OperationalStatus HealthStatus IsPrimordial IsReadOnly ------------ ----------------- ------------ ------------ ---------- pool0 OK Healthy False False
PS> Get-StoragePool FriendlyName OperationalStatus HealthStatus IsPrimordial IsReadOnly ------------ ----------------- ------------ ------------ ---------- Primordial OK Healthy True False pool0 OK Healthy False False
Add Additional Disks to the Pool
Assign the new disks to a variable, the same way we did before.
PS> $newdisk = Get-PhysicalDisk | where {$_.size -eq "10GB"}
PS> $newdisk FriendlyName CanPool OperationalStatus HealthStatus Usage Size ------------ ------- ----------------- ------------ ----- ---- PhysicalDisk7 True OK Healthy Auto-Select 10 GB PhysicalDisk8 True OK Healthy Auto-Select 10 GB
Here we use the Add-PhysicalDisks cmdlet to add them to the Pool. Now from a user experience this command is hard to find. It should probably be a Modify-StoragePool or Add-StoragePoolMembers or similar.
PS> Add-PhysicalDisk -PhysicalDisks $newdisk -StoragePoolFriendlyName pool0
Create Virtual Disk (vdisk0)
This is pretty straight forward. We are just creating a disk.
PS> New-VirtualDisk -StoragePoolFriendlyName pool0 -FriendlyName vdisk0 -ResiliencySettingName mirror -ProvisioningType Thin -Size 30GB FriendlyName ResiliencySettingNa OperationalStatus HealthStatus IsManualAttach Size me ------------ ------------------- ----------------- ------------ -------------- ---- vdisk0 Mirror OK Healthy False 30 GB
Initialize Disk (vdisk0)
The next step is to initialize it.
PS> Get-VirtualDisk vdisk0 | Initialize-Disk -PartitionStyle GPT
Create and Initialize Virtual Disk (vdisk1)
I combined the above two steps into one, via some powershell magic. Functionally the same things are happening though.
PS> New-VirtualDisk -StoragePoolFriendlyName pool0 -FriendlyName vdisk1 -ResiliencySettingName mirror -ProvisioningType Thin -Size 30GB | Initialize-Disk -PartitionStyle GPT
Partition and Format the Virtual Disk
Here is where it gets interesting. I have combined everything into one step, but we have two distinct actions, the creation of the partition, and the formatting of the volume that is created (via the partitioning). In the formatting, you have your choice of file system (of course the FAT’s but also NTFS and ReFS which is the interesting one). If you are logged into the GUI this step will also result in a Windows Explorer pop-up asking if you want to format the disk, you can cancel that you are formatting via the command line.
PS> get-disk | where {$_.uniqueid -eq ((Get-VirtualDisk vdisk0).UniqueId)} | New-Partition -UseMaximumSize -AssignDriveLetter | Format-Volume -FileSystem NTFS
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"):
DriveLetter FileSystemLabel FileSystem DriveType HealthStatus SizeRemaining Size
----------- --------------- ---------- --------- ------------ ------------- ----
E NTFS Fixed Healthy 29.78 GB 29.87 GB
Also if you’d like to do the above without having to confirm your action, pass Format-Volume with -Confirm:$false to avoid that confirmation.
PS> get-disk | where {$_.uniqueid -eq ((Get-VirtualDisk vdisk0).UniqueId)} | New-Partition -UseMaximumSize -AssignDriveLetter | Format-Volume -FileSystem NTFS -Confirm:$false
Well there you have it. All and all I think it is an interesting concept, though it definitely needs some work around integrating the components.