openzfs / zfs

OpenZFS on Linux and FreeBSD
https://openzfs.github.io/openzfs-docs
Other
10.62k stars 1.75k forks source link

Remove inheritence --all. Define all zfsprops explicitly on dataset creation. Make properly recursive zfs cmds. #14319

Open mcladams opened 1 year ago

mcladams commented 1 year ago

I am going to remove this shortly; I have sent this proposal (edited for brevity and understanding and typographical misspellings) to the [zfs-discuss] mailing list

Background Briefing

Initially, in this post over an hour ago I proposed two features to opt-in-or-out of inheritance. and the thinking behind them, with the title:

NEW zfs props inheritance-control: for intential zfs property protection. And for moving datasets. inheritance-noaccept=(unset)|all|property[,property],...

  • (unset): normal behaviour of inheriting unset propertiess from the parent datasets in the hierarchy applies.
  • all: The dataset will not inherit any changed values from upstream; effectively protecting any default properties from changes. Properties that were inheriting a non-default value will revert to the defaultA dataset with *all can be freely renamed (moved) to a different place in the hierarchy of its pool,or zfs sent ao anywhere in a different pool, retaining its properties without any special settings during/after the rename or send
  • property[,property] : Only the specified properties are protected from inheritences, in cases where they might be critical to retain the default value, even when moved (renamed, moved or sent) to a new location in a pool.

inheritance-noprovide=(unset)|all|property[,property],...

  • Given above this other property becomes self-explantory! This is useful when a dataset requires a special property that many children would not want to inherit; such as readonly, or copies 2; or a different compression algorithm or caching/sync behaviour. Rather than changing all child datasets when the changes specific only to the dataset in question are applied this option can be added. YES, I understand the equivalent behaviour could be achieved by specifically setting properties with default values with source default, so they would retain the defaullt values with source local. However this would require many many such changes.

This solidified my thinking that the property source of "inheritance" is only a mask over the unchanged default value, and that inheritence has deep flaws and is not in-line with normal expected file-system beviour.

zfs inheritance is BAD behaviour and is effectively automatic inheriting of inheritance!!

Recursion by default?

not in my linux

mike@lunar-gamer ~ $ ls -al -d SHARE examplerc Music rw------- 1 mike mike 3542 Dec 24 06:52 examplerc drwx------ 2 mike mike 4096 Dec 9 07:34 Music drwxrwxrwx 3 mike mike 4096 Dec 24 06:53 SHARE mike@lunar-gamer ~ $ cp -r examplerc Music SHARE mike@lunar-gamer ~ $ ls -al SHARE -rw------- 1 mike mike 3542 Dec 24 06:53 examplerc drwx------ 2 mike mike 4096 Dec 24 06:53 Music

Under the same owner, copied folders never take on properties of a new parent directory.

mike@lunar-gamer ~ $ sudo mv SHARE2 /usr/local mike@lunar-gamer ~ $ ls -al /usr/local drwxr-xr-x 18 root root 4096 Dec 24 07:08 . rwxr-xr-x 12 root root 4096 Dec 24 06:32 share drwxrwxrwx 3 mike mike 4096 Dec 24 06:53 SHARE2 drwxr-xr-x 2 root root 4096 Jun 14 2022 src

Moving directory to under a new owner does not change the directory properties either.

Describe the feature would like to see added to OpenZFS

An alternative simpler, safe and self-consistenct change to the current "inheritence" behaviour is to remove inheritence as a cascading concept; and use normal linux recursion as an option when setting properties for which that behaviour is desired. So.

We already have recursiong for zfs snapshot, zfs destroy, zfs list. zfs rename will change behaviour to by default the dataset keeping all its own properties, after the move, so add an option to change that during the rename and make it optionally recursive to child datasets that are also move to a new location by zfs rename to the rename command.

Add optional -r for recursion to

Change behaviour on creating a dataset.

If it is the root dataset and a zfs property is not defined with a zpool -O command or zfs set command; SET the default value as belonging to that dataset, an actuall locally owned property. If a zfs property is undefined on a dataset with a parent, take the property of the parent and SET (assign it to) that value as belonging to the dataset, an actual locally owned property.

ZFS properties only change if explicitely asked to change; by:

How will this feature improve OpenZFS?

