zfs-inherit

title: zfs-inherit(8)

summary: set properties on ZFS datasets

text:
# zfs-inherit(8)

## NAME
zfs-set — set properties on ZFS datasets

## SYNOPSIS
zfs

set [-u] property=value [property=value]… filesystem|volume|snapshot…

zfs

get [-r|-d depth] [-Hp] [-j [--json-int]] [-o field[,field]…] [-s source[,source]…] [-t type[,type]…] all|property[,property]… [filesystem|volume|snapshot|bookmark]…

zfs

inherit [-rS] property filesystem|volume|snapshot…

## DESCRIPTION
zfs set [-u] property=value [property=value]… filesystem|volume|snapshot…

Only some properties can be edited. See zfsprops(7) for more information on what properties can be set and acceptable values. Numeric values can be specified as exact values, or in a human-readable form with a suffix of B, K, M, G, T, P, E, Z (for bytes, kilobytes, megabytes, gigabytes, terabytes, petabytes, exabytes, or zettabytes, respectively). User properties can be set on snapshots. For more information, see the User Properties section of zfsprops(7). -u

Update mountpoint, sharenfs, sharesmb property but do not mount or share the dataset.

zfs get [-r|-d depth] [-Hp] [-j [--json-int]] [-o field[,field]…] [-s source[,source]…] [-t type[,type]…] all|property[,property]… [filesystem|volume|snapshot|bookmark]…

Displays properties for the given datasets. If no datasets are specified, then the command displays properties for all datasets on the system. For each property, the following columns are displayed: name

Dataset name

property

Property name

value

Property value

source

Property source local, default, inherited, temporary, received, or - (none).

All columns are displayed by default, though this can be controlled by using the -o option. This command takes a comma-separated list of properties as described in the Native Properties and User Properties sections of zfsprops(7).

The value all can be used to display all properties that apply to the given dataset's type (filesystem, volume, snapshot, or bookmark).

-j, --json [--json-int]

Display the output in JSON format. Specify --json-int to display numbers in integer format instead of strings for JSON output.

-H

Display output in a form more easily parsed by scripts. Any headers are omitted, and fields are explicitly separated by a single tab instead of an arbitrary amount of space.

-d depth

Recursively display any children of the dataset, limiting the recursion to depth. A depth of 1 will display only the dataset and its direct children.

-o field

A comma-separated list of columns to display, defaults to name,property,value,source.

-p

Display numbers in parsable (exact) values.

-r

Recursively display properties for any children.

-s source

A comma-separated list of sources to display. Those properties coming from a source other than those in this list are ignored. Each source must be one of the following: local, default, inherited, temporary, received, or none. The default value is all sources.

-t type

A comma-separated list of types to display, where type is one of filesystem, snapshot, volume, bookmark, or all. fs, snap, or vol can be used as aliases for filesystem, snapshot, or volume.

zfs inherit [-rS] property filesystem|volume|snapshot…

Clears the specified property, causing it to be inherited from an ancestor, restored to default if no ancestor has the property set, or with the -S option reverted to the received value if one exists. See zfsprops(7) for a listing of default values, and details on which properties can be inherited. -r

Recursively inherit the given property for all children.

-S

Revert the property to the received value, if one exists; otherwise, for non-inheritable properties, to the default; otherwise, operate as if the -S option was not specified.

## EXAMPLES

### Example 1: Creating a ZFS File System Hierarchy
The following commands create a file system named pool/home and a file system named pool/home/bob. The mount point /export/home is set for the parent file system, and is automatically inherited by the child file system.

\# zfs create pool/home

\# zfs set mountpoint=/export/home pool/home

\# zfs create pool/home/bob

### Example 2: Disabling and Enabling File System Compression
The following command disables the compression property for all file systems under pool/home. The next command explicitly enables compression for pool/home/anne.

\# zfs set compression=off pool/home

\# zfs set compression=on pool/home/anne

### Example 3: Setting a Quota on a ZFS File System
The following command sets a quota of 50 Gbytes for pool/home/bob:

\# zfs set quota=50G pool/home/bob

### Example 4: Listing ZFS Properties
The following command lists all properties for pool/home/bob:

```
# zfs get all pool/home/bob
NAME           PROPERTY              VALUE                  SOURCE
pool/home/bob  type                  filesystem             -
pool/home/bob  creation              Tue Jul 21 15:53 2009  -
pool/home/bob  used                  21K                    -
pool/home/bob  available             20.0G                  -
pool/home/bob  referenced            21K                    -
pool/home/bob  compressratio         1.00x                  -
pool/home/bob  mounted               yes                    -
pool/home/bob  quota                 20G                    local
pool/home/bob  reservation           none                   default
pool/home/bob  recordsize            128K                   default
pool/home/bob  mountpoint            /pool/home/bob         default
pool/home/bob  sharenfs              off                    default
pool/home/bob  checksum              on                     default
pool/home/bob  compression           on                     local
pool/home/bob  atime                 on                     default
pool/home/bob  devices               on                     default
pool/home/bob  exec                  on                     default
pool/home/bob  setuid                on                     default
pool/home/bob  readonly              off                    default
pool/home/bob  zoned                 off                    default
pool/home/bob  snapdir               hidden                 default
pool/home/bob  acltype               off                    default
pool/home/bob  aclmode               discard                default
pool/home/bob  aclinherit            restricted             default
pool/home/bob  canmount              on                     default
pool/home/bob  xattr                 on                     default
pool/home/bob  copies                1                      default
pool/home/bob  version               4                      -
pool/home/bob  utf8only              off                    -
pool/home/bob  normalization         none                   -
pool/home/bob  casesensitivity       sensitive              -
pool/home/bob  vscan                 off                    default
pool/home/bob  nbmand                off                    default
pool/home/bob  sharesmb              off                    default
pool/home/bob  refquota              none                   default
pool/home/bob  refreservation        none                   default
pool/home/bob  primarycache          all                    default
pool/home/bob  secondarycache        all                    default
pool/home/bob  usedbysnapshots       0                      -
pool/home/bob  usedbydataset         21K                    -
pool/home/bob  usedbychildren        0                      -
pool/home/bob  usedbyrefreservation  0                      -
```

The following command gets a single property value:

```
# zfs get -H -o value compression pool/home/bob
on
```

The following command gets a single property value recursively in JSON format:

```
# zfs get -j -r mountpoint pool/home | jq
{
  "output_version": {
    "command": "zfs get",
    "vers_major": 0,
    "vers_minor": 1
  },
  "datasets": {
    "pool/home": {
      "name": "pool/home",
      "type": "FILESYSTEM",
      "pool": "pool",
      "createtxg": "10",
      "properties": {
        "mountpoint": {
          "value": "/pool/home",
          "source": {
            "type": "DEFAULT",
            "data": "-"
          }
        }
      }
    },
    "pool/home/bob": {
      "name": "pool/home/bob",
      "type": "FILESYSTEM",
      "pool": "pool",
      "createtxg": "1176",
      "properties": {
        "mountpoint": {
          "value": "/pool/home/bob",
          "source": {
            "type": "DEFAULT",
            "data": "-"
          }
        }
      }
    }
  }
}
```

The following command lists all properties with local settings for pool/home/bob:

```
# zfs get -r -s local -o name,property,value all pool/home/bob
NAME           PROPERTY              VALUE
pool/home/bob  quota                 20G
pool/home/bob  compression           on
```

### Example 5: Inheriting ZFS Properties
The following command causes pool/home/bob and pool/home/anne to inherit the checksum property from their parent.

\# zfs inherit checksum pool/home/bob pool/home/anne

### Example 6: Setting User Properties
The following example sets the user-defined com.example:department property for a dataset:

\# zfs set com.example:department=12345 tank/accounting

### Example 7: Setting sharenfs Property Options on a ZFS File System
The following commands show how to set sharenfs property options to enable read-write access for a set of IP addresses and to enable root access for system "neo" on the tank/home file system:

\# zfs set sharenfs='rw=@123.123.0.0/16:[::1],root=neo' tank/home

If you are using DNS for host name resolution, specify the fully-qualified hostname.

## SEE ALSO
zfsprops(7), zfs-list(8)


zfs-list

package: zfs-utils

title: zfs-list(8)

summary: list properties of ZFS datasets

text:
# zfs-list(8)

## NAME
zfs-list — list properties of ZFS datasets

## SYNOPSIS
zfs

list [-r|-d depth] [-Hp] [-j [--json-int]] [-o property[,property]…] [-s property]… [-S property]… [-t type[,type]…] [filesystem|volume|snapshot]…

