ZFS ZFS tank mounted as a dataset?

Code:
(ins)jon:~ zfs list -o name,mounted,mountpoint,canmount
NAME                                                                    MOUNTED  MOUNTPOINT  CANMOUNT
tank                                                                    yes      /tank       on
tank/ROOT                                                               no       none        on
tank/ROOT/13.0-RELEASE-p11                                              no       /           noauto
tank/ROOT/13.0-RELEASE-p8                                               no       /           noauto
tank/ROOT/13.0-RELEASE-p8-nvidia-driver                                 no       /           noauto
tank/ROOT/13.1-STABLE                                                   no       /           noauto
tank/ROOT/13.1-STABLE-20220507.080956                                   no       /           noauto
tank/ROOT/13.1-STABLE-20230224.072050                                   yes      /           noauto

I think I've somehow created a dataset with the same name as the zpool. Both are named tank. I don't need a folder named /tank. Is it safe to run zfs destroy -r /tank? Or should I be setting the properties, i.e canmount=noauto? What are the correct properties for it?

BTW, I didn't see a forum tag for preformatted text. So, I couldn't display the zfs list output with the correct alignment. is there a way to do that?
 
Last edited by a moderator:
Quoting zfsconcepts(7) (please read that man page):
ZFS File System Hierarchy
A ZFS storage pool is a logical collection of devices that provide space
for datasets. A storage pool is also the root of the ZFS file system
hierarchy.

The root of the pool can be accessed as a file system, such as mounting
and unmounting, taking snapshots, and setting properties. The physical
storage characteristics, however, are managed by the zpool(8) command.

There is nothing wrong with what you are seeing and you don't need to destroy anything, leave it as is.
 
I have the boot environment tank/ROOT/13.1-STABLE-20230224.072050 mounted on /. I'd like to get rid of the /tank folder. When I ran sudo zfs create tank/bhyve it created the folder /tank/bhyve instead of /bhyve.

I'm fairly well versed in zfs, but I'm very cautious about changing, especially removing, anything. I think I may have inadvertently mounted tank at some point, but I don't have whatever command I ran save in my shell history.
 
About that dataset being mounted -- it could be a legacy from Solaris where it used to have a boot/ subdirectory containing the grub stuff, so when you are adding/deleting the BE, corresponding grub file(s) could be updated (or I could be imagining things).

In any case, I see that you are using BEs, and if that directory is empty, you could try getting rid of the mount by setting mountpoint=legacy property on tank *dataset* (I just did, nothing bad happened, never really was interested enough to try previously).
 

(ins)jon:~ zfs list -o name,mounted,mountpoint,canmount
NAME MOUNTED MOUNTPOINT CANMOUNT
tank yes /tank on
tank/ROOT no none on
tank/ROOT/13.0-RELEASE-p11 no / noauto
tank/ROOT/13.0-RELEASE-p8 no / noauto
tank/ROOT/13.0-RELEASE-p8-nvidia-driver no / noauto
tank/ROOT/13.1-STABLE no / noauto
tank/ROOT/13.1-STABLE-20220507.080956 no / noauto
tank/ROOT/13.1-STABLE-20230224.072050 yes / noauto


I think I've somehow created a dataset with the same name as the zpool. Both are named tank. I don't need a folder named /tank. Is it safe to run zfs destroy -r /tank? Or should I be setting the properties, i.e canmount=noauto? What are the correct properties for it?

BTW, I didn't see a forum tag for preformatted text. So, I couldn't display the zfs list output with the correct alignment. is there a way to do that?
If you don’t want /tank, just set canmount=off on tank.
 
I think I've somehow created a dataset with the same name as the zpool. Both are named tank. I don't need a folder named /tank.
Nope, you have just a pool named tank, but no dataset named tank.
If you run # zfs list, no arguments, the name of the pool always gets listed on the first line.

If I remember my reading of the manuals, you do kind of need the /tank folder, it's the mountpoint for your entire pool! So leave it alone!

