share nfs zfs solaris

por | 17 octubre, 2018

In Solaris 11.1 Oracle decided to change the way that they stored filesystem share information.  I personally loved the change, but that was without understanding what the change really was.  For more information on how to enable NFS exports see my previous article here.

Setup Our Environment

Everything we are doing will be on some test file systems, with no data.  So lets put everything in place.

# zfs create tank/fs1
# zfs set share=name=tank_fs1,path=/tank/fs1,prot=nfs,sec=sys,[email protected] tank/fs1
name=tank_fs1,path=/tank/fs1,prot=nfs,sec=sys,[email protected]

Now lets create our child filesystem, and export it the same way.

# zfs create tank/fs1/sub1
# zfs set share=name=tank_fs1_sub1,path=/tank/fs1/sub1,prot=nfs,sec=sys,[email protected] tank/fs1/sub1
name=tank_fs1_sub1,path=/tank/fs1/sub1,prot=nfs,sec=sys,[email protected]

Now this will simulate a situation that I was in.  I had originally exported everything at a higher level (fs1) and then as the dataset grew it became necessary to export it at the child level (sub1) in order to have more granular control.  So now we have two exports, and only need sub1.

Disable Unused NFS Export

Since fs1 is no longer needed lets disable its export.

# zfs set share.nfs=off tank/fs1

Lets take a look at fs1 to see if our configuration is still active.

# zfs get share tank/fs1

OK it is empty.  But since I don’t need this any more I want to make sure that there are no remaining artifacts.  So lets re-enable it and confirm that the configuration is gone.

 # zfs set share.nfs=on tank/fs1
# zfs get share tank/fs1
tank/fs1  share     name=tank_fs1,path=/tank/fs1,prot=nfs,sec=sys,[email protected]  local

OK, so our configuration is still there, but it is disabled by share.nfs=off.  It must be kept elsewhere in the file system.

FYI, this is included in the ZFS metadata, so if you were to export you zpool and take it to another system, it would come over to the other system.

Explore ZFS Properties

Lets disable fs1 and start poking around.

# zfs set share.nfs=off tank/fs1

First thing to do is a get all.  This will list all of the properties of the filesystem.  I trimmed it back to only display the one that I found interesting.

# zfs get all tank/fs1
tank/fs1  share.*               ...                    local

OK so lets look a little bit closer at this share.* property.

# zfs get share.* tank/fs1
bad property list: invalid property specifier 'share.*', use 'share.all'
For more info, run: zfs help get

So share.* is not a valid property, it means that there are sub-properties, apparently share.all will display the sub-properties.

# zfs get share.all tank/fs1
tank/fs1       off        local
tank/fs1  share.autoname              default
tank/fs1  share.desc                  default
tank/fs1  share.nfs        off        local
tank/fs1  share.nfs.*      ...        default
tank/fs1  share.point      /tank/fs1  default
tank/fs1  share.protocols             -
tank/fs1  share.smb        off        default
tank/fs1  share.smb.*      ...        default

Oh boy, now we are getting somewhere, here is our share.nfs, and we can also see that share.nfs has sub-properties as well.  Also notice that smb is also stored here in the same fashion.

# zfs get share.nfs.all tank/fs1
tank/fs1  share.nfs.aclok      off    default
tank/fs1  share.nfs.anon              default
tank/fs1  share.nfs.charset.*  ...    default
tank/fs1  share.nfs.cksum             default
tank/fs1  share.nfs.index             default
tank/fs1  share.nfs.log               default
tank/fs1  share.nfs.noaclfab   off    default
tank/fs1  share.nfs.nosub      off    default
tank/fs1  share.nfs.nosuid     off    default
tank/fs1  share.nfs.sec               default
tank/fs1  share.nfs.sec.*      ...    default

Under share.nfs.all we have a lot of NFS parameters, the most important at this point is share.nfs.sec.all, so lets look there.

# zfs get share.nfs.sec.all tank/fs1
NAME      PROPERTY                 VALUE  SOURCE
tank/fs1  share.nfs.sec.default.*  ...    default
tank/fs1  share.nfs.sec.dh.*       ...    default
tank/fs1  share.nfs.sec.krb5.*     ...    default
tank/fs1  share.nfs.sec.krb5i.*    ...    default
tank/fs1  share.nfs.sec.krb5p.*    ...    default
tank/fs1  share.nfs.sec.none.*     ...    default
tank/fs1  share.nfs.sec.sys.*      ...    default

We are getting warmer.  Now we have the share.nfs.sec.sys.all to take a look at.

# zfs get share.nfs.sec.sys.all tank/fs1
NAME      PROPERTY                        VALUE  SOURCE
tank/fs1  share.nfs.sec.sys.none                 default
tank/fs1                   default
tank/fs1  share.nfs.sec.sys.root                 default
tank/fs1  share.nfs.sec.sys.root_mapping         default
tank/fs1                   default

OK well we have run out of levels to go deeper, but I still don’t see anything.  Perhaps if we call the property by name?

# zfs get tank/fs1
tank/fs1         default

