ZPOOL(8)

๐Ÿ‘‘ ZPOOL โ€” configure ZFS storage pools ๐Ÿ’พโœจ

okay bestie, welcome to zpool(8), the System Manager's Manual entry that runs your entire storage empire. this is the tool that makes ZFS pools happen. let's get into it ๐Ÿซถ


โœจ NAME โœจ

zpool โ€” configure ZFS storage pools


๐ŸŒธ SYNOPSIS ๐ŸŒธ

zpool -?V
zpool version [-j]
zpool subcommand [arguments]

๐Ÿ’– DESCRIPTION ๐Ÿ’–

so the zpool command configures ZFS storage pools, and if you don't know what that means, bestie, let me hold your hand: a storage pool is a collection of devices that provides physical storage and data replication for ZFS datasets. that's it, that's the whole vibe. every dataset inside a pool shares the same space โ€” they're all roommates, no cap. ๐Ÿ 

if you wanna learn about managing datasets (not pools), go read zfs(8).

and for the full glow-up tour of creating and managing ZFS storage pools, the zpoolconcepts(7) manual page is your girl. ๐Ÿ“–


๐Ÿฆ‹ SUBCOMMANDS ๐Ÿฆ‹

heads up bestie: all subcommands that modify state are logged persistently to the pool in their original form. every single one. the pool remembers everything, it's giving receipts forever. ๐Ÿ’€๐Ÿ“

the zpool command provides subcommands to create and destroy storage pools, add capacity to storage pools, and provide information about the storage pools. here's the full lineup:

  • zpool -? โ€” displays a help message. classic.
  • zpool -V, --version
  • zpool version [-j] โ€” displays the software version of the zpool userland utility and the ZFS kernel module. add the -j option and it outputs in JSON format. โœจ

๐ŸŽ€ Creation ๐ŸŽ€

  • zpool-create(8) โ€” creates a new storage pool containing the virtual devices specified on the command line. new pool, who dis. ๐Ÿ’…
  • zpool-initialize(8) โ€” begins initializing by writing to all unallocated regions on the specified devices, or all eligible devices in the pool if no individual devices are specified.

๐Ÿ’€ Destruction ๐Ÿ’€

  • zpool-destroy(8) โ€” destroys the given pool, freeing up any devices for other use. rip bozo, but like, consensually. ๐Ÿชฆ
  • zpool-labelclear(8) โ€” removes ZFS label information from the specified device.

๐Ÿงš Virtual Devices ๐Ÿงš

  • zpool-attach(8) / zpool-detach(8) โ€” converts a non-redundant disk into a mirror, or increases the redundancy level of an existing mirror (attach), or performs the inverse operation (detach).
  • zpool-add(8) / zpool-remove(8) โ€” adds the specified virtual devices to the given pool, or removes the specified device from the pool.
  • zpool-replace(8) โ€” replaces an existing device (which may be faulted) with a new one. glow-up for a broken disk, fr fr. ๐Ÿ”ฅ
  • zpool-split(8) โ€” creates a new pool by splitting all mirrors in an existing pool (which decreases its redundancy). one pool becomes two, but at what cost ๐Ÿ˜ญ

๐ŸŒˆ Properties ๐ŸŒˆ

available pool properties are listed in the zpoolprops(7) manual page.

  • zpool-list(8) โ€” lists the given pools along with a health status and space usage.
  • zpool-get(8) / zpool-set(8) โ€” retrieves the given list of properties (or all properties if all is used) for the specified storage pool(s).

๐Ÿ‘‘ Monitoring ๐Ÿ‘‘

  • zpool-status(8) โ€” displays the detailed health status for the given pools.
  • zpool-iostat(8) โ€” displays logical I/O statistics for the given pools/vdevs. physical I/O operations may be observed via iostat(1).
  • zpool-events(8) โ€” lists all recent events generated by the ZFS kernel modules. these events are consumed by the zed(8) and used to automate administrative tasks such as replacing a failed device with a hot spare. that manual page also describes the subclasses and event payloads that can be generated.
  • zpool-history(8) โ€” displays the command history of the specified pool(s), or all pools if no pool is specified. it's the group chat scrollback of your pool, iykyk. ๐Ÿ’ฌ

