Skip to content

Commit

Permalink
Make zfs-share service resilient to stale exports
Browse files Browse the repository at this point in the history
The are a few cases where stale entries in /etc/exports.d/zfs.exports 
will cause the nfs-server service to fail when starting up.

Since the nfs-server startup consumes /etc/exports.d/zfs.exports, the 
zfs-share service (which rebuilds the list of zfs exports) should run 
before the nfs-server service.

To make the zfs-share service resilient to stale exports, this change 
truncates the zfs config file as part of the zfs share -a operation.

Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Don Brady <don.brady@delphix.com>
Closes #13775
  • Loading branch information
don-brady committed Sep 9, 2022
1 parent 60d9957 commit ede037c
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 24 deletions.
3 changes: 3 additions & 0 deletions cmd/zfs/zfs_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7093,6 +7093,9 @@ share_mount(int op, int argc, char **argv)
share_mount_state.sm_total = cb.cb_used;
pthread_mutex_init(&share_mount_state.sm_lock, NULL);

/* For a 'zfs share -a' operation start with a clean slate. */
zfs_truncate_shares(NULL);

/*
* libshare isn't mt-safe, so only do the operation in parallel
* if we're mounting. Additionally, the key-loading option must
Expand Down
2 changes: 1 addition & 1 deletion etc/systemd/system/zfs-share.service.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[Unit]
Description=ZFS file system shares
Documentation=man:zfs(8)
After=nfs-server.service nfs-kernel-server.service
Before=nfs-server.service nfs-kernel-server.service
After=smb.service
Before=rpc-statd-notify.service
Wants=zfs-mount.service
Expand Down
3 changes: 2 additions & 1 deletion include/libzfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2020 by Delphix. All rights reserved.
* Copyright (c) 2011, 2022 by Delphix. All rights reserved.
* Copyright Joyent, Inc.
* Copyright (c) 2013 Steven Hartland. All rights reserved.
* Copyright (c) 2016, Intel Corporation.
Expand Down Expand Up @@ -895,6 +895,7 @@ _LIBZFS_H int zfs_unshare(zfs_handle_t *zhp, const char *mountpoint,
_LIBZFS_H int zfs_unshareall(zfs_handle_t *zhp,
const enum sa_protocol *proto);
_LIBZFS_H void zfs_commit_shares(const enum sa_protocol *proto);
_LIBZFS_H void zfs_truncate_shares(const enum sa_protocol *proto);

_LIBZFS_H int zfs_nicestrtonum(libzfs_handle_t *, const char *, uint64_t *);

Expand Down
12 changes: 11 additions & 1 deletion lib/libshare/libshare.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
/*
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 Gunnar Beutner
* Copyright (c) 2018, 2020 by Delphix. All rights reserved.
* Copyright (c) 2018, 2022 by Delphix. All rights reserved.
*/

#include <stdio.h>
Expand Down Expand Up @@ -96,6 +96,16 @@ sa_commit_shares(enum sa_protocol protocol)
fstypes[protocol]->commit_shares();
}

void
sa_truncate_shares(enum sa_protocol protocol)
{
/* CSTYLED */
VALIDATE_PROTOCOL(protocol, );

if (fstypes[protocol]->truncate_shares != NULL)
fstypes[protocol]->truncate_shares();
}

