Zfs: once altered, the `canmount` property can never be reverted to `default` source

Created on 2 Feb 2017  路  12Comments  路  Source: openzfs/zfs

System information


Type | Version/Name
--- | ---
Distribution Name | ubuntu
Distribution Version | xenial
Linux Kernel | 4.4.0-59-generic
Architecture | amd64
ZFS Version | 0.7.0-rc3_19_g935550f
SPL Version | 0.7.0-rc3

Describe the problem you're observing

if set, canmount property source always remains local, it can never be reverted to default
I expect to be able to revert this to 'default'

Describe how to reproduce the problem

root@linux:~# truncate -s 128M testfile
root@linux:~# zpool create test ~/testfile
root@linux:~# zfs get canmount test
NAME  PROPERTY  VALUE     SOURCE
test  canmount  on        default
root@linux:~# zfs set canmount=noauto test
root@linux:~# zfs get canmount test
NAME  PROPERTY  VALUE     SOURCE
test  canmount  noauto    local
root@linux:~# zfs inherit canmount test
'canmount' property cannot be inherited
root@linux:~# zfs set canmount=on test
root@linux:~# zfs get canmount test
NAME  PROPERTY  VALUE     SOURCE
test  canmount  on        local

Include any warning/errors/backtraces from the system logs

Documentation Question good first issue

All 12 comments

This affects upstream too, not a ZoL-specific issue:

[root@52-54-00-d3-7a-f3 ~]# zfs set canmount=noauto $POOLNAME/fs
[root@52-54-00-d3-7a-f3 ~]# zfs get -o all canmount $POOLNAME/fs
NAME         PROPERTY  VALUE     RECEIVED  SOURCE
testpool/fs  canmount  noauto    -         local
[root@52-54-00-d3-7a-f3 ~]# zfs inherit canmount $POOLNAME/fs
'canmount' property cannot be inherited
[root@52-54-00-d3-7a-f3 ~]# zfs get -o all canmount $POOLNAME/fs
NAME         PROPERTY  VALUE     RECEIVED  SOURCE
testpool/fs  canmount  noauto    -         local
[root@52-54-00-d3-7a-f3 ~]#  
[root@52-54-00-d3-7a-f3 ~]# uname -a
SunOS 52-54-00-d3-7a-f3 5.11 joyent_20170202T040152Z i86pc i386 i86pc
[root@52-54-00-d3-7a-f3 ~]# 

This affects upstream too

yes but it is impossible for regular end-users to file issues on openzfs github or illumos issue tracker.

Sometimes you can use zfs inherit -S to wipe it out. This command is intended to revert to the received value (where applicable) but if a received value is not available it reverts to default/inherited.

The quota and I imagine reservation properties suffer the same problem.

Generally the ZFS command inherit is equivalent to a sort of unset command, yet it doesn't quite do the same thing.

@mailinglists35 right. My point was just stating that we're not missing something from upstream: this seems an entirely new issue. I also checked here https://www.illumos.org/projects/illumos-gate/issues but could not find anything that seems related to this.

Granted that, by the looks of it, this seems a bug (nice catch by the way) what's the specific use case here? The only thing you can't do right now is revert to the default value once you have received it, in which case you can still zfs set the property.

It's mainly a cleanliness thing. I often use zfs get -r -s local[,inherited] all $poolname and it would be nice if values which are defaults didn't show up. Problem is once a property that doesn't inherit under the usual rules is set, it can never be unset.

Problem is once a property that doesn't inherit under the usual rules is set, it can never be unset.

But as you said zfs inherit -S does in fact "unset" the local value. The real issue is that we can't "unset" received properties.

Is there a good reason why zfs inherit should not be able to revert all writeable properties to their default, irregarding of inheritable or not?

Is there a good reason why zfs inherit should not be able to revert all writeable properties to their default, irregarding of inheritable or not?

Yes. zfs inherit places an explicit inherit on a property: the way this is implemented is by adding a property entry with the suffix "$inherit" to the dataset. This is different from an implicit inherit which is when no value is set locally and we, by default, just inherit from the parent.