๐Ÿ’œ Maintenance ๐Ÿ’œ

  • zpool-prefetch(8) โ€” prefetches specific types of pool data.
  • zpool-scrub(8) โ€” begins a scrub or resumes a paused scrub. self-care for your disks, periodt. ๐Ÿง–
  • zpool-checkpoint(8) โ€” checkpoints the current state of pool, which can be later restored by zpool import --rewind-to-checkpoint.
  • zpool-trim(8) โ€” initiates an immediate on-demand TRIM operation for all of the free space in a pool. this operation informs the underlying storage devices of all blocks in the pool which are no longer allocated and allows thinly provisioned devices to reclaim the space. declutter queen. ๐Ÿงน
  • zpool-sync(8) โ€” this command forces all in-core dirty data to be written to the primary pool storage and not the ZIL. it will also update administrative information including quota reporting. without arguments, zpool sync will sync all pools on the system. otherwise, it will sync only the specified pool(s).
  • zpool-upgrade(8) โ€” manage the on-disk format version of storage pools.
  • zpool-wait(8) โ€” waits until all background activity of the given types has ceased in the given pool. it's giving "girl wait for me at the bus stop" but for I/O. ๐Ÿ™ˆ

๐Ÿฉน Fault Resolution ๐Ÿฉน

  • zpool-offline(8) / zpool-online(8) โ€” takes the specified physical device offline or brings it online.
  • zpool-resilver(8) โ€” starts a resilver. if an existing resilver is already running it will be restarted from the beginning. yeah, from scratch. no cap. ๐Ÿ˜ค
  • zpool-reopen(8) โ€” reopen all the vdevs associated with the pool.
  • zpool-clear(8) โ€” clears device errors in a pool.

๐Ÿ“ฆ Import & Export ๐Ÿ“ฆ

  • zpool-import(8) โ€” make disks containing ZFS storage pools available for use on the system.
  • zpool-export(8) โ€” exports the given pools from the system.
  • zpool-reguid(8) โ€” generates a new unique identifier for the pool.

โญ EXIT STATUS โญ

the following exit values are returned:

  • 0 โ€” successful completion. slay. ๐ŸŽ‰
  • 1 โ€” an error occurred. ๐Ÿ˜ญ
  • 2 โ€” invalid command line options were specified. bestie. read the flags. ๐Ÿ’…

โœจ EXAMPLES โœจ

okay bestie, this is the part where it all clicks. real commands, real output, real "ohhhh THAT'S what that flag does" moments. let's go ๐Ÿ’…


๐ŸŒธ Example 1: Creating a RAID-Z Storage Pool

making a pool with one single raidz root vdev made of six disks, iconic:

# zpool create tank raidz sda sdb sdc sdd sde sdf

๐ŸŒธ Example 2: Creating a Mirrored Storage Pool

two mirrors, two disks each, no notes:

# zpool create tank mirror sda sdb mirror sdc sdd

๐ŸŒธ Example 3: Creating a ZFS Storage Pool by Using Partitions

non-redundant pool, two partitions, living on the edge a little:

# zpool create tank sda1 sdb2

๐ŸŒธ Example 4: Creating a ZFS Storage Pool by Using Files

same vibe but with files instead of disks. not recommended, but lowkey great for experimenting:

# zpool create tank /path/to/file/a /path/to/file/b

๐ŸŒธ Example 5: Making a non-mirrored ZFS Storage Pool mirrored

glow-up time โœจ takes an existing single device sda and attaches sdb so it becomes a mirror:

# zpool attach tank sda sdb

๐ŸŒธ Example 6: Adding a Mirror to a ZFS Storage Pool

adds two mirrored disks to pool tank, assuming the pool is already made of two-way mirrors. the extra space is immediately available to every dataset in the pool:

# zpool add tank mirror sda sdb

๐ŸŒธ Example 7: Listing Available ZFS Storage Pools

lists every pool on the system. here zion is FAULTED because a device is missing ๐Ÿ˜ญ. output looks a lil like this:

# zpool list
NAME    SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
rpool  19.9G  8.43G  11.4G         -    33%    42%  1.00x  ONLINE  -
tank   61.5G  20.0G  41.5G         -    48%    32%  1.00x  ONLINE  -
zion       -      -      -         -      -      -      -  FAULTED -

๐ŸŒธ Example 8: Destroying a ZFS Storage Pool

โš ๏ธ okay so this one is the villain arc. it nukes pool tank and every dataset inside it. -f forces it through. no takebacks, no undo, fr fr.
# zpool destroy -f tank

๐ŸŒธ Example 9: Exporting a ZFS Storage Pool

exports the devices in pool tank so they can be relocated or imported later. it's giving "packing your bags":

# zpool export tank

๐ŸŒธ Example 10: Importing a ZFS Storage Pool

shows available pools, then imports tank for use on the system. output is roughly:

# zpool import
  pool: tank
    id: 15451357997522795478
 state: ONLINE
