Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove dependency on sharetab file and refactor sharing logic #10300

Merged
merged 1 commit into from
Jul 13, 2020
Merged

Remove dependency on sharetab file and refactor sharing logic #10300

merged 1 commit into from
Jul 13, 2020

Conversation

grwilson
Copy link
Member

@grwilson grwilson commented May 7, 2020

Motivation and Context

The current implementation of 'sharenfs' and 'sharesmb' relies on
the use of the sharetab file. The use of this file is os-specific
and not required by linux or freebsd. Currently the code must
maintain updates to this file which adds complexity and presents
a significant performance impact when sharing many datasets. In
addition, concurrently running 'zfs sharenfs' command results in
missing entries in the sharetab file leading to unexpected failures.

Description

This change removes the sharetab logic from the linux and freebsd
implementation of 'sharenfs' and 'sharesmb'. It still preserves an
os-specific library which contains the logic required for sharing
NFS or SMB. The following entry points exist in the vastly simplified
libshare library:

  • sa_enable_share -- shares a dataset but may not commit the change
  • sa_disable_share -- unshares a dataset but may not commit the change
  • sa_is_shared -- determine if a dataset is shared
  • sa_share_commit -- notify NFS/SMB subsystem to commit the shares
  • sa_validate_shareopts -- determine if sharing options are valid

The sa_share_commit entry point is provided as a performance enhancement
and is not required. The sa_enable_share/sa_disable_share may commit
the share as part of the implementation. Libshare provides a framework
for both NFS and SMB but some operating systems may not fully support
these protocols or all features of the protocol.

NFS Operation:
For linux, libshare updates /etc/exports.d/zfs.exports to add
and remove shares and then commits the changes by invoking 'exportfs -r'.
This file, is automatically read by the kernel NFS implementation which
makes for better integration with the NFS systemd service. For FreeBSD,
libshare updates /etc/zfs/exports to add and remove shares and then
commits the changes by sending a SIGHUP to mountd.

SMB Operation:
For linux, libshare adds and removes files in /var/lib/samba/usershares
by calling the 'net' command directly. There is no need to commit the
changes. FreeBSD does not support SMB.

Performance Results

To test sharing performance we created a pool with an increasing number
of datasets and invoked various zfs actions that would enable and disable
sharing. The performance testing was limited to NFS sharing. The following
tests were performed on an 8 vCPU system with 128GB and a pool comprised
of 4 50GB SSDs:

Scale testing:

  • Share all filesystems in parallel -- zfs sharenfs=on &
  • Unshare all filesystems in parallel -- zfs sharenfs=off &

Functional testing:

  • share each filesystem serially -- zfs share -a
  • unshare each filesystem serially -- zfs unshare -a
  • reset sharenfs property and unshare -- zfs inherit -r sharenfs

For 'zfs sharenfs=on' scale testing we saw an average reduction in time
of 89.43% and for 'zfs sharenfs=off' we saw an average reduction in time
of 83.36%.

Functional testing also shows a huge improvement:

  • zfs share -- 97.97% reduction in time
  • zfs unshare -- 96.47% reduction in time
  • zfs inhert -r sharenfs -- 99.01% reduction in time

The following charts show the results of scale testing. For each tests we create an increasing number of datasets and then invoke the respective 'sharenfs' command in the background.

baseline sharenfs=off and new sharenfs=off
basline sharenfs=on and new sharenfs=on

Signed-off-by: George Wilson gwilson@delphix.com
External-Issue: DLPX-68690

@behlendorf behlendorf added the Status: Code Review Needed Ready for review and testing label May 7, 2020
@behlendorf behlendorf self-requested a review May 7, 2020 16:50
@ahrens ahrens added the Component: Userspace user space functionality label May 7, 2020
@ahrens ahrens self-requested a review May 7, 2020 16:59
@grwilson
Copy link
Member Author

I have updated the PR since one of the commits was missed and I also had to remove some leftover debugging code. I have also fixed up the lint errors and style errors that were reported.

