Skip to content

Commit

Permalink
WIP: Concurrent modifications to "/etc/dfs/sharetab" does not work
Browse files Browse the repository at this point in the history
Signed-off-by: Prakash Surya <prakash.surya@delphix.com>

Requires-builders: all
  • Loading branch information
grwilson authored and Prakash Surya committed Sep 24, 2018
1 parent dda5500 commit 1fe7a60
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 3 deletions.
1 change: 1 addition & 0 deletions include/sys/fs/zfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,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: 53 additions & 3 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,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)
{
Expand All @@ -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);

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
6 changes: 6 additions & 0 deletions lib/libzfs/libzfs_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,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.
Expand All @@ -879,6 +880,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);
}

Expand Down Expand Up @@ -910,6 +912,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;
Expand All @@ -925,17 +928,20 @@ 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 {
(void) zfs_error_fmt(hdl,
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);
}

Expand Down

0 comments on commit 1fe7a60

Please sign in to comment.