## DESCRIPTION
By default, all file systems and volumes are displayed, with the following fields: name, used, available, referenced, mountpoint. Snapshots are displayed if the listsnapshots pool property is on (the default is off) or if the -t snapshot or -t all options are specified.

-H

Used for scripting mode. Do not print headers, and separate fields by a single tab instead of arbitrary white space.

-j, --json [--json-int]

Print the output in JSON format. Specify --json-int to print the numbers in integer format instead of strings in JSON output.

-d depth

Recursively display any children of the dataset, limiting the recursion to depth. A depth of 1 will display only the dataset and its direct children.

-o property

A comma-separated list of properties to display. Each property must be:

- One of the properties described in the Native Properties section of zfsprops(7)

- A user property

- The value name to display the dataset name

- The value space to display space usage properties on file systems and volumes. This is a shortcut for specifying -o name,avail,used,usedsnap,usedds,usedrefreserv,usedchild -t filesystem,volume.

-p

Display numbers in parsable (exact) values.

-r

Recursively display any children of the dataset on the command line.

-s property

A property for sorting the output by column in ascending order based on the value of the property. The property must be one of the properties described in the Properties section of zfsprops(7) or the value name to sort by the dataset name. Multiple properties can be specified to operate together using multiple -s or -S options. Multiple -s and -S options are evaluated from left to right to supply sort keys in decreasing order of priority. Property types operate as follows:

- Numeric types sort in numeric order.

- String types sort in alphabetical order.

- Types inappropriate for a row sort that row to the literal bottom, regardless of the specified ordering.

If no sort columns are specified, or if two lines of output would sort equally across all specified columns, then datasets and bookmarks are sorted by name, whereas snapshots are sorted first by the name of their dataset and then by the time of their creation. When no sort columns are specified but snapshots are listed, this default behavior causes snapshots to be grouped under their datasets in chronological order by creation time.

-S property

Same as -s, but sorts by property in descending order.

-t type

A comma-separated list of types to display, where type is one of filesystem, snapshot, volume, bookmark, or all. For example, specifying -t snapshot displays only snapshots. fs, snap, or vol can be used as aliases for filesystem, snapshot, or volume.

## EXAMPLES

### Example 1: Listing ZFS Datasets
The following command lists all active file systems and volumes in the system. Snapshots are displayed if listsnaps=on. The default is off. See zpoolprops(7) for more information on pool properties.

```
# zfs list
NAME                      USED  AVAIL  REFER  MOUNTPOINT
pool                      450K   457G    18K  /pool
pool/home                 315K   457G    21K  /export/home
pool/home/anne             18K   457G    18K  /export/home/anne
pool/home/bob             276K   457G   276K  /export/home/bob
```

### Example 2: Listing ZFS filesystems and snapshots in JSON format

```
# zfs list -j -t filesystem,snapshot | jq
{
  "output_version": {
    "command": "zfs list",
    "vers_major": 0,
    "vers_minor": 1
  },
  "datasets": {
    "pool": {
      "name": "pool",
      "type": "FILESYSTEM",
      "pool": "pool",
      "properties": {
        "used": {
          "value": "290K",
          "source": {
            "type": "NONE",
            "data": "-"
          }
        },
        "available": {
          "value": "30.5G",
          "source": {
            "type": "NONE",
            "data": "-"
          }
        },
        "referenced": {
          "value": "24K",
          "source": {
            "type": "NONE",
            "data": "-"
          }
        },
        "mountpoint": {
          "value": "/pool",
          "source": {
            "type": "DEFAULT",
            "data": "-"
          }
        }
      }
    },
    "pool/home": {
      "name": "pool/home",
      "type": "FILESYSTEM",
      "pool": "pool",
      "properties": {
        "used": {
          "value": "48K",
          "source": {
            "type": "NONE",
            "data": "-"
          }
        },
        "available": {
          "value": "30.5G",
          "source": {
            "type": "NONE",
            "data": "-"
          }
        },
        "referenced": {
          "value": "24K",
          "source": {
            "type": "NONE",
            "data": "-"
          }
        },
        "mountpoint": {
          "value": "/mnt/home",
          "source": {
            "type": "LOCAL",
            "data": "-"
          }
        }
      }
    },
    "pool/home/bob": {
      "name": "pool/home/bob",
      "type": "FILESYSTEM",
      "pool": "pool",
      "properties": {
        "used": {
          "value": "24K",
          "source": {
            "type": "NONE",
            "data": "-"
          }
        },
        "available": {
          "value": "30.5G",
          "source": {
            "type": "NONE",
            "data": "-"
          }
        },
        "referenced": {
          "value": "24K",
          "source": {
            "type": "NONE",
            "data": "-"
          }
        },
        "mountpoint": {
          "value": "/mnt/home/bob",
          "source": {
            "type": "INHERITED",
            "data": "pool/home"
          }
        }
      }
    },
    "pool/home/bob@v1": {
      "name": "pool/home/bob@v1",
      "type": "SNAPSHOT",
      "pool": "pool",
      "dataset": "pool/home/bob",
      "snapshot_name": "v1",
      "properties": {
        "used": {
          "value": "0B",
          "source": {
            "type": "NONE",
            "data": "-"
          }
        },
        "available": {
          "value": "-",
          "source": {
            "type": "NONE",
            "data": "-"
          }
        },
        "referenced": {
          "value": "24K",
          "source": {
            "type": "NONE",
            "data": "-"
          }
        },
        "mountpoint": {
          "value": "-",
          "source": {
            "type": "NONE",
            "data": "-"
          }
        }
      }
    }
  }
}
```

## SEE ALSO
zfsprops(7), zfs-get(8)

branch: sisyphus


zfs-load-key

title: zfs-load-key(8)

text:
# zfs-load-key(8)

## NAME
zfs-load-key — load, unload, or change encryption key of ZFS dataset

## SYNOPSIS
zfs

load-key [-nr] [-L keylocation] -a|filesystem

zfs

unload-key [-r] -a|filesystem

zfs

change-key [-l] [-o keylocation=value] [-o keyformat=value] [-o pbkdf2iters=value] filesystem

zfs

change-key -i [-l] filesystem

## DESCRIPTION
zfs load-key [-nr] [-L keylocation] -a|filesystem

Load the key for filesystem, allowing it and all children that inherit the keylocation property to be accessed. The key will be expected in the format specified by the keyformat and location specified by the keylocation property. Note that if the keylocation is set to prompt the terminal will interactively wait for the key to be entered. Loading a key will not automatically mount the dataset. If that functionality is desired, zfs mount -l will ask for the key and mount the dataset (see zfs-mount(8)). Once the key is loaded the keystatus property will become available. -r

Recursively loads the keys for the specified filesystem and all descendent encryption roots.

-a

Loads the keys for all encryption roots in all imported pools.

-n

Do a dry-run ("No-op") load-key. This will cause zfs to simply check that the provided key is correct. This command may be run even if the key is already loaded.

-L keylocation

Use keylocation instead of the keylocation property. This will not change the value of the property on the dataset. Note that if used with either -r or -a, keylocation may only be given as prompt.

zfs unload-key [-r] -a|filesystem

Unloads a key from ZFS, removing the ability to access the dataset and all of its children that inherit the keylocation property. This requires that the dataset is not currently open or mounted. Once the key is unloaded the keystatus property will become unavailable. -r

Recursively unloads the keys for the specified filesystem and all descendent encryption roots.

-a

Unloads the keys for all encryption roots in all imported pools.

zfs change-key [-l] [-o keylocation=value] [-o keyformat=value] [-o pbkdf2iters=value] filesystem

zfs change-key -i [-l] filesystem

Changes the user's key (e.g. a passphrase) used to access a dataset. This command requires that the existing key for the dataset is already loaded. This command may also be used to change the keylocation, keyformat, and pbkdf2iters properties as needed. If the dataset was not previously an encryption root it will become one. Alternatively, the -i flag may be provided to cause an encryption root to inherit the parent's key instead. If the user's key is compromised, zfs change-key does not necessarily protect existing or newly-written data from attack. Newly-written data will continue to be encrypted with the same master key as the existing data. The master key is compromised if an attacker obtains a user key and the corresponding wrapped master key. Currently, zfs change-key does not overwrite the previous wrapped master key on disk, so it is accessible via forensic analysis for an indeterminate length of time.

In the event of a master key compromise, ideally the drives should be securely erased to remove all the old data (which is readable using the compromised master key), a new pool created, and the data copied back. This can be approximated in place by creating new datasets, copying the data (e.g. using zfs send | zfs recv), and then clearing the free space with zpool trim --secure if supported by your hardware, otherwise zpool initialize.