As an example, here's my dump from # zfs list :
Code:
NAME                        USED  AVAIL     REFER  MOUNTPOINT
zroot                      81.6G   376G       96K  /zroot
zroot/ROOT                 13.9G   376G       96K  none
zroot/ROOT/default         13.9G   376G     13.9G  /
zroot/jails                1.90G   376G      104K  /zroot/jails
zroot/jails/basejail        488M   376G      488M  /zroot/jails/basejail
zroot/jails/firefox         968M   376G       96K  /zroot/jails/firefox
zroot/jails/firefox/home    182M   376G      182M  /zroot/jails/firefox/root/usr/home
zroot/jails/firefox/root    554M   376G     1.02G  /zroot/jails/firefox/root
zroot/jails/firefox/tmp     104K   376G      104K  /zroot/jails/firefox/root/tmp
zroot/jails/firefox/var     233M   376G      233M  /zroot/jails/firefox/root/var
zroot/jails/practice       2.79M   376G     2.41M  /zroot/jails/practice
zroot/jails/practice/root   388K   376G      488M  /zroot/jails/practice/root
zroot/jails/practice_01     488M   376G      488M  /zroot/jails/practice_01
zroot/tmp                   488K   376G      488K  /tmp
zroot/usr                  64.2G   376G       96K  /usr
zroot/usr/home             21.7G   376G     21.7G  /usr/home
zroot/usr/ports            41.8G   376G     41.8G  /usr/ports
zroot/usr/src               759M   376G      759M  /usr/src
zroot/var                  1.56G   376G       96K  /var
zroot/var/audit              96K   376G       96K  /var/audit
zroot/var/crash            1.56G   376G     1.56G  /var/crash
zroot/var/log               932K   376G      932K  /var/log
zroot/var/mail              288K   376G      288K  /var/mail
zroot/var/tmp               120K   376G      120K  /var/tmp
 
If mountpoint=legacy is set to pool (parent), than all newly created child datasets will inherit from it and won't be mounted.
Code:
 # zfs create tank/bhyve
 # zfs get mountpoint,mounted tank tank/bhyve
NAME         PROPERTY     VALUE      SOURCE
tank         mountpoint   legacy     local
tank         mounted      no         -
tank/bhyve   mountpoint   legacy     inherited from tank
tank/bhyver  mounted      no         -
In this case any newly created child dataset needs the mountpoint property set:

If the mountpoint property of newly created child datasets needs to be set, then one can as well let the mountpoint property of tank as is.

If you want to get rid of the /tank directory, set mountpoint=none to tank and rm -r /tank. Make sure there are no child datasets with their mount points under it. If there are, those datasets need another mount point set.
I'd like to get rid of the /tank folder. When I ran sudo zfs create tank/bhyve it created the folder /tank/bhyve instead of /bhyve.
Code:
 # zfs create -o mountpoint=/bhyve tank/bhyve
or present child dataset
Code:
 # zfs set mountpoint=/bhyve tank/bhyve
 
It is important to realise the commonalities and differences between the layered storage structures of non-ZFS filesystems like UFS, and ZFS filesystems. UFS must have separate slices (i.e., physical and fixed sized "partitions") for separate filesystems that are to be mapped or mounted to the hierarchical filesystem with / at the top of that hierarchy.

ZFS is a pooled storage system where all the filesystems (within one pool) share many resources: one such property is space; hence the name pooled. In effect this creates an additional storage layer structure that isn't present in a traditional filesystem structure like UFS (see for example ZFS Administration, Part X- Creating Filesystems by Aaron Toponce). Datasets within a pool are somewhat like slices ("partitions") in that they represent separate filesystems that can/must be mapped into the (mounting) hierarchy below /.

The usual default dataset structures within a pool and its accompanying mounting mappings currently follow the structure as shown by astyle. Your structure with your "tank" pool deviates from that[4]. Because ZFS is a pooled system all datasets reside inside one pool[1].