Use cases for zfs systems are continually expanding from initially only server applications over a decade ago. Today software testers, security specialiasts, enthusiasts may have many boot environments and distributions in one pool, and (in)frequently change and move some datasets location or properties as the system requirements evolve. For inexperienced administrators of zfs pools, inheritence has some traps, and ...

ZFS properties should only change if explicitely asked to change; by:

Additional context

I'm aware that this would be a large change to address some edge use problems so will likely never happen, but I still believe its a feature, possibly even addressing an issue that we have "inherited" from Sun/Oracle when zfs was on single boot environemtn single distribution servers only; and datasets didn't go walkabout here and there. My suggestion to change canmout is simple and uncontroversal by comparioson.

mcladams commented 1 year ago

I am going to remove this shortly; I have sent this proposal (edited for brevity and understanding and typographical misspellings) to the [zfs-discuss] mailing list.

gmelikov commented 1 year ago

Off-topic - this is the right place to propose changes, so you don't need to remove this issue.

On-topic - Honestly, I don't see a problem here. Inheritance is really helpful here, and it's explicit:

$ zfs get compression rpool/home
NAME        PROPERTY     VALUE           SOURCE
rpool/home  compression  lz4             inherited from rpool

Yes, some other tools may not have inheritance after entities creation. It's a lack of feature, as for me, not the only right way.

It's not a recursion by default, it's explicit inheritance of (mutable) non-explicitly set properties. But we can add recursive flags for some more commands, for ex. for zfs set, although it needs to work through to get desired behavior (it may be a different feature-request).

It would be great if you can describe more real-world problematic cases.

This solidified my thinking that the property source of "inheritance" is only a mask over the unchanged default value, and that inheritence has deep flaws and is not in-line with normal expected file-system beviour.

It's not a file-system behavior, it's a file-system-management (or volume manager)'s part of ZFS's behavior.

mcladams commented 1 year ago

Thankyou for clarification. Some examples.

My encryption root is zroot. On zroot I have properties such as copies=2 , setuid=off, devices=off that I do not want every child dataset to have; I wish child datasets to have default properties. Yes I can explicitly set such but it is laborious.

At other times, I have an important dataset I wish to make readonly (for example). However this dataset has several children which I do wish that property to be set.

Also - it is not well known by users that zfs send [-R | -p] sends the property of inheritence; not the value of that inherited property at the previous location. And; by default; all properties default are inherited from the current parent dataset. Therefore sending, cloning, renaming may have undesired behaviour when the new parent dataset properties are not default.

My desired behaviour would be: zfs create .. all properties are inherited from the creation parent, yes fine zfs anything involving a dataset haveing a new different parent ; keep previous default properties and do not inherit from the new parent

Off-topic: zfs rename is extremely powerfull and potentially dangerous for the ill-informed Other zfs functions should have recursion; the first that springs to mind is zfs clone I cant bring to mind others right now; but I do know I use the below a lot: for ds in \$(zfs -Ho name -r parentset); do zfs something \$ds; done

gmelikov commented 1 year ago

My encryption root is zroot. On zroot I have properties such as copies=2 , setuid=off, devices=off that I do not want every child dataset to have; I wish child datasets to have default properties. Yes I can explicitly set such but it is laborious.

it is not recommended to use root dataset for data, because it will have some drawbacks (for ex. with snapshots, your case, etc). You can look at root dataset's props as defaults for pool, which you can override in child dataset.

At other times, I have an important dataset I wish to make readonly (for example). However this dataset has several children which I do wish that property to be set.

you can just set what you want in this case.

My desired behaviour would be:

I think you may want to make your datasets structure more organized by your needs and tasks. If you want something readonly - it usually be better to have full branch of datasets readonly, otherwise it's a special case which you can easily set even now.

Yes, there is no inheritance in usual POSIX FS's (for ex.) rights model, BUT usually someone works with it as there is inheritance (home dir will have rights of one user, main part of etc is readonly for all, etc).

We may make some tools or arguments to make it easier, but it easily can be done with one-line scripts without a need of great change of ZFS CLI or datasets inheritance change.

mcladams commented 1 year ago

Added later to the above by edit you may have missed: zfs rename is extremely powerfull and potentially dangerous for the ill-informed Other zfs functions should have recursion; the first that springs to mind is zfs clone I cant bring to mind others right now; but I do know I use the below a lot: for ds in $(zfs -Ho name -r parentset); do zfs something $ds; done