int
sa_validate_shareopts(const char *options, enum sa_protocol protocol)
{
Expand Down
3 changes: 2 additions & 1 deletion lib/libshare/libshare_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
/*
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 Gunnar Beutner
* Copyright (c) 2019, 2020 by Delphix. All rights reserved.
* Copyright (c) 2019, 2022 by Delphix. All rights reserved.
*/
#ifndef _LIBSPL_LIBSHARE_IMPL_H
#define _LIBSPL_LIBSHARE_IMPL_H
Expand All @@ -39,6 +39,7 @@ typedef struct {
boolean_t (*const is_shared)(sa_share_impl_t share);
int (*const validate_shareopts)(const char *shareopts);
int (*const commit_shares)(void);
void (*const truncate_shares)(void);
} sa_fstype_t;

extern const sa_fstype_t libshare_nfs_type, libshare_smb_type;
Expand Down
12 changes: 12 additions & 0 deletions lib/libshare/nfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <stdio.h>
#include <errno.h>
#include <libshare.h>
#include <unistd.h>
#include "nfs.h"


Expand Down Expand Up @@ -281,6 +282,17 @@ nfs_toggle_share(const char *lockfile, const char *exports,
return (error);
}

void
nfs_reset_shares(const char *lockfile, const char *exports)
{
int nfs_lock_fd = -1;

if (nfs_exports_lock(lockfile, &nfs_lock_fd) == 0) {
(void) ! truncate(exports, 0);
nfs_exports_unlock(lockfile, &nfs_lock_fd);
}
}

static boolean_t
nfs_is_shared_cb(void *userdata, char *line, boolean_t found_mountpoint)
{
Expand Down
2 changes: 2 additions & 0 deletions lib/libshare/nfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
/*
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 Gunnar Beutner
* Copyright (c) 2022 by Delphix. All rights reserved.
*/

#include "libshare_impl.h"
Expand All @@ -33,3 +34,4 @@ boolean_t nfs_is_shared_impl(const char *exports, sa_share_impl_t impl_share);
int nfs_toggle_share(const char *lockfile, const char *exports,
const char *expdir, sa_share_impl_t impl_share,
int(*cbk)(sa_share_impl_t impl_share, FILE *tmpfile));
void nfs_reset_shares(const char *lockfile, const char *exports);
9 changes: 8 additions & 1 deletion lib/libshare/os/freebsd/nfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Copyright (c) 2020 by Delphix. All rights reserved.
* Copyright (c) 2020, 2022 by Delphix. All rights reserved.
*/

#include <sys/cdefs.h>
Expand Down Expand Up @@ -195,11 +195,18 @@ nfs_commit_shares(void)
return (SA_OK);
}

static void
nfs_truncate_shares(void)
{
nfs_reset_shares(ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE);
}

const sa_fstype_t libshare_nfs_type = {
.enable_share = nfs_enable_share,
.disable_share = nfs_disable_share,
.is_shared = nfs_is_shared,

.validate_shareopts = nfs_validate_shareopts,
.commit_shares = nfs_commit_shares,
.truncate_shares = nfs_truncate_shares,
};
9 changes: 8 additions & 1 deletion lib/libshare/os/linux/nfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 Gunnar Beutner
* Copyright (c) 2012 Cyril Plisko. All rights reserved.
* Copyright (c) 2019, 2020 by Delphix. All rights reserved.
* Copyright (c) 2019, 2022 by Delphix. All rights reserved.
*/

#include <dirent.h>
Expand Down Expand Up @@ -495,13 +495,20 @@ nfs_commit_shares(void)
return (libzfs_run_process(argv[0], argv, 0));
}

static void
nfs_truncate_shares(void)
{
nfs_reset_shares(ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE);
}

const sa_fstype_t libshare_nfs_type = {
.enable_share = nfs_enable_share,
.disable_share = nfs_disable_share,
.is_shared = nfs_is_shared,

.validate_shareopts = nfs_validate_shareopts,
.commit_shares = nfs_commit_shares,
.truncate_shares = nfs_truncate_shares,
};

static boolean_t
Expand Down
3 changes: 2 additions & 1 deletion lib/libspl/include/libshare.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright (c) 2019, 2020 by Delphix. All rights reserved.
* Copyright (c) 2019, 2022 by Delphix. All rights reserved.
*/
#ifndef _LIBSPL_LIBSHARE_H
#define _LIBSPL_LIBSHARE_H extern __attribute__((visibility("default")))
Expand Down Expand Up @@ -88,6 +88,7 @@ _LIBSPL_LIBSHARE_H int sa_enable_share(const char *, const char *, const char *,
_LIBSPL_LIBSHARE_H int sa_disable_share(const char *, enum sa_protocol);
_LIBSPL_LIBSHARE_H boolean_t sa_is_shared(const char *, enum sa_protocol);
_LIBSPL_LIBSHARE_H void sa_commit_shares(enum sa_protocol);
_LIBSPL_LIBSHARE_H void sa_truncate_shares(enum sa_protocol);

/* protocol specific interfaces */
_LIBSPL_LIBSHARE_H int sa_validate_shareopts(const char *, enum sa_protocol);
Expand Down

0 comments on commit ede037c

Please sign in to comment.