Rich (BB code):
(ins)jon:~ zfs list -o name,mounted,mountpoint,canmount
NAME                                                                    MOUNTED  MOUNTPOINT  CANMOUNT
tank                                                                    yes      /tank       on
tank/ROOT                                                               no       none        on
tank/ROOT/13.0-RELEASE-p11                                              no       /           noauto
tank/ROOT/13.0-RELEASE-p8                                               no       /           noauto
tank/ROOT/13.0-RELEASE-p8-nvidia-driver                                 no       /           noauto
tank/ROOT/13.1-STABLE                                                   no       /           noauto
tank/ROOT/13.1-STABLE-20220507.080956                                   no       /           noauto
tank/ROOT/13.1-STABLE-20230224.072050                                   yes      /           noauto
[...] I think I may have inadvertently mounted tank at some point, but I don't have whatever command I ran save in my shell history.
"tank" is your pool name; at boot time this pool gets (automatically) imported and its datasets get mounted according to their respective canmount & mountpoint properties[2]. At the top of your dataset hierarchy is your pool "tank"; any dataset inside "tank" is subordinate to it; it's placed relative to tank (yellow highlighted in the first column); in your current view above those are all the datasets ROOT and its (subordinate) child datasets, including your BEs.

[...] When I ran sudo zfs create tank/bhyve it created the folder /tank/bhyve instead of /bhyve.

zfsconcepts(7):
Rich (BB code):
Mount Points
     Creating a    ZFS file system    is a simple operation, so the number of    file
     systems per system    is likely to be    numerous.  To cope with    this, ZFS au-
     tomatically manages mounting and unmounting file systems without the need
     to    edit the /etc/fstab file.  All automatically managed file systems are
     mounted by    ZFS at boot time.

     By    default, file systems are mounted under    /path, where path is the name
     of    the file system    in the ZFS namespace.  Directories are created and de-
     stroyed as    needed.

     A file system can also have a mount point set in the mountpoint property.
     This directory is created as needed, and ZFS automatically    mounts the
     file system when the zfs mount -a command is invoked (without editing
     /etc/fstab).  The mountpoint property can be inherited, so    if pool/home
     has a mount point of /export/stuff, then pool/home/user automatically in-
     herits a mount point of /export/stuff/user.

     A file system mountpoint property of none prevents    the file system    from
     being mounted.
In your case, the top in your dataset hierarchy, tank (i.e. your pool name) has as mountpoint property /tank. It has its canmount property set to on and thus it will appear as /tank in your mounted filesystem hierarchy. This /tank directory will initially be empty and functions as sort of a marker for newly created data sets: those wil be placed there when not otherwise specified[3].

zfs-create(8):
Code:
DESCRIPTION
     zfs create    [-Pnpuv] [-o property=value]a| filesystem
       Creates a new ZFS file system.  The file    system is automatically
       mounted according to the    mountpoint property inherited from the parent,
       unless the -u option is used.
With sudo zfs create tank/bhyve you've created a new dataset tank/bhyve in the dataset hierarchy of your pool "tank" having its mountpoint property (i.e. /tank) inherited from its parent in the dataset hierarchy: tank, creating a new directory /tank/bhyve in your filesystem hierarchy, then using that as mounpoint and lastly actually mounting it there (see also the quotation above of zfsconcepts(7) where the dataset pool/export/stuff/user is mapped to mountpoint /export/stuff/user).



If you don’t want /tank, just set canmount=off on tank.
Before creating a new dataset there, with the aid of zfs set canmount=off tank you could get rid of /tank. However, unless overridden, the mountpoint property /tank will be used at the creation of any new dataset immediately below the top of the dataset hierarchy (tank):
Code:
# zfs set canmount=off tank                                                     
# zfs create tank/bhyve                                                   
# zfs list -o name,mounted,mountpoint,canmount                                  
NAME               MOUNTED  MOUNTPOINT    CANMOUNT                              
tank                    no  /tank              off                              
tank/ROOT               no  none                on                              
tank/ROOT/default      yes  /                   on                              
   <snap>