-l

Ensures the key is loaded before attempting to change the key. This is effectively equivalent to running zfs load-key filesystem; zfs change-key filesystem

-o property=value

Allows the user to set encryption key properties (keyformat, keylocation, and pbkdf2iters) while changing the key. This is the only way to alter keyformat and pbkdf2iters after the dataset has been created.

-i

Indicates that zfs should make filesystem inherit the key of its parent. Note that this command can only be run on an encryption root that has an encrypted parent.

### Encryption
Enabling the encryption feature allows for the creation of encrypted filesystems and volumes. ZFS will encrypt file and volume data, file attributes, ACLs, permission bits, directory listings, FUID mappings, and userused/groupused data. ZFS will not encrypt metadata related to the pool structure, including dataset and snapshot names, dataset hierarchy, properties, file size, file holes, and deduplication tables (though the deduplicated data itself is encrypted).

Key rotation is managed by ZFS. Changing the user's key (e.g. a passphrase) does not require re-encrypting the entire dataset. Datasets can be scrubbed, resilvered, renamed, and deleted without the encryption keys being loaded (see the load-key subcommand for more info on key loading).

Creating an encrypted dataset requires specifying the encryption and keyformat properties at creation time, along with an optional keylocation and pbkdf2iters. After entering an encryption key, the created dataset will become an encryption root. Any descendant datasets will inherit their encryption key from the encryption root by default, meaning that loading, unloading, or changing the key for the encryption root will implicitly do the same for all inheriting datasets. If this inheritance is not desired, simply supply a keyformat when creating the child dataset or use zfs change-key to break an existing relationship, creating a new encryption root on the child. Note that the child's keyformat may match that of the parent while still creating a new encryption root, and that changing the encryption property alone does not create a new encryption root; this would simply use a different cipher suite with the same key as its encryption root. The one exception is that clones will always use their origin's encryption key. As a result of this exception, some encryption-related properties (namely keystatus, keyformat, keylocation, and pbkdf2iters) do not inherit like other ZFS properties and instead use the value determined by their encryption root. Encryption root inheritance can be tracked via the read-only encryptionroot property.

Encryption changes the behavior of a few ZFS operations. Encryption is applied after compression so compression ratios are preserved. Normally checksums in ZFS are 256 bits long, but for encrypted data the checksum is 128 bits of the user-chosen checksum and 128 bits of MAC from the encryption suite, which provides additional protection against maliciously altered data. Deduplication is still possible with encryption enabled but for security, datasets will only deduplicate against themselves, their snapshots, and their clones.

There are a few limitations on encrypted datasets. Encrypted data cannot be embedded via the embedded_data feature. Encrypted datasets may not have copies=3 since the implementation stores some encryption metadata where the third copy would normally be. Since compression is applied before encryption, datasets may be vulnerable to a CRIME-like attack if applications accessing the data allow for it. Deduplication with encryption will leak information about which blocks are equivalent in a dataset and will incur an extra CPU cost for each block written.

## SEE ALSO
zfsprops(7), zfs-create(8), zfs-set(8)


zfs-mount

title: zfs-mount(8)

summary: manage mount state of ZFS filesystems

text:
# zfs-mount(8)

## NAME
zfs-mount — manage mount state of ZFS filesystems

## SYNOPSIS
zfs

mount [-j]

zfs

mount [-Oflv] [-o options] -a|-R filesystem|filesystem

zfs

unmount [-fu] -a|filesystem|mountpoint

## DESCRIPTION
zfs mount [-j]

Displays all ZFS file systems currently mounted. -j, --json

Displays all mounted file systems in JSON format.

zfs mount [-Oflv] [-o options] -a|-R filesystem|filesystem

Mount ZFS filesystem on a path described by its mountpoint property, if the path exists and is empty. If mountpoint is set to legacy, the filesystem should be instead mounted using mount(8). -O

Perform an overlay mount. Allows mounting in non-empty mountpoint. See mount(8) for more information.

-a

Mount all available ZFS file systems. Invoked automatically as part of the boot process if configured.

-R

Mount the specified filesystems along with all their children.

filesystem

Mount the specified filesystem.

-o options

An optional, comma-separated list of mount options to use temporarily for the duration of the mount. See the Temporary Mount Point Properties section of zfsprops(7) for details.

-l

Load keys for encrypted filesystems as they are being mounted. This is equivalent to executing zfs load-key on each encryption root before mounting it. Note that if a filesystem has keylocation=prompt, this will cause the terminal to interactively block after asking for the key.

-v

Report mount progress.

-f

Attempt to force mounting of all filesystems, even those that couldn't normally be mounted (e.g. redacted datasets).

zfs unmount [-fu] -a|filesystem|mountpoint

Unmounts currently mounted ZFS file systems. -a

Unmount all available ZFS file systems. Invoked automatically as part of the shutdown process.

-f

Forcefully unmount the file system, even if it is currently in use. This option is not supported on Linux.

-u

Unload keys for any encryption roots unmounted by this command.

filesystem|mountpoint

Unmount the specified filesystem. The command can also be given a path to a ZFS file system mount point on the system.


zfs-mount-generator

title: zfs-mount-generator(8)

text:
# zfs-mount-generator(8)

## NAME
zfs-mount-generator — generate systemd mount units for ZFS filesystems

## SYNOPSIS
/lib/systemd/system-generators/zfs-mount-generator

## DESCRIPTION
zfs-mount-generator is a systemd.generator(7) that generates native systemd.mount(5) units for configured ZFS datasets.

### Properties
mountpoint=

Skipped if legacy or none.

canmount=

Skipped if off. Skipped if only noauto datasets exist for a given mountpoint and there's more than one. Datasets with yes take precedence over ones with noauto for the same mountpoint. Sets logical noauto flag if noauto. Encryption roots always generate zfs-load-key@root.service, even if off.

atime=, relatime=, devices=, exec=, readonly=, setuid=, nbmand=

Used to generate mount options equivalent to zfs mount.

encroot=, keylocation=

If the dataset is an encryption root, its mount unit will bind to zfs-load-key@root.service, with additional dependencies as follows: keylocation=prompt

None, uses systemd-ask-password(1)

keylocation=https://URL (et al.)

Wants=, After=: network-online.target

keylocation=file://<path>

RequiresMountsFor=path

The service also uses the same Wants=, After=, Requires=, and RequiresMountsFor=, as the mount unit.

org.openzfs.systemd:requires=path[ path]…

Sets Requires= for the mount- and key-loading unit.

org.openzfs.systemd:requires-mounts-for=path[ path]…

Sets RequiresMountsFor= for the mount- and key-loading unit.

org.openzfs.systemd:before=unit[ unit]…

Sets Before= for the mount unit.

org.openzfs.systemd:after=unit[ unit]…

Sets After= for the mount unit.

org.openzfs.systemd:wanted-by=unit[ unit]…

Sets logical noauto flag (see below). If not none, sets WantedBy= for the mount unit.

org.openzfs.systemd:required-by=unit[ unit]…

Sets logical noauto flag (see below). If not none, sets RequiredBy= for the mount unit.

org.openzfs.systemd:nofail=(unset)|on|off

Waxes or wanes strength of default reverse dependencies of the mount unit, see below.

org.openzfs.systemd:ignore=on|off

Skip if on. Defaults to off.

### Unit Ordering And Dependencies
Additionally, unless the pool the dataset resides on is imported at generation time, both units gain Wants=zfs-import.target and After=zfs-import.target.

Additionally, unless the logical noauto flag is set, the mount unit gains a reverse-dependency for local-fs.target of strength

(unset)

WantedBy= + Before=

on

WantedBy=

off

RequiredBy= + Before=

### Cache File
Because ZFS pools may not be available very early in the boot process, information on ZFS mountpoints must be stored separately. The output of

zfs list -Ho name,⟨every property above in order⟩

for datasets that should be mounted by systemd should be kept at /etc/zfs/zfs-list.cache/poolname, and, if writeable, will be kept synchronized for the entire pool by the history_event-zfs-list-cacher.sh ZEDLET, if enabled (see zed(8)).

## ENVIRONMENT
If the ZFS_DEBUG environment variable is nonzero (or unset and /proc/cmdline contains "debug"), print summary accounting information at the end.

## EXAMPLES
To begin, enable tracking for the pool:

\# touch /etc/zfs/zfs-list.cache/poolname

Then enable the tracking ZEDLET: # ln -s /usr/libexec/zfs/zed.d/history_event-zfs-list-cacher.sh /etc/zfs/zed.d

