Virtualization: from drives to LUNs, the big picture
-
Phase 0: Start here
-
Phase 1: The hardware
-
Phase 2: Virtualization
-
Phase 3: Resilience and data protection
-
Phase 4: Generations, models and rack layouts
-
Phase 5: Wrap-up
DS8000 virtualization is the way a DS8000 takes a shelf full of flash drives and turns them into the tidy disks your servers see, such as /dev/mapper/mpatha on Linux or Disk 3 in Windows. The host never touches a real drive; what it gets is a logical volume the DS8000 has built from small slices of many drives.
You met the parts inside the frame in the hardware lessons, and now you’ll climb the software ladder that sits on top of them: array sites, arrays, ranks, extent pools, volumes, LSSs and volume groups. Every rung has its own job, and once those jobs are clear, the DS CLI commands in the rest of this course start to make sense.
Think of this as the map lesson for the virtualization phase. Lessons 10 to 17 zoom into one rung each, but here you build the whole ladder once, end to end, in the practice shell, so you’ve seen how the pieces fit before you study them one by one.
Phase 2 roadmap: 9 Virtualization (you are here) → 10 RAID → 11 Ranks and extents → 12 Extent pools → 13 FB and CKD volumes → 14 LSS and LCU → 15 Thin provisioning → 16 Easy Tier → 17 Volume groups.
| Time | You need | By the end you can |
|---|---|---|
| 60 to 75 minutes | Python 3 and the practice shell in C:\ds8k-lab (set up in Lesson 1) | Name the seven layers in order, say what each one adds, and build a drive-to-host chain with mkarray, mkrank, mkextpool, mkfbvol and mkhost |
What it is, in one line
DS8000 virtualization is a stack of layers that takes groups of 8 physical drives, protects them, slices them, pools the capacity and hands it to hosts as logical volumes they treat like real disks.
In Simple Words
A chocolate factory and its gift boxes
Imagine a chocolate factory where big slabs of chocolate come out of the kitchen, always eight slabs on a tray. A worker first wraps each tray in strong foil so that if one slab breaks it can be rebuilt from the others, and then a machine cuts the tray into small, equal squares. All the squares end up in two big bins, one on the left side of the shop and one on the right. When a customer orders a gift box of 100 squares, the shopkeeper fills it from a bin, picking a few squares from lots of different trays. The customer never sees a tray, only a nice box with a label on it, and the shop’s register says which customer may collect which box.
In a DS8000, the tray of eight slabs is an array site, and wrapping it in foil (RAID) turns it into an array. Cutting it into squares gives you a rank full of extents, and the two bins are extent pools, one per server. The gift box is a volume, its label is the volume ID with its LSS, and the register is the volume group that decides which host may see which volumes.
Engineer's View
The seven layers, with the real rules
IBM’s Redbook for the DS8A00 describes virtualization as abstracting physical drives into logical volumes that hosts treat as physical drives. On open systems those are LUNs, and on IBM Z they are 3390 volumes. Here are the layers, from the bottom up:
| Layer | What it is | Key rules on DS8A00 |
|---|---|---|
| Array site | 8 identical drives (same capacity and class) | The system chooses these at install time and balances them across both enclosures of an HPFE Gen3 pair, with up to 6 array sites per HPFE pair. There’s no server affinity at this stage. |
| Array | One array site with a RAID level | There’s always one array per array site. You get RAID 6 (the default) or RAID 10; RAID 5 isn’t supported. Types: 5+P+Q+S, 6+P+Q, 3+3+2S, 4+4. |
| Rank | The array formatted as FB or CKD and cut into extents | There’s one rank per array, so people use rank and array almost as synonyms. FB extents are 1 GiB (large) or 16 MiB (small), and CKD extents are 1113 cylinders or 21 cylinders. If you encrypt, the encryption group has to exist before the first rank. |
| Extent pool | A set of ranks of the same type and extent size | This is where server affinity gets decided: rank group 0 belongs to server 0 and rank group 1 to server 1, so you need at least two pools, one per server. Small extents are the default. |
| Logical volume | A set of extents from one pool | You can have up to 65,280 volumes in total. An FB LUN goes up to 16 TiB (4 TiB if you use Copy Services), and a CKD volume up to 1,182,006 cylinders, which is about 1 TB. |
| LSS / LCU | The group a volume belongs to, set by its ID | Up to 255 LSSs, with IDs 00 to FE (FF is reserved), and up to 256 volumes in each. Even LSSs belong to server 0 and odd ones to server 1. Each address group of 16 LSSs is either all FB or all CKD. |
| Volume group + host | Which volumes a host may see | Only FB needs volume groups. You can have up to 8,320 volume groups and 8,192 host attachments, and the DS GUI quietly creates the volume group for you in the background. |
A volume ID has four hex digits, XYZZ, where X is the address group, XY is the LSS and ZZ is the volume inside that LSS. So volume 2101 is the second volume in LSS 21, in address group 2, and server 1 owns it because 21 is odd.
There’s one thing the table can’t show you: a rank and an LSS have no fixed link. A volume in LSS 20 can take extents from any rank in a server 0 pool, and that freedom is a big part of why DS8000 virtualization is so flexible.
On DS8900F: the layers and rules are the same. The drives sit in HPFE Gen2 enclosures rather than Gen3, but arrays, ranks, pools and LSSs behave the same way.
How it works, step by step
Follow eight brand-new flash drives all the way up to a Linux server, using a typical project at work: the database team has asked for two 100 GiB disks for a new application server called saat_host1.
1Drives become an array site
When IBM’s service engineer installs an HPFE Gen3 pair, the DS8000 groups its drives into array sites of 8. You don’t get to choose which drives go together; the system picks them so that each site is spread over both enclosures of the pair and both paths to the servers.
The array site also settles which drives stay as spares. Every HPFE Gen3 pair keeps two global spares, and they’re taken from the first 16 drives.
2The array site becomes a RAID array
You run mkarray and choose the RAID level, which on a DS8A00 means RAID 6 (the default) or RAID 10. The first two RAID 6 arrays in an HPFE pair are 5+P+Q+S, meaning five drives of data, two of parity and one spare, and the later arrays in the same pair are 6+P+Q.
Don’t read “P” and “Q” as two fixed parity drives. The parity rotates across all the members, so every drive does an equal share of the work.
3The array becomes a rank, cut into extents
mkrank formats the array as FB (for open systems) or CKD (for IBM Z) and slices it into extents. An FB extent is either 16 MiB (small, the default) or 1 GiB (large), and a CKD extent is 21 or 1113 cylinders.
Every extent is striped across all the drives in the array, so even one 16 MiB extent is served by every drive in the rank.
4Ranks go into an extent pool, and the pool picks a server
On its own, a rank belongs to nobody. Once you assign it to an extent pool with chrank -extpool, it picks up the pool’s rank group: rank group 0 is managed by server 0 and rank group 1 by server 1. That’s why a normal setup has pools in pairs, one for server 0 and one for server 1, so the two servers share the work.
5A volume is carved from the pool
mkfbvol takes extents from one pool and calls them a volume. The extents don’t need to sit next to each other, and by default they rotate across all the ranks in the pool, so a 100 GiB volume with small extents is 6,400 extents of 16 MiB.
A volume can never span two pools, though it can span every rank inside its own pool.
6The volume ID picks the LSS and the owning server
The ID you give a volume, say 2000, is more than a name. Its first two digits (20) are the LSS; an even LSS means server 0 and an odd one means server 1, and the volume has to come from a pool in the matching rank group.
For FB, the LSS is created automatically along with its first volume. For CKD you have to create the LCU yourself first, with mklcu.
7A host and its volume group decide who can see it
Last of all, you tell the DS8000 who the host is by giving it the WWPNs, the worldwide port names of the host’s HBAs, and then you map volumes to it. Behind the scenes the DS8000 keeps a volume group, a named list of the volumes this host is allowed to access. Any host that isn’t on that list sees nothing, even if it’s zoned to the same ports. That’s the top rung, and from here the host scans its bus and finds its new disks.
You’ll notice the DS GUI does steps 2 to 4 in one wizard and hides volume groups from you completely. The DS CLI lets you run each step separately, which is why the lab shows you every layer.
Hands-on lab: build the whole ladder from drive to host
Before you run any command, double-check it
Read every command twice before you press Enter. Check the target: the system or account, the IDs, the names and the sizes. These commands are for learning and were tested in our lab, not on your system. At work, run the read-only list commands first, follow your change process, make sure a backup exists, and ask a second person to check anything that changes or deletes data. You run them at your own risk.
In the lab you’ll build the whole ladder once: one array site → one RAID 6 array → one rank → one extent pool → two volumes → one host that can see them. Open PowerShell, go to your lab folder and log in to the practice shell the same way as in Lesson 1 (cd C:\ds8k-lab, then python ds8sim.py). If it isn’t installed yet, you can get it from the DS8000 practice shell page.
Practice shell note: the practice shell is our own teaching tool, not IBM software. Real DS CLI output looks very close to this but isn’t identical. Messages starting with SIM, plus a few CMU messages listed on the practice shell page (in this lesson, CMUN02805E and CMUN02030E in the break lab), come from the practice shell. The boxes below show what the shell printed for us, and only the date and time will be different for you.
1Start clean and pick an array site
Every lab starts from the factory state. After the reset, look only at the FlashTier2 array sites, because those are the ones you’ll use today.
Type these at the dscli> prompt:
simctl reset
lsarraysite -l -diskclass FlashTier2You should see this:
dscli> simctl reset
SIM0100I simctl: factory state restored (users and passwords kept; use simctl reset -all to reset them too).
dscli> lsarraysite -l -diskclass FlashTier2
Date/Time: 24 October 2026 10:41:07 UTC IBM DSCLI Version: 7.10.10.348 DS: IBM.2107-78SV001
arsite DA Pair dkcap (10^9B) diskrpm State Array diskclass encrypt
==========================================================================
S7 2 3840.0 65000 Unassigned - FlashTier2 supported
S8 2 3840.0 65000 Unassigned - FlashTier2 supportedsimctl is a practice shell command, not part of DS CLI. In the table, S7 and S8 are two array sites of 8 drives each, dkcap 3840.0 means 3.84 TB drives (decimal, 10^9 bytes), and DA Pair 2 is the flash RAID adapter pair that drives them.
State Unassigned and Array - tell you no RAID has been built yet. This is layer 1, which is all you get out of the box.
✅ Checkpoint: Both FlashTier2 array sites show State Unassigned.
2Turn an array site into a RAID 6 array
Type these at the dscli> prompt:
mkarray -raidtype 6 -arsite S7
lsarray -lYou should see this:
dscli> mkarray -raidtype 6 -arsite S7
CMUC00004I mkarray: Array A0 successfully created.
dscli> lsarray -l
Date/Time: 24 October 2026 10:41:07 UTC IBM DSCLI Version: 7.10.10.348 DS: IBM.2107-78SV001
Array State Data RAIDtype arsite Rank DA Pair DDMcap (10^9B) diskclass encrypt
===========================================================================================
A0 Unassigned Normal 6 (5+P+Q+S) S7 - 2 3840.0 FlashTier2 supportedA0 is your first array, built from S7. Its RAIDtype 6 (5+P+Q+S) shows the system kept one drive of this site as a spare, since spares come from the first array sites in each enclosure pair. Rank - and State Unassigned mean the array hasn’t been formatted yet.
✅ Checkpoint: A0 exists with RAIDtype 6 (5+P+Q+S).
3Format the array as an FB rank
This lab DS8000 encrypts data at rest, which means every rank has to name the encryption key group, so check its number first.
Type these at the dscli> prompt:
lskeygrp
mkrank -array A0 -keygrp 1 -stgtype fb
lsrank -lYou should see this:
dscli> lskeygrp
Date/Time: 24 October 2026 10:41:07 UTC IBM DSCLI Version: 7.10.10.348 DS: IBM.2107-78SV001
ID state reckeystate reckeydate datakeydate keyprotocol type name
=======================================================================
1 accessible disabled - 10/01/2026 LOCAL DAR DAR_1
dscli> mkrank -array A0 -keygrp 1 -stgtype fb
CMUC00007I mkrank: Rank R0 successfully created.
dscli> lsrank -l
Date/Time: 24 October 2026 10:41:07 UTC IBM DSCLI Version: 7.10.10.348 DS: IBM.2107-78SV001
ID Group State datastate Array RAIDtype extpoolID extpoolnam stgtype exts usedexts keygrp marray extsize totalLogicalCap(MiB/cyl) usedLogicalCap(MiB/cyl) totalPhysicalCap(MiB/cyl) usedPhysicalCap(MiB/cyl) compressionRatio compressionType
=====================================================================================================================================================================================================================================================
R0 - Unassigned Normal A0 6 - - fb 1132965 0 1 MA1 16MiB 18127440 0 18127441 0 1.00 noneTake a moment over the long line. R0 sits on array A0, its stgtype is fb and its extsize is 16MiB, the default small extent. exts 1132965 is the number of 16 MiB slices in the rank, and usedexts 0 tells you none of them are in use yet.
Now look at Group - and extpoolID -: the rank has no server yet. This is the Redbook rule at work, where server affinity comes from the pool and not from the rank.
✅ Checkpoint: R0 shows extsize 16MiB, Group – and State Unassigned.
4Create a pool for server 0 and give it the rank
Type these at the dscli> prompt:
mkextpool -rankgrp 0 -keygrp 1 -stgtype fb lab_fb_0
chrank -extpool P0 R0
lsextpoolYou should see this:
dscli> mkextpool -rankgrp 0 -keygrp 1 -stgtype fb lab_fb_0
CMUC00000I mkextpool: Extent pool P0 successfully created.
dscli> chrank -extpool P0 R0
CMUC00008I chrank: Rank R0 successfully modified.
dscli> lsextpool
Date/Time: 24 October 2026 10:41:07 UTC IBM DSCLI Version: 7.10.10.348 DS: IBM.2107-78SV001
Name ID stgtype rankgrp status availstor (2^30B) %allocated available reserved numvols
==========================================================================================
lab_fb_0 P0 fb 0 below 17701 0 1132901 64 0The pool got ID P0 and rankgrp 0, so server 0 now manages R0. availstor 17701 is roughly 17.3 TiB you can hand out, and available 1132901 is the free extent count, 64 fewer than the rank because the shell holds back a small reserve per rank (you’ll see it under reserved).
status below means the pool is under its warning threshold, which is where you want it.
✅ Checkpoint: lsextpool shows P0 with rankgrp 0 and about 17,701 GiB available.
5Carve two volumes and look at their LSS
Type these at the dscli> prompt:
mkfbvol -extpool P0 -cap 100 -name app_#h 2000-2001
lsfbvol
lslssYou should see this:
dscli> mkfbvol -extpool P0 -cap 100 -name app_#h 2000-2001
CMUC00025I mkfbvol: FB volume 2000 successfully created.
CMUC00025I mkfbvol: FB volume 2001 successfully created.
dscli> lsfbvol
Date/Time: 24 October 2026 10:41:07 UTC IBM DSCLI Version: 7.10.10.348 DS: IBM.2107-78SV001
Name ID accstate datastate configstate deviceMTM datatype extpool cap (2^30B) cap (10^9B) cap (blocks)
============================================================================================================
app_2000 2000 Online Normal Normal 2107-900 FB 512 P0 100.0 - 209715200
app_2001 2001 Online Normal Normal 2107-900 FB 512 P0 100.0 - 209715200
dscli> lslss
Date/Time: 24 October 2026 10:41:07 UTC IBM DSCLI Version: 7.10.10.348 DS: IBM.2107-78SV001
ID Group addrgrp stgtype confgvols subsys
=========================================
20 0 2 fb 2 0xFF20The #h in the name was replaced by each volume’s hex ID, which is how you ended up with app_2000 and app_2001. Each is 100 GiB, or 209,715,200 blocks of 512 bytes, and deviceMTM 2107-900 is the device type the host will report.
You never ran a command to make an LSS, and yet lslss shows LSS 20, because FB LSSs appear on their own with their first volume. Group 0 matches the even number, and addrgrp 2 is the address group (the first digit of the ID).
✅ Checkpoint: lslss shows LSS 20 in Group 0 with 2 volumes.