@ghost
Copy link

ghost commented May 13, 2020

I think the zfs_share tests are being skipped on FreeBSD in setup. There were some issues with my attempt at libtest is_shared hanging in some situations so I punted at the time. I will see if I can manually run the test to verify functionality for now.

@ghost
Copy link

ghost commented May 14, 2020

I'm finding this in /etc/zfs/exports when running zfs_share tests after fixing libtest and the zfs_share setup to run on FreeBSD (before the concurrent shares test):

# !!! DO NOT EDIT THIS FILE MANUALLY !!!

S FILE MANUALLY !!!
S FILE MANUALLY !!!
S FILE MANUALLY !!!
 FILE MANUALLY !!!
NUALLY !!!
/var/tmp/testdir1       on
 FILE MANUALLY !!!
 FILE MANUALLY !!!
S FILE MANUALLY !!!
 FILE MANUALLY !!!

Needless to say, the tests do not go well :)

That is with this PR applied. I don't see this behavior on master.

lib/libshare/libshare.c Outdated Show resolved Hide resolved
lib/libshare/libshare.c Outdated Show resolved Hide resolved
lib/libshare/libshare.c Outdated Show resolved Hide resolved
lib/libshare/libshare_impl.h Outdated Show resolved Hide resolved
lib/libshare/os/linux/nfs.c Show resolved Hide resolved
lib/libshare/os/linux/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/linux/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/linux/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/linux/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/linux/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/linux/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/linux/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/linux/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/linux/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/linux/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/linux/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/linux/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/linux/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/linux/nfs.c Show resolved Hide resolved
lib/libzfs/libzfs_changelist.c Outdated Show resolved Hide resolved
@ahrens
Copy link
Member

ahrens commented Jun 3, 2020

From talking to @grwilson, this PR also fixes #7943.

@codecov
Copy link

codecov bot commented Jun 8, 2020

Codecov Report

Merging #10300 into master will increase coverage by 0.28%.
The diff coverage is 70.97%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #10300      +/-   ##
==========================================
+ Coverage   79.51%   79.80%   +0.28%     
==========================================
  Files         393      393              
  Lines      124638   124460     -178     
==========================================
+ Hits        99106    99320     +214     
+ Misses      25532    25140     -392     
Flag Coverage Δ
#kernel 80.16% <ø> (+<0.01%) ⬆️
#user 66.19% <70.97%> (+1.11%) ⬆️
Impacted Files Coverage Δ
lib/libzfs/libzfs_util.c 73.01% <ø> (-0.08%) ⬇️
lib/libzfs/os/linux/libzfs_mount_os.c 71.69% <ø> (+8.67%) ⬆️
lib/libshare/os/linux/smb.c 20.40% <20.00%> (ø)
cmd/zfs/zfs_main.c 82.57% <66.66%> (-0.08%) ⬇️
lib/libzfs/libzfs_mount.c 82.88% <67.92%> (-1.60%) ⬇️
lib/libshare/os/linux/nfs.c 75.34% <68.15%> (ø)
lib/libshare/libshare.c 49.11% <87.23%> (-18.57%) ⬇️
lib/libzfs/libzfs_changelist.c 85.01% <89.47%> (+0.64%) ⬆️
cmd/zpool/zpool_main.c 81.01% <100.00%> (+0.10%) ⬆️
lib/libzfs/libzfs_dataset.c 76.95% <100.00%> (+0.09%) ⬆️
... and 59 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e59a377...54e7bb2. Read the comment docs.

lib/libshare/os/linux/nfs.c Outdated Show resolved Hide resolved
lib/libshare/libshare_impl.h Outdated Show resolved Hide resolved
lib/libshare/os/freebsd/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/freebsd/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/freebsd/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/freebsd/nfs.c Show resolved Hide resolved
lib/libshare/os/linux/nfs.c Show resolved Hide resolved
lib/libshare/os/freebsd/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/freebsd/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/freebsd/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/freebsd/nfs.c Outdated Show resolved Hide resolved
lib/libshare/os/freebsd/nfs.c Show resolved Hide resolved
lib/libshare/os/freebsd/nfs.c Show resolved Hide resolved
Copy link