Regarding: dataset and pool structure This might become a more usual type of installation in the future: 2 x ssds with partitions EFI, swap, zroot (mirrored) (for the entire remaining disk) I have 2 x 1 TB ssds on most laptops and boxes now with such; the zpool is the entire disk Therefore I cant separate OS from data at the pool level; only the datset level.

gmelikov commented 1 year ago

Therefore I cant separate OS from data at the pool level; only the datset level.

Why do you want to separate it at the pool level? Do you mean several pools by that? You can just create several pools.

Otherwise - just don't use root dataset, and create ROOT dataset for OS and data dataset for data, and create children datasets there as you want. You may want to look at our RootOnZFS guides https://openzfs.github.io/openzfs-docs/Getting%20Started/Debian/Debian%20Bullseye%20Root%20on%20ZFS.html#step-3-system-installation

mcladams commented 1 year ago

This isn't my first rodeo. Installed first zfs on root system using debootstrap and an ubuntu2004 server iso.

I think I'm running edge cases. Heck when ubuntu's zsys first started I built zsys in arch and debian so they and snapshots would be in my ubuntu grub menu. Aside: Not many distributions have a 10_linux_zfs in grub.d

Offtopic: zfs list default options fail; I have my own alias because crucial properties of canmount and mounted are not exposed by a simple zfs list. alias zls='zfs list -o name,used,available,referenced,canmount,mounted,mountpoint' and a function zlsm() { zls $@ | grep -e ' on ' -e ' yes ' ; }

Off topic: zls -r zroot for this box

NAME                                 USED  AVAIL     REFER  CANMOUNT  MOUNTED  MOUNTPOINT
zroot                                120G  72.9G      244K  off       no       none
zroot/DATA                          3.25G  72.9G      288K  off       no       /data
zroot/DATA/media                    2.19G  72.9G     2.09G  on        yes      /data/media
zroot/DATA/projects                  480M  72.9G      303M  on        yes      /data/projects
zroot/DATA/projects/ref              192K  72.9G      192K  on        yes      /data/projects/ref
zroot/DATA/storage                   606M  72.9G      606M  -         -        -
zroot/DATA/vm                        192K  72.9G      192K  on        yes      /data/vm
zroot/DATA/zvol                      192K  72.9G      192K  off       no       none
zroot/LINUX                         5.81G  72.9G      192K  off       no       /
zroot/LINUX/opt                     3.85G  72.9G     3.67G  on        yes      /opt
zroot/LINUX/srv                      272K  72.9G      192K  on        yes      /srv
zroot/LINUX/usr                      245M  72.9G      192K  off       no       /usr
zroot/LINUX/usr/local                245M  72.9G      241M  on        yes      /usr/local
zroot/LINUX/var                     1.72G  72.9G      192K  off       no       /var
zroot/LINUX/var/lib                 1.72G  72.9G      192K  off       no       /var/lib
zroot/LINUX/var/lib/containers       192K  72.9G      192K  off       no       /var/lib/containers
zroot/LINUX/var/lib/snapd           1.72G  72.9G      520K  noauto    no       /var/lib/snapd
zroot/LINUX/var/lib/snapd/snaps     1.72G  72.9G     1.72G  noauto    no       /var/lib/snapd/snaps
zroot/ROOT                           111G  72.9G      192K  off       no       none
zroot/ROOT/debian11                 24.8G  72.9G      192K  off       no       none
zroot/ROOT/debian11/console         1.19G  72.9G     1.06G  noauto    no       /
zroot/ROOT/debian11/home            4.09G  72.9G     4.00G  noauto    no       /home
zroot/ROOT/debian11/mx21-fluxbox    1.49G  72.9G     2.35G  noauto    no       /
zroot/ROOT/debian11/pve-console     2.34G  72.9G     3.18G  noauto    no       /
zroot/ROOT/debian11/pve-mystery     3.29G  72.9G     3.29G  noauto    no       /
zroot/ROOT/debian11/pve30-cli       5.02G  72.9G     5.61G  noauto    no       /
zroot/ROOT/debian11/pve30-gnm       6.82G  72.9G     6.88G  noauto    no       /
zroot/ROOT/debian11/root             527M  72.9G      525M  noauto    no       /root
zroot/ROOT/debtesting               18.8G  72.9G      192K  off       no       none
zroot/ROOT/debtesting/console       1.36G  72.9G     1.20G  noauto    no       /
zroot/ROOT/debtesting/home           541M  72.9G      486M  noauto    yes      /home
zroot/ROOT/debtesting/kaisen_kde    87.7M  72.9G     14.6G  on        no       none
zroot/ROOT/debtesting/kaisen_lxqt   16.8G  72.9G     14.6G  noauto    yes      /
zroot/ROOT/debtesting/root          44.7M  72.9G     33.5M  noauto    yes      /root
zroot/ROOT/fedora36                 12.5G  72.9G      192K  off       no       none
zroot/ROOT/fedora36/home             400M  72.9G      400M  noauto    no       /home
zroot/ROOT/fedora36/nobara          12.2G  72.9G     8.89G  noauto    no       /
zroot/ROOT/fedora36/root             584K  72.9G      308K  noauto    no       /root
zroot/ROOT/ubuntu2204               8.48G  72.9G      192K  off       no       /
zroot/ROOT/ubuntu2204/gnome         7.17G  72.9G     5.33G  noauto    no       /
zroot/ROOT/ubuntu2204/home           612M  72.9G      333M  noauto    no       /home
zroot/ROOT/ubuntu2204/root           201M  72.9G      199M  noauto    no       /root
zroot/ROOT/ubuntu2204/server         519M  72.9G     5.98G  noauto    no       /
zroot/ROOT/ubuntu2304               41.2G  72.9G      192K  off       no       none
zroot/ROOT/ubuntu2304/gnome-nosnap  25.7G  72.9G     15.1G  noauto    no       /
zroot/ROOT/ubuntu2304/home          6.27G  72.9G     2.41G  noauto    no       /home
zroot/ROOT/ubuntu2304/root          20.9M  72.9G     14.6M  noauto    no       /root
zroot/ROOT/ubuntu2304/studio-kde    9.19G  72.9G     11.1G  noauto    no       /
zroot/ROOT/void                     5.31G  72.9G      192K  off       no       none
zroot/ROOT/void/home                 192K  72.9G      192K  noauto    no       /home
zroot/ROOT/void/root                 192K  72.9G      192K  noauto    no       /root
zroot/ROOT/void/void-xcfe           5.31G  72.9G     5.31G  noauto    no       /