6Give a host access to the volumes
The Linux server saat_host1 has two HBA ports, and their WWPNs are already logged in to the lab DS8000.
Type these at the dscli> prompt:
mkhost -type "Linux Server" -hostport 10000090FA13B914,10000090FA13B915 saat_host1
chhost -action map -volume 2000-2001 saat_host1
lsvolgrp
showhost saat_host1You should see this:
dscli> mkhost -type "Linux Server" -hostport 10000090FA13B914,10000090FA13B915 saat_host1
CMUC00530I mkhost: The host saat_host1 is successfully created.
dscli> chhost -action map -volume 2000-2001 saat_host1
CMUC00531I chhost: The host saat_host1 is successfully modified.
dscli> lsvolgrp
Date/Time: 24 October 2026 10:41:07 UTC IBM DSCLI Version: 7.10.10.348 DS: IBM.2107-78SV001
Name ID Type
==========================
saat_host1 V0 SCSI Map 256
dscli> showhost saat_host1
Date/Time: 24 October 2026 10:41:07 UTC IBM DSCLI Version: 7.10.10.348 DS: IBM.2107-78SV001
Name saat_host1
Type Linux Server
State Online
AddrMode scsimap256
Volumes 2
Host ports 2
I/O ports 16 (all)
AddrDiscovery lunpolling
LBS 512
Cluster -You mapped volumes to a host, and the DS8000 quietly created volume group V0 for it, type SCSI Map 256, which is the hidden top layer. State Online means the host ports are logged in, and AddrDiscovery lunpolling is the way a Linux host finds its LUNs.
I/O ports 16 (all) means the host is allowed to log in through any DS8000 port, and the SAN zoning decides which ones it ends up using. You’ll look at volume groups properly in Lesson 17.
✅ Checkpoint: showhost shows Volumes 2 and State Online.
7Check every layer with a script
So why 1,132,965 extents? Let a script walk the whole ladder for you, the way storage teams check a new box: it asks the DS CLI about each layer and puts the maths next to the real numbers.
Save it on your laptop as C:\ds8k-lab\layers.py, next to ds8sim.py. It runs on the laptop, not on the DS8000.
A script can’t answer password prompts, so you need to save your password in a password file first. If security.dat and auto.profile are already in your lab folder from an earlier lesson, skip this part (the shell would only tell you the record already exists).
Run this (PowerShell, with your own password both times):
python ds8sim.py -hmc1 10.0.0.1 -user admin -passwd YourPassw0rd managepwfile -action add -name admin -pw YourPassw0rd -pwfile security.datYou should see this:
CMUC00206I managepwfile: Record 10.0.0.1/admin successfully added to password file security.dat.Then save these eight lines as auto.profile in the same folder. With banner: off, header: on and format: delim, every list comes back as one header row followed by comma-separated rows, which Python reads easily. Implementation Lesson 2 covers profiles in full.
auto.profile:
hmc1: 10.0.0.1
username: admin
pwfile: security.dat
devid: IBM.2107-78SV001
banner: off
header: on
format: delim
delim: ,Now save the script. It runs lsarraysite, lsarray, lsrank, lsextpool, lsfbvol and lsvolgrp through the profile, one layer after another.
The script:
# layers.py - walk the DS8000 virtualization ladder: array site -> array -> rank -> pool -> volumes -> volume group
# Runs on your workstation or jump server, not on the DS8000.
# It talks to the DS8000 only through the DS CLI (auto.profile: banner off, header on, format delim).
import csv, re, subprocess
DSCLI = ["python", "ds8sim.py", "-cfg", "auto.profile"] # at work: ["dscli", "-cfg", "auto.profile"]
def dscli(*args):
"""Run one DS CLI command and return its rows as dictionaries."""
out = subprocess.run(DSCLI + list(args), capture_output=True, text=True).stdout
lines = [l for l in out.splitlines() if l and not l.startswith("SaatVedha") and not l.startswith("CMUC")]
return list(csv.DictReader(lines))
TB, GiB, MiB = 10**12, 2**30, 2**20 # drive makers use decimal TB
DRIVES_PER_SITE = 8 # every DS8A00 array site has 8 drives
def data_drives(raidtype): # "6 (5+P+Q+S)" -> 5, "10 (4x2)" -> 4
m = re.search(r"\((\d+)", raidtype)
return int(m.group(1))
def show(layer, what, text):
print(f"{layer} {what:<16}: {text}")
sites = {s["arsite"]: s for s in dscli("lsarraysite", "-l")}
ranks = {r["Array"]: r for r in dscli("lsrank", "-l")}
pools = {p["ID"]: p for p in dscli("lsextpool", "-l")}
vols = dscli("lsfbvol", "-l")
for a in dscli("lsarray", "-l"):
drive = float(a["DDMcap (10^9B)"]) * 10**9
raw = DRIVES_PER_SITE * drive
usable = data_drives(a["RAIDtype"]) * drive
show(1, f"Array site {a['arsite']}", f"{DRIVES_PER_SITE} x {drive/TB:.2f} TB {sites[a['arsite']]['diskclass']} = {raw/TB:.2f} TB raw")
show(2, f"Array {a['Array']}", f"RAID {a['RAIDtype']} -> {usable/TB:.2f} TB = {usable/GiB:,.0f} GiB")
r = ranks.get(a["Array"])
if not r:
show(3, "Rank", "none yet")
continue
ext = 16 * MiB if r["extsize"] == "16MiB" else GiB
maths = int(usable // ext)
exts = int(r["exts"])
show(3, f"Rank {r['ID']}", f"{exts:,} extents of {r['extsize']} (pure maths {maths:,}, {100*(maths-exts)/maths:.1f}% less)")
p = pools.get(r["extpoolID"])
if not p:
show(4, "Pool", "none yet")
continue
avail = int(p["available"])
show(4, f"Pool {p['ID']} {p['Name']}", f"rank group {p['rankgrp']}, {avail:,} extents available = {int(p['availstor (2^30B)']):,} GiB")
for v in vols:
if v["extpool"] == p["ID"]:
gib = int(v["cap (blocks)"]) * 512 / GiB
show(5, f"Volume {v['ID']}", f"{v['Name']}, {gib:.0f} GiB = {int(gib*GiB // ext):,} extents")
print(f" Room left in {p['ID']} for {avail // int(100*GiB // ext)} more 100 GiB volumes")
groups = dscli("lsvolgrp")
show(6, "Volume groups", ", ".join(f"{g['ID']} {g['Name']} ({g['Type']})" for g in groups) or "none")Run this in a second PowerShell window in C:\ds8k-lab:
python layers.pyYou should see this:
1 Array site S7 : 8 x 3.84 TB FlashTier2 = 30.72 TB raw
2 Array A0 : RAID 6 (5+P+Q+S) -> 19.20 TB = 17,881 GiB
3 Rank R0 : 1,132,965 extents of 16MiB (pure maths 1,144,409, 1.0% less)
4 Pool P0 lab_fb_0: rank group 0, 1,120,101 extents available = 17,501 GiB
5 Volume 2000 : app_2000, 100 GiB = 6,400 extents
5 Volume 2001 : app_2001, 100 GiB = 6,400 extents
Room left in P0 for 175 more 100 GiB volumes
6 Volume groups : V0 saat_host1 (SCSI Map 256)The raw 30.72 TB shrinks to 19.20 TB after RAID 6 and the spare, since only 5 of the 8 drives hold data. On paper that gives 1,144,409 extents, but the rank has 1,132,965, about 1% less, because the practice shell keeps that 1% back as a stand-in for formatting and metadata.
A real DS8000 also gives up some space to metadata, but its figures come from IBM’s own formulas, so expect a different number on a real box. What you should remember is that each layer costs a bit of capacity, and the host never gets the raw TB.
At work you’d run the same script from a jump server with dscli instead of ds8sim.py, so after each build you can print the full ladder of a box in one go and attach it to the change record.
✅ Checkpoint: Your script prints 6,400 extents for each 100 GiB volume and room for 175 more.
Type quit when you’re done.
Break It, Then Fix It
Keep the shell open from the lab. You’ll add a second array and then try to put a volume on the wrong server, two mistakes that turn up in real projects, usually because someone skipped a layer.
1Break it: build a rank and forget a layer
Make an array from the second site, then create the rank the way a lot of people type it the first time.
Type these at the dscli> prompt:
mkarray -raidtype 6 -arsite S8
mkrank -array A1 -stgtype fbYou’ll get this error:
dscli> mkarray -raidtype 6 -arsite S8
CMUC00004I mkarray: Array A1 successfully created.
dscli> mkrank -array A1 -stgtype fb
CMUN02805E mkrank: The -keygrp parameter is required because data-at-rest encryption is enabled. Run lskeygrp to see the encryption key group ID.Why: this lab system has an encryption group, and the Redbook rule is “all or nothing”. Every rank has to belong to that one encryption group, so the rank command needs to be told which one. The wording of this message comes from the practice shell; a real DS8000 refuses too, but may phrase it differently.
The bigger point is about layers. Encryption is decided before the first rank exists, and if a company wants it later, it has to delete the whole logical configuration and rebuild it, then restore the data from backup.
Fix it:
mkrank -array A1 -keygrp 1 -stgtype fb
lsrankYou should see this:
dscli> mkrank -array A1 -keygrp 1 -stgtype fb
CMUC00007I mkrank: Rank R1 successfully created.
dscli> lsrank
Date/Time: 24 October 2026 10:41:07 UTC IBM DSCLI Version: 7.10.10.348 DS: IBM.2107-78SV001
ID Group State datastate Array RAIDtype extpoolID stgtype
==============================================================
R0 0 Normal Normal A0 6 P0 fb
R1 - Unassigned Normal A1 6 - fbCompare the two rows. R0 is in pool P0, so it shows Group 0 and State Normal, while R1 has no pool and therefore no group and no server yet.
✅ Checkpoint: lsrank shows R1 with Group – and State Unassigned.
2Break it: put an odd LSS volume in a server 0 pool
The web team asks for a 50 GiB disk, and you give it ID 2100 so it lands on server 1, then type the pool you already have.
Type these at the dscli> prompt:
mkfbvol -extpool P0 -cap 50 -name web_#h 2100You’ll get this error:
dscli> mkfbvol -extpool P0 -cap 50 -name web_#h 2100
CMUN02030E mkfbvol: 21: Volumes in an odd LSS must be created in an extent pool of rank group 1. Extent pool P0 belongs to rank group 0.Why: ID 2100 puts the volume in LSS 21, which is odd, so server 1 has to own it, but P0 is a rank group 0 pool owned by server 0. The DS8000 won’t let one server manage a volume whose extents sit in the other server’s pool.
(The message text is from the practice shell.)
People forget this rule more than any other: the volume ID and the pool have to agree on the server.
To fix it, build the server 1 pool, give it R1, and create the volume there:
mkextpool -rankgrp 1 -keygrp 1 -stgtype fb lab_fb_1
chrank -extpool P1 R1
mkfbvol -extpool P1 -cap 50 -name web_#h 2100
lsextpool
lslssYou should see this:
dscli> mkextpool -rankgrp 1 -keygrp 1 -stgtype fb lab_fb_1
CMUC00000I mkextpool: Extent pool P1 successfully created.
dscli> chrank -extpool P1 R1
CMUC00008I chrank: Rank R1 successfully modified.
dscli> mkfbvol -extpool P1 -cap 50 -name web_#h 2100
CMUC00025I mkfbvol: FB volume 2100 successfully created.
dscli> lsextpool
Date/Time: 24 October 2026 10:41:07 UTC IBM DSCLI Version: 7.10.10.348 DS: IBM.2107-78SV001
Name ID stgtype rankgrp status availstor (2^30B) %allocated available reserved numvols
==========================================================================================
lab_fb_0 P0 fb 0 below 17501 1 1120101 64 2
lab_fb_1 P1 fb 1 below 17651 0 1129701 64 1
dscli> lslss
Date/Time: 24 October 2026 10:41:07 UTC IBM DSCLI Version: 7.10.10.348 DS: IBM.2107-78SV001
ID Group addrgrp stgtype confgvols subsys
=========================================
20 0 2 fb 2 0xFF20
21 1 2 fb 1 0xFF21
Now you have the shape every real DS8000 should have, a pool pair with one pool per server. LSS 20 (even, Group 0) holds two volumes and LSS 21 (odd, Group 1) holds one, and both sit in address group 2, which has now become an FB address group.
Check the pools as well. P0’s availstor went down from 17,701 to 17,501 GiB, which is the 200 GiB of your two volumes, and P1 shows 17,651 GiB, the same size rank minus the 50 GiB web volume.
✅ Checkpoint: lslss shows LSS 20 in Group 0 and LSS 21 in Group 1.
This happened at work
The 96 TB promise that was really 60
A logistics company was moving its warehouse tracking system onto a new DS8000, and in one of the planning meetings someone asked the newly hired storage admin how much space the new HPFE pair would give. He counted the drives on the order, 32 drives of 3.84 TB, and said “about 120 TB, so the 96 TB you asked for fits easily”. In his head one drive was one LUN, because at his last job, on a small array, he had handed whole disks to servers.
The application team planned the whole migration around that number. Two weeks before go-live the storage team built the arrays, and the four array sites gave two 5+P+Q+S arrays and two 6+P+Q arrays, so only 22 of the 32 drives held data. Once RAID, spares and metadata were taken out, the pools held a little over 75 TiB, not 120, and since the team also had to leave free space in the pools for Easy Tier and growth, the real budget for volumes was closer to 60 TiB.
Impact: the migration slipped by six weeks while a second HPFE pair was ordered and installed, and the warehouse had to run on the old, slow array through its busiest season of the year.
Root cause: nobody had done the layer maths. Raw TB got quoted as usable capacity, and no one in that meeting asked “after RAID and spares?”
Fix: these days the team sizes every request from the top down: the volumes needed, plus pool headroom, plus metadata, then RAID 6 and spares, and only then drives. IBM’s sizing tool, or a small spreadsheet like the calculator in this lesson, gets you the same answer in a few minutes.
Lesson: a host never gets a drive; it gets extents from a pool that sits on RAID arrays. Quote usable capacity, and always say which layer your number comes from.
Common mistakes and troubleshooting
| Symptom | Likely cause | What to check / fix |
|---|---|---|
| Capacity promised to a project is far more than the pool shows | Raw drive TB quoted as usable | Work it out per array: 5 or 6 data drives out of 8 with RAID 6, then extents, then metadata. Check the availstor in lsextpool. |
mkfbvol refuses an ID with a rank group error | Odd LSS ID with a rank group 0 pool, or even ID with a rank group 1 pool | Even LSS IDs go in rank group 0 pools and odd ones in rank group 1. Check rankgrp in lsextpool. |
| A new rank is not giving any space | Rank created but never assigned to a pool | Run lsrank. If you see Group – and State Unassigned, it still needs chrank -extpool. |
| All the load sits on one server | Only one pool, or all volumes in even LSSs | Build your pools in pairs and spread volumes across even and odd LSSs. |
| A host is zoned but sees no disks | No host or no mapping, so the volume group is empty | Check showhost for Volumes and lsvolgrp. |
| FB volume creation fails in a whole range of IDs | The address group was already claimed by CKD | An address group (16 LSSs) is either all FB or all CKD, so use another range or check lslcu. |
| Someone wants to turn on encryption on a running system | Encryption group was not created before the ranks | That needs a full delete and rebuild of the logical configuration, so make the call on day one. |
When the numbers don’t add up, walk the ladder from the bottom: lsarraysite, lsarray, lsrank, lsextpool, lsfbvol, lslss, lsvolgrp. The problem usually sits in the first layer that looks wrong.
Keep a one-line note for each pool in your team wiki with its rank group, extent size, ranks and the LSS ranges it serves. It saves a lot of guesswork at 2 a.m.
Interview questions
Click a question to open it. Each one is worded the way an interviewer would ask it, and underneath you’ll find why they ask it and one way you could answer in your own words.
Fresher level
1. Can you walk me through the layers between a flash drive and a LUN on a DS8000?
Why they ask this: They want to know you can name the whole ladder in the right order, since nearly every other DS8000 question builds on it.
How you might answer: I’d start at the bottom. Eight identical drives make an array site, the array site becomes a RAID 6 or RAID 10 array, and that array gets formatted as an FB or CKD rank and cut into extents, 16 MiB or 1 GiB for FB.
The ranks then go into extent pools, and the pool’s rank group decides whether server 0 or server 1 owns them. A volume is a set of extents from one pool, its ID sets the LSS, and the volume group controls which host can see it.
2. Why does a host never see a physical drive on a DS8000?
Why they ask this: They’re checking whether you understand what virtualization gives you, because a lot of freshers think a LUN is a slice of one disk.
How you might answer: A volume is built from extents, and each extent is striped across all the drives in a RAID array. On top of that, by default the extents of one volume rotate across all the ranks in the pool.
So a single LUN is spread over a lot of drives, which helps performance, and it means the DS8000 can delete, grow or move volumes without the host caring where the bytes live.
2–5 years experience
3. A colleague runs mkfbvol with ID 2100 in pool P0 and gets an error. What’s going on, and how do you fix it?
Why they ask this: It shows whether you understand server affinity through LSS numbers and rank groups, and it’s one of the most common day-one mistakes.
How you might answer: ID 2100 puts the volume in LSS 21, which is odd, so it’s a server 1 volume. If P0 is a rank group 0 pool, it belongs to server 0, and the DS8000 won’t accept that mix.
I’d either create the volume in a rank group 1 pool such as P1, or, if it really belongs on server 0, pick an even LSS like 2000. After that I’d check the overall layout still spreads volumes evenly across both servers.
4. What’s the difference between an array, a rank and an extent pool? When would you have more than one rank in a pool?
Why they ask this: They want precise words, because people mix these three up and end up with wrong designs.
How you might answer: The array is the RAID-protected group of drives. The rank is that array formatted for FB or CKD and cut into extents, and on a DS8000 you always get one rank per array. The pool groups ranks of the same type and extent size and ties them to a server.
I’d nearly always put several ranks in a pool, so that volumes stripe across them, and Easy Tier needs more than one rank to rebalance anyway. Most systems do best with one pool pair per storage type.
Senior level
5. You’re designing the logical layout for a new DS8A50 that will serve both VMware and IBM Z. How do you lay out pools and address groups?
Why they ask this: Senior engineers have to plan for mixed workloads, both servers and future growth, so the interviewer is listening for structure and for the FB/CKD separation rules.
How you might answer: I’d set up two FB pools and two CKD pools, one of each per rank group, and spread the ranks evenly so both servers carry about the same capacity. A pool is FB or CKD only and its extent size is fixed, so I’d settle on small or large extents up front.
For addressing I’d reserve whole address groups, say address groups 0 and 1 for CKD LCUs and 2 to 4 for FB, since each group of 16 LSSs can only be one type. I’d also keep each application’s volumes in their own LSSs, which makes Copy Services consistency groups much simpler later on.
6. The business asks for 200 TiB usable. How do you get from that number to a drive count?
Why they ask this: They want to hear you size from the top down and count every layer’s overhead, because promising more capacity than you can deliver is a classic senior-level failure.
How you might answer: I’d begin with the 200 TiB of volumes, add pool headroom for growth and Easy Tier moves, and add the metadata overhead. Then I’d convert that into arrays, where with RAID 6 each array site gives 5 or 6 data drives out of 8 depending on spares.
That gives me the number of array sites and HPFE pairs, and I’d confirm it with IBM’s sizing tool before anyone places an order. I’d also note which layer each number belongs to, so nobody mixes up raw and usable later.
Quick quiz
Q1. How many drives make one array site on a DS8A00?
- 4
- 6
- 8
- 16
Show answer
C: An array site is always 8 identical drives with the same capacity and drive class.
Q2. At which layer does a rank get its server (CPC) affinity?
- When the array site is created
- When the array is created
- When the rank is assigned to an extent pool
- When the volume is mapped to a host
Show answer
C: A rank has no server of its own. It takes the rank group of the extent pool it joins, where rank group 0 is server 0 and rank group 1 is server 1.
Q3. What is the default FB extent size on a DS8A00?
- 16 MiB
- 64 MiB
- 1 GiB
- 21 cylinders
Show answer
A: Small extents (16 MiB for FB, 21 cylinders for CKD) are the default, and large extents are 1 GiB or 1113 cylinders.
Q4. Volume 2101 is managed by which server, and in which LSS?
- Server 0, LSS 01
- Server 1, LSS 21
- Server 0, LSS 20
- Server 1, LSS 10
Show answer
B: The first two hex digits are the LSS (21), and odd LSSs belong to server 1.
Q5. Which layer do you need only for FB (open systems) hosts?
- Rank
- Extent pool
- Volume group
- Array
Show answer
C: Volume groups decide which FB volumes an open systems host can see. CKD hosts use a default volume group and their IOCDS.
Quick recap
- DS8000 virtualization is a ladder: array site → array → rank → extent pool → volume → LSS/LCU → volume group and host.
- An array site is 8 identical drives, and an array adds RAID 6 (the default) or RAID 10, always one array per site.
- A rank formats the array as FB or CKD and cuts it into extents: 16 MiB or 1 GiB for FB, 21 or 1113 cylinders for CKD.
- Server affinity comes from the extent pool’s rank group, so build pools in pairs, one per server.
- A volume ID (XYZZ) sets the LSS; even LSSs go with rank group 0 pools and server 0, odd ones with rank group 1 and server 1.
- Volume groups decide which FB volumes a host may see; the GUI creates them for you and the DS CLI shows them.
- Each layer costs some capacity, so quote usable TB, not raw.
Next lesson
Lesson 10: Array sites, arrays and RAID 6 / RAID 10 → You compare the four DS8A00 array types, work out RAID 6 and RAID 10 capacity, and see how spares and rebuilds work.
Further reading: DS8000 virtualization
Want to go deeper into DS8000 virtualization? Chapter 3 of IBM’s IBM Storage DS8A00 Architecture and Implementation Guide (IBM Redbooks) explains every layer with diagrams. To review how the practice shell was set up, go back to Lesson 1: What an IBM DS8000 is.
You can also see the full plan for this course on the IBM DS8000 Architecture course page.
