From f14ae905a1094b4d6c96103f37e9e3effb1a99d4 Mon Sep 17 00:00:00 2001 From: Prakash Surya Date: Fri, 21 Sep 2018 08:47:42 -0700 Subject: [PATCH] LX-931 umount failed in destroyFilesystems Signed-off-by: Bryant G. Ly Conflicts: tests/test-runner/bin/zts-report.py --- include/sys/fs/zfs.h | 1 + lib/libshare/libshare.c | 56 +++++++++++++++++++++++++++-- lib/libspl/include/libshare.h | 3 ++ lib/libzfs/libzfs_mount.c | 6 ++++ tests/test-runner/bin/zts-report.py | 1 + 5 files changed, 64 insertions(+), 3 deletions(-) diff --git a/include/sys/fs/zfs.h b/include/sys/fs/zfs.h index 69befab74158..e7b284f7dc90 100644 --- a/include/sys/fs/zfs.h +++ b/include/sys/fs/zfs.h @@ -1142,6 +1142,7 @@ typedef struct ddt_histogram { #define ZFS_DRIVER "zfs" #define ZFS_DEV "/dev/zfs" #define ZFS_SHARETAB "/etc/dfs/sharetab" +#define ZFS_SHARETAB_LOCK "/etc/dfs/sharetab.lck" #define ZFS_SUPER_MAGIC 0x2fc12fc1 diff --git a/lib/libshare/libshare.c b/lib/libshare/libshare.c index 0965911cf0a6..15a3caff7072 100644 --- a/lib/libshare/libshare.c +++ b/lib/libshare/libshare.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -165,6 +166,58 @@ parse_sharetab(sa_handle_impl_t impl_handle) fclose(fp); } +static int sharetab_fd = -1; + +int +sharetab_lock(void) +{ + struct flock lock; + + assert(sharetab_fd == -1); + + if (mkdir("/etc/dfs", 0755) < 0 && errno != EEXIST) { + perror("sharetab_lock: failed to create /etc/dfs"); + return (-1); + } + + sharetab_fd = open(ZFS_SHARETAB_LOCK, (O_RDWR | O_CREAT), 0600); + + if (sharetab_fd < 0) { + perror("sharetab_lock: failed to open"); + return (-1); + } + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + if (fcntl(sharetab_fd, F_SETLKW, &lock) < 0) { + perror("sharetab_lock: failed to lock"); + return (-1); + } + return (0); +} + +int +sharetab_unlock(void) +{ + struct flock lock; + int retval = -1; + + if (sharetab_fd < 0) + return (-1); + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + if (fcntl(sharetab_fd, F_SETLK, &lock) == 0) + retval = 0; + close(sharetab_fd); + sharetab_fd = -1; + return (retval); +} + + static void update_sharetab(sa_handle_impl_t impl_handle) { @@ -175,9 +228,6 @@ update_sharetab(sa_handle_impl_t impl_handle) sa_fstype_t *fstype; const char *resource; - if (mkdir("/etc/dfs", 0755) < 0 && errno != EEXIST) { - return; - } temp_fd = mkstemp(tempfile); diff --git a/lib/libspl/include/libshare.h b/lib/libspl/include/libshare.h index 4016ff03141c..524e34da3c25 100644 --- a/lib/libspl/include/libshare.h +++ b/lib/libspl/include/libshare.h @@ -83,6 +83,9 @@ extern sa_share_t sa_find_share(sa_handle_t, char *); extern int sa_enable_share(sa_group_t, char *); extern int sa_disable_share(sa_share_t, char *); +extern int sharetab_lock(void); +extern int sharetab_unlock(void); + /* protocol specific interfaces */ extern int sa_parse_legacy_options(sa_group_t, char *, char *); diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c index 9d6a0183e8a2..794b7a6dddc1 100644 --- a/lib/libzfs/libzfs_mount.c +++ b/lib/libzfs/libzfs_mount.c @@ -871,6 +871,7 @@ zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto) if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL)) return (0); + verify(sharetab_lock() == 0); for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) { /* * Return success if there are no share options. @@ -886,6 +887,7 @@ zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto) (void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED, dgettext(TEXT_DOMAIN, "cannot share '%s': %s"), zfs_get_name(zhp), sa_errorstr(ret)); + verify(sharetab_unlock() == 0); return (-1); } @@ -917,6 +919,7 @@ zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto) proto_table[*curr_proto].p_share_err, dgettext(TEXT_DOMAIN, "cannot share '%s'"), zfs_get_name(zhp)); + verify(sharetab_unlock() == 0); return (-1); } hdl->libzfs_shareflags |= ZFSSHARE_MISS; @@ -932,6 +935,7 @@ zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto) proto_table[*curr_proto].p_share_err, dgettext(TEXT_DOMAIN, "cannot share '%s'"), zfs_get_name(zhp)); + verify(sharetab_unlock() == 0); return (-1); } } else { @@ -939,10 +943,12 @@ zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto) proto_table[*curr_proto].p_share_err, dgettext(TEXT_DOMAIN, "cannot share '%s'"), zfs_get_name(zhp)); + verify(sharetab_unlock() == 0); return (-1); } } + verify(sharetab_unlock() == 0); return (0); } diff --git a/tests/test-runner/bin/zts-report.py b/tests/test-runner/bin/zts-report.py index d046c13a55ef..91ec27a682dc 100755 --- a/tests/test-runner/bin/zts-report.py +++ b/tests/test-runner/bin/zts-report.py @@ -272,6 +272,7 @@ 'snapshot/clone_001_pos': ['FAIL', known_reason], 'snapshot/snapshot_009_pos': ['FAIL', '7961'], 'snapshot/snapshot_010_pos': ['FAIL', '7961'], + 'snapshot/rollback_003_pos': ['FAIL', '6143'], 'snapused/snapused_004_pos': ['FAIL', '5513'], 'tmpfile/setup': ['SKIP', tmpfile_reason], 'threadsappend/threadsappend_001_pos': ['FAIL', '6136'],