\# systemctl enable zfs-zed.service

\# systemctl restart zfs-zed.service

If no history event is in the queue, inject one to ensure the ZEDLET runs to refresh the cache file by setting a monitored property somewhere on the pool:

\# zfs set relatime=off poolname/dset

\# zfs inherit relatime poolname/dset

To test the generator output:

$ mkdir /tmp/zfs-mount-generator

$ /lib/systemd/system-generators/zfs-mount-generator /tmp/zfs-mount-generator

If the generated units are satisfactory, instruct systemd to re-run all generators: # systemctl daemon-reload

## SEE ALSO
systemd.mount(5), systemd.target(5), zfs(5), systemd.generator(7), systemd.special(7), zed(8), zpool-events(8)


zfs-program

title: zfs-program(8)

summary: execute ZFS channel programs

text:
# zfs-program(8)

## NAME
zfs-program — execute ZFS channel programs

## SYNOPSIS
zfs

program [-jn] [-t instruction-limit] [-m memory-limit] pool script [script arguments]

## DESCRIPTION
The ZFS channel program interface allows ZFS administrative operations to be run programmatically as a Lua script. The entire script is executed atomically, with no other administrative operations taking effect concurrently. A library of ZFS calls is made available to channel program scripts. Channel programs may only be run with root privileges.

A modified version of the Lua 5.2 interpreter is used to run channel program scripts. The Lua 5.2 manual can be found at http://www.lua.org/manual/5.2/

The channel program given by script will be run on pool, and any attempts to access or modify other pools will cause an error.

## OPTIONS
-j, --json

Display channel program output in JSON format. When this flag is specified and standard output is empty - channel program encountered an error. The details of such an error will be printed to standard error in plain text.

-n

Executes a read-only channel program, which runs faster. The program cannot change on-disk state by calling functions from the zfs.sync submodule. The program can be used to gather information such as properties and determining if changes would succeed (zfs.check.*). Without this flag, all pending changes must be synced to disk before a channel program can complete.

-t instruction-limit

Limit the number of Lua instructions to execute. If a channel program executes more than the specified number of instructions, it will be stopped and an error will be returned. The default limit is 10 million instructions, and it can be set to a maximum of 100 million instructions.

-m memory-limit

Memory limit, in bytes. If a channel program attempts to allocate more memory than the given limit, it will be stopped and an error returned. The default memory limit is 10 MiB, and can be set to a maximum of 100 MiB.

All remaining argument strings will be passed directly to the Lua script as described in the LUA INTERFACE section below.

## LUA INTERFACE
A channel program can be invoked either from the command line, or via a library call to lzc_channel_program().

### Arguments
Arguments passed to the channel program are converted to a Lua table. If invoked from the command line, extra arguments to the Lua script will be accessible as an array stored in the argument table with the key 'argv':

```
args = ...
argv = args["argv"]
-- argv == {1="arg1", 2="arg2", ...}
```

If invoked from the libzfs interface, an arbitrary argument list can be passed to the channel program, which is accessible via the same "..." syntax in Lua:

```
args = ...
-- args == {"foo"="bar", "baz"={...}, ...}
```

Note that because Lua arrays are 1-indexed, arrays passed to Lua from the libzfs interface will have their indices incremented by 1. That is, the element in arr[0] in a C array passed to a channel program will be stored in arr[1] when accessed from Lua.

### Return Values
Lua return statements take the form:

return ret0, ret1, ret2, ...

Return statements returning multiple values are permitted internally in a channel program script, but attempting to return more than one value from the top level of the channel program is not permitted and will throw an error. However, tables containing multiple values can still be returned. If invoked from the command line, a return statement:

```
a = {foo="bar", baz=2}
return a
```

Will be output formatted as:

```
Channel program fully executed with return value:
    return:
        baz: 2
        foo: 'bar'
```

### Fatal Errors
If the channel program encounters a fatal error while running, a non-zero exit status will be returned. If more information about the error is available, a singleton list will be returned detailing the error:

error: "error string, including Lua stack trace"

If a fatal error is returned, the channel program may have not executed at all, may have partially executed, or may have fully executed but failed to pass a return value back to userland.

If the channel program exhausts an instruction or memory limit, a fatal error will be generated and the program will be stopped, leaving the program partially executed. No attempt is made to reverse or undo any operations already performed. Note that because both the instruction count and amount of memory used by a channel program are deterministic when run against the same inputs and filesystem state, as long as a channel program has run successfully once, you can guarantee that it will finish successfully against a similar size system.

If a channel program attempts to return too large a value, the program will fully execute but exit with a nonzero status code and no return value.

Note: ZFS API functions do not generate Fatal Errors when correctly invoked, they return an error code and the channel program continues executing. See the ZFS API section below for function-specific details on error return codes.

### Lua to C Value Conversion
When invoking a channel program via the libzfs interface, it is necessary to translate arguments and return values from Lua values to their C equivalents, and vice-versa.

There is a correspondence between nvlist values in C and Lua tables. A Lua table which is returned from the channel program will be recursively converted to an nvlist, with table values converted to their natural equivalents:

string

->

string

number

->

int64

boolean

->

boolean_value

nil

->

boolean (no value)

table

->

nvlist

Likewise, table keys are replaced by string equivalents as follows:

string

->

no change

number

->

signed decimal string ("%lld")

boolean

->

"true" | "false"

Any collision of table key strings (for example, the string "true" and a true boolean value) will cause a fatal error.

Lua numbers are represented internally as signed 64-bit integers.

## LUA STANDARD LIBRARY
The following Lua built-in base library functions are available:

assert

rawlen

collectgarbage

rawget

error

rawset

getmetatable

select

ipairs

setmetatable

next

tonumber

pairs

tostring

rawequal

type

All functions in the coroutine, string, and table built-in submodules are also available. A complete list and documentation of these modules is available in the Lua manual.

The following functions base library functions have been disabled and are not available for use in channel programs:

dofile

loadfile

load

pcall

print

xpcall

## ZFS API

### Function Arguments
Each API function takes a fixed set of required positional arguments and optional keyword arguments. For example, the destroy function takes a single positional string argument (the name of the dataset to destroy) and an optional "defer" keyword boolean argument. When using parentheses to specify the arguments to a Lua function, only positional arguments can be used:

zfs.sync.destroy("rpool@snap")

To use keyword arguments, functions must be called with a single argument that is a Lua table containing entries mapping integers to positional arguments and strings to keyword arguments:

zfs.sync.destroy({1="rpool@snap", defer=true})

The Lua language allows curly braces to be used in place of parenthesis as syntactic sugar for this calling convention:

zfs.sync.snapshot{"rpool@snap", defer=true}

### Function Return Values
If an API function succeeds, it returns 0. If it fails, it returns an error code and the channel program continues executing. API functions do not generate Fatal Errors except in the case of an unrecoverable internal file system error.

In addition to returning an error code, some functions also return extra details describing what caused the error. This extra description is given as a second return value, and will always be a Lua table, or Nil if no error details were returned. Different keys will exist in the error details table depending on the function and error case. Any such function may be called expecting a single return value:

errno = zfs.sync.promote(dataset)

Or, the error details can be retrieved:

```
errno, details = zfs.sync.promote(dataset)
if (errno == EEXIST) then
    assert(details ~= Nil)
    list_of_conflicting_snapshots = details
end
```

The following global aliases for API function error return codes are defined for use in channel programs:

EPERM

ECHILD

ENODEV

ENOSPC

ENOENT

EAGAIN

ENOTDIR

ESPIPE

ESRCH

ENOMEM

EISDIR

EROFS

EINTR

EACCES

EINVAL

EMLINK

EIO

EFAULT

ENFILE

EPIPE

ENXIO

ENOTBLK

EMFILE

EDOM

E2BIG

EBUSY

ENOTTY

ERANGE

ENOEXEC

EEXIST

ETXTBSY

EDQUOT

EBADF

EXDEV

EFBIG

### API Functions
For detailed descriptions of the exact behavior of any ZFS administrative operations, see the main zfs(8) manual page.

zfs.debug(msg)

Record a debug message in the zfs_dbgmsg log. A log of these messages can be printed via mdb's "::zfs_dbgmsg" command, or can be monitored live by running dtrace -n 'zfs-dbgmsg{trace(stringof(arg0))}'

msg (string)

Debug message to be printed.

zfs.exists(dataset)

Returns true if the given dataset exists, or false if it doesn't. A fatal error will be thrown if the dataset is not in the target pool. That is, in a channel program running on rpool, zfs.exists("rpool/nonexistent_fs") returns false, but zfs.exists("somepool/fs_that_may_exist") will error.