@bgly bgly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works very well for me with the latest. Tested against 1000's of shares/unshares along with many clients connected writing data while shares/unshares are occurring. Prior this would cause stale file handlers and with this patch that is completely eliminated.

lib/libshare/Makefile.am Outdated Show resolved Hide resolved
lib/libshare/Makefile.am Outdated Show resolved Hide resolved
lib/libshare/os/freebsd/nfs.c Outdated Show resolved Hide resolved
lib/libzfs/libzfs_mount.c Outdated Show resolved Hide resolved
@behlendorf behlendorf requested a review from ahrens July 7, 2020 22:36
@ghost
Copy link

ghost commented Jul 8, 2020

@grwilson The failure in zfs_share_concurrent_shares on stable/12 seems to have been pretty consistent. Do you have any indication of what this is about? I was hoping it would be resolved by https://reviews.freebsd.org/rS362713 but that is in the image used by the bot as of the 2nd.

@behlendorf behlendorf added Status: Accepted Ready to integrate (reviewed, tested) and removed Status: Code Review Needed Ready for review and testing labels Jul 10, 2020
== Motivation and Context

The current implementation of 'sharenfs' and 'sharesmb' relies on
the use of the sharetab file. The use of this file is os-specific
and not required by linux or freebsd. Currently the code must
maintain updates to this file which adds complexity and presents
a significant performance impact when sharing many datasets. In
addition, concurrently running 'zfs sharenfs' command results in
missing entries in the sharetab file leading to unexpected failures.

== Description

This change removes the sharetab logic from the linux and freebsd
implementation of 'sharenfs' and 'sharesmb'. It still preserves an
os-specific library which contains the logic required for sharing
NFS or SMB. The following entry points exist in the vastly simplified
libshare library:

- sa_enable_share -- shares a dataset but may not commit the change
- sa_disable_share -- unshares a dataset but may not commit the change
- sa_is_shared -- determine if a dataset is shared
- sa_commit_share -- notify NFS/SMB subsystem to commit the shares
- sa_validate_shareopts -- determine if sharing options are valid

The sa_commit_share entry point is provided as a performance enhancement
and is not required. The sa_enable_share/sa_disable_share may commit
the share as part of the implementation. Libshare provides a framework
for both NFS and SMB but some operating systems may not fully support
these protocols or all features of the protocol.

NFS Operation:
For linux, libshare updates /etc/exports.d/zfs.exports to add
and remove shares and then commits the changes by invoking
'exportfs -r'. This file, is automatically read by the kernel NFS
implementation which makes for better integration with the NFS systemd
service. For FreeBSD, libshare updates /etc/zfs/exports to add and
remove shares and then commits the changes by sending a SIGHUP to
mountd.

SMB Operation:
For linux, libshare adds and removes files in /var/lib/samba/usershares
by calling the 'net' command directly. There is no need to commit the
changes. FreeBSD does not support SMB.

== Performance Results

To test sharing performance we created a pool with an increasing number
of datasets and invoked various zfs actions that would enable and
disable sharing. The performance testing was limited to NFS sharing.
The following tests were performed on an 8 vCPU system with 128GB and
a pool comprised of 4 50GB SSDs:

Scale testing:
- Share all filesystems in parallel -- zfs sharenfs=on <dataset> &
- Unshare all filesystems in parallel -- zfs sharenfs=off <dataset> &

Functional testing:
- share each filesystem serially -- zfs share -a
- unshare each filesystem serially -- zfs unshare -a
- reset sharenfs property and unshare -- zfs inherit -r sharenfs <pool>

For 'zfs sharenfs=on' scale testing we saw an average reduction in time
of 89.43% and for 'zfs sharenfs=off' we saw an average reduction in time
of 83.36%.