And zlsm (canmount on and/or mounted)

vault/data/media                    4.39G      302M  on        yes      /data/media
vault/data/opt                        96K       96K  on        yes      /data/opt
vault/devops/PVE/vz                 89.1G     5.01G  on        yes      /var/lib/vz
vault/media/APP/downloads           53.0G     53.0G  on        yes      /share/downloads
vault/media/APP/glob                20.6G      104G  on        yes      /share/glob
vault/media/APP/library_pc           176G      176G  on        yes      /share/library_pc
vault/media/LINUX/lxsteam           2.08G     1.58G  on        yes      /home/mike/.local/Steam
vault/media/MUSIC/dj_bylabel         167G      167G  on        yes      /share/dj_bylabel
vault/media/VIDEO/library            139G      139G  on        yes      /share/library
zroot/DATA/media                    2.19G     2.09G  on        yes      /data/media
zroot/DATA/projects                  480M      303M  on        yes      /data/projects
zroot/DATA/projects/ref              192K      192K  on        yes      /data/projects/ref
zroot/DATA/vm                        192K      192K  on        yes      /data/vm
zroot/LINUX/opt                     3.85G     3.67G  on        yes      /opt
zroot/LINUX/srv                      272K      192K  on        yes      /srv
zroot/LINUX/usr/local                245M      241M  on        yes      /usr/local
zroot/ROOT/debtesting/home           542M      487M  noauto    yes      /home
zroot/ROOT/debtesting/kaisen_kde    87.7M     14.6G  on        no       none
zroot/ROOT/debtesting/kaisen_lxqt   16.8G     14.6G  noauto    yes      /
zroot/ROOT/debtesting/root          44.7M     33.5M  noauto    yes      /root

Oops, need to fix that zroot/ROOT/debtesting/kaisen_kde from canmount on to noauto. No to mention two sources for /data/media

overlay=off by default was awesome, it brought to light -for me- errors such as the latter above.