tank/bhyve             yes  /tank/bhyve         on

___
[1] Unless you have multiple pools, then each pool must "reside in a different slice"; usually that means different (sets of) physical hard disks where VDEVs from which a pool is constructed are used for another pool.

[2] As mentioned in the first quoted paragraph, ZFS manages its mounting outside of /etc/filetab by default; if you set any mountpoint property of a dataset to legacy you must explicitly manage those mounts either through /etc/filetab or manually through mount(8), as mentioned in answers by others.

[3] See for example ZFS default datasets from ca. 6:44 min.
This is from the following presentation and gives a good view of some of the (advanced) possibilities that BEs offer:

[4] As your dataset structure seems to deviate from the default given your output quoted above, you, for example, do not have a separate dataset for tank/usr/home, tank/var/log and tank/var/mail. That means that the files in /usr/home, /var/log or /var/mail respectively belong to the dataset used for BEs; usually that is not what you want. It adds to the space occupied by the BEs but, more importantly, any change in those directories that falls inside a BE will revert to its state belonging to any other (older) BE when you decide to or must revert to another BE. Please refer to the presentation at [3] where this is explained further. The following references may also be helpful:
  1. Managing Boot Environments by Klara systems - July 15, 2021
  2. Let’s Talk OpenZFS Snapshots by Klara systems - July 28, 2021
  3. Basics of ZFS Snapshot Management by Klara Systems - May 12, 2021
  4. Advanced ZFS Snapshots by Klara Systems - October 27, 2021
 
Well, I want to thank everyone that commented. I appreciate all the insights and the reminders of things I once knew and had forgotten. 😜 It's been a long time since I set this up. I've gone from PC-BSD -> FuryBSD -> FreeBSD releases and now I'm running 13.2-STABLE.

I think my mistake was just expecting the /bhyve dataset to be mounted at /bhyve without adding the -o mountpoint parameter. I've also returned tank to its default settings.
 
As your dataset structure seems to deviate from the default given your output quoted above, you, for example, do not have a separate dataset for tank/usr/home, tank/var/log and tank/var/mail.

Actually, I do. I just truncated the command output for brevity. Sorry, I didn't make that clear in my posts.

Code:
NAME                                                                    MOUNTED  MOUNTPOINT      CANMOUNT
tank                                                                    no       /tank           on
tank/ROOT                                                               no       none            on
tank/ROOT/13.0-RELEASE-p11                                              no       /               noauto
tank/ROOT/13.0-RELEASE-p8                                               no       /               noauto
tank/ROOT/13.0-RELEASE-p8-nvidia-driver                                 no       /               noauto
tank/ROOT/13.1-STABLE                                                   no       /               noauto
tank/ROOT/13.1-STABLE-20220507.080956                                   no       /               noauto
tank/ROOT/13.1-STABLE-20230224.072050                                   yes      /               noauto
tank/ROOT/13.1-STABLE-20230224.072050-before_pkg_upgrade                no       /               noauto
tank/ROOT/13.1-STABLE-20230224.072050-before_switch_to_poudriere-devel  no       /               noauto
tank/ROOT/13.1-STABLE-20230224.072050-pkg_upgrade                       no       /               noauto
tank/bhyve                                                              yes      /bhyve          on
tank/bhyve/alpine                                                       yes      /bhyve/alpine   on
tank/bhyve/freebsd                                                      yes      /bhyve/freebsd  on
tank/bhyve/freebsd/disk0                                                -        -               -
tank/tmp                                                                yes      /tmp            on
tank/usr                                                                no       /usr            off
tank/usr/home                                                           yes      /usr/home       on
tank/usr/ports                                                          yes      /usr/ports      on
tank/usr/src                                                            yes      /usr/src        on
tank/var                                                                no       /var            off
tank/var/audit                                                          yes      /var/audit      on
tank/var/crash                                                          yes      /var/crash      on
tank/var/log                                                            yes      /var/log        on
tank/var/mail                                                           yes      /var/mail       on
tank/var/tmp                                                            yes      /var/tmp        on
 