root@debian-8-zfs:~# zfs set exec=off $POOLNAME
root@debian-8-zfs:~# zfs set copies=2 $POOLNAME
root@debian-8-zfs:~# zfs create $POOLNAME/send -o compression=gzip
root@debian-8-zfs:~# zfs snap $POOLNAME/send@snap1
root@debian-8-zfs:~# zfs send -p $POOLNAME/send@snap1 | zfs recv $POOLNAME/recv
root@debian-8-zfs:~# zfs inherit compression $POOLNAME/recv
root@debian-8-zfs:~# zfs inherit copies $POOLNAME/recv
root@debian-8-zfs:~# zfs set atime=off $POOLNAME/recv
root@debian-8-zfs:~# zfs get -o all atime,exec,copies,compression $POOLNAME/recv
NAME           PROPERTY     VALUE     RECEIVED  SOURCE
testpool/recv  atime        off       -         local
testpool/recv  exec         off       -         inherited from testpool
testpool/recv  copies       2         -         inherited from testpool
testpool/recv  compression  off       gzip      default

As you can see both "copies" and "exec" are inherited from testpool, while "compression" was reverted to the default value (off) with zfs inherit.

If we take a look at the ZAP entries we can see the two different types of inheritance:

root@debian-8-zfs:~# zdb -dddd $POOLNAME 79
Dataset mos [META], ID 0, cr_txg 4, 61.5K, 55 objects, rootbp DVA[0]=<0:7b400:200> DVA[1]=<0:7b600:200> DVA[2]=<0:7b800:200> [L0 DMU objset] fletcher4 lz4 LE contiguous unique triple size=800L/200P birth=19L/19P fill=55 cksum=eb9e09091:54029acdcbe:fa4bc2314430:20478e3814ba5c

    Object  lvl   iblk   dblk  dsize  dnsize  lsize   %full  type
        79    1   128K    512      0     512    512  100.00  DSL props
    dnode flags: USED_BYTES 
    dnode maxblkid: 0
    microzap: 512 bytes, 5 entries

        atime = 0 
        $hasrecvd = 0 
        compression$inherit = 0 
        compression$recvd = 10 
        copies$inherit = 0 

  • "copies$inherit" is the explicit inherit we set with zfs inherit copies $POOLNAME/recv.
  • "exec" is the implicit inherit and doesn't need any ZAP entry because its value is, by default, inherited by the parent dataset (remember we zfs set exec=off $POOLNAME earlier).

If we let zfs inherit "work" on non-inheritable properties the DSL will only get confused about their value when it finds the "$inherit" ZAP entry: they would probably effectively inherit from their parent, which is kind of defeat the purpose of being non-inheritable to being with.

@loli10K thanks for the code side explanation.

So far I looked at it from a user perspective and understood zfs inherit as simply removing a previously set property from the dataset (so the lookup for it would traverse up the parents to find a set one or fall back to the default if none is found).

Tracking properties reverted to 'inherited' seems to just be needless metadata bloat to me, what do I overlook?

Tracking properties reverted to 'inherited' seems to just be needless metadata bloat to me

We need the "explicit inherit" functionality when we want to override values of received properties so they don't take precedence; this without the need to manually set every properties on sub-datasets.

In my example we have both compression$inherit and compression$recvd ZAP entries on $POOLNAME/recv and the effective compression value ("gzip") is inherited from the parent: now we can zfs set compression=lz4 just on the root dataset and every children will inherit. This wouldn't be possible without explicit inheritance.

We could, theoretically, expand the code to allow the user to remove every ZAP entry (which AFAIK is not yet possible) and revert canmount and other non-inheritable properties to a "true" default state, we just need to modify every function in the zfs_prop_inherit() -> ... -> ioctl() -> ... -> dsl_prop_set_sync_impl() callpath.

FWIW, zfs inherit -S works works for reverting values of properties to the default on illumos. Even though it's documented to "[r]evert the property to the received value if one exists; otherwise operate as if the -S option was not specified", it behaves differently for properties without received values.

[trisk@catte]% zfs get canmount abyss/crashplan
NAME             PROPERTY  VALUE     SOURCE
abyss/crashplan  canmount  on        local
[trisk@catte]% pfexec zfs inherit canmount abyss/crashplan
'canmount' property cannot be inherited                                                                                                 
[trisk@catte]% pfexec zfs inherit -S canmount abyss/crashplan
[trisk@catte]% zfs get canmount abyss/crashplan
NAME             PROPERTY  VALUE     SOURCE
abyss/crashplan  canmount  on        default

I haven't checked this on ZoL yet.

inherit -S works for me now.

Was this page helpful?
0 / 5 - 0 ratings