dataset (string)

Dataset to check for existence. Must be in the target pool.

zfs.get_prop(dataset, property)

Returns two values. First, a string, number or table containing the property value for the given dataset. Second, a string containing the source of the property (i.e. the name of the dataset in which it was set or nil if it is readonly). Throws a Lua error if the dataset is invalid or the property doesn't exist. Note that Lua only supports int64 number types whereas ZFS number properties are uint64. This means very large values (like GUIDs) may wrap around and appear negative.

dataset (string)

Filesystem or snapshot path to retrieve properties from.

property (string)

Name of property to retrieve. All filesystem, snapshot and volume properties are supported except for mounted and iscsioptions. Also supports the written@snap and written#bookmark properties and the ⟨user|group⟩⟨quota|used⟩@id properties, though the id must be in numeric form.

zfs.sync submodule

The sync submodule contains functions that modify the on-disk state. They are executed in "syncing context". The available sync submodule functions are as follows:

zfs.sync.clone(snapshot, newdataset)

Create a new filesystem from a snapshot. Returns 0 if the filesystem was successfully created, and a nonzero error code otherwise. Note: Due to general limitations in channel programs, a filesystem created this way will not be mounted, regardless of the value of the mountpoint and canmount properties. This limitation may be removed in the future, so it is recommended that you set mountpoint=none or canmount=off or noauto to avoid surprises.

snapshot (string)

Name of the source snapshot to clone.

newdataset (string)

Name of the target dataset to create.

zfs.sync.destroy(dataset, [defer=true|false])

Destroy the given dataset. Returns 0 on successful destroy, or a nonzero error code if the dataset could not be destroyed (for example, if the dataset has any active children or clones).

dataset (string)

Filesystem or snapshot to be destroyed.

[defer (boolean)]

Valid only for destroying snapshots. If set to true, and the snapshot has holds or clones, allows the snapshot to be marked for deferred deletion rather than failing.

zfs.sync.inherit(dataset, property)

Clears the specified property in the given dataset, causing it to be inherited from an ancestor, or restored to the default if no ancestor property is set. The zfs inherit -S option has not been implemented. Returns 0 on success, or a nonzero error code if the property could not be cleared.

dataset (string)

Filesystem or snapshot containing the property to clear.

property (string)

The property to clear. Allowed properties are the same as those for the zfs inherit command.

zfs.sync.promote(dataset)

Promote the given clone to a filesystem. Returns 0 on successful promotion, or a nonzero error code otherwise. If EEXIST is returned, the second return value will be an array of the clone's snapshots whose names collide with snapshots of the parent filesystem.

dataset (string)

Clone to be promoted.

zfs.sync.rollback(filesystem)

Rollback to the previous snapshot for a dataset. Returns 0 on successful rollback, or a nonzero error code otherwise. Rollbacks can be performed on filesystems or zvols, but not on snapshots or mounted datasets. EBUSY is returned in the case where the filesystem is mounted.

filesystem (string)

Filesystem to rollback.

zfs.sync.set_prop(dataset, property, value)

Sets the given property on a dataset. Currently only user properties are supported. Returns 0 if the property was set, or a nonzero error code otherwise.

dataset (string)

The dataset where the property will be set.

property (string)

The property to set.

value (string)

The value of the property to be set.

zfs.sync.snapshot(dataset)

Create a snapshot of a filesystem. Returns 0 if the snapshot was successfully created, and a nonzero error code otherwise. Note: Taking a snapshot will fail on any pool older than legacy version 27. To enable taking snapshots from ZCP scripts, the pool must be upgraded.

dataset (string)

Name of snapshot to create.

zfs.sync.rename_snapshot(dataset, oldsnapname, newsnapname)

Rename a snapshot of a filesystem or a volume. Returns 0 if the snapshot was successfully renamed, and a nonzero error code otherwise.

dataset (string)

Name of the snapshot's parent dataset.

oldsnapname (string)

Original name of the snapshot.

newsnapname (string)

New name of the snapshot.

zfs.sync.bookmark(source, newbookmark)

Create a bookmark of an existing source snapshot or bookmark. Returns 0 if the new bookmark was successfully created, and a nonzero error code otherwise. Note: Bookmarking requires the corresponding pool feature to be enabled.

source (string)

Full name of the existing snapshot or bookmark.

newbookmark (string)

Full name of the new bookmark.

zfs.check submodule

For each function in the zfs.sync submodule, there is a corresponding zfs.check function which performs a "dry run" of the same operation. Each takes the same arguments as its zfs.sync counterpart and returns 0 if the operation would succeed, or a non-zero error code if it would fail, along with any other error details. That is, each has the same behavior as the corresponding sync function except for actually executing the requested change. For example, zfs.check.destroy("fs") returns 0 if zfs.sync.destroy("fs") would successfully destroy the dataset. The available zfs.check functions are:

zfs.check.clone(snapshot, newdataset)

zfs.check.destroy(dataset, [defer=true|false])

zfs.check.promote(dataset)

zfs.check.rollback(filesystem)

zfs.check.set_property(dataset, property, value)

zfs.check.snapshot(dataset)

zfs.list submodule

The zfs.list submodule provides functions for iterating over datasets and properties. Rather than returning tables, these functions act as Lua iterators, and are generally used as follows:

```
for child in zfs.list.children("rpool") do
    ...
end
```

The available zfs.list functions are:

zfs.list.clones(snapshot)

Iterate through all clones of the given snapshot.

snapshot (string)

Must be a valid snapshot path in the current pool.

zfs.list.snapshots(dataset)

Iterate through all snapshots of the given dataset. Each snapshot is returned as a string containing the full dataset name, e.g. "pool/fs@snap".

dataset (string)

Must be a valid filesystem or volume.

zfs.list.children(dataset)

Iterate through all direct children of the given dataset. Each child is returned as a string containing the full dataset name, e.g. "pool/fs/child".

dataset (string)

Must be a valid filesystem or volume.

zfs.list.bookmarks(dataset)

Iterate through all bookmarks of the given dataset. Each bookmark is returned as a string containing the full dataset name, e.g. "pool/fs#bookmark".

dataset (string)

Must be a valid filesystem or volume.

zfs.list.holds(snapshot)

Iterate through all user holds on the given snapshot. Each hold is returned as a pair of the hold's tag and the timestamp (in seconds since the epoch) at which it was created.

snapshot (string)

Must be a valid snapshot.

zfs.list.properties(dataset)

An alias for zfs.list.user_properties (see relevant entry).

dataset (string)

Must be a valid filesystem, snapshot, or volume.

zfs.list.user_properties(dataset)

Iterate through all user properties for the given dataset. For each step of the iteration, output the property name, its value, and its source. Throws a Lua error if the dataset is invalid.

dataset (string)

Must be a valid filesystem, snapshot, or volume.

zfs.list.system_properties(dataset)

Returns an array of strings, the names of the valid system (non-user defined) properties for the given dataset. Throws a Lua error if the dataset is invalid.

dataset (string)

Must be a valid filesystem, snapshot or volume.

## EXAMPLES

### Example 1
The following channel program recursively destroys a filesystem and all its snapshots and children in a naive manner. Note that this does not involve any error handling or reporting.

```
function destroy_recursive(root)
    for child in zfs.list.children(root) do
        destroy_recursive(child)
    end
    for snap in zfs.list.snapshots(root) do
        zfs.sync.destroy(snap)
    end
    zfs.sync.destroy(root)
end
destroy_recursive("pool/somefs")
```

### Example 2
A more verbose and robust version of the same channel program, which properly detects and reports errors, and also takes the dataset to destroy as a command line argument, would be as follows:

```
succeeded = {}
failed = {}

function destroy_recursive(root)
    for child in zfs.list.children(root) do
        destroy_recursive(child)
    end
    for snap in zfs.list.snapshots(root) do
        err = zfs.sync.destroy(snap)
        if (err ~= 0) then
            failed[snap] = err
        else
            succeeded[snap] = err
        end
    end
    err = zfs.sync.destroy(root)
    if (err ~= 0) then
        failed[root] = err
    else
        succeeded[root] = err
    end
end

args = ...
argv = args["argv"]

destroy_recursive(argv[1])

results = {}
results["succeeded"] = succeeded
results["failed"] = failed
return results
```

### Example 3
The following function performs a forced promote operation by attempting to promote the given clone and destroying any conflicting snapshots.