action: The pool can be imported using its name or numeric identifier.
config:

        tank        ONLINE
          mirror    ONLINE
            sda     ONLINE
            sdb     ONLINE

# zpool import tank

๐ŸŒธ Example 11: Upgrading All ZFS Storage Pools to the Current Version

upgrades every ZFS pool to the current version of the software:

# zpool upgrade -a
This system is currently running ZFS version 2.

๐ŸŒธ Example 12: Managing Hot Spares

makes a new pool with a hot spare ready to go:

# zpool create tank mirror sda sdb spare sdc

if one of the disks ever fails, the pool drops to degraded. swap the dead one out like this:

# zpool replace tank sda sdd

once the data has been resilvered, the spare gets automatically removed and becomes available again in case another device fails. wanna yeet the hot spare from the pool permanently? :

# zpool remove tank sdc

๐ŸŒธ Example 13: Creating a ZFS Pool with Mirrored Separate Intent Logs

a pool with two, two-way mirrors plus mirrored log devices:

# zpool create pool mirror sda sdb mirror sdc sdd log mirror sde sdf

๐ŸŒธ Example 14: Adding Cache Devices to a ZFS Pool

adds two disks as cache devices:

# zpool add pool cache sdc sdd

once they're in, the cache devices gradually fill with content from main memory. depending on how big your cache devices are, filling could take over an hour ๐Ÿ˜ด. you can watch capacity and reads with the iostat subcommand:

# zpool iostat -v pool 5

๐ŸŒธ Example 15: Removing a Mirrored top-level (Log or Data) Device

these commands remove the mirrored log device mirror-2 and the mirrored top-level data device mirror-1.

starting config:

      pool: tank
     state: ONLINE
     scrub: none requested
config:

       NAME        STATE     READ WRITE CKSUM
       tank        ONLINE       0     0     0
         mirror-0  ONLINE       0     0     0
           sda     ONLINE       0     0     0
           sdb     ONLINE       0     0     0
         mirror-1  ONLINE       0     0     0
           sdc     ONLINE       0     0     0
           sdd     ONLINE       0     0     0
       logs
         mirror-2  ONLINE       0     0     0
           sde     ONLINE       0     0     0
           sdf     ONLINE       0     0     0

removing the mirrored log mirror-2:

# zpool remove tank mirror-2

at this point the log device is just gone โ€” both sides of the mirror removed ๐Ÿซก:

      pool: tank
     state: ONLINE
      scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0
          mirror-1  ONLINE       0     0     0
            sdc     ONLINE       0     0     0
            sdd     ONLINE       0     0     0

removing the mirrored data mirror-1:

# zpool remove tank mirror-1

after mirror-1 has been evacuated, the pool is still redundant, but total space shrinks:

      pool: tank
     state: ONLINE
      scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     0

๐ŸŒธ Example 16: Displaying expanded space on a device

shows detailed info for pool data. this pool is one single raidz vdev where one device bumped its capacity by 10 GiB. here's the tea: the pool can't use that extra capacity until every device under the raidz vdev has been expanded ๐Ÿฅฒ

# zpool list -v data
NAME         SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
data        23.9G  14.6G  9.30G         -    48%    61%  1.00x  ONLINE  -
  raidz1    23.9G  14.6G  9.30G         -    48%
    sda         -      -      -         -      -
    sdb         -      -      -       10G      -
    sdc         -      -      -         -      -

๐ŸŒธ Example 17: Adding output columns

extra columns can be added to zpool status and zpool iostat output with -c. obsessed.

# zpool status -c vendor,model,size
   NAME     STATE  READ WRITE CKSUM vendor  model        size
   tank     ONLINE 0    0     0
   mirror-0 ONLINE 0    0     0
   U1       ONLINE 0    0     0     SEAGATE ST8000NM0075 7.3T
   U10      ONLINE 0    0     0     SEAGATE ST8000NM0075 7.3T
   U11      ONLINE 0    0     0     SEAGATE ST8000NM0075 7.3T
   U12      ONLINE 0    0     0     SEAGATE ST8000NM0075 7.3T
   U13      ONLINE 0    0     0     SEAGATE ST8000NM0075 7.3T
   U14      ONLINE 0    0     0     SEAGATE ST8000NM0075 7.3T

# zpool iostat -vc size
              capacity     operations     bandwidth
pool        alloc   free   read  write   read  write  size
----------  -----  -----  -----  -----  -----  -----  ----
rpool       14.6G  54.9G      4     55   250K  2.69M
  sda1      14.6G  54.9G      4     55   250K  2.69M   70G
