Skip to content

Commit

Permalink
Merge pull request openzfs#6 from bgly/spp-10.1.6
Browse files Browse the repository at this point in the history
SPPSUP-1149: Fix sharenfs issues with locking
  • Loading branch information
Bryant G. Ly authored Nov 7, 2019
2 parents 03fd8f0 + 6f4219b commit b6f63a1
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 5 deletions.
14 changes: 14 additions & 0 deletions cmd/zfs/zfs_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,20 @@ parseprop(nvlist_t *props, char *propname)
"specified multiple times\n"), propname);
return (B_FALSE);
}

/*
* If we are setting the sharenfs property, lock the sharetab to
* ensure concurrent writers don't update the file simultaneously.
* The sharetab will remain locked until the process exits.
*/
if (strcmp(propname, zfs_prop_to_name(ZFS_PROP_SHARENFS)) == 0) {
if (sharetab_lock() != 0) {
(void) fprintf(stderr, gettext("unable to set "
"property: %s\n"), strerror(errno));
exit(1);
}
}

if (nvlist_add_string(props, propname, propval) != 0)
nomem();
return (B_TRUE);
Expand Down
13 changes: 12 additions & 1 deletion cmd/zpool/zpool_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@

#include <libzfs.h>
#include <libzutil.h>
#include <libshare.h>

#include "zpool_util.h"
#include "zfs_comutil.h"
Expand Down Expand Up @@ -1614,12 +1615,15 @@ zpool_do_destroy(int argc, char **argv)
return (1);
}

verify(sharetab_lock() == 0);
if (zpool_disable_datasets(zhp, force) != 0) {
(void) fprintf(stderr, gettext("could not destroy '%s': "
"could not unmount datasets\n"), zpool_get_name(zhp));
zpool_close(zhp);
verify(sharetab_unlock() == 0);
return (1);
}
verify(sharetab_unlock() == 0);

/* The history must be logged as part of the export */
log_history = B_FALSE;
Expand All @@ -1644,8 +1648,12 @@ zpool_export_one(zpool_handle_t *zhp, void *data)
{
export_cbdata_t *cb = data;

if (zpool_disable_datasets(zhp, cb->force || cb->hardforce) != 0)
verify(sharetab_lock() == 0);
if (zpool_disable_datasets(zhp, cb->force || cb->hardforce) != 0) {
verify(sharetab_unlock() == 0);
return (1);
}
verify(sharetab_unlock() == 0);

/* The history must be logged as part of the export */
log_history = B_FALSE;
Expand Down Expand Up @@ -2827,12 +2835,15 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
ret = 1;
}

verify(sharetab_lock() == 0);
if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
!(flags & ZFS_IMPORT_ONLY) &&
zpool_enable_datasets(zhp, mntopts, 0) != 0) {
zpool_close(zhp);
verify(sharetab_unlock() == 0);
return (1);
}
verify(sharetab_unlock() == 0);

zpool_close(zhp);
return (ret);
Expand Down
1 change: 1 addition & 0 deletions include/sys/fs/zfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
56 changes: 52 additions & 4 deletions lib/libshare/libshare.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <strings.h>
#include <libintl.h>
Expand Down Expand Up @@ -165,6 +166,57 @@ parse_sharetab(sa_handle_impl_t impl_handle)
fclose(fp);
}

static int sharetab_fd = -1;

int
sharetab_lock(void)
{
struct flock lock;

verify(sharetab_fd == -1);

if (mkdir("/etc/dfs", 0755) < 0 && errno != EEXIST) {
perror("sharetab_lock: failed to create /etc/dfs");
return (errno);
}

sharetab_fd = open(ZFS_SHARETAB_LOCK, (O_RDWR | O_CREAT), 0600);

if (sharetab_fd < 0) {
perror("sharetab_lock: failed to open");
return (errno);
}

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 (errno);
}
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)
{
Expand All @@ -175,10 +227,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);

if (temp_fd < 0)
Expand Down
3 changes: 3 additions & 0 deletions lib/libspl/include/libshare.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);

Expand Down
1 change: 1 addition & 0 deletions tests/test-runner/bin/zts-report.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'],
Expand Down

0 comments on commit b6f63a1

Please sign in to comment.