Functional testing also shows a huge improvement:
- zfs share -- 97.97% reduction in time
- zfs unshare -- 96.47% reduction in time
- zfs inhert -r sharenfs -- 99.01% reduction in time

Signed-off-by: George Wilson <gwilson@delphix.com>
Closes #1603
Closes #7692
Closes #7943
External-Issue: DLPX-68690
@grwilson
Copy link
Member Author

@grwilson The failure in zfs_share_concurrent_shares on stable/12 seems to have been pretty consistent. Do you have any indication of what this is about? I was hoping it would be resolved by https://reviews.freebsd.org/rS362713 but that is in the image used by the bot as of the 2nd.

I've have reproduced this on freebsd 12.1/stable (build r363017) and noticed that the output of showmount -E (which is used by the test suite to detect if the filesystem is shared) does not show the accurate count immediately. I ran a simple test where I shared 1000 filesystems in parallel and immediately ran showmount -E and it displayed 994 filesystem but rerunning it again displays the correct value. I suspect that mountd is being delayed because of the number of updates happening during the test and so we don't get an inaccurate result from showmount -E and fail the test.

I have marked this test as flakey in freebsd since it does work on 12.1/release.

@behlendorf behlendorf merged commit c15d36c into openzfs:master Jul 13, 2020
jsai20 pushed a commit to jsai20/zfs that referenced this pull request Mar 30, 2021
== Motivation and Context

The current implementation of 'sharenfs' and 'sharesmb' relies on
the use of the sharetab file. The use of this file is os-specific
and not required by linux or freebsd. Currently the code must
maintain updates to this file which adds complexity and presents
a significant performance impact when sharing many datasets. In
addition, concurrently running 'zfs sharenfs' command results in
missing entries in the sharetab file leading to unexpected failures.

== Description

This change removes the sharetab logic from the linux and freebsd
implementation of 'sharenfs' and 'sharesmb'. It still preserves an
os-specific library which contains the logic required for sharing
NFS or SMB. The following entry points exist in the vastly simplified
libshare library:

- sa_enable_share -- shares a dataset but may not commit the change
- sa_disable_share -- unshares a dataset but may not commit the change
- sa_is_shared -- determine if a dataset is shared
- sa_commit_share -- notify NFS/SMB subsystem to commit the shares
- sa_validate_shareopts -- determine if sharing options are valid

The sa_commit_share entry point is provided as a performance enhancement
and is not required. The sa_enable_share/sa_disable_share may commit
the share as part of the implementation. Libshare provides a framework
for both NFS and SMB but some operating systems may not fully support
these protocols or all features of the protocol.

NFS Operation:
For linux, libshare updates /etc/exports.d/zfs.exports to add
and remove shares and then commits the changes by invoking
'exportfs -r'. This file, is automatically read by the kernel NFS
implementation which makes for better integration with the NFS systemd
service. For FreeBSD, libshare updates /etc/zfs/exports to add and
remove shares and then commits the changes by sending a SIGHUP to
mountd.

SMB Operation:
For linux, libshare adds and removes files in /var/lib/samba/usershares
by calling the 'net' command directly. There is no need to commit the
changes. FreeBSD does not support SMB.

== Performance Results

To test sharing performance we created a pool with an increasing number
of datasets and invoked various zfs actions that would enable and
disable sharing. The performance testing was limited to NFS sharing.
The following tests were performed on an 8 vCPU system with 128GB and
a pool comprised of 4 50GB SSDs:

Scale testing:
- Share all filesystems in parallel -- zfs sharenfs=on <dataset> &
- Unshare all filesystems in parallel -- zfs sharenfs=off <dataset> &

Functional testing:
- share each filesystem serially -- zfs share -a
- unshare each filesystem serially -- zfs unshare -a
- reset sharenfs property and unshare -- zfs inherit -r sharenfs <pool>

For 'zfs sharenfs=on' scale testing we saw an average reduction in time
of 89.43% and for 'zfs sharenfs=off' we saw an average reduction in time
of 83.36%.

