| your Linux construction kit
Source
← Back to Overview

Disk Labels & Asset Management — know what's in the rack before you open the door.

When a disk fails at 3 AM, you don't want to be guessing which slot it's in, what pool it belongs to, or where to order a replacement. Structured disk labels solve this by encoding everything you need directly into the ZFS pool metadata and onto the physical label.

This isn't a product. It's a pattern. A convention for labeling disks so that any operator can walk up to any rack, scan a QR code, and know exactly what they're looking at — without opening a spreadsheet, without checking a wiki, without calling someone who "knows the setup."

The label format

Human-readable side

Print this. Stick it on the drive caddy or the front of the chassis. Any operator can read it.

──────────────────────────────────────────────
PHYSICAL LOCATION
  Region:     CA-WEST-1
  Datacenter: YVR01
  Building:   A
  Row:        R12
  Rack:       R12-08
  Chassis:    CH01
  Slot:       SLOT07

ZFS INFORMATION
  ZFS Pool:   prd-caw1-db-gold-nvme
  VDEV:       slot07
  Role:       DATA VDEV
  Layout:     draid2:10d:2c:128s

HARDWARE DETAILS
  Vendor:     Samsung
  Model:      PM9A3
  Interface:  NVMe PCIe 4.0 x4
  Capacity:   3.84 TB
  Serial:     S6ZUNX0R123456A
  Firmware:   EDA92Q5Q
  SMART Base: 2025-01-01

LIFECYCLE / INVENTORY
  Asset ID:   UB-DSK-CAW1-88322
  Installed:  2025-02-12
  Warranty:   2028-02-12
  Supplier:   CDW Canada
  RMA URL:    https://cdw.ca/rma/S6ZUNX0R123456A
  Reorder URL:
    https://cdw.ca/p/samsung-pm9a3-3.84tb/PM9A3-3840
──────────────────────────────────────────────
         QR-CODE: scan for full inventory
──────────────────────────────────────────────

Machine-readable side (JSON)

Encode this into the QR code. Scannable by any phone. Parseable by any script. Feed it into your inventory system, your monitoring, your alerting.

{
  "asset_id": "UB-DSK-CAW1-88322",
  "serial": "S6ZUNX0R123456A",
  "zfs": {
    "pool": "prd-caw1-db-gold-nvme",
    "vdev": "slot07",
    "role": "data",
    "layout": "draid2:10d:2c:128s"
  },
  "location": {
    "region": "CA-WEST-1",
    "datacenter": "YVR01",
    "building": "A",
    "row": "R12",
    "rack": "R12-08",
    "chassis": "CH01",
    "slot": "SLOT07"
  },
  "hardware": {
    "vendor": "Samsung",
    "model": "PM9A3",
    "capacity_tb": 3.84,
    "interface": "NVMe",
    "firmware": "EDA92Q5Q"
  },
  "lifecycle": {
    "installed": "2025-02-12",
    "warranty_expiry": "2028-02-12",
    "supplier": "CDW Canada",
    "rma_url": "https://cdw.ca/rma/S6ZUNX0R123456A",
    "reorder_url": "https://cdw.ca/p/samsung-pm9a3-3.84tb/PM9A3-3840"
  }
}

Why this matters

Without labels

Disk fails. Which slot? Check the serial against the spreadsheet. Which pool? SSH in and run zpool status. Under warranty? Open the vendor portal and search by serial. Replacement part number? Find the invoice from 2 years ago. RMA process? Google the vendor's support page. 30 minutes just to figure out what happened.

With labels

Disk fails. Walk to the rack. Read the label: Rack R12-08, Slot 7, pool prd-caw1-db-gold-nvme, Samsung PM9A3, warranty expires 2028. Scan the QR code: RMA link opens in your browser. Reorder link opens in another tab. 30 seconds. Everything you need. No SSH. No spreadsheet.

Build your own labels

Step 1: Define your naming convention

Before you label anything, decide on a naming scheme. This should be consistent across your entire fleet.

Region
Cloud-style: CA-WEST-1, US-EAST-2, EU-CENTRAL-1. Or simple: VAN, NYC, LON.
Datacenter
Airport code + number: YVR01, JFK02. Or building name: HQ, DR-SITE.
Rack
Row + position: R12-08 = Row 12, Position 8. Matches the physical layout.
Pool name
Environment + region + role + media: prd-caw1-db-gold-nvme = Production, CA-WEST-1, Database, Gold tier, NVMe.
Asset ID
Company prefix + type + region + serial: UB-DSK-CAW1-88322 = UnixBox, Disk, CA-WEST-1, #88322.

Step 2: Generate the label

A simple bash script that generates both the human-readable label and the QR code JSON:

#!/bin/bash
# generate-disk-label.sh — create a label for a new disk