Actually, I do. I just truncated the command output for brevity. Sorry, I didn't make that clear in my posts.


NAME MOUNTED MOUNTPOINT CANMOUNT
tank no /tank on
tank/ROOT no none on
tank/ROOT/13.0-RELEASE-p11 no / noauto
tank/ROOT/13.0-RELEASE-p8 no / noauto
tank/ROOT/13.0-RELEASE-p8-nvidia-driver no / noauto
tank/ROOT/13.1-STABLE no / noauto
tank/ROOT/13.1-STABLE-20220507.080956 no / noauto
tank/ROOT/13.1-STABLE-20230224.072050 yes / noauto
tank/ROOT/13.1-STABLE-20230224.072050-before_pkg_upgrade no / noauto
tank/ROOT/13.1-STABLE-20230224.072050-before_switch_to_poudriere-devel no / noauto
tank/ROOT/13.1-STABLE-20230224.072050-pkg_upgrade no / noauto
tank/bhyve yes /bhyve on
tank/bhyve/alpine yes /bhyve/alpine on
tank/bhyve/freebsd yes /bhyve/freebsd on
tank/bhyve/freebsd/disk0 - - -
tank/tmp yes /tmp on
tank/usr no /usr off
tank/usr/home yes /usr/home on
tank/usr/ports yes /usr/ports on
tank/usr/src yes /usr/src on
tank/var no /var off
tank/var/audit yes /var/audit on
tank/var/crash yes /var/crash on
tank/var/log yes /var/log on
tank/var/mail yes /var/mail on
tank/var/tmp yes /var/tmp on
Code:
NAME                                                                    MOUNTED  MOUNTPOINT      CANMOUNT
tank                                                                    no       /tank           on
tank/ROOT                                                               no       none            on
tank/ROOT/13.0-RELEASE-p11                                              no       /               noauto
tank/ROOT/13.0-RELEASE-p8                                               no       /               noauto
tank/ROOT/13.0-RELEASE-p8-nvidia-driver                                 no       /               noauto
tank/ROOT/13.1-STABLE                                                   no       /               noauto
tank/ROOT/13.1-STABLE-20220507.080956                                   no       /               noauto
tank/ROOT/13.1-STABLE-20230224.072050                                   yes      /               noauto
tank/ROOT/13.1-STABLE-20230224.072050-before_pkg_upgrade                no       /               noauto
tank/ROOT/13.1-STABLE-20230224.072050-before_switch_to_poudriere-devel  no       /               noauto
tank/ROOT/13.1-STABLE-20230224.072050-pkg_upgrade                       no       /               noauto
tank/bhyve                                                              yes      /bhyve          on
tank/bhyve/alpine                                                       yes      /bhyve/alpine   on
tank/bhyve/freebsd                                                      yes      /bhyve/freebsd  on
tank/bhyve/freebsd/disk0                                                -        -               -
tank/tmp                                                                yes      /tmp            on
tank/usr                                                                no       /usr            off
tank/usr/home                                                           yes      /usr/home       on
tank/usr/ports                                                          yes      /usr/ports      on
tank/usr/src                                                            yes      /usr/src        on
tank/var                                                                no       /var            off
tank/var/audit                                                          yes      /var/audit      on
tank/var/crash                                                          yes      /var/crash      on
tank/var/log                                                            yes      /var/log        on
tank/var/mail                                                           yes      /var/mail       on
tank/var/tmp                                                            yes      /var/tmp        on