----------  -----  -----  -----  -----  -----  -----  ----

โœจ ENVIRONMENT VARIABLES โœจ

bestie these are the little vibe knobs in your shell that change how zpool acts ๐Ÿ’– set them, export them, live your truth

  • ZFS_ABORT โ€” makes zpool dump core on exit, purely so you can run ::findleaks on it. yeah. that's the whole point. go off i guess ๐Ÿ’€
  • ZFS_COLOR โ€” turns on ANSI color in zpool status and zpool iostat output. aesthetic โœจ
  • ZPOOL_AUTO_POWER_ON_SLOT โ€” automatically tries to turn on the drive enclosure slot power for a drive when you run zpool online or zpool clear. literally the same effect as passing the --power option to those commands. queen behavior ๐Ÿ‘‘
  • ZPOOL_POWER_ON_SLOT_TIMEOUT_MS โ€” the max time in milliseconds to wait for a slot power sysfs value to return the correct value after writing it. like, for example: after writing "on" to the sysfs enclosure slot power_control file, it can take a sec for the enclosure to power down the slot and return "on" if you read back the power_control value. defaults to 30 seconds (30000ms) if it's not set โณ
  • ZPOOL_IMPORT_PATH โ€” the search path for devices or files to use with the pool. it's a colon-separated list of directories where zpool looks for device nodes and files. basically the same as the -d option in zpool import ๐Ÿฆ‹
  • ZPOOL_IMPORT_UDEV_TIMEOUT_MS โ€” the max time in milliseconds that zpool import will wait for an expected device to be available. it's giving patience, but like, a measured amount ๐Ÿ˜ญ
  • ZPOOL_STATUS_NON_NATIVE_ASHIFT_IGNORE โ€” if you set this, it suppresses the warning about non-native vdev ashift in zpool status. the value itself is not used โ€” only the presence or absence of the variable matters. iconically unserious ๐Ÿ™ˆ
  • ZPOOL_VDEV_NAME_GUID โ€” makes zpool subcommands output vdev GUIDs by default. this behavior is identical to the zpool status -g command line option ๐ŸŽ€
  • ZPOOL_VDEV_NAME_FOLLOW_LINKS โ€” makes zpool subcommands follow links for vdev names by default. this behavior is identical to the zpool status -L command line option ๐Ÿ”—
  • ZPOOL_VDEV_NAME_PATH โ€” makes zpool subcommands output full vdev path names by default. this behavior is identical to the zpool status -P command line option ๐Ÿ›ฃ๏ธ
  • ZFS_VDEV_DEVID_OPT_OUT โ€” okay so older OpenZFS implementations had issues when trying to display pool config vdev names if a devid NVP value was present in the pool's config. like, for example, a pool that originated on illumos platform would have a devid value in the config and zpool status would fail when listing the config. this would also be true for future Linux-based pools. setting ZFS_VDEV_DEVID_OPT_OUT lets a pool be stripped of any devid values on import, or prevents them from being added on zpool create or zpool add ๐Ÿšซ
  • ZPOOL_SCRIPTS_AS_ROOT โ€” allows a privileged user to run zpool status/iostat -c. normally, only unprivileged users are allowed to run -c. the audacity ๐Ÿ’…
  • ZPOOL_SCRIPTS_PATH โ€” the search path for scripts when running zpool status/iostat -c. it's a colon-separated list of directories and it overrides the default ~/.zpool.d and /etc/zfs/zpool.d search paths ๐Ÿ—‚๏ธ
  • ZPOOL_SCRIPTS_ENABLED โ€” allows a user to run zpool status/iostat -c. if ZPOOL_SCRIPTS_ENABLED is not set, it is assumed that the user is allowed to run zpool status/iostat -c. no cap โœจ
  • ZFS_MODULE_TIMEOUT โ€” time, in seconds, to wait for /dev/zfs to appear. defaults to 10, max 600 (10 minutes). if <0, wait forever; if 0, don't wait. extremes only, i respect it ๐Ÿ˜Œ

๐Ÿ’ซ INTERFACE STABILITY ๐Ÿ’ซ

Evolving

(translation: it's growing, it's changing, it's in its era ๐ŸŒฑ)


๐ŸŒˆ SEE ALSO ๐ŸŒˆ

the whole friend group, fr fr ๐Ÿซถ


and that's the whole page bestie ๐ŸŽ€ this one shipped from the OpenZFS girlies, dated November 19, 2024, and it lives at ZPOOL(8). go forth and manage your pools, you absolute icon ๐Ÿ‘‘๐Ÿ’–โœจ

๐Ÿ“ฆ where this page comes from