SERIAL="${1:?Usage: generate-disk-label.sh SERIAL}"
POOL="${2:-rpool}"
SLOT="${3:-SLOT01}"
RACK="${4:-R01-01}"

# Query disk hardware info
VENDOR=$(smartctl -i /dev/disk/by-id/*${SERIAL}* 2>/dev/null | grep "Model" | awk -F: '{print $2}' | xargs)
CAPACITY=$(smartctl -i /dev/disk/by-id/*${SERIAL}* 2>/dev/null | grep "Capacity" | awk -F'[\\[\\]]' '{print $2}')
FW=$(smartctl -i /dev/disk/by-id/*${SERIAL}* 2>/dev/null | grep "Firmware" | awk -F: '{print $2}' | xargs)

# Get ZFS pool info
VDEV=$(zpool status "$POOL" 2>/dev/null | grep "$SERIAL" | awk '{print $1}')
LAYOUT=$(zpool status "$POOL" 2>/dev/null | grep -A1 "config:" | tail -1 | awk '{print $1}')

# Generate JSON
cat <<EOF
{
  "asset_id": "DSK-$(echo $RACK | tr -d '-')-$(date +%s | tail -c 6)",
  "serial": "${SERIAL}",
  "zfs": {
    "pool": "${POOL}",
    "vdev": "${VDEV:-unknown}",
    "role": "data"
  },
  "location": {
    "rack": "${RACK}",
    "slot": "${SLOT}"
  },
  "hardware": {
    "vendor": "${VENDOR:-unknown}",
    "capacity": "${CAPACITY:-unknown}",
    "firmware": "${FW:-unknown}"
  },
  "lifecycle": {
    "installed": "$(date +%Y-%m-%d)",
    "warranty_expiry": "$(date -d '+3 years' +%Y-%m-%d 2>/dev/null || date -v+3y +%Y-%m-%d)"
  }
}
EOF

Step 3: Generate the QR code

# Install qrencode
kpkg install qrencode

# Generate QR code from the JSON
./generate-disk-label.sh S6ZUNX0R123456A rpool SLOT07 R12-08 | \
    qrencode -o label-S6ZUNX0R123456A.png -s 6

# Print it — stick it on the drive caddy
lp label-S6ZUNX0R123456A.png

Step 4: Store in ZFS metadata (optional)

ZFS user properties let you attach arbitrary metadata to pools and datasets. Store the label data directly in the pool so it travels with the disks:

# Set custom properties on the pool
zfs set kldload:asset_id="UB-DSK-CAW1-88322" rpool
zfs set kldload:rack="R12-08" rpool
zfs set kldload:slot="SLOT07" rpool
zfs set kldload:supplier="CDW Canada" rpool
zfs set kldload:warranty="2028-02-12" rpool

# Read them back
zfs get all rpool | grep kldload:

# These properties survive pool export/import
# They travel with the disks — move them to another machine
# and the metadata is still there
ZFS user properties are tattoos on the pool. They go wherever the disks go. No external database needed.

Scaling it up

Fleet inventory from ZFS metadata

If every pool has kldload: properties, you can build a fleet inventory by querying every machine:

# Query all nodes via Salt
salt "*" cmd.run "zfs get -H -o property,value all rpool | grep kldload:"

# Output:
# node-01: kldload:rack    R12-08
# node-01: kldload:slot    SLOT07
# node-01: kldload:asset_id UB-DSK-CAW1-88322
# node-02: kldload:rack    R12-09
# ...

# Feed into monitoring — alert when warranty expires
# Feed into automation — auto-order replacements
# Feed into CMDB — zero manual entry

When a disk fails

The complete workflow with labels:

  1. zpool status shows DEGRADED — disk S6ZUNX0R123456A is FAULTED
  2. zfs get kldload:rack rpoolR12-08. Walk to the rack.
  3. Read the label: Slot 7, Samsung PM9A3, warranty until 2028
  4. Scan QR code → RMA link opens. Click "Submit RMA."
  5. Scan QR code → Reorder link opens. Click "Buy." Overnight shipping.
  6. New disk arrives. Slot it in. zpool replace rpool S6ZUNX0R123456A /dev/disk/by-id/NEW_SERIAL
  7. Print new label. Stick it on. Update the ZFS property: zfs set kldload:serial=NEW_SERIAL rpool
  8. Resilver completes. Pool is ONLINE. Total downtime: zero. Total confusion: zero.
Every disk has a passport. When it fails, you know exactly what to order, where to put it, and who to call. No spreadsheets. No tribal knowledge. No 3 AM panic.
This is a convention, not a product. There's no software to install. No database to maintain. Just a naming scheme, a bash script, and ZFS user properties. Adapt it to your environment. Make it yours. The pattern is what matters.