```
function force_promote(ds)
   errno, details = zfs.check.promote(ds)
   if (errno == EEXIST) then
       assert(details ~= Nil)
       for i, snap in ipairs(details) do
           zfs.sync.destroy(ds .. "@" .. snap)
       end
   elseif (errno ~= 0) then
       return errno
   end
   return zfs.sync.promote(ds)
end
```


zfs-project

title: zfs-project(8)

summary: manage projects in ZFS filesystem

text:
# zfs-project(8)

## NAME
zfs-project — manage projects in ZFS filesystem

## SYNOPSIS
zfs

project [-d|-r] file|directory…

zfs

project -C [-kr] file|directory…

zfs

project -c [-0] [-d|-r] [-p id] file|directory…

zfs

project [-p id] [-rs] file|directory…

## DESCRIPTION
zfs project [-d|-r] file|directory…

List project identifier (ID) and inherit flag of files and directories. -d

Show the directory project ID and inherit flag, not its children.

-r

List subdirectories recursively.

zfs project -C [-kr] file|directory…

Clear project inherit flag and/or ID on the files and directories. -k

Keep the project ID unchanged. If not specified, the project ID will be reset to zero.

-r

Clear subdirectories' flags recursively.

zfs project -c [-0] [-d|-r] [-p id] file|directory…

Check project ID and inherit flag on the files and directories: report entries without the project inherit flag, or with project IDs different from the target directory's project ID or the one specified with -p. -0

Delimit filenames with a NUL byte instead of newline, don't output diagnoses.

-d

Check the directory project ID and inherit flag, not its children.

-p id

Compare to id instead of the target files and directories' project IDs.

-r

Check subdirectories recursively.

zfs project -p id [-rs] file|directory…

Set project ID and/or inherit flag on the files and directories. -p id

Set the project ID to the given value.

-r

Set on subdirectories recursively.

-s

Set project inherit flag on the given files and directories. This is usually used for setting up tree quotas with -r. In that case, the directory's project ID will be set for all its descendants, unless specified explicitly with -p.

## SEE ALSO
zfs-projectspace(8)


zfs-projectspace

title: zfs-projectspace(8)

summary: display space and quotas of ZFS dataset

text:
# zfs-projectspace(8)

## NAME
zfs-userspace — display space and quotas of ZFS dataset

## SYNOPSIS
zfs

userspace [-Hinp] [-o field[,field]…] [-s field]… [-S field]… [-t type[,type]…] filesystem|snapshot|path

zfs

groupspace [-Hinp] [-o field[,field]…] [-s field]… [-S field]… [-t type[,type]…] filesystem|snapshot|path

zfs

projectspace [-Hp] [-o field[,field]…] [-s field]… [-S field]… filesystem|snapshot|path

## DESCRIPTION
zfs userspace [-Hinp] [-o field[,field]…] [-s field]… [-S field]… [-t type[,type]…] filesystem|snapshot|path

Displays space consumed by, and quotas on, each user in the specified filesystem, snapshot, or path. If a path is given, the filesystem that contains that path will be used. This corresponds to the userused@user, userobjused@user, userquota@user, and userobjquota@user properties. -H

Do not print headers, use tab-delimited output.

-S field

Sort by this field in reverse order. See -s.

-i

Translate SID to POSIX ID. The POSIX ID may be ephemeral if no mapping exists. Normal POSIX interfaces (like stat(2), ls -l) perform this translation, so the -i option allows the output from zfs userspace to be compared directly with those utilities. However, -i may lead to confusion if some files were created by an SMB user before a SMB-to-POSIX name mapping was established. In such a case, some files will be owned by the SMB entity and some by the POSIX entity. However, the -i option will report that the POSIX entity has the total usage and quota for both.

-n

Print numeric ID instead of user/group name.

-o field[,field]…

Display only the specified fields from the following set: type, name, used, quota. The default is to display all fields.

-p

Use exact (parsable) numeric output.

-s field

Sort output by this field. The -s and -S flags may be specified multiple times to sort first by one field, then by another. The default is -s type -s name.

-t type[,type]…

Print only the specified types from the following set: all, posixuser, smbuser, posixgroup, smbgroup. The default is -t posixuser,smbuser. The default can be changed to include group types.

zfs groupspace [-Hinp] [-o field[,field]…] [-s field]… [-S field]… [-t type[,type]…] filesystem|snapshot

Displays space consumed by, and quotas on, each group in the specified filesystem or snapshot. This subcommand is identical to userspace, except that the default types to display are -t posixgroup,smbgroup.

zfs projectspace [-Hp] [-o field[,field]…] [-s field]… [-S field]… filesystem|snapshot|path

Displays space consumed by, and quotas on, each project in the specified filesystem or snapshot. This subcommand is identical to userspace, except that the project identifier is a numeral, not a name. So need neither the option -i for SID to POSIX ID nor -n for numeric ID, nor -t for types.

## SEE ALSO
zfsprops(7), zfs-set(8)


zfs-promote

title: zfs-promote(8)

text:
# zfs-promote(8)

## NAME
zfs-promote — promote clone dataset to no longer depend on origin snapshot

## SYNOPSIS
zfs

promote clone

## DESCRIPTION
The zfs promote command makes it possible to destroy the dataset that the clone was created from. The clone parent-child dependency relationship is reversed, so that the origin dataset becomes a clone of the specified dataset.

The snapshot that was cloned, and any snapshots previous to this snapshot, are now owned by the promoted clone. The space they use moves from the origin dataset to the promoted clone, so enough space must be available to accommodate these snapshots. No new space is consumed by this operation, but the space accounting is adjusted. The promoted clone must not have any conflicting snapshot names of its own. The zfs rename subcommand can be used to rename any conflicting snapshots.

## EXAMPLES

### Example 1: Promoting a ZFS Clone
The following commands illustrate how to test out changes to a file system, and then replace the original file system with the changed one, using clones, clone promotion, and renaming:

```
# zfs create pool/project/production
  populate /pool/project/production with data
# zfs snapshot pool/project/production@today
# zfs clone pool/project/production@today pool/project/beta
  make changes to /pool/project/beta and test them
# zfs promote pool/project/beta
# zfs rename pool/project/production pool/project/legacy
# zfs rename pool/project/beta pool/project/production
  once the legacy version is no longer needed, it can be destroyed
# zfs destroy pool/project/legacy
```

## SEE ALSO
zfs-clone(8), zfs-rename(8)


zfs-receive

title: zfs-receive(8)

summary: create snapshot from backup stream

text:
# zfs-receive(8)

## NAME
zfs-receive — create snapshot from backup stream

## SYNOPSIS
zfs

receive [-FhMnsuv] [-o origin=snapshot] [-o property=value] [-x property] filesystem|volume|snapshot

zfs

receive [-FhMnsuv] [-d|-e] [-o origin=snapshot] [-o property=value] [-x property] filesystem

zfs

receive -A filesystem|volume

zfs

receive -c [-vn] filesystem|snapshot

## DESCRIPTION
zfs receive [-FhMnsuv] [-o origin=snapshot] [-o property=value] [-x property] filesystem|volume|snapshot

zfs receive [-FhMnsuv] [-d|-e] [-o origin=snapshot] [-o property=value] [-x property] filesystem

Creates a snapshot whose contents are as specified in the stream provided on standard input. If a full stream is received, then a new file system is created as well. Streams are created using the zfs send subcommand, which by default creates a full stream. zfs recv can be used as an alias for zfs receive. If an incremental stream is received, then the destination file system must already exist, and its most recent snapshot must match the incremental stream's source. For zvols, the destination device link is destroyed and recreated, which means the zvol cannot be accessed during the receive operation.

When a snapshot replication package stream that is generated by using the zfs send -R command is received, any snapshots that do not exist on the sending location are destroyed by using the zfs destroy -d command.

The ability to send and receive deduplicated send streams has been removed. However, a deduplicated send stream created with older software can be converted to a regular (non-deduplicated) stream by using the zstream redup command.

If -o property=value or -x property is specified, it applies to the effective value of the property throughout the entire subtree of replicated datasets. Effective property values will be set (-o) or inherited (-x) on the topmost in the replicated subtree. In descendant datasets, if the property is set by the send stream, it will be overridden by forcing the property to be inherited from the top‐most file system. Received properties are retained in spite of being overridden and may be restored with zfs inherit -S. Specifying -o origin=snapshot is a special case because, even if origin is a read-only property and cannot be set, it's allowed to receive the send stream as a clone of the given snapshot.

Raw encrypted send streams (created with zfs send -w) may only be received as is, and cannot be re-encrypted, decrypted, or recompressed by the receive process. Unencrypted streams can be received as encrypted datasets, either through inheritance or by specifying encryption parameters with the -o options. Note that the keylocation property cannot be overridden to prompt during a receive. This is because the receive process itself is already using the standard input for the send stream. Instead, the property can be overridden after the receive completes.