So that is empty as well.  Perhaps that has something to do with the export being disabled?  Lets confirm our export is disabled.

# zfs get share.nfs tank/fs1
tank/fs1  share.nfs  off    local

Doesn’t get any more disabled than that. Well lets check the sub1 file system.

# zfs get share.nfs tank/fs1/sub1
tank/fs1/sub1  share.nfs  on     local

So we can see that it is enabled, lets check the share property to see what our whole string is.

# zfs get share tank/fs1/sub1
tank/fs1/sub1  share     name=tank_fs1_sub1,path=/tank/fs1/sub1,prot=nfs,sec=sys,[email protected]  local

Based on that string we should have =

# zfs get tank/fs1/sub1
NAME           PROPERTY              VALUE  SOURCE
tank/fs1/sub1         default

OK well that was unexpected.  Property is empty on the enabled export file system as well.  We must be missing something.

Back to the Drawing Board

Out of pure desperation and a fair bit of luck.  I was attempting to lookup the help command on zfs get, and accidentally typed list instead.  But look at what I found.

# zfs help list
list [-rH][-d max] [-o property[,...]] [-t type[,...]] [-s property] ...
[-S property] ... [filesystem|volume|snapshot|share] ...

There is a share file system type.  Certainly that must have something to do with everything I am seeing?

# zfs list -t share
NAME                                                                   USED  AVAIL  REFER  MOUNTPOINT
tank/fs1%tank_fs1                                                         -      -      -  /tank/fs1
tank/fs1/sub1%tank_fs1_sub1                                               -      -      -  /tank/fs1/sub1

Clearly we are onto something here.  We have a share file system type for both our enabled and our disabled NFS export.  Lets see what kind of properties these new file system types have.

ZFS File System Share Type

# zfs get all tank/fs1%tank_fs1
NAME               PROPERTY    VALUE                  SOURCE
tank/fs1%tank_fs1  creation    Sat Sep 21 10:09 2013  -
tank/fs1%tank_fs1  mountpoint  /tank/fs1              -
tank/fs1%tank_fs1  share.*     ...                    local
tank/fs1%tank_fs1  zoned       off                    default

Well there is a share.* so that must be what we are looking for.  Lets try our previous command against this new file system and take a look at what we get.

# zfs get share.nfs.sec.sys.all tank/fs1%tank_fs1
NAME               PROPERTY                        VALUE       SOURCE
tank/fs1%tank_fs1  share.nfs.sec.sys.none                      default
tank/fs1%tank_fs1                        default
tank/fs1%tank_fs1  share.nfs.sec.sys.root                      default
tank/fs1%tank_fs1  share.nfs.sec.sys.root_mapping              default
tank/fs1%tank_fs1            @  local

Well there is that elusive read write statement.

Updating NFS Security Statements

Now lets see what happens when we change it.

# zfs set [email protected]:@ tank/fs1%tank_fs1

Here we have added a second IP address to be allowed to read and write, on our disabled NFS export.

# zfs get share.nfs.sec.sys.all tank/fs1%tank_fs1
NAME               PROPERTY                        VALUE                  SOURCE
tank/fs1%tank_fs1  share.nfs.sec.sys.none                                 default
tank/fs1%tank_fs1                                   default
tank/fs1%tank_fs1  share.nfs.sec.sys.root                                 default
tank/fs1%tank_fs1  share.nfs.sec.sys.root_mapping                         default
tank/fs1%tank_fs1            @  local

The property is successfully updated on the share file system type.  Lets see if it also enabled the NFS export.

# zfs get share tank/fs1

Still disabled, that is perfect.  Now lets see what happens on an enabled NFS export.

# zfs set [email protected]:@ tank/fs1/sub1%tank_fs1_sub1

Now we have added 2 new IPs to have read only access to this export.  Lets check its effect.

# zfs get share.nfs.sec.sys.all tank/fs1/sub1%tank_fs1_sub1
NAME                         PROPERTY                        VALUE                  SOURCE
tank/fs1/sub1%tank_fs1_sub1  share.nfs.sec.sys.none                                 default
tank/fs1/sub1%tank_fs1_sub1            @  local
tank/fs1/sub1%tank_fs1_sub1  share.nfs.sec.sys.root                                 default
tank/fs1/sub1%tank_fs1_sub1  share.nfs.sec.sys.root_mapping                         default
tank/fs1/sub1%tank_fs1_sub1            @             local

The properties were successfully updated.  Lets check the file system to see if the share properties were brought over.

# zfs get share tank/fs1/sub1
tank/fs1/sub1  share     name=tank_fs1_sub1,path=/tank/fs1/sub1,prot=nfs,sec=sys,[email protected]:@,[email protected]  local

That looks perfect, and lets ask NFS what it knows.

# showmount -e
export list for server1:
/tank/fs1/sub1                      @,@,@

Wonderful!  That is exactly what we wanted.  Now one final thing.

Removing NFS Export Configuration Permanently

Now since there is this whole different type of file system to store the share configuration, removing it becomes incredibly easy.

# zfs destroy tank/fs1%tank_fs1

That pretty much wraps up everything.