Functional testing also shows a huge improvement:
- zfs share -- 97.97% reduction in time
- zfs unshare -- 96.47% reduction in time
- zfs inhert -r sharenfs -- 99.01% reduction in time

Reviewed-by: Matt Ahrens <matt@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Ryan Moeller <ryan@ixsystems.com>
Reviewed-by: Bryant G. Ly <bryangly@gmail.com>
Signed-off-by: George Wilson <gwilson@delphix.com>
External-Issue: DLPX-68690
Closes openzfs#1603
Closes openzfs#7692
Closes openzfs#7943
Closes openzfs#10300
sempervictus pushed a commit to sempervictus/zfs that referenced this pull request May 31, 2021
== Motivation and Context

The current implementation of 'sharenfs' and 'sharesmb' relies on
the use of the sharetab file. The use of this file is os-specific
and not required by linux or freebsd. Currently the code must
maintain updates to this file which adds complexity and presents
a significant performance impact when sharing many datasets. In
addition, concurrently running 'zfs sharenfs' command results in
missing entries in the sharetab file leading to unexpected failures.

== Description

This change removes the sharetab logic from the linux and freebsd
implementation of 'sharenfs' and 'sharesmb'. It still preserves an
os-specific library which contains the logic required for sharing
NFS or SMB. The following entry points exist in the vastly simplified
libshare library:

- sa_enable_share -- shares a dataset but may not commit the change
- sa_disable_share -- unshares a dataset but may not commit the change
- sa_is_shared -- determine if a dataset is shared
- sa_commit_share -- notify NFS/SMB subsystem to commit the shares
- sa_validate_shareopts -- determine if sharing options are valid

The sa_commit_share entry point is provided as a performance enhancement
and is not required. The sa_enable_share/sa_disable_share may commit
the share as part of the implementation. Libshare provides a framework
for both NFS and SMB but some operating systems may not fully support
these protocols or all features of the protocol.

NFS Operation:
For linux, libshare updates /etc/exports.d/zfs.exports to add
and remove shares and then commits the changes by invoking
'exportfs -r'. This file, is automatically read by the kernel NFS
implementation which makes for better integration with the NFS systemd
service. For FreeBSD, libshare updates /etc/zfs/exports to add and
remove shares and then commits the changes by sending a SIGHUP to
mountd.

SMB Operation:
For linux, libshare adds and removes files in /var/lib/samba/usershares
by calling the 'net' command directly. There is no need to commit the
changes. FreeBSD does not support SMB.

== Performance Results

To test sharing performance we created a pool with an increasing number
of datasets and invoked various zfs actions that would enable and
disable sharing. The performance testing was limited to NFS sharing.
The following tests were performed on an 8 vCPU system with 128GB and
a pool comprised of 4 50GB SSDs:

Scale testing:
- Share all filesystems in parallel -- zfs sharenfs=on <dataset> &
- Unshare all filesystems in parallel -- zfs sharenfs=off <dataset> &

Functional testing:
- share each filesystem serially -- zfs share -a
- unshare each filesystem serially -- zfs unshare -a
- reset sharenfs property and unshare -- zfs inherit -r sharenfs <pool>

For 'zfs sharenfs=on' scale testing we saw an average reduction in time
of 89.43% and for 'zfs sharenfs=off' we saw an average reduction in time
of 83.36%.

Functional testing also shows a huge improvement:
- zfs share -- 97.97% reduction in time
- zfs unshare -- 96.47% reduction in time
- zfs inhert -r sharenfs -- 99.01% reduction in time

Reviewed-by: Matt Ahrens <matt@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Ryan Moeller <ryan@ixsystems.com>
Reviewed-by: Bryant G. Ly <bryangly@gmail.com>
Signed-off-by: George Wilson <gwilson@delphix.com>
External-Issue: DLPX-68690
Closes openzfs#1603
Closes openzfs#7692
Closes openzfs#7943
Closes openzfs#10300
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Userspace user space functionality Status: Accepted Ready to integrate (reviewed, tested)
Projects
None yet
4 participants