The added security provided by raw sends adds some restrictions to the send and receive process. ZFS will not allow a mix of raw receives and non-raw receives. Specifically, any raw incremental receives that are attempted after a non-raw receive will fail. Non-raw receives do not have this restriction and, therefore, are always possible. Because of this, it is best practice to always use either raw sends for their security benefits or non-raw sends for their flexibility when working with encrypted datasets, but not a combination.

The reason for this restriction stems from the inherent restrictions of the AEAD ciphers that ZFS uses to encrypt data. When using ZFS native encryption, each block of data is encrypted against a randomly generated number known as the "initialization vector" (IV), which is stored in the filesystem metadata. This number is required by the encryption algorithms whenever the data is to be decrypted. Together, all of the IVs provided for all of the blocks in a given snapshot are collectively called an "IV set". When ZFS performs a raw send, the IV set is transferred from the source to the destination in the send stream. When ZFS performs a non-raw send, the data is decrypted by the source system and re-encrypted by the destination system, creating a snapshot with effectively the same data, but a different IV set. In order for decryption to work after a raw send, ZFS must ensure that the IV set used on both the source and destination side match. When an incremental raw receive is performed on top of an existing snapshot, ZFS will check to confirm that the "from" snapshot on both the source and destination were using the same IV set, ensuring the new IV set is consistent.

The name of the snapshot (and file system, if a full stream is received) that this subcommand creates depends on the argument type and the use of the -d or -e options.

If the argument is a snapshot name, the specified snapshot is created. If the argument is a file system or volume name, a snapshot with the same name as the sent snapshot is created within the specified filesystem or volume. If neither of the -d or -e options are specified, the provided target snapshot name is used exactly as provided.

The -d and -e options cause the file system name of the target snapshot to be determined by appending a portion of the sent snapshot's name to the specified target filesystem. If the -d option is specified, all but the first element of the sent snapshot's file system path (usually the pool name) is used and any required intermediate file systems within the specified one are created. If the -e option is specified, then only the last element of the sent snapshot's file system name (i.e. the name of the source file system itself) is used as the target file system name.

-F

Force a rollback of the file system to the most recent snapshot before performing the receive operation. If receiving an incremental replication stream (for example, one generated by zfs send -R [-i|-I]), destroy snapshots and file systems that do not exist on the sending side.

-d

Discard the first element of the sent snapshot's file system name, using the remaining elements to determine the name of the target file system for the new snapshot as described in the paragraph above.

-e

Discard all but the last element of the sent snapshot's file system name, using that element to determine the name of the target file system for the new snapshot as described in the paragraph above.

-h

Skip the receive of holds. There is no effect if holds are not sent.

-M

Force an unmount of the file system while receiving a snapshot. This option is not supported on Linux.

-n

Do not actually receive the stream. This can be useful in conjunction with the -v option to verify the name the receive operation would use.

-o origin=snapshot

Forces the stream to be received as a clone of the given snapshot. If the stream is a full send stream, this will create the filesystem described by the stream as a clone of the specified snapshot. Which snapshot was specified will not affect the success or failure of the receive, as long as the snapshot does exist. If the stream is an incremental send stream, all the normal verification will be performed.

-o property=value

Sets the specified property as if the command zfs set property=value was invoked immediately before the receive. When receiving a stream from zfs send -R, causes the property to be inherited by all descendant datasets, as through zfs inherit property was run on any descendant datasets that have this property set on the sending system. If the send stream was sent with -c then overriding the compression property will have no effect on received data but the compression property will be set. To have the data recompressed on receive remove the -c flag from the send stream.

Any editable property can be set at receive time. Set-once properties bound to the received data, such as normalization and casesensitivity, cannot be set at receive time even when the datasets are newly created by zfs receive. Additionally both settable properties version and volsize cannot be set at receive time.

The -o option may be specified multiple times, for different properties. An error results if the same property is specified in multiple -o or -x options.

The -o option may also be used to override encryption properties upon initial receive. This allows unencrypted streams to be received as encrypted datasets. To cause the received dataset (or root dataset of a recursive stream) to be received as an encryption root, specify encryption properties in the same manner as is required for zfs create. For instance:

\# zfs send tank/test@snap1 | zfs recv -o encryption=on -o keyformat=passphrase -o keylocation=file:///path/to/keyfile

Note that -o keylocation=prompt may not be specified here, since the standard input is already being utilized for the send stream. Once the receive has completed, you can use zfs set to change this setting after the fact. Similarly, you can receive a dataset as an encrypted child by specifying -x encryption to force the property to be inherited. Overriding encryption properties (except for keylocation) is not possible with raw send streams.

-s

If the receive is interrupted, save the partially received state, rather than deleting it. Interruption may be due to premature termination of the stream (e.g. due to network failure or failure of the remote system if the stream is being read over a network connection), a checksum error in the stream, termination of the zfs receive process, or unclean shutdown of the system. The receive can be resumed with a stream generated by zfs send -t token, where the token is the value of the receive_resume_token property of the filesystem or volume which is received into.

To use this flag, the storage pool must have the extensible_dataset feature enabled. See zpool-features(7) for details on ZFS feature flags.

-u

File system that is associated with the received stream is not mounted.

-v

Print verbose information about the stream and the time required to perform the receive operation.

-x property

Ensures that the effective value of the specified property after the receive is unaffected by the value of that property in the send stream (if any), as if the property had been excluded from the send stream. If the specified property is not present in the send stream, this option does nothing.

If a received property needs to be overridden, the effective value will be set or inherited, depending on whether the property is inheritable or not.

In the case of an incremental update, -x leaves any existing local setting or explicit inheritance unchanged.

All -o restrictions (e.g. set-once) apply equally to -x.

zfs receive -A filesystem|volume

Abort an interrupted zfs receive -s, deleting its saved partially received state.

zfs receive -c [-vn] filesystem|snapshot

Attempt to repair data corruption in the specified dataset, by using the provided stream as the source of healthy data. This method of healing can only heal data blocks present in the stream. Metadata can not be healed by corrective receive. Running a scrub is recommended post-healing to ensure all data corruption was repaired. It's important to consider why corruption has happened in the first place. If you have slowly failing hardware - periodically repairing the data is not going to save you from data loss later on when the hardware fails completely.

## EXAMPLES

### Example 1: Remotely Replicating ZFS Data
The following commands send a full stream and then an incremental stream to a remote machine, restoring them into poolB/received/fs@a and poolB/received/fs@b, respectively. poolB must contain the file system poolB/received, and must not initially contain poolB/received/fs.

```
# zfs send pool/fs@a |
    ssh host zfs receive poolB/received/fs@a
# zfs send -i a pool/fs@b |
    ssh host zfs receive poolB/received/fs
```

### Example 2: Using the zfs receive -d Option
The following command sends a full stream of poolA/fsA/fsB@snap to a remote machine, receiving it into poolB/received/fsA/fsB@snap. The fsA/fsB@snap portion of the received snapshot's name is determined from the name of the sent snapshot. poolB must contain the file system poolB/received. If poolB/received/fsA does not exist, it is created as an empty file system.

```
# zfs send poolA/fsA/fsB@snap |
    ssh host zfs receive -d poolB/received
```

## SEE ALSO
zfs-send(8), zstream(8)


zfs-recv

title: zfs-recv(8)

summary: create snapshot from backup stream

text:
# zfs-recv(8)

## NAME
zfs-receive — create snapshot from backup stream

## SYNOPSIS
zfs

receive [-FhMnsuv] [-o origin=snapshot] [-o property=value] [-x property] filesystem|volume|snapshot

zfs

receive [-FhMnsuv] [-d|-e] [-o origin=snapshot] [-o property=value] [-x property] filesystem

zfs

receive -A filesystem|volume

zfs

receive -c [-vn] filesystem|snapshot

## DESCRIPTION
zfs receive [-FhMnsuv] [-o origin=snapshot] [-o property=value] [-x property] filesystem|volume|snapshot

zfs receive [-FhMnsuv] [-d|-e] [-o origin=snapshot] [-o property=value] [-x property] filesystem

Creates a snapshot whose contents are as specified in the stream provided on standard input. If a full stream is received, then a new file system is created as well. Streams are created using the zfs send subcommand, which by default creates a full stream. zfs recv can be used as an alias for zfs receive. If an incremental stream is received, then the destination file system must already exist, and its most recent snapshot must match the incremental stream's source. For zvols, the destination device link is destroyed and recreated, which means the zvol cannot be accessed during the receive operation.

