Christopher Siden
The Problem
ZFS on-disk formats are versioned using a single integer (last OpenSolaris version was 28 for pools) This worked when Sun controlled ZFS versioning, but in Illumos multiple organizations may be working on new ZFS versions in parallel What happens when Delphix uses ZFS version 30 for a new async destroy feature and Nexenta uses ZFS version 30 for RAIDZ 4? We don't want to have to coordinate allocation of version numbers between every organization working on ZFS Some organizations may want to maintain their own on-disk format changes separately from those maintained in Illumos
Last summer Basil Crow, an intern at Delphix, implemented the core components Delphix has integrated the "SPA/zpool versioning" part of that work into the next version of our product We plan to push this work back into Illumos soon
Version Numbers
Legacy version numbers still exist for pool versions 1-28 Continue using "zpool upgrade" to control legacy versions Feature flags has legacy version 1000 (implies 1-28) Legacy version never changes again Future on-disk format changes are enabled/disabled independently via feature flags Feature flags are exposed as pool properties Property name is: "feature@<org-name>:<feature-name>" <org-name> is the reverse DNS name of the organization which developed the feature (for guaranteed unique names) Properties can be shortened to "feature@<feature-name>" if this is unambiguous For example "feature@com.delphix:async_destroy" -> "feature@async_destroy"
Enabling Features
Feature properties can have one of three values: disabled - this feature will not be used, no on-disk format changes will be made (backwards compatible) enabled - this feature will be used, no on-disk format changes have been made yet, but the software may make them at any time (still backwards compatible) active - this feature has made backwards incompatible on-disk format changes to the pool The only value administrators can set is "enabled" Features cannot be set to "disabled" once enabled Enabling a feature automatically upgrades the pool legacy version to version 1000 Enabling a feature automatically enables any other features it depends on By default new pools are created with all supported features enabled (use the -d option to disable by default)
Example
root@dlpx:~# zpool create -o version=28 example ~/example # feature property exists, but is disabled due to pool version root@dlpx:~# zpool get all example NAME PROPERTY VALUE example version 28 example feature@com.delphix:async_destroy disabled root@dlpx:~# zpool set feature@async_destroy=enabled example # legacy version number has been automatically upgraded to 1000 # (displayed as '-' to indicate it is no longer in use) # feature property value has changed root@dlpx:~# zpool get all example NAME PROPERTY VALUE example version example feature@com.delphix:async_destroy enabled
Handling Incompatibilities
On-disk format changes can have one of two forms "features for write" must be supported by software in order to write to the pool, the feature does not need to be supported to open the pool in read-only mode "features for read" must be supported in order to read from the pool, there is no way to open a pool without reading from it For example, Delphix's async_destroy feature adds a new on-disk data structure to keep track of freed datasets, software does not need to know about this data structure to read the pool Trying to import a pool with unsupported features in the "active" state prints detailed error information listing the incompatible features
Examples
# import pool with unsupported feature for read root@dlpx:~# sudo zpool import -d ~/ example This pool uses the following feature(s) not supported by this system: com.example:unsupported (descriptive string) cannot import 'example': unsupported version or feature # import pool with unsupported feature for write root@dlpx:~# sudo zpool import -d ~/ example This pool uses the following feature(s) not supported by this system: com.example:unsupported (descriptive string) cannot import 'example': unsupported version or feature root@dlpx:~# sudo zpool import -d ~/ -o readonly=on example root@dlpx:~#
For sysadmins
The task of the average administrator has not changed 1. Upgrade software 2. Use the latest pool version zpool upgrade -a Additional benefits for administrators with special needs Evaluate and enable features one at a time (particularly useful if you are running a ZFS aware appliance) Gives features the option to "undo" their on disk changes changing the feature's state from "active" back to "enabled", making the pool compatible with an older software version again (some features may not be able to do this)
Async Destroy
Asynchronous destruction of ZFS filesystems Before Time to run "zfs destroy pool/fs" depends on size of pool/fs Interrupted destroy (e.g. by system crash) is completed the next time the pool is opened (i.e. next boot hangs) After Destroy operation does minimal metadata manipulation in a single transaction Data blocks are moved to free list Free list is processed in the background until empty
The Future
ZPL/filesystem feature flags Enum indirection tables object types checksum/compression algos send stream record types More useful frameworks to help with merging features