Using [CODE][/CODE] tags makes it easier to read than [CMD][/CMD]... and makes it clear that the /tank folder is just a mountpoint for the tank pool... there's no dataset with the name tank...
 
Just to make this clear, the pool is called tank, but as a user you do not store any data directly on the pool. There used to be a mistake in the FreeBSD documentation that suggested otherwise, that "/tank" was somehow the pool itself and that you weren't making use of ZFS features without creating sub-datasets, but this was wrong.

By default, you have one root dataset called, surprisingly "tank" (or whatever the pool is called). This is a ZFS dataset just like any other, and has the same functionality, as such being managed by the zfs command. ZFS relies on this existing of course, because it's designed for all additional datasets to be created as a hierarchy underneath it, similar to the root folder on other file systems.

You're better off leaving the root dataset alone (although you can set properties such as compression on it if you want them to be pool-wide). By default a sub-dataset such as tank/bhyve would be mounted at /tank/bhyve, which I prefer in most cases as it keeps all the additional datasets on the pool logically together, but that is easily changed by updating the mountpoint property on that dataset.
 
By default, you have one root dataset called, surprisingly "tank" (or whatever the pool is called). This is a ZFS dataset just like any other, and has the same functionality, as such being managed by the zfs command. ZFS relies on this existing of course, because it's designed for all additional datasets to be created as a hierarchy underneath it, similar to the root folder on other file systems.
Umm... there is actually a difference between datasets and pools. There's no such thing as 'root dataset that is also the pool'. Don't confuse ppl... 😩
 
Yes there a a difference, and everyone else is getting more and more confused by statements such as this:

the /tank folder is just a mountpoint for the tank pool there's no dataset with the name tank...

You have a pool with the given name, as listed/managed with the zpool command.
This is not mounted anywhere. It is nonsense to suggest a pool can be mounted or written to directly. You "import" a pool, and datasets are mounted.
Code:
# zpool list
NAME      SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
storage   920G   449G   471G        -         -    57%    48%  1.00x  ONLINE  -

You have a dataset (ZFS filesystem) on that pool with the same name.
Code:
# zfs list
NAME                    USED  AVAIL  REFER  MOUNTPOINT
storage                 449G   442G    25K  /storage

Note how this is listed and managed with the zfs command, can be mounted and used as a posix compliant file system, and supports all the properties of a zfs filesystem dataset, because it is one.

I didn't say the root dataset is also the pool, I said the pool contains a root dataset, which is a ZFS filesystem (posix compliant filesystem as apposed to a zvol, the other main type of dataset). This is identical in functionality to any sub ZFS filesystems you create:

Code:
# zfs get all storage
NAME     PROPERTY              VALUE                  SOURCE
storage  type                  filesystem             -
storage  creation              Mon Jul 22 12:51 2019  -
... more zfs dataset/filesystem properties ...

Again, note that a storage dataset indeed exists, and is of type filesystem.
 
Yeah, all pools have at least one dataset, the root dataset with same name. You can scrub a pool (with zpool-scrub(8)), but not a dataset. If you try to pass the name of a dataset (other than thge root dataset) to the # zpool-scrub, you'll probably get a complaint from ZFS about that...
 
And if you don't really want to store data in the top-level (shares the pool name) dataset, make sure /tank is currently empty, and then zfs set mountpoint=none tank && rmdir /tank. You can also set canmount=off. You don't have any datasets currently inheriting from it for a mountpoint setting (no tank/foo mounted at /tank/foo datasets), so this should be harmless so long as /tank is currently empty.

Many people (the default FreeBSD install included) avoid mounting the top-level dataset; you can't rename or destroy that dataset like you can all others, so it is special and somewhat limited / less flexible, and (for many users) just serves as the root of the dataset layout tree.
 
I have for
tank : canmount=off mountpoint=none
tank/ROOT : canmount=off mountpoint=none
tank/ROOT/default : canmount=off mountpoint=legacy
This last dataset contains /etc , /usr , /var , ...
 
Back
Top