When a snapshot replication package stream that is generated by using the zfs send -R command is received, any snapshots that do not exist on the sending location are destroyed by using the zfs destroy -d command.

The ability to send and receive deduplicated send streams has been removed. However, a deduplicated send stream created with older software can be converted to a regular (non-deduplicated) stream by using the zstream redup command.

If -o property=value or -x property is specified, it applies to the effective value of the property throughout the entire subtree of replicated datasets. Effective property values will be set (-o) or inherited (-x) on the topmost in the replicated subtree. In descendant datasets, if the property is set by the send stream, it will be overridden by forcing the property to be inherited from the top‐most file system. Received properties are retained in spite of being overridden and may be restored with zfs inherit -S. Specifying -o origin=snapshot is a special case because, even if origin is a read-only property and cannot be set, it's allowed to receive the send stream as a clone of the given snapshot.

Raw encrypted send streams (created with zfs send -w) may only be received as is, and cannot be re-encrypted, decrypted, or recompressed by the receive process. Unencrypted streams can be received as encrypted datasets, either through inheritance or by specifying encryption parameters with the -o options. Note that the keylocation property cannot be overridden to prompt during a receive. This is because the receive process itself is already using the standard input for the send stream. Instead, the property can be overridden after the receive completes.

The added security provided by raw sends adds some restrictions to the send and receive process. ZFS will not allow a mix of raw receives and non-raw receives. Specifically, any raw incremental receives that are attempted after a non-raw receive will fail. Non-raw receives do not have this restriction and, therefore, are always possible. Because of this, it is best practice to always use either raw sends for their security benefits or non-raw sends for their flexibility when working with encrypted datasets, but not a combination.

The reason for this restriction stems from the inherent restrictions of the AEAD ciphers that ZFS uses to encrypt data. When using ZFS native encryption, each block of data is encrypted against a randomly generated number known as the "initialization vector" (IV), which is stored in the filesystem metadata. This number is required by the encryption algorithms whenever the data is to be decrypted. Together, all of the IVs provided for all of the blocks in a given snapshot are collectively called an "IV set". When ZFS performs a raw send, the IV set is transferred from the source to the destination in the send stream. When ZFS performs a non-raw send, the data is decrypted by the source system and re-encrypted by the destination system, creating a snapshot with effectively the same data, but a different IV set. In order for decryption to work after a raw send, ZFS must ensure that the IV set used on both the source and destination side match. When an incremental raw receive is performed on top of an existing snapshot, ZFS will check to confirm that the "from" snapshot on both the source and destination were using the same IV set, ensuring the new IV set is consistent.

The name of the snapshot (and file system, if a full stream is received) that this subcommand creates depends on the argument type and the use of the -d or -e options.

If the argument is a snapshot name, the specified snapshot is created. If the argument is a file system or volume name, a snapshot with the same name as the sent snapshot is created within the specified filesystem or volume. If neither of the -d or -e options are specified, the provided target snapshot name is used exactly as provided.

The -d and -e options cause the file system name of the target snapshot to be determined by appending a portion of the sent snapshot's name to the specified target filesystem. If the -d option is specified, all but the first element of the sent snapshot's file system path (usually the pool name) is used and any required intermediate file systems within the specified one are created. If the -e option is specified, then only the last element of the sent snapshot's file system name (i.e. the name of the source file system itself) is used as the target file system name.

-F

Force a rollback of the file system to the most recent snapshot before performing the receive operation. If receiving an incremental replication stream (for example, one generated by zfs send -R [-i|-I]), destroy snapshots and file systems that do not exist on the sending side.

-d

Discard the first element of the sent snapshot's file system name, using the remaining elements to determine the name of the target file system for the new snapshot as described in the paragraph above.

-e

Discard all but the last element of the sent snapshot's file system name, using that element to determine the name of the target file system for the new snapshot as described in the paragraph above.

-h

Skip the receive of holds. There is no effect if holds are not sent.

-M

Force an unmount of the file system while receiving a snapshot. This option is not supported on Linux.

-n

Do not actually receive the stream. This can be useful in conjunction with the -v option to verify the name the receive operation would use.

-o origin=snapshot

Forces the stream to be received as a clone of the given snapshot. If the stream is a full send stream, this will create the filesystem described by the stream as a clone of the specified snapshot. Which snapshot was specified will not affect the success or failure of the receive, as long as the snapshot does exist. If the stream is an incremental send stream, all the normal verification will be performed.

-o property=value

Sets the specified property as if the command zfs set property=value was invoked immediately before the receive. When receiving a stream from zfs send -R, causes the property to be inherited by all descendant datasets, as through zfs inherit property was run on any descendant datasets that have this property set on the sending system. If the send stream was sent with -c then overriding the compression property will have no effect on received data but the compression property will be set. To have the data recompressed on receive remove the -c flag from the send stream.

Any editable property can be set at receive time. Set-once properties bound to the received data, such as normalization and casesensitivity, cannot be set at receive time even when the datasets are newly created by zfs receive. Additionally both settable properties version and volsize cannot be set at receive time.

The -o option may be specified multiple times, for different properties. An error results if the same property is specified in multiple -o or -x options.

The -o option may also be used to override encryption properties upon initial receive. This allows unencrypted streams to be received as encrypted datasets. To cause the received dataset (or root dataset of a recursive stream) to be received as an encryption root, specify encryption properties in the same manner as is required for zfs create. For instance:

\# zfs send tank/test@snap1 | zfs recv -o encryption=on -o keyformat=passphrase -o keylocation=file:///path/to/keyfile

Note that -o keylocation=prompt may not be specified here, since the standard input is already being utilized for the send stream. Once the receive has completed, you can use zfs set to change this setting after the fact. Similarly, you can receive a dataset as an encrypted child by specifying -x encryption to force the property to be inherited. Overriding encryption properties (except for keylocation) is not possible with raw send streams.

-s

If the receive is interrupted, save the partially received state, rather than deleting it. Interruption may be due to premature termination of the stream (e.g. due to network failure or failure of the remote system if the stream is being read over a network connection), a checksum error in the stream, termination of the zfs receive process, or unclean shutdown of the system. The receive can be resumed with a stream generated by zfs send -t token, where the token is the value of the receive_resume_token property of the filesystem or volume which is received into.

To use this flag, the storage pool must have the extensible_dataset feature enabled. See zpool-features(7) for details on ZFS feature flags.

-u

File system that is associated with the received stream is not mounted.

-v

Print verbose information about the stream and the time required to perform the receive operation.

-x property

Ensures that the effective value of the specified property after the receive is unaffected by the value of that property in the send stream (if any), as if the property had been excluded from the send stream. If the specified property is not present in the send stream, this option does nothing.

If a received property needs to be overridden, the effective value will be set or inherited, depending on whether the property is inheritable or not.

In the case of an incremental update, -x leaves any existing local setting or explicit inheritance unchanged.

All -o restrictions (e.g. set-once) apply equally to -x.

zfs receive -A filesystem|volume

Abort an interrupted zfs receive -s, deleting its saved partially received state.

zfs receive -c [-vn] filesystem|snapshot

Attempt to repair data corruption in the specified dataset, by using the provided stream as the source of healthy data. This method of healing can only heal data blocks present in the stream. Metadata can not be healed by corrective receive. Running a scrub is recommended post-healing to ensure all data corruption was repaired. It's important to consider why corruption has happened in the first place. If you have slowly failing hardware - periodically repairing the data is not going to save you from data loss later on when the hardware fails completely.

## EXAMPLES

### Example 1: Remotely Replicating ZFS Data
The following commands send a full stream and then an incremental stream to a remote machine, restoring them into poolB/received/fs@a and poolB/received/fs@b, respectively. poolB must contain the file system poolB/received, and must not initially contain poolB/received/fs.

```
# zfs send pool/fs@a |
    ssh host zfs receive poolB/received/fs@a
# zfs send -i a pool/fs@b |
    ssh host zfs receive poolB/received/fs
```

### Example 2: Using the zfs receive -d Option
The following command sends a full stream of poolA/fsA/fsB@snap to a remote machine, receiving it into poolB/received/fsA/fsB@snap. The fsA/fsB@snap portion of the received snapshot's name is determined from the name of the sent snapshot. poolB must contain the file system poolB/received. If poolB/received/fsA does not exist, it is created as an empty file system.

```
# zfs send poolA/fsA/fsB@snap |
    ssh host zfs receive -d poolB/received
```

## SEE ALSO
zfs-send(8), zstream(8)