Tadeu Bento

Aaron’s ZFS Guide: Getting and Setting Properties


🗂️ Aaron’s ZFS Guide – Table of Contents

Zpool AdministrationZFS AdministrationAppendices
0. Install ZFS on Debian GNU/Linux9. Copy-on-writeA. Visualizing The ZFS Intent Log (ZIL)
1. VDEVs10. Creating FilesystemsB. Using USB Drives
2. RAIDZ11. Compression and DeduplicationC. Why You Should Use ECC RAM
3. The ZFS Intent Log (ZIL)12. Snapshots and ClonesD. The True Cost Of Deduplication
4. The Adjustable Replacement Cache (ARC)13. Sending and Receiving Filesystems
5. Exporting and Importing Storage Pools14. ZVOLsLinked Content / Mirrored
6. Scrub and Resilver15. iSCSI, NFS and SambaAaron’s ZFS Guide Linked: ZFS RAIDZ stripe width
7. Getting and Setting Properties16. Getting and Setting PropertiesAaron’s ZFS Guide Linked: How A ZIL Improves Disk Latencies
8. Best Practices and Caveats17. Best Practices and Caveats

Motivation

Just as with Zpool properties, datasets also contain properties that can be changed. Because datasets are where you actually store your data, there are quite a bit more than with storage pools. Further, properties can be inherited from parent datasets. Again, not every property is tunable. Many are read-only. But, this again gives us the ability to tune our filesystem based on our storage needs. One aspect with ZFS datasets also, is the ability to set your own custom properties. These are known as “user properties” and differ from “native properties”.

Because there are just so many properties, I’ve decided to put the administration “above the fold”, and put the properties, along with some final thoughts at the end of the post.

Getting and Setting Properties

As with getting and setting storage pool properties, there are a few ways that you can get at dataset properties as well- you can get all properties at once, only one property, or more than one, comma-separated. For example, suppose I wanted to get just the compression ration of the dataset. I could issue the following command:

# zfs get compressratio tank/test
NAME       PROPERTY       VALUE  SOURCE
tank/test  compressratio  1.00x  -

If I wanted to get multiple settings, say the amount of disk used by the dataset, as well as how much is available, and the compression ratio, I could issue this command instead:

# zfs get used,available,compressratio tank/test
tank/test  used                  1.00G                  -
tank/test  available             975M                   -
tank/test  compressratio         1.00x                  -

And of course, if I wanted to get all the settings available, I could run:

# zfs get all tank/test
NAME       PROPERTY              VALUE                  SOURCE
tank/test  type                  filesystem             -
tank/test  creation              Tue Jan  1  6:07 2013  -
tank/test  used                  1.00G                  -
tank/test  available             975M                   -
tank/test  referenced            1.00G                  -
tank/test  compressratio         1.00x                  -
tank/test  mounted               yes                    -
tank/test  quota                 none                   default
tank/test  reservation           none                   default
tank/test  recordsize            128K                   default
tank/test  mountpoint            /tank/test             default
tank/test  sharenfs              off                    default
tank/test  checksum              on                     default
tank/test  compression           lzjb                   inherited from tank
tank/test  atime                 on                     default
tank/test  devices               on                     default
tank/test  exec                  on                     default
tank/test  setuid                on                     default
tank/test  readonly              off                    default
tank/test  zoned                 off                    default
tank/test  snapdir               hidden                 default
tank/test  aclinherit            restricted             default
tank/test  canmount              on                     default
tank/test  xattr                 on                     default
tank/test  copies                1                      default
tank/test  version               5                      -
tank/test  utf8only              off                    -
tank/test  normalization         none                   -
tank/test  casesensitivity       sensitive              -
tank/test  vscan                 off                    default
tank/test  nbmand                off                    default
tank/test  sharesmb              off                    default
tank/test  refquota              none                   default
tank/test  refreservation        none                   default
tank/test  primarycache          all                    default
tank/test  secondarycache        all                    default
tank/test  usedbysnapshots       0                      -
tank/test  usedbydataset         1.00G                  -
tank/test  usedbychildren        0                      -
tank/test  usedbyrefreservation  0                      -
tank/test  logbias               latency                default
tank/test  dedup                 off                    default
tank/test  mlslabel              none                   default
tank/test  sync                  standard               default
tank/test  refcompressratio      1.00x                  -
tank/test  written               0                      -

Inheritance

As you may have noticed in the output above, properties can be inherited from their parents. In that case, I set the compression algorithm to “lzjb” on the storage pool filesystem “tank” (“tank” is more than just a storage pool- it is a valid ZFS dataset). As such, any datasets created under the “tank” dataset will inherit that property. Let’s create a nested dataset, and see how this comes into play:

