diff --git a/lib/libshare/nfs.c b/lib/libshare/nfs.c index bdf5e5483c..44d3e93d42 100644 --- a/lib/libshare/nfs.c +++ b/lib/libshare/nfs.c @@ -38,7 +38,7 @@ static int nfs_lock_fd = -1; * updates to the exports file. Each protocol is responsible for * providing the necessary locking to ensure consistency. */ -__attribute__((visibility("hidden"))) int +static int nfs_exports_lock(const char *name) { int err; @@ -61,7 +61,7 @@ nfs_exports_lock(const char *name) return (0); } -__attribute__((visibility("hidden"))) void +static void nfs_exports_unlock(const char *name) { verify(nfs_lock_fd > 0); @@ -75,7 +75,7 @@ nfs_exports_unlock(const char *name) nfs_lock_fd = -1; } -__attribute__((visibility("hidden"))) char * +static char * nfs_init_tmpfile(const char *prefix, const char *mdir) { char *tmpfile = NULL; @@ -105,7 +105,7 @@ nfs_init_tmpfile(const char *prefix, const char *mdir) return (tmpfile); } -__attribute__((visibility("hidden"))) int +static int nfs_fini_tmpfile(const char *exports, char *tmpfile) { if (rename(tmpfile, exports) == -1) { @@ -120,8 +120,9 @@ nfs_fini_tmpfile(const char *exports, char *tmpfile) } __attribute__((visibility("hidden"))) int -nfs_disable_share_impl(const char *lockfile, const char *exports, - const char *expdir, sa_share_impl_t impl_share) +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, char *filename)) { int error; char *filename; @@ -137,14 +138,20 @@ nfs_disable_share_impl(const char *lockfile, const char *exports, } error = nfs_copy_entries(filename, impl_share->sa_mountpoint); - if (error != SA_OK) { - unlink(filename); - free(filename); - nfs_exports_unlock(lockfile); - return (error); - } + if (error != SA_OK) + goto fullerr; + + error = cbk(impl_share, filename); + if (error != SA_OK) + goto fullerr; error = nfs_fini_tmpfile(exports, filename); nfs_exports_unlock(lockfile); return (error); + +fullerr: + unlink(filename); + free(filename); + nfs_exports_unlock(lockfile); + return (error); } diff --git a/lib/libshare/nfs.h b/lib/libshare/nfs.h index 9eca798dbf..4dbcdf5985 100644 --- a/lib/libshare/nfs.h +++ b/lib/libshare/nfs.h @@ -30,12 +30,7 @@ void libshare_nfs_init(void); -int nfs_exports_lock(const char *name); -void nfs_exports_unlock(const char *name); - -char *nfs_init_tmpfile(const char *prefix, const char *mdir); -int nfs_fini_tmpfile(const char *exports, char *tmpfile); - int nfs_copy_entries(char *filename, const char *mountpoint); -int nfs_disable_share_impl(const char *lockfile, const char *exports, - const char *expdir, 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, char *filename)); diff --git a/lib/libshare/os/freebsd/nfs.c b/lib/libshare/os/freebsd/nfs.c index 487333bd99..323c9269f1 100644 --- a/lib/libshare/os/freebsd/nfs.c +++ b/lib/libshare/os/freebsd/nfs.c @@ -193,38 +193,15 @@ nfs_copy_entries(char *filename, const char *mountpoint) } static int -nfs_enable_share(sa_share_impl_t impl_share) +nfs_enable_share_impl(sa_share_impl_t impl_share, char *filename) { - char *filename = NULL; - int error; - - if ((filename = nfs_init_tmpfile(ZFS_EXPORTS_FILE, NULL)) == NULL) - return (SA_SYSTEM_ERR); - - error = nfs_exports_lock(ZFS_EXPORTS_LOCK); - if (error != 0) { - unlink(filename); - free(filename); - return (error); - } - - error = nfs_copy_entries(filename, impl_share->sa_mountpoint); - if (error != SA_OK) { - unlink(filename); - free(filename); - nfs_exports_unlock(ZFS_EXPORTS_LOCK); - return (error); - } - FILE *fp = fopen(filename, "a+e"); if (fp == NULL) { fprintf(stderr, "failed to open %s file: %s", filename, strerror(errno)); - unlink(filename); - free(filename); - nfs_exports_unlock(ZFS_EXPORTS_LOCK); return (SA_SYSTEM_ERR); } + char *shareopts = FSINFO(impl_share, nfs_fstype)->shareopts; if (strcmp(shareopts, "on") == 0) shareopts = ""; @@ -233,30 +210,38 @@ nfs_enable_share(sa_share_impl_t impl_share) translate_opts(shareopts)) < 0) { fprintf(stderr, "failed to write to %s\n", filename); fclose(fp); - unlink(filename); - free(filename); - nfs_exports_unlock(ZFS_EXPORTS_LOCK); return (SA_SYSTEM_ERR); } if (fclose(fp) != 0) { fprintf(stderr, "Unable to close file %s: %s\n", filename, strerror(errno)); - unlink(filename); - free(filename); - nfs_exports_unlock(ZFS_EXPORTS_LOCK); return (SA_SYSTEM_ERR); } - error = nfs_fini_tmpfile(ZFS_EXPORTS_FILE, filename); - nfs_exports_unlock(ZFS_EXPORTS_LOCK); - return (error); + + return (SA_OK); +} + +static int +nfs_enable_share(sa_share_impl_t impl_share) +{ + return (nfs_toggle_share( + ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE, NULL, impl_share, + nfs_enable_share_impl)); +} + +static int +nfs_disable_share_impl(sa_share_impl_t impl_share, char *filename) +{ + return (SA_OK); } static int nfs_disable_share(sa_share_impl_t impl_share) { - return (nfs_disable_share_impl( - ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE, NULL, impl_share)); + return (nfs_toggle_share( + ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE, NULL, impl_share, + nfs_disable_share_impl)); } static boolean_t diff --git a/lib/libshare/os/linux/nfs.c b/lib/libshare/os/linux/nfs.c index 1abb5bf162..c236f25698 100644 --- a/lib/libshare/os/linux/nfs.c +++ b/lib/libshare/os/linux/nfs.c @@ -467,61 +467,45 @@ nfs_copy_entries(char *filename, const char *mountpoint) * Enables NFS sharing for the specified share. */ static int -nfs_enable_share(sa_share_impl_t impl_share) +nfs_enable_share_impl(sa_share_impl_t impl_share, char *filename) { char *shareopts, *linux_opts; - char *filename = NULL; int error; - if ((filename = - nfs_init_tmpfile(ZFS_EXPORTS_FILE, ZFS_EXPORTS_DIR)) == NULL) - return (SA_SYSTEM_ERR); - - error = nfs_exports_lock(ZFS_EXPORTS_LOCK); - if (error != 0) { - unlink(filename); - free(filename); - return (error); - } - - error = nfs_copy_entries(filename, impl_share->sa_mountpoint); - if (error != SA_OK) { - unlink(filename); - free(filename); - nfs_exports_unlock(ZFS_EXPORTS_LOCK); - return (error); - } - shareopts = FSINFO(impl_share, nfs_fstype)->shareopts; error = get_linux_shareopts(shareopts, &linux_opts); - if (error != SA_OK) { - unlink(filename); - free(filename); - nfs_exports_unlock(ZFS_EXPORTS_LOCK); + if (error != SA_OK) return (error); - } error = foreach_nfs_host(impl_share, filename, nfs_add_entry, linux_opts); free(linux_opts); - if (error == 0) { - error = nfs_fini_tmpfile(ZFS_EXPORTS_FILE, filename); - } else { - unlink(filename); - free(filename); - } - nfs_exports_unlock(ZFS_EXPORTS_LOCK); return (error); } +static int +nfs_enable_share(sa_share_impl_t impl_share) +{ + return (nfs_toggle_share( + ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE, ZFS_EXPORTS_DIR, impl_share, + nfs_enable_share_impl)); +} + /* * Disables NFS sharing for the specified share. */ +static int +nfs_disable_share_impl(sa_share_impl_t impl_share, char *filename) +{ + return (SA_OK); +} + static int nfs_disable_share(sa_share_impl_t impl_share) { - return (nfs_disable_share_impl( - ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE, ZFS_EXPORTS_DIR, impl_share)); + return (nfs_toggle_share( + ZFS_EXPORTS_LOCK, ZFS_EXPORTS_FILE, ZFS_EXPORTS_DIR, impl_share, + nfs_disable_share_impl)); } static boolean_t