diff --git a/lib/libshare/Makefile.am b/lib/libshare/Makefile.am index 7cef13c3d..e42609c64 100644 --- a/lib/libshare/Makefile.am +++ b/lib/libshare/Makefile.am @@ -7,6 +7,7 @@ noinst_LTLIBRARIES = libshare.la USER_C = \ libshare_impl.h \ libshare.c \ + nfs.c \ nfs.h \ smb.h diff --git a/lib/libshare/nfs.c b/lib/libshare/nfs.c new file mode 100644 index 000000000..7657c9d72 --- /dev/null +++ b/lib/libshare/nfs.c @@ -0,0 +1,73 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + + +#include +#include +#include +#include +#include "nfs.h" + + +static int nfs_lock_fd = -1; + + +/* + * nfs_exports_[lock|unlock] are used to guard against conconcurrent + * updates to the exports file. Each protocol is responsible for + * providing the necessary locking to ensure consistency. + */ +__attribute__((visibility("hidden"))) int +nfs_exports_lock(const char *name) +{ + int err; + + nfs_lock_fd = open(name, O_RDWR | O_CREAT | O_CLOEXEC, 0600); + if (nfs_lock_fd == -1) { + err = errno; + fprintf(stderr, "failed to lock %s: %s\n", name, strerror(err)); + return (err); + } + + if (flock(nfs_lock_fd, LOCK_EX) != 0) { + err = errno; + fprintf(stderr, "failed to lock %s: %s\n", name, strerror(err)); + (void) close(nfs_lock_fd); + nfs_lock_fd = -1; + return (err); + } + + return (0); +} + +__attribute__((visibility("hidden"))) void +nfs_exports_unlock(const char *name) +{ + verify(nfs_lock_fd > 0); + + if (flock(nfs_lock_fd, LOCK_UN) != 0) { + fprintf(stderr, "failed to unlock %s: %s\n", + name, strerror(errno)); + } + + (void) close(nfs_lock_fd); + nfs_lock_fd = -1; +} diff --git a/lib/libshare/nfs.h b/lib/libshare/nfs.h index b9ea6ee2f..79c28bb7f 100644 --- a/lib/libshare/nfs.h +++ b/lib/libshare/nfs.h @@ -24,4 +24,9 @@ * Copyright (c) 2011 Gunnar Beutner */ +#define FILE_HEADER "# !!! DO NOT EDIT THIS FILE MANUALLY !!!\n\n" + void libshare_nfs_init(void); + +int nfs_exports_lock(const char *name); +void nfs_exports_unlock(const char *name); diff --git a/lib/libshare/os/freebsd/nfs.c b/lib/libshare/os/freebsd/nfs.c index b0394dfab..40e3d8bbf 100644 --- a/lib/libshare/os/freebsd/nfs.c +++ b/lib/libshare/os/freebsd/nfs.c @@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$"); #include "nfs.h" #define _PATH_MOUNTDPID "/var/run/mountd.pid" -#define FILE_HEADER "# !!! DO NOT EDIT THIS FILE MANUALLY !!!\n\n" #define OPTSSIZE 1024 #define MAXLINESIZE (PATH_MAX + OPTSSIZE) #define ZFS_EXPORTS_FILE "/etc/zfs/exports" @@ -55,49 +54,6 @@ __FBSDID("$FreeBSD$"); static sa_fstype_t *nfs_fstype; -static int nfs_lock_fd = -1; - -/* - * The nfs_exports_[lock|unlock] is used to guard against conconcurrent - * updates to the exports file. Each protocol is responsible for - * providing the necessary locking to ensure consistency. - */ -static int -nfs_exports_lock(void) -{ - int err; - - nfs_lock_fd = open(ZFS_EXPORTS_LOCK, - O_RDWR | O_CREAT | O_CLOEXEC, 0600); - if (nfs_lock_fd == -1) { - err = errno; - fprintf(stderr, "failed to lock %s: %s\n", - ZFS_EXPORTS_LOCK, strerror(err)); - return (err); - } - if (flock(nfs_lock_fd, LOCK_EX) != 0) { - err = errno; - fprintf(stderr, "failed to lock %s: %s\n", - ZFS_EXPORTS_LOCK, strerror(err)); - (void) close(nfs_lock_fd); - return (err); - } - return (0); -} - -static void -nfs_exports_unlock(void) -{ - verify(nfs_lock_fd > 0); - - if (flock(nfs_lock_fd, LOCK_UN) != 0) { - fprintf(stderr, "failed to unlock %s: %s\n", - ZFS_EXPORTS_LOCK, strerror(errno)); - } - close(nfs_lock_fd); - nfs_lock_fd = -1; -} - /* * Read one line from a file. Skip comments, empty lines and a line with a * mountpoint specified in the 'skip' argument. @@ -281,7 +237,7 @@ nfs_enable_share(sa_share_impl_t impl_share) if ((filename = nfs_init_tmpfile()) == NULL) return (SA_SYSTEM_ERR); - error = nfs_exports_lock(); + error = nfs_exports_lock(ZFS_EXPORTS_LOCK); if (error != 0) { unlink(filename); free(filename); @@ -292,7 +248,7 @@ nfs_enable_share(sa_share_impl_t impl_share) if (error != SA_OK) { unlink(filename); free(filename); - nfs_exports_unlock(); + nfs_exports_unlock(ZFS_EXPORTS_LOCK); return (error); } @@ -302,7 +258,7 @@ nfs_enable_share(sa_share_impl_t impl_share) strerror(errno)); unlink(filename); free(filename); - nfs_exports_unlock(); + nfs_exports_unlock(ZFS_EXPORTS_LOCK); return (SA_SYSTEM_ERR); } char *shareopts = FSINFO(impl_share, nfs_fstype)->shareopts; @@ -315,7 +271,7 @@ nfs_enable_share(sa_share_impl_t impl_share) fclose(fp); unlink(filename); free(filename); - nfs_exports_unlock(); + nfs_exports_unlock(ZFS_EXPORTS_LOCK); return (SA_SYSTEM_ERR); } @@ -324,11 +280,11 @@ nfs_enable_share(sa_share_impl_t impl_share) filename, strerror(errno)); unlink(filename); free(filename); - nfs_exports_unlock(); + nfs_exports_unlock(ZFS_EXPORTS_LOCK); return (SA_SYSTEM_ERR); } error = nfs_fini_tmpfile(filename); - nfs_exports_unlock(); + nfs_exports_unlock(ZFS_EXPORTS_LOCK); return (error); } @@ -341,7 +297,7 @@ nfs_disable_share(sa_share_impl_t impl_share) if ((filename = nfs_init_tmpfile()) == NULL) return (SA_SYSTEM_ERR); - error = nfs_exports_lock(); + error = nfs_exports_lock(ZFS_EXPORTS_LOCK); if (error != 0) { unlink(filename); free(filename); @@ -352,12 +308,12 @@ nfs_disable_share(sa_share_impl_t impl_share) if (error != SA_OK) { unlink(filename); free(filename); - nfs_exports_unlock(); + nfs_exports_unlock(ZFS_EXPORTS_LOCK); return (error); } error = nfs_fini_tmpfile(filename); - nfs_exports_unlock(); + nfs_exports_unlock(ZFS_EXPORTS_LOCK); return (error); } diff --git a/lib/libshare/os/linux/nfs.c b/lib/libshare/os/linux/nfs.c index a7bcbd138..08c7db1bc 100644 --- a/lib/libshare/os/linux/nfs.c +++ b/lib/libshare/os/linux/nfs.c @@ -42,7 +42,6 @@ #include "libshare_impl.h" #include "nfs.h" -#define FILE_HEADER "# !!! DO NOT EDIT THIS FILE MANUALLY !!!\n\n" #define ZFS_EXPORTS_DIR "/etc/exports.d" #define ZFS_EXPORTS_FILE ZFS_EXPORTS_DIR"/zfs.exports" #define ZFS_EXPORTS_LOCK ZFS_EXPORTS_FILE".lock" @@ -55,49 +54,6 @@ typedef int (*nfs_shareopt_callback_t)(const char *opt, const char *value, typedef int (*nfs_host_callback_t)(const char *sharepath, const char *filename, const char *host, const char *security, const char *access, void *cookie); -static int nfs_lock_fd = -1; - -/* - * The nfs_exports_[lock|unlock] is used to guard against conconcurrent - * updates to the exports file. Each protocol is responsible for - * providing the necessary locking to ensure consistency. - */ -static int -nfs_exports_lock(void) -{ - int err; - - nfs_lock_fd = open(ZFS_EXPORTS_LOCK, - O_RDWR | O_CREAT | O_CLOEXEC, 0600); - if (nfs_lock_fd == -1) { - err = errno; - fprintf(stderr, "failed to lock %s: %s\n", - ZFS_EXPORTS_LOCK, strerror(err)); - return (err); - } - if (flock(nfs_lock_fd, LOCK_EX) != 0) { - err = errno; - fprintf(stderr, "failed to lock %s: %s\n", - ZFS_EXPORTS_LOCK, strerror(err)); - (void) close(nfs_lock_fd); - return (err); - } - return (0); -} - -static void -nfs_exports_unlock(void) -{ - verify(nfs_lock_fd > 0); - - if (flock(nfs_lock_fd, LOCK_UN) != 0) { - fprintf(stderr, "failed to unlock %s: %s\n", - ZFS_EXPORTS_LOCK, strerror(errno)); - } - close(nfs_lock_fd); - nfs_lock_fd = -1; -} - /* * Invokes the specified callback function for each Solaris share option * listed in the specified string. @@ -563,7 +519,7 @@ nfs_enable_share(sa_share_impl_t impl_share) if ((filename = nfs_init_tmpfile()) == NULL) return (SA_SYSTEM_ERR); - error = nfs_exports_lock(); + error = nfs_exports_lock(ZFS_EXPORTS_LOCK); if (error != 0) { unlink(filename); free(filename); @@ -574,7 +530,7 @@ nfs_enable_share(sa_share_impl_t impl_share) if (error != SA_OK) { unlink(filename); free(filename); - nfs_exports_unlock(); + nfs_exports_unlock(ZFS_EXPORTS_LOCK); return (error); } @@ -583,7 +539,7 @@ nfs_enable_share(sa_share_impl_t impl_share) if (error != SA_OK) { unlink(filename); free(filename); - nfs_exports_unlock(); + nfs_exports_unlock(ZFS_EXPORTS_LOCK); return (error); } @@ -596,7 +552,7 @@ nfs_enable_share(sa_share_impl_t impl_share) unlink(filename); free(filename); } - nfs_exports_unlock(); + nfs_exports_unlock(ZFS_EXPORTS_LOCK); return (error); } @@ -612,7 +568,7 @@ nfs_disable_share(sa_share_impl_t impl_share) if ((filename = nfs_init_tmpfile()) == NULL) return (SA_SYSTEM_ERR); - error = nfs_exports_lock(); + error = nfs_exports_lock(ZFS_EXPORTS_LOCK); if (error != 0) { unlink(filename); free(filename); @@ -623,11 +579,11 @@ nfs_disable_share(sa_share_impl_t impl_share) if (error != SA_OK) { unlink(filename); free(filename); - nfs_exports_unlock(); + nfs_exports_unlock(ZFS_EXPORTS_LOCK); return (error); } error = nfs_fini_tmpfile(filename); - nfs_exports_unlock(); + nfs_exports_unlock(ZFS_EXPORTS_LOCK); return (error); }