# zfs create -o compression=gzip tank/test/one
# zfs get -r compression tank
NAME           PROPERTY     VALUE     SOURCE
tank           compression  lzjb      local
tank/test      compression  lzjb      inherited from tank
tank/test/one  compression  gzip      local

Notice that the “tank” and “tank/test” datasets are using the “lzjb” compression algorithm, where “tank/test” inherited it from its parent “tank”. Whereas with the “tank/test/one” dataset, we chose a different compression algorithm. Let’s now inherit the parent compression algorithm from “tank”, and see what happens to “tank/test/one”:

# zfs inherit compression tank/test/one
# zfs get -r compression tank
NAME           PROPERTY     VALUE     SOURCE
tank           compression  lzjb      local
tank/test      compression  lzjb      inherited from tank
tank/test/one  compression  lzjb      inherited from tank

In this case, we made the change from the “gzip” algorithm to the “lzjb” algorithm, by inheriting from its parent. Now, the “zfs inherit” command also supports recursion. I can set the “tank” dataset to be “gzip”, and apply the property recursively to all children datasets:

# zfs set compression=gzip tank
# zfs inherit -r compression tank/test
# zfs get -r compression tank
NAME           PROPERTY     VALUE     SOURCE
tank           compression  gzip      local
tank/test      compression  gzip      inherited from tank
tank/test/one  compression  gzip      inherited from tank

Be very careful when using the “-r” switch. Suppose you quickly typed the command, and gave the “tank” dataset as your argument, rather than “tank/test”:

# zfs inherit -r compression tank
# zfs get -r compression tank
NAME           PROPERTY     VALUE     SOURCE
tank           compression  off       default
tank/test      compression  off       default
tank/test/one  compression  off       default

What happened? All compression algorithms got reset to their defaults of “off”. As a result, be very fearful of the “-r” recursive switch with the “zfs inherit” command. As you can see here, this is a way that you can clear dataset properties back to their defaults, and apply it to all children. This applies to datasets, volumes and snapshots.

User Dataset Properties

Now that you understand about inheritance, you can understand setting custom user properties on your datasets. The goal of user properties is for applications designed around ZFS specifically, to take advantage of those settings. For example, poudriere is a tool for FreeBSD designed to test package production, and to build FreeBSD packages in bulk. If using ZFS with FreeBSD, you can create a dataset for poudriere, and then create some custom properties for it to take advantage of.

Custom user dataset properties have no effect on ZFS performance. Think of them merely as “annotation” for administrators and developers. User properties must use a colon “:” in the property name to distinguish them from native dataset properties. They may contain lowercase letters, numbers, the colon “:”, dash “-“, period “.” and underscore “_”. They can be at ost 256 characters, and must not begin with a dash “-“.

To create a custom property, just use the “module:property” syntax. This is not enforced by ZFS, but is probably the cleanest approach:

# zfs set poudriere:type=ports tank/test/one
# zfs set poudriere:name=my_ports_tree tank/test/one
# zfs get all tank/test/one | grep poudriere
tank/test/one  poudriere:name        my_ports_tree          local
tank/test/one  poudriere:type        ports                  local

I am not aware of a way to remove user properties from a ZFS filesystem. As such, if it bothers you, and is cluttering up your property list, the only way to remove the user property is to create another dataset with the properties you want, copy over the data, then destroy the old cluttered dataset. Of course, you can inherit user properties with “zfs inherit” as well. And all the standard utilities, such as “zfs set”, “zfs get”, “zfs list”, et cetera will work with user properties.

With that said, let’s get to the native properties.

Native ZFS Dataset Properties

Final Thoughts

As you have probably noticed, some ZFS dataset properties are not fully implemented with ZFS on Linux, such as sharing a volume via iSCSI. Other dataset properties apply to the whole pool, such as the case with deduplication, even though they are applied to specific datasets. Many properties only apply to newly written data, and are not retroactive. As such, be aware of each property, and the pros/cons of what it provides. Because the parent storage pool is also a valid ZFS dataset, any child datasets will inherit non-default properties, as seen. And, the same is true for nested datasets, snapshots and volumes.

With ZFS dataset properties, you now have all the tuning at your fingertips to setup a solid ZFS storage backend. And everything has been handled with the “zfs” command, and its necessary subcommands. In fact, up to this point, we’ve only learned two commands: “zpool” and “zfs”, yet we’ve been able to build and configure powerful, large, redundant, consistent, fast and tuned ZFS filesystems. This is unprecedented in the storage world, especially with GNU/Linux. The only thing left to discuss is some best practices and caveats, and then a brief post on the “zdb” command (which you should never need), and we’ll be done with this series. Hell, if you’ve made it this far, I commend you. This has been no small series (believe me, my fingers hate me).


This article includes content by Aaron Toponce, originally published on pthree.org in 2012, which is unfortunately no longer available online. I’ve mirrored his valuable work here to ensure that readers continue to have access to this information.

Exit mobile version