diff options
-rwxr-xr-x | configure | 3 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | lib/Makefile.am | 3 | ||||
-rw-r--r-- | lib/Makefile.in | 3 | ||||
-rw-r--r-- | lib/libshare/Makefile.am | 15 | ||||
-rw-r--r-- | lib/libshare/Makefile.in | 662 | ||||
-rw-r--r-- | lib/libshare/libshare.c | 810 | ||||
-rw-r--r-- | lib/libshare/libshare_impl.h | 70 | ||||
-rw-r--r-- | lib/libshare/nfs.c | 705 | ||||
-rw-r--r-- | lib/libshare/nfs.h | 27 | ||||
-rw-r--r-- | lib/libspl/include/libshare.h | 56 | ||||
-rw-r--r-- | lib/libzfs/libzfs_mount.c | 42 | ||||
-rw-r--r-- | module/zfs/zfs_ioctl.c | 150 |
13 files changed, 2380 insertions, 167 deletions
@@ -20555,7 +20555,7 @@ fi $as_echo "$enable_debug" >&6; } -ac_config_files="$ac_config_files Makefile dracut/Makefile dracut/90zfs/Makefile etc/Makefile etc/udev/Makefile etc/udev/rules.d/Makefile etc/init.d/Makefile etc/zfs/Makefile man/Makefile man/man8/Makefile lib/Makefile lib/libspl/Makefile lib/libspl/asm-generic/Makefile lib/libspl/asm-i386/Makefile lib/libspl/asm-x86_64/Makefile lib/libspl/include/Makefile lib/libspl/include/ia32/Makefile lib/libspl/include/ia32/sys/Makefile lib/libspl/include/rpc/Makefile lib/libspl/include/sys/Makefile lib/libspl/include/sys/sysevent/Makefile lib/libspl/include/sys/dktp/Makefile lib/libspl/include/util/Makefile lib/libavl/Makefile lib/libefi/Makefile lib/libnvpair/Makefile lib/libunicode/Makefile lib/libuutil/Makefile lib/libzpool/Makefile lib/libzfs/Makefile cmd/Makefile cmd/zdb/Makefile cmd/zfs/Makefile cmd/zinject/Makefile cmd/zpool/Makefile cmd/ztest/Makefile cmd/zpios/Makefile cmd/mount_zfs/Makefile cmd/zpool_layout/Makefile cmd/zvol_id/Makefile cmd/zpool_id/Makefile cmd/sas_switch_id/Makefile module/Makefile module/avl/Makefile module/nvpair/Makefile module/unicode/Makefile module/zcommon/Makefile module/zfs/Makefile module/zpios/Makefile include/Makefile include/linux/Makefile include/sys/Makefile include/sys/fs/Makefile include/sys/fm/Makefile include/sys/fm/fs/Makefile scripts/Makefile scripts/zpios-profile/Makefile scripts/zpios-test/Makefile scripts/zpool-config/Makefile scripts/zpool-layout/Makefile scripts/common.sh zfs.spec zfs-modules.spec zfs-script-config.sh" +ac_config_files="$ac_config_files Makefile dracut/Makefile dracut/90zfs/Makefile etc/Makefile etc/udev/Makefile etc/udev/rules.d/Makefile etc/init.d/Makefile etc/zfs/Makefile man/Makefile man/man8/Makefile lib/Makefile lib/libspl/Makefile lib/libspl/asm-generic/Makefile lib/libspl/asm-i386/Makefile lib/libspl/asm-x86_64/Makefile lib/libspl/include/Makefile lib/libspl/include/ia32/Makefile lib/libspl/include/ia32/sys/Makefile lib/libspl/include/rpc/Makefile lib/libspl/include/sys/Makefile lib/libspl/include/sys/sysevent/Makefile lib/libspl/include/sys/dktp/Makefile lib/libspl/include/util/Makefile lib/libavl/Makefile lib/libefi/Makefile lib/libnvpair/Makefile lib/libunicode/Makefile lib/libuutil/Makefile lib/libzpool/Makefile lib/libzfs/Makefile lib/libshare/Makefile cmd/Makefile cmd/zdb/Makefile cmd/zfs/Makefile cmd/zinject/Makefile cmd/zpool/Makefile cmd/ztest/Makefile cmd/zpios/Makefile cmd/mount_zfs/Makefile cmd/zpool_layout/Makefile cmd/zvol_id/Makefile cmd/zpool_id/Makefile cmd/sas_switch_id/Makefile module/Makefile module/avl/Makefile module/nvpair/Makefile module/unicode/Makefile module/zcommon/Makefile module/zfs/Makefile module/zpios/Makefile include/Makefile include/linux/Makefile include/sys/Makefile include/sys/fs/Makefile include/sys/fm/Makefile include/sys/fm/fs/Makefile scripts/Makefile scripts/zpios-profile/Makefile scripts/zpios-test/Makefile scripts/zpool-config/Makefile scripts/zpool-layout/Makefile scripts/common.sh zfs.spec zfs-modules.spec zfs-script-config.sh" cat >confcache <<\_ACEOF @@ -21501,6 +21501,7 @@ do "lib/libuutil/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libuutil/Makefile" ;; "lib/libzpool/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libzpool/Makefile" ;; "lib/libzfs/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libzfs/Makefile" ;; + "lib/libshare/Makefile") CONFIG_FILES="$CONFIG_FILES lib/libshare/Makefile" ;; "cmd/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/Makefile" ;; "cmd/zdb/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/zdb/Makefile" ;; "cmd/zfs/Makefile") CONFIG_FILES="$CONFIG_FILES cmd/zfs/Makefile" ;; diff --git a/configure.ac b/configure.ac index 33654de9f..fda9faf43 100644 --- a/configure.ac +++ b/configure.ac @@ -84,6 +84,7 @@ AC_CONFIG_FILES([ lib/libuutil/Makefile lib/libzpool/Makefile lib/libzfs/Makefile + lib/libshare/Makefile cmd/Makefile cmd/zdb/Makefile cmd/zfs/Makefile diff --git a/lib/Makefile.am b/lib/Makefile.am index c0f387896..0d518d220 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1 +1,2 @@ -SUBDIRS = libspl libavl libefi libnvpair libunicode libuutil libzpool libzfs +SUBDIRS = libspl libavl libefi libnvpair libshare +SUBDIRS += libunicode libuutil libzpool libzfs diff --git a/lib/Makefile.in b/lib/Makefile.in index 107aa7678..b5c4d8755 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -301,7 +301,8 @@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -SUBDIRS = libspl libavl libefi libnvpair libunicode libuutil libzpool libzfs +SUBDIRS = libspl libavl libefi libnvpair libshare libunicode libuutil \ + libzpool libzfs all: all-recursive .SUFFIXES: diff --git a/lib/libshare/Makefile.am b/lib/libshare/Makefile.am new file mode 100644 index 000000000..b66df8c56 --- /dev/null +++ b/lib/libshare/Makefile.am @@ -0,0 +1,15 @@ +include $(top_srcdir)/config/Rules.am + +DEFAULT_INCLUDES += \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/lib/libspl/include + +lib_LTLIBRARIES = libshare.la + +libshare_la_SOURCES = \ + $(top_srcdir)/lib/libshare/libshare.c \ + $(top_srcdir)/lib/libshare/nfs.c \ + $(top_srcdir)/lib/libshare/libshare_impl.h \ + $(top_srcdir)/lib/libshare/nfs.h + +libshare_la_LDFLAGS = -version-info 1:0:0 diff --git a/lib/libshare/Makefile.in b/lib/libshare/Makefile.in new file mode 100644 index 000000000..c0122cda7 --- /dev/null +++ b/lib/libshare/Makefile.in @@ -0,0 +1,662 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/config/Rules.am +subdir = lib/libshare +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = \ + $(top_srcdir)/config/always-no-unused-but-set-variable.m4 \ + $(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \ + $(top_srcdir)/config/kernel-bdev-logical-size.m4 \ + $(top_srcdir)/config/kernel-bio-empty-barrier.m4 \ + $(top_srcdir)/config/kernel-bio-end-io-t-args.m4 \ + $(top_srcdir)/config/kernel-bio-failfast.m4 \ + $(top_srcdir)/config/kernel-bio-rw-syncio.m4 \ + $(top_srcdir)/config/kernel-blk-end-request.m4 \ + $(top_srcdir)/config/kernel-blk-fetch-request.m4 \ + $(top_srcdir)/config/kernel-blk-requeue-request.m4 \ + $(top_srcdir)/config/kernel-blk-rq-bytes.m4 \ + $(top_srcdir)/config/kernel-blk-rq-pos.m4 \ + $(top_srcdir)/config/kernel-blk-rq-sectors.m4 \ + $(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \ + $(top_srcdir)/config/kernel-check-disk-size-change.m4 \ + $(top_srcdir)/config/kernel-d-obtain-alias.m4 \ + $(top_srcdir)/config/kernel-evict-inode.m4 \ + $(top_srcdir)/config/kernel-fmode-t.m4 \ + $(top_srcdir)/config/kernel-fsync.m4 \ + $(top_srcdir)/config/kernel-get-disk-ro.m4 \ + $(top_srcdir)/config/kernel-insert-inode-locked.m4 \ + $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \ + $(top_srcdir)/config/kernel-kobj-name-len.m4 \ + $(top_srcdir)/config/kernel-mount-nodev.m4 \ + $(top_srcdir)/config/kernel-open-bdev-exclusive.m4 \ + $(top_srcdir)/config/kernel-rq-for-each_segment.m4 \ + $(top_srcdir)/config/kernel-rq-is_sync.m4 \ + $(top_srcdir)/config/kernel-security-inode-init.m4 \ + $(top_srcdir)/config/kernel-truncate-setsize.m4 \ + $(top_srcdir)/config/kernel-xattr-handler.m4 \ + $(top_srcdir)/config/kernel.m4 \ + $(top_srcdir)/config/user-arch.m4 \ + $(top_srcdir)/config/user-frame-larger-than.m4 \ + $(top_srcdir)/config/user-ioctl.m4 \ + $(top_srcdir)/config/user-libblkid.m4 \ + $(top_srcdir)/config/user-libuuid.m4 \ + $(top_srcdir)/config/user-nptl_guard_within_stack.m4 \ + $(top_srcdir)/config/user-selinux.m4 \ + $(top_srcdir)/config/user-zlib.m4 $(top_srcdir)/config/user.m4 \ + $(top_srcdir)/config/zfs-build.m4 \ + $(top_srcdir)/config/zfs-meta.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/zfs_config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libshare_la_LIBADD = +am_libshare_la_OBJECTS = libshare.lo nfs.lo +libshare_la_OBJECTS = $(am_libshare_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libshare_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libshare_la_LDFLAGS) $(LDFLAGS) -o $@ +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libshare_la_SOURCES) +DIST_SOURCES = $(libshare_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALIEN = @ALIEN@ +ALIEN_VERSION = @ALIEN_VERSION@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_CFLAGS = @DEBUG_CFLAGS@ +DEBUG_STACKFLAGS = @DEBUG_STACKFLAGS@ +DEFAULT_INIT_SCRIPT = @DEFAULT_INIT_SCRIPT@ +DEFAULT_PACKAGE = @DEFAULT_PACKAGE@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DPKG = @DPKG@ +DPKGBUILD = @DPKGBUILD@ +DPKGBUILD_VERSION = @DPKGBUILD_VERSION@ +DPKG_VERSION = @DPKG_VERSION@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FRAME_LARGER_THAN = @FRAME_LARGER_THAN@ +GREP = @GREP@ +HAVE_ALIEN = @HAVE_ALIEN@ +HAVE_DPKG = @HAVE_DPKG@ +HAVE_DPKGBUILD = @HAVE_DPKGBUILD@ +HAVE_RPM = @HAVE_RPM@ +HAVE_RPMBUILD = @HAVE_RPMBUILD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KERNELCPPFLAGS = @KERNELCPPFLAGS@ +KERNELMAKE_PARAMS = @KERNELMAKE_PARAMS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBBLKID = @LIBBLKID@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSELINUX = @LIBSELINUX@ +LIBTOOL = @LIBTOOL@ +LIBUUID = @LIBUUID@ +LINUX = @LINUX@ +LINUX_OBJ = @LINUX_OBJ@ +LINUX_SYMBOLS = @LINUX_SYMBOLS@ +LINUX_VERSION = @LINUX_VERSION@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NO_UNUSED_BUT_SET_VARIABLE = @NO_UNUSED_BUT_SET_VARIABLE@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RPM = @RPM@ +RPMBUILD = @RPMBUILD@ +RPMBUILD_VERSION = @RPMBUILD_VERSION@ +RPM_VERSION = @RPM_VERSION@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPL = @SPL@ +SPL_OBJ = @SPL_OBJ@ +SPL_SYMBOLS = @SPL_SYMBOLS@ +SPL_VERSION = @SPL_VERSION@ +STRIP = @STRIP@ +TARGET_ASM_DIR = @TARGET_ASM_DIR@ +VENDOR = @VENDOR@ +VERSION = @VERSION@ +ZFS_CONFIG = @ZFS_CONFIG@ +ZFS_META_ALIAS = @ZFS_META_ALIAS@ +ZFS_META_AUTHOR = @ZFS_META_AUTHOR@ +ZFS_META_DATA = @ZFS_META_DATA@ +ZFS_META_LICENSE = @ZFS_META_LICENSE@ +ZFS_META_LT_AGE = @ZFS_META_LT_AGE@ +ZFS_META_LT_CURRENT = @ZFS_META_LT_CURRENT@ +ZFS_META_LT_REVISION = @ZFS_META_LT_REVISION@ +ZFS_META_NAME = @ZFS_META_NAME@ +ZFS_META_RELEASE = @ZFS_META_RELEASE@ +ZFS_META_VERSION = @ZFS_META_VERSION@ +ZLIB = @ZLIB@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +DEFAULT_INCLUDES = -include ${top_builddir}/zfs_config.h \ + -I$(top_srcdir)/include -I$(top_srcdir)/lib/libspl/include +AM_LIBTOOLFLAGS = --silent +AM_CFLAGS = -Wall -Wstrict-prototypes -fno-strict-aliasing \ + ${NO_UNUSED_BUT_SET_VARIABLE} ${DEBUG_CFLAGS} -D_GNU_SOURCE \ + -D__EXTENSIONS__ -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS \ + -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE \ + -DTEXT_DOMAIN=\"zfs-linux-user\" +lib_LTLIBRARIES = libshare.la +libshare_la_SOURCES = \ + $(top_srcdir)/lib/libshare/libshare.c \ + $(top_srcdir)/lib/libshare/nfs.c \ + $(top_srcdir)/lib/libshare/libshare_impl.h \ + $(top_srcdir)/lib/libshare/nfs.h + +libshare_la_LDFLAGS = -version-info 1:0:0 +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/Rules.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/libshare/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu lib/libshare/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libshare.la: $(libshare_la_OBJECTS) $(libshare_la_DEPENDENCIES) + $(AM_V_CCLD)$(libshare_la_LINK) -rpath $(libdir) $(libshare_la_OBJECTS) $(libshare_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libshare.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfs.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libshare.lo: $(top_srcdir)/lib/libshare/libshare.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libshare.lo -MD -MP -MF $(DEPDIR)/libshare.Tpo -c -o libshare.lo `test -f '$(top_srcdir)/lib/libshare/libshare.c' || echo '$(srcdir)/'`$(top_srcdir)/lib/libshare/libshare.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libshare.Tpo $(DEPDIR)/libshare.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/lib/libshare/libshare.c' object='libshare.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libshare.lo `test -f '$(top_srcdir)/lib/libshare/libshare.c' || echo '$(srcdir)/'`$(top_srcdir)/lib/libshare/libshare.c + +nfs.lo: $(top_srcdir)/lib/libshare/nfs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nfs.lo -MD -MP -MF $(DEPDIR)/nfs.Tpo -c -o nfs.lo `test -f '$(top_srcdir)/lib/libshare/nfs.c' || echo '$(srcdir)/'`$(top_srcdir)/lib/libshare/nfs.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nfs.Tpo $(DEPDIR)/nfs.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$(top_srcdir)/lib/libshare/nfs.c' object='nfs.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nfs.lo `test -f '$(top_srcdir)/lib/libshare/nfs.c' || echo '$(srcdir)/'`$(top_srcdir)/lib/libshare/nfs.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-libLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/lib/libshare/libshare.c b/lib/libshare/libshare.c new file mode 100644 index 000000000..c34e83919 --- /dev/null +++ b/lib/libshare/libshare.c @@ -0,0 +1,810 @@ +/* + * 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 + */ + +/* + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011 Gunnar Beutner + */ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <strings.h> +#include <libintl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <libzfs.h> +#include <libshare.h> +#include "libshare_impl.h" +#include "nfs.h" + +static sa_share_impl_t find_share(sa_handle_impl_t handle, + const char *sharepath); +static sa_share_impl_t alloc_share(const char *sharepath); +static void free_share(sa_share_impl_t share); + +static void parse_sharetab(sa_handle_impl_t impl_handle); +static int process_share(sa_handle_impl_t impl_handle, + sa_share_impl_t impl_share, char *pathname, char *resource, + char *fstype, char *options, char *description, + char *dataset, boolean_t from_sharetab); +static void update_sharetab(sa_handle_impl_t impl_handle); + +static int update_zfs_share(sa_share_impl_t impl_handle, const char *proto); +static int update_zfs_shares(sa_handle_impl_t impl_handle, const char *proto); + +static int fstypes_count; +static sa_fstype_t *fstypes; + +sa_fstype_t * +register_fstype(const char *name, const sa_share_ops_t *ops) +{ + sa_fstype_t *fstype; + + fstype = calloc(sizeof (sa_fstype_t), 1); + + if (fstype == NULL) + return NULL; + + fstype->name = name; + fstype->ops = ops; + fstype->fsinfo_index = fstypes_count; + + fstypes_count++; + + fstype->next = fstypes; + fstypes = fstype; + + return fstype; +} + +sa_handle_t +sa_init(int init_service) +{ + sa_handle_impl_t impl_handle; + + impl_handle = calloc(sizeof (struct sa_handle_impl), 1); + + if (impl_handle == NULL) + return NULL; + + impl_handle->zfs_libhandle = libzfs_init(); + + if (impl_handle->zfs_libhandle != NULL) { + libzfs_print_on_error(impl_handle->zfs_libhandle, B_TRUE); + } + + parse_sharetab(impl_handle); + update_zfs_shares(impl_handle, NULL); + + return ((sa_handle_t)impl_handle); +} + +__attribute__((constructor)) static void +libshare_init(void) +{ + libshare_nfs_init(); + + /* + * This bit causes /etc/dfs/sharetab to be updated before libzfs gets a + * chance to read that file; this is necessary because the sharetab file + * might be out of sync with the NFS kernel exports (e.g. due to reboots + * or users manually removing shares) + */ + sa_fini(sa_init(0)); +} + +static void +parse_sharetab(sa_handle_impl_t impl_handle) { + FILE *fp; + char line[512]; + char *eol, *pathname, *resource, *fstype, *options, *description; + + fp = fopen("/etc/dfs/sharetab", "r"); + + if (fp == NULL) + return; + + while (fgets(line, sizeof (line), fp) != NULL) { + eol = line + strlen(line) - 1; + + while (eol >= line) { + if (*eol != '\r' && *eol != '\n') + break; + + *eol = '\0'; + eol--; + } + + pathname = line; + + if ((resource = strchr(pathname, '\t')) == NULL) + continue; + + *resource = '\0'; + resource++; + + if ((fstype = strchr(resource, '\t')) == NULL) + continue; + + *fstype = '\0'; + fstype++; + + if ((options = strchr(fstype, '\t')) == NULL) + continue; + + *options = '\0'; + options++; + + if ((description = strchr(fstype, '\t')) != NULL) { + *description = '\0'; + description++; + } + + if (strcmp(resource, "-") == 0) + resource = NULL; + + (void) process_share(impl_handle, NULL, pathname, resource, + fstype, options, description, NULL, B_TRUE); + } + + fclose(fp); +} + +static void +update_sharetab(sa_handle_impl_t impl_handle) +{ + sa_share_impl_t impl_share; + int temp_fd; + FILE *temp_fp; + char tempfile[] = "/etc/dfs/sharetab.XXXXXX"; + sa_fstype_t *fstype; + const char *resource; + + if (mkdir("/etc/dfs", 0755) < 0 && errno != EEXIST) { + return; + } + + temp_fd = mkstemp(tempfile); + + if (temp_fd < 0) + return; + + temp_fp = fdopen(temp_fd, "w"); + + if (temp_fp == NULL) + return; + + impl_share = impl_handle->shares; + while (impl_share != NULL) { + fstype = fstypes; + while (fstype != NULL) { + if (FSINFO(impl_share, fstype)->active && + FSINFO(impl_share, fstype)->shareopts != NULL) { + resource = FSINFO(impl_share, fstype)->resource; + + if (resource == NULL) + resource = "-"; + + fprintf(temp_fp, "%s\t%s\t%s\t%s\n", + impl_share->sharepath, resource, + fstype->name, + FSINFO(impl_share, fstype)->shareopts); + } + + fstype = fstype->next; + } + + impl_share = impl_share->next; + } + + fflush(temp_fp); + fsync(temp_fd); + fclose(temp_fp); + + rename(tempfile, "/etc/dfs/sharetab"); +} + +typedef struct update_cookie_s { + sa_handle_impl_t handle; + const char *proto; +} update_cookie_t; + +static int +update_zfs_shares_cb(zfs_handle_t *zhp, void *pcookie) +{ + update_cookie_t *udata = (update_cookie_t *)pcookie; + char mountpoint[ZFS_MAXPROPLEN]; + char shareopts[ZFS_MAXPROPLEN]; + char *dataset; + zfs_type_t type = zfs_get_type(zhp); + + if (type == ZFS_TYPE_FILESYSTEM && + zfs_iter_filesystems(zhp, update_zfs_shares_cb, pcookie) != 0) { + zfs_close(zhp); + return 1; + } + + if (type != ZFS_TYPE_FILESYSTEM) { + zfs_close(zhp); + return 0; + } + + if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint, + sizeof (mountpoint), NULL, NULL, 0, B_FALSE) != 0) { + zfs_close(zhp); + return 0; + } + + dataset = (char *)zfs_get_name(zhp); + + if (dataset == NULL) { + zfs_close(zhp); + return 0; + } + + if (!zfs_is_mounted(zhp, NULL)) { + zfs_close(zhp); + return 0; + } + + if ((udata->proto == NULL || strcmp(udata->proto, "nfs") == 0) && + zfs_prop_get(zhp, ZFS_PROP_SHARENFS, shareopts, + sizeof (shareopts), NULL, NULL, 0, B_FALSE) == 0 && + strcmp(shareopts, "off") != 0) { + (void) process_share(udata->handle, NULL, mountpoint, NULL, + "nfs", shareopts, NULL, dataset, B_FALSE); + } + + if ((udata->proto == NULL || strcmp(udata->proto, "smb") == 0) && + zfs_prop_get(zhp, ZFS_PROP_SHARESMB, shareopts, + sizeof (shareopts), NULL, NULL, 0, B_FALSE) == 0 && + strcmp(shareopts, "off") != 0) { + (void) process_share(udata->handle, NULL, mountpoint, NULL, + "smb", shareopts, NULL, dataset, B_FALSE); + } + + zfs_close(zhp); + + return 0; +} + +static int +update_zfs_share(sa_share_impl_t impl_share, const char *proto) +{ + sa_handle_impl_t impl_handle = impl_share->handle; + zfs_handle_t *zhp; + update_cookie_t udata; + + if (impl_handle->zfs_libhandle == NULL) + return SA_SYSTEM_ERR; + + assert(impl_share->dataset != NULL); + + zhp = zfs_open(impl_share->handle->zfs_libhandle, impl_share->dataset, + ZFS_TYPE_FILESYSTEM); + + if (zhp == NULL) + return SA_SYSTEM_ERR; + + udata.handle = impl_handle; + udata.proto = proto; + (void) update_zfs_shares_cb(zhp, &udata); + + return SA_OK; +} + +static int +update_zfs_shares(sa_handle_impl_t impl_handle, const char *proto) +{ + update_cookie_t udata; + + if (impl_handle->zfs_libhandle == NULL) + return SA_SYSTEM_ERR; + + udata.handle = impl_handle; + udata.proto = proto; + (void) zfs_iter_root(impl_handle->zfs_libhandle, update_zfs_shares_cb, + &udata); + + return SA_OK; +} + +static int +process_share(sa_handle_impl_t impl_handle, sa_share_impl_t impl_share, + char *pathname, char *resource, char *proto, + char *options, char *description, char *dataset, + boolean_t from_sharetab) +{ + struct stat statbuf; + int rc; + char *resource_dup = NULL, *dataset_dup = NULL; + boolean_t new_share; + sa_fstype_t *fstype; + + new_share = B_FALSE; + + if (impl_share == NULL) + impl_share = find_share(impl_handle, pathname); + + if (impl_share == NULL) { + if (lstat(pathname, &statbuf) != 0 || + !S_ISDIR(statbuf.st_mode)) + return SA_BAD_PATH; + + impl_share = alloc_share(pathname); + + if (impl_share == NULL) { + rc = SA_NO_MEMORY; + goto err; + } + + new_share = B_TRUE; + } + + if (dataset != NULL) { + dataset_dup = strdup(dataset); + + if (dataset_dup == NULL) { + rc = SA_NO_MEMORY; + goto err; + } + } + + free(impl_share->dataset); + impl_share->dataset = dataset_dup; + + rc = SA_INVALID_PROTOCOL; + + fstype = fstypes; + while (fstype != NULL) { + if (strcmp(fstype->name, proto) == 0) { + if (resource != NULL) { + resource_dup = strdup(resource); + + if (resource_dup == NULL) { + rc = SA_NO_MEMORY; + goto err; + } + } + + free(FSINFO(impl_share, fstype)->resource); + FSINFO(impl_share, fstype)->resource = resource_dup; + + rc = fstype->ops->update_shareopts(impl_share, + resource, options); + + if (rc == SA_OK && from_sharetab) + FSINFO(impl_share, fstype)->active = B_TRUE; + + break; + } + + fstype = fstype->next; + } + + if (rc != SA_OK) + goto err; + + if (new_share) { + impl_share->handle = impl_handle; + + impl_share->next = impl_handle->shares; + impl_handle->shares = impl_share; + + } + +err: + if (rc != SA_OK) { + if (new_share) + free_share(impl_share); + } + + return rc; +} + +void +sa_fini(sa_handle_t handle) +{ + sa_handle_impl_t impl_handle = (sa_handle_impl_t)handle; + sa_share_impl_t impl_share, next; + sa_share_impl_t *pcurr; + + if (impl_handle == NULL) + return; + + /* + * clean up shares which don't have a non-NULL dataset property, + * which means they're in sharetab but we couldn't find their + * ZFS dataset. + */ + pcurr = &(impl_handle->shares); + impl_share = *pcurr; + while (impl_share != NULL) { + next = impl_share->next; + + if (impl_share->dataset == NULL) { + /* remove item from the linked list */ + *pcurr = next; + + sa_disable_share(impl_share, NULL); + + free_share(impl_share); + } else { + pcurr = &(impl_share->next); + } + + impl_share = next; + } + + update_sharetab(impl_handle); + + if (impl_handle->zfs_libhandle != NULL) + libzfs_fini(impl_handle->zfs_libhandle); + + impl_share = impl_handle->shares; + while (impl_share != NULL) { + next = impl_share->next; + free_share(impl_share); + impl_share = next; + } + + free(impl_handle); +} + +static sa_share_impl_t +find_share(sa_handle_impl_t impl_handle, const char *sharepath) +{ + sa_share_impl_t impl_share; + + impl_share = impl_handle->shares; + while (impl_share != NULL) { + if (strcmp(impl_share->sharepath, sharepath) == 0) { + break; + } + + impl_share = impl_share->next; + } + + return impl_share; +} + +sa_share_t +sa_find_share(sa_handle_t handle, char *sharepath) +{ + return (sa_share_t)find_share((sa_handle_impl_t)handle, sharepath); +} + +int +sa_enable_share(sa_share_t share, char *protocol) +{ + sa_share_impl_t impl_share = (sa_share_impl_t)share; + int rc, ret; + boolean_t found_protocol; + sa_fstype_t *fstype; + +#ifdef DEBUG + fprintf(stderr, "sa_enable_share: share->sharepath=%s, protocol=%s\n", + impl_share->sharepath, protocol); +#endif + + assert(impl_share->handle != NULL); + + ret = SA_OK; + found_protocol = B_FALSE; + + fstype = fstypes; + while (fstype != NULL) { + if (protocol == NULL || strcmp(fstype->name, protocol) == 0) { + update_zfs_share(impl_share, fstype->name); + + rc = fstype->ops->enable_share(impl_share); + + if (rc != SA_OK) + ret = rc; + else + FSINFO(impl_share, fstype)->active = B_TRUE; + + found_protocol = B_TRUE; + } + + fstype = fstype->next; + } + + update_sharetab(impl_share->handle); + + return (found_protocol ? ret : SA_INVALID_PROTOCOL); +} + +int +sa_disable_share(sa_share_t share, char *protocol) +{ + sa_share_impl_t impl_share = (sa_share_impl_t)share; + int rc, ret; + boolean_t found_protocol; + sa_fstype_t *fstype; + +#ifdef DEBUG + fprintf(stderr, "sa_disable_share: share->sharepath=%s, protocol=%s\n", + impl_share->sharepath, protocol); +#endif + + ret = SA_OK; + found_protocol = B_FALSE; + + fstype = fstypes; + while (fstype != NULL) { + if (protocol == NULL || strcmp(fstype->name, protocol) == 0) { + rc = fstype->ops->disable_share(impl_share); + + if (rc == SA_OK) { + fstype->ops->clear_shareopts(impl_share); + + FSINFO(impl_share, fstype)->active = B_FALSE; + } else + ret = rc; + + found_protocol = B_TRUE; + } + + fstype = fstype->next; + } + + update_sharetab(impl_share->handle); + + return (found_protocol ? ret : SA_INVALID_PROTOCOL); +} + +/* + * sa_errorstr(err) + * + * convert an error value to an error string + */ +char * +sa_errorstr(int err) +{ + static char errstr[32]; + char *ret = NULL; + + switch (err) { + case SA_OK: + ret = dgettext(TEXT_DOMAIN, "ok"); + break; + case SA_NO_SUCH_PATH: + ret = dgettext(TEXT_DOMAIN, "path doesn't exist"); + break; + case SA_NO_MEMORY: + ret = dgettext(TEXT_DOMAIN, "no memory"); + break; + case SA_DUPLICATE_NAME: + ret = dgettext(TEXT_DOMAIN, "name in use"); + break; + case SA_BAD_PATH: + ret = dgettext(TEXT_DOMAIN, "bad path"); + break; + case SA_NO_SUCH_GROUP: + ret = dgettext(TEXT_DOMAIN, "no such group"); + break; + case SA_CONFIG_ERR: + ret = dgettext(TEXT_DOMAIN, "configuration error"); + break; + case SA_SYSTEM_ERR: + ret = dgettext(TEXT_DOMAIN, "system error"); + break; + case SA_SYNTAX_ERR: + ret = dgettext(TEXT_DOMAIN, "syntax error"); + break; + case SA_NO_PERMISSION: + ret = dgettext(TEXT_DOMAIN, "no permission"); + break; + case SA_BUSY: + ret = dgettext(TEXT_DOMAIN, "busy"); + break; + case SA_NO_SUCH_PROP: + ret = dgettext(TEXT_DOMAIN, "no such property"); + break; + case SA_INVALID_NAME: + ret = dgettext(TEXT_DOMAIN, "invalid name"); + break; + case SA_INVALID_PROTOCOL: + ret = dgettext(TEXT_DOMAIN, "invalid protocol"); + break; + case SA_NOT_ALLOWED: + ret = dgettext(TEXT_DOMAIN, "operation not allowed"); + break; + case SA_BAD_VALUE: + ret = dgettext(TEXT_DOMAIN, "bad property value"); + break; + case SA_INVALID_SECURITY: + ret = dgettext(TEXT_DOMAIN, "invalid security type"); + break; + case SA_NO_SUCH_SECURITY: + ret = dgettext(TEXT_DOMAIN, "security type not found"); + break; + case SA_VALUE_CONFLICT: + ret = dgettext(TEXT_DOMAIN, "property value conflict"); + break; + case SA_NOT_IMPLEMENTED: + ret = dgettext(TEXT_DOMAIN, "not implemented"); + break; + case SA_INVALID_PATH: + ret = dgettext(TEXT_DOMAIN, "invalid path"); + break; + case SA_NOT_SUPPORTED: + ret = dgettext(TEXT_DOMAIN, "operation not supported"); + break; + case SA_PROP_SHARE_ONLY: + ret = dgettext(TEXT_DOMAIN, "property not valid for group"); + break; + case SA_NOT_SHARED: + ret = dgettext(TEXT_DOMAIN, "not shared"); + break; + case SA_NO_SUCH_RESOURCE: + ret = dgettext(TEXT_DOMAIN, "no such resource"); + break; + case SA_RESOURCE_REQUIRED: + ret = dgettext(TEXT_DOMAIN, "resource name required"); + break; + case SA_MULTIPLE_ERROR: + ret = dgettext(TEXT_DOMAIN, "errors from multiple protocols"); + break; + case SA_PATH_IS_SUBDIR: + ret = dgettext(TEXT_DOMAIN, "path is a subpath of share"); + break; + case SA_PATH_IS_PARENTDIR: + ret = dgettext(TEXT_DOMAIN, "path is parent of a share"); + break; + case SA_NO_SECTION: + ret = dgettext(TEXT_DOMAIN, "protocol requires a section"); + break; + case SA_NO_PROPERTIES: + ret = dgettext(TEXT_DOMAIN, "properties not found"); + break; + case SA_NO_SUCH_SECTION: + ret = dgettext(TEXT_DOMAIN, "section not found"); + break; + case SA_PASSWORD_ENC: + ret = dgettext(TEXT_DOMAIN, "passwords must be encrypted"); + break; + case SA_SHARE_EXISTS: + ret = dgettext(TEXT_DOMAIN, "path or file is already shared"); + break; + default: + (void) snprintf(errstr, sizeof (errstr), + dgettext(TEXT_DOMAIN, "unknown %d"), err); + ret = errstr; + } + return (ret); +} + +int +sa_parse_legacy_options(sa_group_t group, char *options, char *proto) +{ + sa_fstype_t *fstype; + +#ifdef DEBUG + fprintf(stderr, "sa_parse_legacy_options: options=%s, proto=%s\n", + options, proto); +#endif + + fstype = fstypes; + while (fstype != NULL) { + if (strcmp(fstype->name, proto) != 0) { + fstype = fstype->next; + continue; + } + + return fstype->ops->validate_shareopts(options); + } + + return SA_INVALID_PROTOCOL; +} + +boolean_t +sa_needs_refresh(sa_handle_t handle) +{ + return B_TRUE; +} + +libzfs_handle_t * +sa_get_zfs_handle(sa_handle_t handle) +{ + sa_handle_impl_t impl_handle = (sa_handle_impl_t)handle; + + if (impl_handle == NULL) + return NULL; + + return impl_handle->zfs_libhandle; +} + +static sa_share_impl_t +alloc_share(const char *sharepath) +{ + sa_share_impl_t impl_share; + + impl_share = calloc(sizeof (struct sa_share_impl), 1); + + if (impl_share == NULL) + return NULL; + + impl_share->sharepath = strdup(sharepath); + + if (impl_share->sharepath == NULL) { + free(impl_share); + return NULL; + } + + impl_share->fsinfo = calloc(sizeof (sa_share_fsinfo_t), fstypes_count); + + if (impl_share->fsinfo == NULL) { + free(impl_share->sharepath); + free(impl_share); + return NULL; + } + + return impl_share; +} + +static void +free_share(sa_share_impl_t impl_share) { + sa_fstype_t *fstype; + + fstype = fstypes; + while (fstype != NULL) { + fstype->ops->clear_shareopts(impl_share); + + free(FSINFO(impl_share, fstype)->resource); + + fstype = fstype->next; + } + + free(impl_share->sharepath); + free(impl_share->dataset); + free(impl_share->fsinfo); + free(impl_share); +} + +int +sa_zfs_process_share(sa_handle_t handle, sa_group_t group, sa_share_t share, + char *mountpoint, char *proto, zprop_source_t source, char *shareopts, + char *sourcestr, char *dataset) +{ + sa_handle_impl_t impl_handle = (sa_handle_impl_t)handle; + sa_share_impl_t impl_share = (sa_share_impl_t)share; + +#ifdef DEBUG + fprintf(stderr, "sa_zfs_process_share: mountpoint=%s, proto=%s, " + "shareopts=%s, sourcestr=%s, dataset=%s\n", mountpoint, proto, + shareopts, sourcestr, dataset); +#endif + + return process_share(impl_handle, impl_share, mountpoint, NULL, + proto, shareopts, NULL, dataset, B_FALSE); +} + +void +sa_update_sharetab_ts(sa_handle_t handle) +{ + sa_handle_impl_t impl_handle = (sa_handle_impl_t)handle; + + update_sharetab(impl_handle); +} diff --git a/lib/libshare/libshare_impl.h b/lib/libshare/libshare_impl.h new file mode 100644 index 000000000..dfcec2ff9 --- /dev/null +++ b/lib/libshare/libshare_impl.h @@ -0,0 +1,70 @@ +/* + * 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 + */ + +/* + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011 Gunnar Beutner + */ + +struct sa_handle_impl; + +typedef struct sa_share_fsinfo { + boolean_t active; + char *resource; + char *shareopts; +} sa_share_fsinfo_t; + +typedef struct sa_share_impl { + struct sa_share_impl *next; + + struct sa_handle_impl *handle; + + char *sharepath; + char *dataset; + + sa_share_fsinfo_t *fsinfo; /* per-fstype information */ +} *sa_share_impl_t; + +#define FSINFO(impl_share, fstype) (&(impl_share->fsinfo[fstype->fsinfo_index])) + +typedef struct sa_share_ops { + int (*enable_share)(sa_share_impl_t share); + int (*disable_share)(sa_share_impl_t share); + int (*validate_shareopts)(const char *shareopts); + int (*update_shareopts)(sa_share_impl_t impl_share, + const char *resource, const char *shareopts); + void (*clear_shareopts)(sa_share_impl_t impl_share); +} sa_share_ops_t; + +typedef struct sa_fstype { + struct sa_fstype *next; + + const char *name; + const sa_share_ops_t *ops; + int fsinfo_index; +} sa_fstype_t; + +typedef struct sa_handle_impl { + libzfs_handle_t *zfs_libhandle; + sa_share_impl_t shares; +} *sa_handle_impl_t; + +sa_fstype_t *register_fstype(const char *name, const sa_share_ops_t *ops); diff --git a/lib/libshare/nfs.c b/lib/libshare/nfs.c new file mode 100644 index 000000000..60edaa2c3 --- /dev/null +++ b/lib/libshare/nfs.c @@ -0,0 +1,705 @@ +/* + * 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 + */ + +/* + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011 Gunnar Beutner + */ + +#include <stdio.h> +#include <strings.h> +#include <fcntl.h> +#include <sys/wait.h> +#include <unistd.h> +#include <libzfs.h> +#include <libshare.h> +#include "libshare_impl.h" + +static sa_fstype_t *nfs_fstype; +static boolean_t nfs_available; + +typedef int (*nfs_shareopt_callback_t)(const char *opt, const char *value, + void *cookie); + +typedef int (*nfs_host_callback_t)(const char *sharepath, const char *host, + const char *security, const char *access, void *cookie); + +static int +foreach_nfs_shareopt(const char *shareopts, + nfs_shareopt_callback_t callback, void *cookie) +{ + char *shareopts_dup, *opt, *cur, *value; + int was_nul, rc; + + if (shareopts == NULL) + return SA_OK; + + shareopts_dup = strdup(shareopts); + + if (shareopts_dup == NULL) + return SA_NO_MEMORY; + + opt = shareopts_dup; + was_nul = 0; + + while (1) { + cur = opt; + + while (*cur != ',' && *cur != '\0') + cur++; + + if (*cur == '\0') + was_nul = 1; + + *cur = '\0'; + + if (cur > opt) { + value = strchr(opt, '='); + + if (value != NULL) { + *value = '\0'; + value++; + } + + rc = callback(opt, value, cookie); + + if (rc != SA_OK) { + free(shareopts_dup); + return rc; + } + } + + opt = cur + 1; + + if (was_nul) + break; + } + + free(shareopts_dup); + + return 0; +} + +typedef struct nfs_host_cookie_s { + nfs_host_callback_t callback; + const char *sharepath; + void *cookie; + const char *security; +} nfs_host_cookie_t; + +static int +foreach_nfs_host_cb(const char *opt, const char *value, void *pcookie) +{ + int rc; + const char *access; + char *host_dup, *host, *next; + nfs_host_cookie_t *udata = (nfs_host_cookie_t *)pcookie; + +#ifdef DEBUG + fprintf(stderr, "foreach_nfs_host_cb: key=%s, value=%s\n", opt, value); +#endif + + if (strcmp(opt, "sec") == 0) + udata->security = value; + + if (strcmp(opt, "rw") == 0 || strcmp(opt, "ro") == 0) { + if (value == NULL) + value = "*"; + + access = opt; + + host_dup = strdup(value); + + if (host_dup == NULL) + return SA_NO_MEMORY; + + host = host_dup; + + do { + next = strchr(host, ':'); + if (next != NULL) { + *next = '\0'; + next++; + } + + rc = udata->callback(udata->sharepath, host, + udata->security, access, udata->cookie); + + if (rc != SA_OK) { + free(host_dup); + + return rc; + } + + host = next; + } while (host != NULL); + + free(host_dup); + } + + return SA_OK; +} + +static int +foreach_nfs_host(sa_share_impl_t impl_share, nfs_host_callback_t callback, + void *cookie) +{ + nfs_host_cookie_t udata; + char *shareopts; + + udata.callback = callback; + udata.sharepath = impl_share->sharepath; + udata.cookie = cookie; + udata.security = "sys"; + + shareopts = FSINFO(impl_share, nfs_fstype)->shareopts; + + return foreach_nfs_shareopt(shareopts, foreach_nfs_host_cb, + &udata); +} + +static int +get_linux_hostspec(const char *solaris_hostspec, char **plinux_hostspec) +{ + /* + * For now we just support CIDR masks (e.g. @192.168.0.0/16) and host + * wildcards (e.g. *.example.org). + */ + if (solaris_hostspec[0] == '@') { + /* + * Solaris host specifier, e.g. @192.168.0.0/16; we just need + * to skip the @ in this case + */ + *plinux_hostspec = strdup(solaris_hostspec + 1); + } else { + *plinux_hostspec = strdup(solaris_hostspec); + } + + if (*plinux_hostspec == NULL) { + return SA_NO_MEMORY; + } + + return SA_OK; +} + +static int +nfs_enable_share_one(const char *sharepath, const char *host, + const char *security, const char *access, void *pcookie) +{ + pid_t pid; + int rc, status; + char *linuxhost, *hostpath, *opts; + const char *linux_opts = (const char *)pcookie; + + pid = fork(); + + if (pid < 0) + return SA_SYSTEM_ERR; + + if (pid > 0) { + while ((rc = waitpid(pid, &status, 0)) <= 0 && errno == EINTR) + ; /* empty loop body */ + + if (rc <= 0) + return SA_SYSTEM_ERR; + + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + return SA_CONFIG_ERR; + + return SA_OK; + } + + /* child */ + + /* exportfs -i -o sec=XX,rX,<opts> <host>:<sharepath> */ + + rc = get_linux_hostspec(host, &linuxhost); + + if (rc < 0) + exit(1); + + hostpath = malloc(strlen(linuxhost) + 1 + strlen(sharepath) + 1); + + if (hostpath == NULL) { + free(linuxhost); + + exit(1); + } + + sprintf(hostpath, "%s:%s", linuxhost, sharepath); + + free(linuxhost); + + if (linux_opts == NULL) + linux_opts = ""; + + opts = malloc(4 + strlen(security) + 4 + strlen(linux_opts) + 1); + + if (opts == NULL) + exit(1); + + sprintf(opts, "sec=%s,%s,%s", security, access, linux_opts); + +#ifdef DEBUG + fprintf(stderr, "sharing %s with opts %s\n", hostpath, opts); +#endif + + rc = execlp("/usr/sbin/exportfs", "exportfs", "-i", \ + "-o", opts, hostpath, NULL); + + if (rc < 0) { + free(hostpath); + free(opts); + exit(1); + } + + exit(0); +} + +static int +add_linux_shareopt(char **plinux_opts, const char *key, const char *value) +{ + size_t len = 0; + char *new_linux_opts; + + if (*plinux_opts != NULL) + len = strlen(*plinux_opts); + + new_linux_opts = realloc(*plinux_opts, len + 1 + strlen(key) + + (value ? 1 + strlen(value) : 0) + 1); + + if (new_linux_opts == NULL) + return SA_NO_MEMORY; + + new_linux_opts[len] = '\0'; + + if (len > 0) + strcat(new_linux_opts, ","); + + strcat(new_linux_opts, key); + + if (value != NULL) { + strcat(new_linux_opts, "="); + strcat(new_linux_opts, value); + } + + *plinux_opts = new_linux_opts; + + return SA_OK; +} + +static int +get_linux_shareopts_cb(const char *key, const char *value, void *cookie) +{ + char **plinux_opts = (char **)cookie; + + /* host-specific options, these are taken care of elsewhere */ + if (strcmp(key, "ro") == 0 || strcmp(key, "rw") == 0 || + strcmp(key, "sec") == 0) + return SA_OK; + + if (strcmp(key, "anon") == 0) + key = "anonuid"; + + if (strcmp(key, "root_mapping") == 0) { + (void) add_linux_shareopt(plinux_opts, "root_squash", NULL); + key = "anonuid"; + } + + if (strcmp(key, "nosub") == 0) + key = "subtree_check"; + + if (strcmp(key, "insecure") != 0 && strcmp(key, "secure") != 0 && + strcmp(key, "async") != 0 && strcmp(key, "sync") != 0 && + strcmp(key, "no_wdelay") != 0 && strcmp(key, "wdelay") != 0 && + strcmp(key, "nohide") != 0 && strcmp(key, "hide") != 0 && + strcmp(key, "crossmnt") != 0 && + strcmp(key, "no_subtree_check") != 0 && + strcmp(key, "subtree_check") != 0 && + strcmp(key, "insecure_locks") != 0 && + strcmp(key, "secure_locks") != 0 && + strcmp(key, "no_auth_nlm") != 0 && strcmp(key, "auth_nlm") != 0 && + strcmp(key, "no_acl") != 0 && strcmp(key, "mountpoint") != 0 && + strcmp(key, "mp") != 0 && strcmp(key, "fsuid") != 0 && + strcmp(key, "refer") != 0 && strcmp(key, "replicas") != 0 && + strcmp(key, "root_squash") != 0 && + strcmp(key, "no_root_squash") != 0 && + strcmp(key, "all_squash") != 0 && + strcmp(key, "no_all_squash") != 0 && + strcmp(key, "anonuid") != 0 && strcmp(key, "anongid") != 0) { + return SA_SYNTAX_ERR; + } + + (void) add_linux_shareopt(plinux_opts, key, value); + + return SA_OK; +} + +static int +get_linux_shareopts(const char *shareopts, char **plinux_opts) +{ + int rc; + + assert(plinux_opts != NULL); + + *plinux_opts = NULL; + + /* default options for Solaris shares */ + (void) add_linux_shareopt(plinux_opts, "no_subtree_check", NULL); + (void) add_linux_shareopt(plinux_opts, "no_root_squash", NULL); + (void) add_linux_shareopt(plinux_opts, "mountpoint", NULL); + + rc = foreach_nfs_shareopt(shareopts, get_linux_shareopts_cb, plinux_opts); + + if (rc != SA_OK) { + free(*plinux_opts); + *plinux_opts = NULL; + } + + return rc; +} + +static int +nfs_enable_share(sa_share_impl_t impl_share) +{ + char *shareopts, *linux_opts; + int rc; + + if (!nfs_available) { + return SA_SYSTEM_ERR; + } + + shareopts = FSINFO(impl_share, nfs_fstype)->shareopts; + + if (shareopts == NULL) + return SA_OK; + + rc = get_linux_shareopts(shareopts, &linux_opts); + + if (rc != SA_OK) + return rc; + + rc = foreach_nfs_host(impl_share, nfs_enable_share_one, linux_opts); + + free(linux_opts); + + return rc; +} + +static int +nfs_disable_share_one(const char *sharepath, const char *host, + const char *security, const char *access, void *cookie) +{ + pid_t pid; + int rc, status; + char *linuxhost, *hostpath; + + pid = fork(); + + if (pid < 0) + return SA_SYSTEM_ERR; + + if (pid > 0) { + while ((rc = waitpid(pid, &status, 0)) <= 0 && errno == EINTR) + ; /* empty loop body */ + + if (rc <= 0) + return SA_SYSTEM_ERR; + + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + return SA_CONFIG_ERR; + + return SA_OK; + } + + /* child */ + + rc = get_linux_hostspec(host, &linuxhost); + + if (rc < 0) + exit(1); + + hostpath = malloc(strlen(linuxhost) + 1 + strlen(sharepath) + 1); + + if (hostpath == NULL) { + free(linuxhost); + exit(1); + } + + sprintf(hostpath, "%s:%s", linuxhost, sharepath); + + free(linuxhost); + +#ifdef DEBUG + fprintf(stderr, "unsharing %s\n", hostpath); +#endif + + rc = execlp("/usr/sbin/exportfs", "exportfs", "-u", \ + hostpath, NULL); + + if (rc < 0) { + free(hostpath); + exit(1); + } + + exit(0); +} + +static int +nfs_disable_share(sa_share_impl_t impl_share) +{ + if (!nfs_available) { + /* + * The share can't possibly be active, so nothing + * needs to be done to disable it. + */ + return SA_OK; + } + + return foreach_nfs_host(impl_share, nfs_disable_share_one, NULL); +} + +static int +nfs_validate_shareopts(const char *shareopts) +{ + char *linux_opts; + int rc; + + rc = get_linux_shareopts(shareopts, &linux_opts); + + if (rc != SA_OK) + return rc; + + free(linux_opts); + + return SA_OK; +} + +/* + * TODO: Rather than invoking "exportfs -v" once for each share we should only + * call it once for all shares. + */ +static boolean_t +is_share_active(sa_share_impl_t impl_share) +{ + pid_t pid; + int rc, status; + int pipes[2]; + FILE *exportfs_stdout; + char line[512]; + char *tab, *cur; + boolean_t share_active = B_FALSE; + + if (pipe(pipes) < 0) + return B_FALSE; + + pid = fork(); + + if (pid < 0) + return B_FALSE; + + if (pid > 0) { + share_active = B_FALSE; + + exportfs_stdout = fdopen(pipes[0], "r"); + close(pipes[1]); + + while (fgets(line, sizeof(line), exportfs_stdout) != NULL) { + if (share_active) + continue; + + /* + * exportfs uses separate lines for the share path + * and the export options when the share path is longer + * than a certain amount of characters; this ignores + * the option lines + */ + if (line[0] == '\t') + continue; + + tab = strchr(line, '\t'); + + if (tab != NULL) { + *tab = '\0'; + cur = tab - 1; + } else { + /* + * there's no tab character, which means the + * NFS options are on a separate line; we just + * need to remove the new-line character + * at the end of the line + */ + cur = line + strlen(line) - 1; + } + + /* remove trailing spaces and new-line characters */ + while (cur >= line && + (*cur == ' ' || *cur == '\n')) + *cur-- = '\0'; + + if (strcmp(line, impl_share->sharepath) == 0) { + share_active = B_TRUE; + + /* + * We can't break here just yet, otherwise + * exportfs might die due to write() failing + * with EPIPE once we've closed the pipe file + * descriptor - we need to read until EOF + * occurs on the stdout pipe. + */ + } + } + + fclose(exportfs_stdout); + + while ((rc = waitpid(pid, &status, 0)) <= 0 && errno == EINTR) + ; /* empty loop body */ + + if (rc <= 0) + return B_FALSE; + + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + return B_FALSE; + + return share_active; + } + + /* child */ + + /* exportfs -v */ + + close(pipes[0]); + + if (dup2(pipes[1], STDOUT_FILENO) < 0) + exit(1); + + rc = execlp("/usr/sbin/exportfs", "exportfs", "-v", NULL); + + if (rc < 0) { + exit(1); + } + + exit(0); +} + +static int +nfs_update_shareopts(sa_share_impl_t impl_share, const char *resource, + const char *shareopts) +{ + char *shareopts_dup; + boolean_t needs_reshare = B_FALSE; + char *old_shareopts; + + FSINFO(impl_share, nfs_fstype)->active = is_share_active(impl_share); + + old_shareopts = FSINFO(impl_share, nfs_fstype)->shareopts; + + if (strcmp(shareopts, "on") == 0) + shareopts = "rw"; + + if (FSINFO(impl_share, nfs_fstype)->active && old_shareopts != NULL && + strcmp(old_shareopts, shareopts) != 0) { + needs_reshare = B_TRUE; + nfs_disable_share(impl_share); + } + + shareopts_dup = strdup(shareopts); + + if (shareopts_dup == NULL) + return SA_NO_MEMORY; + + if (old_shareopts != NULL) + free(old_shareopts); + + FSINFO(impl_share, nfs_fstype)->shareopts = shareopts_dup; + + if (needs_reshare) + nfs_enable_share(impl_share); + + return SA_OK; +} + + +static void +nfs_clear_shareopts(sa_share_impl_t impl_share) +{ + free(FSINFO(impl_share, nfs_fstype)->shareopts); + FSINFO(impl_share, nfs_fstype)->shareopts = NULL; +} + +static const sa_share_ops_t nfs_shareops = { + .enable_share = nfs_enable_share, + .disable_share = nfs_disable_share, + + .validate_shareopts = nfs_validate_shareopts, + .update_shareopts = nfs_update_shareopts, + .clear_shareopts = nfs_clear_shareopts, +}; + +static int +nfs_check_exportfs(void) +{ + pid_t pid; + int rc, status, null_fd; + + pid = fork(); + + if (pid < 0) + return SA_SYSTEM_ERR; + + if (pid > 0) { + while ((rc = waitpid(pid, &status, 0)) <= 0 && errno == EINTR) + ; /* empty loop body */ + + if (rc <= 0) + return SA_SYSTEM_ERR; + + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + return SA_CONFIG_ERR; + + return SA_OK; + } + + /* child */ + + null_fd = open("/dev/null", O_RDONLY); + + if (null_fd < 0 || dup2(null_fd, 1) < 0 || dup2(null_fd, 2) < 0) + exit(1); + + close(null_fd); + + rc = execlp("/usr/sbin/exportfs", "exportfs", NULL); + + if (rc < 0) { + exit(1); + } + + exit(0); +} + +void +libshare_nfs_init(void) +{ + nfs_available = (nfs_check_exportfs() == SA_OK); + + nfs_fstype = register_fstype("nfs", &nfs_shareops); +} diff --git a/lib/libshare/nfs.h b/lib/libshare/nfs.h new file mode 100644 index 000000000..b9ea6ee2f --- /dev/null +++ b/lib/libshare/nfs.h @@ -0,0 +1,27 @@ +/* + * 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 + */ + +/* + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011 Gunnar Beutner + */ + +void libshare_nfs_init(void); diff --git a/lib/libspl/include/libshare.h b/lib/libspl/include/libshare.h index f1fbfad2b..a35bfacd7 100644 --- a/lib/libspl/include/libshare.h +++ b/lib/libspl/include/libshare.h @@ -34,9 +34,63 @@ typedef void *sa_share_t; #define SA_INIT_SHARE_API 0x0001 /* init share specific interface */ #define SA_INIT_CONTROL_API 0x0002 /* init control specific interface */ -/* Error values */ +/* + * defined error values + */ + #define SA_OK 0 +#define SA_NO_SUCH_PATH 1 /* provided path doesn't exist */ #define SA_NO_MEMORY 2 /* no memory for data structures */ +#define SA_DUPLICATE_NAME 3 /* object name is already in use */ +#define SA_BAD_PATH 4 /* not a full path */ +#define SA_NO_SUCH_GROUP 5 /* group is not defined */ #define SA_CONFIG_ERR 6 /* system configuration error */ +#define SA_SYSTEM_ERR 7 /* system error, use errno */ +#define SA_SYNTAX_ERR 8 /* syntax error on command line */ +#define SA_NO_PERMISSION 9 /* no permission for operation */ +#define SA_BUSY 10 /* resource is busy */ +#define SA_NO_SUCH_PROP 11 /* property doesn't exist */ +#define SA_INVALID_NAME 12 /* name of object is invalid */ +#define SA_INVALID_PROTOCOL 13 /* specified protocol not valid */ +#define SA_NOT_ALLOWED 14 /* operation not allowed */ +#define SA_BAD_VALUE 15 /* bad value for property */ +#define SA_INVALID_SECURITY 16 /* invalid security type */ +#define SA_NO_SUCH_SECURITY 17 /* security set not found */ +#define SA_VALUE_CONFLICT 18 /* property value conflict */ +#define SA_NOT_IMPLEMENTED 19 /* plugin interface not implemented */ +#define SA_INVALID_PATH 20 /* path is sub-dir of existing share */ +#define SA_NOT_SUPPORTED 21 /* operation not supported for proto */ +#define SA_PROP_SHARE_ONLY 22 /* property valid on share only */ +#define SA_NOT_SHARED 23 /* path is not shared */ +#define SA_NO_SUCH_RESOURCE 24 /* resource not found */ +#define SA_RESOURCE_REQUIRED 25 /* resource name is required */ +#define SA_MULTIPLE_ERROR 26 /* multiple protocols reported error */ +#define SA_PATH_IS_SUBDIR 27 /* check_path found path is subdir */ +#define SA_PATH_IS_PARENTDIR 28 /* check_path found path is parent */ +#define SA_NO_SECTION 29 /* protocol requires section info */ +#define SA_NO_SUCH_SECTION 30 /* no section found */ +#define SA_NO_PROPERTIES 31 /* no properties found */ +#define SA_PASSWORD_ENC 32 /* passwords must be encrypted */ +#define SA_SHARE_EXISTS 33 /* path or file is already shared */ + +/* initialization */ +extern sa_handle_t sa_init(int); +extern void sa_fini(sa_handle_t); +extern char *sa_errorstr(int); + +/* share control */ +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 *); + +/* protocol specific interfaces */ +extern int sa_parse_legacy_options(sa_group_t, char *, char *); + +/* ZFS functions */ +extern boolean_t sa_needs_refresh(sa_handle_t handle); +libzfs_handle_t *sa_get_zfs_handle(sa_handle_t handle); +extern int sa_zfs_process_share(sa_handle_t handle, sa_group_t group, + sa_share_t share, char *mountpoint, char *proto, zprop_source_t source, + char *shareopts, char *sourcestr, char *dataset); #endif /* _LIBSPL_LIBSHARE_H */ diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c index 6b70cbbec..7b9cd8078 100644 --- a/lib/libzfs/libzfs_mount.c +++ b/lib/libzfs/libzfs_mount.c @@ -117,21 +117,20 @@ zfs_share_proto_t share_all_proto[] = { }; /* - * Search for NFS and SMB exports for the given mountpoint and protocol, returning + * Search the sharetab for the given mountpoint and protocol, returning * a zfs_share_type_t value. */ static zfs_share_type_t is_shared(libzfs_handle_t *hdl, const char *mountpoint, zfs_share_proto_t proto) { char buf[MAXPATHLEN], *tab; + char *ptr; if (hdl->libzfs_sharetab == NULL) return (SHARED_NOT_SHARED); (void) fseek(hdl->libzfs_sharetab, 0, SEEK_SET); - /* Search /etc/exports for NFS exports */ - /* FIXME: Assumes the file is tab delimited. */ while (fgets(buf, sizeof (buf), hdl->libzfs_sharetab) != NULL) { /* the mountpoint is the first entry on each line */ @@ -140,15 +139,31 @@ is_shared(libzfs_handle_t *hdl, const char *mountpoint, zfs_share_proto_t proto) *tab = '\0'; if (strcmp(buf, mountpoint) == 0) { - if (proto == PROTO_NFS) - return (SHARED_NFS); - else - return (SHARED_NOT_SHARED); + /* + * the protocol field is the third field + * skip over second field + */ + ptr = ++tab; + if ((tab = strchr(ptr, '\t')) == NULL) + continue; + ptr = ++tab; + if ((tab = strchr(ptr, '\t')) == NULL) + continue; + *tab = '\0'; + if (strcmp(ptr, + proto_table[proto].p_name) == 0) { + switch (proto) { + case PROTO_NFS: + return (SHARED_NFS); + case PROTO_SMB: + return (SHARED_SMB); + default: + return (0); + } + } } } - /* XXX: Search /etc/samba/smb.conf for SMB exports, return SHARED_SMB */ - return (SHARED_NOT_SHARED); } @@ -665,12 +680,12 @@ _zfs_init_libshare(void) char path[MAXPATHLEN]; char isa[MAXISALEN]; -#if defined(_LP64) +/*#if defined(_LP64) if (sysinfo(SI_ARCHITECTURE_64, isa, MAXISALEN) == -1) isa[0] = '\0'; -#else +#else*/ isa[0] = '\0'; -#endif +/*#endif*/ (void) snprintf(path, MAXPATHLEN, "/usr/lib/%s/libshare.so.1", isa); @@ -854,14 +869,11 @@ zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto) return (0); if ((ret = zfs_init_libshare(hdl, SA_INIT_SHARE_API)) != SA_OK) { -#ifdef HAVE_SHARE (void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED, dgettext(TEXT_DOMAIN, "cannot share '%s': %s"), zfs_get_name(zhp), _sa_errorstr != NULL ? _sa_errorstr(ret) : ""); return (-1); -#endif /* HAVE_SHARE */ - return (0); } for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) { diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index b50f02383..efb6bf5e7 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -4152,143 +4152,10 @@ zfs_ioc_userspace_upgrade(zfs_cmd_t *zc) return (error); } -/* - * We don't want to have a hard dependency - * against some special symbols in sharefs - * nfs, and smbsrv. Determine them if needed when - * the first file system is shared. - * Neither sharefs, nfs or smbsrv are unloadable modules. - */ -#ifdef HAVE_SHARE -int (*znfsexport_fs)(void *arg); -int (*zshare_fs)(enum sharefs_sys_op, share_t *, uint32_t); -int (*zsmbexport_fs)(void *arg, boolean_t add_share); - -int zfs_nfsshare_inited; -int zfs_smbshare_inited; - -ddi_modhandle_t nfs_mod; -ddi_modhandle_t sharefs_mod; -ddi_modhandle_t smbsrv_mod; -kmutex_t zfs_share_lock; - -static int -zfs_init_sharefs() -{ - int error; - - ASSERT(MUTEX_HELD(&zfs_share_lock)); - /* Both NFS and SMB shares also require sharetab support. */ - if (sharefs_mod == NULL && ((sharefs_mod = - ddi_modopen("fs/sharefs", - KRTLD_MODE_FIRST, &error)) == NULL)) { - return (ENOSYS); - } - if (zshare_fs == NULL && ((zshare_fs = - (int (*)(enum sharefs_sys_op, share_t *, uint32_t)) - ddi_modsym(sharefs_mod, "sharefs_impl", &error)) == NULL)) { - return (ENOSYS); - } - return (0); -} -#endif /* HAVE_SHARE */ - static int zfs_ioc_share(zfs_cmd_t *zc) { -#ifdef HAVE_SHARE - int error; - int opcode; - - switch (zc->zc_share.z_sharetype) { - case ZFS_SHARE_NFS: - case ZFS_UNSHARE_NFS: - if (zfs_nfsshare_inited == 0) { - mutex_enter(&zfs_share_lock); - if (nfs_mod == NULL && ((nfs_mod = ddi_modopen("fs/nfs", - KRTLD_MODE_FIRST, &error)) == NULL)) { - mutex_exit(&zfs_share_lock); - return (ENOSYS); - } - if (znfsexport_fs == NULL && - ((znfsexport_fs = (int (*)(void *)) - ddi_modsym(nfs_mod, - "nfs_export", &error)) == NULL)) { - mutex_exit(&zfs_share_lock); - return (ENOSYS); - } - error = zfs_init_sharefs(); - if (error) { - mutex_exit(&zfs_share_lock); - return (ENOSYS); - } - zfs_nfsshare_inited = 1; - mutex_exit(&zfs_share_lock); - } - break; - case ZFS_SHARE_SMB: - case ZFS_UNSHARE_SMB: - if (zfs_smbshare_inited == 0) { - mutex_enter(&zfs_share_lock); - if (smbsrv_mod == NULL && ((smbsrv_mod = - ddi_modopen("drv/smbsrv", - KRTLD_MODE_FIRST, &error)) == NULL)) { - mutex_exit(&zfs_share_lock); - return (ENOSYS); - } - if (zsmbexport_fs == NULL && ((zsmbexport_fs = - (int (*)(void *, boolean_t))ddi_modsym(smbsrv_mod, - "smb_server_share", &error)) == NULL)) { - mutex_exit(&zfs_share_lock); - return (ENOSYS); - } - error = zfs_init_sharefs(); - if (error) { - mutex_exit(&zfs_share_lock); - return (ENOSYS); - } - zfs_smbshare_inited = 1; - mutex_exit(&zfs_share_lock); - } - break; - default: - return (EINVAL); - } - - switch (zc->zc_share.z_sharetype) { - case ZFS_SHARE_NFS: - case ZFS_UNSHARE_NFS: - if (error = - znfsexport_fs((void *) - (uintptr_t)zc->zc_share.z_exportdata)) - return (error); - break; - case ZFS_SHARE_SMB: - case ZFS_UNSHARE_SMB: - if (error = zsmbexport_fs((void *) - (uintptr_t)zc->zc_share.z_exportdata, - zc->zc_share.z_sharetype == ZFS_SHARE_SMB ? - B_TRUE: B_FALSE)) { - return (error); - } - break; - } - - opcode = (zc->zc_share.z_sharetype == ZFS_SHARE_NFS || - zc->zc_share.z_sharetype == ZFS_SHARE_SMB) ? - SHAREFS_ADD : SHAREFS_REMOVE; - - /* - * Add or remove share from sharetab - */ - error = zshare_fs(opcode, - (void *)(uintptr_t)zc->zc_share.z_sharedata, - zc->zc_share.z_sharemax); - - return (error); -#else - return (ENOTSUP); -#endif /* HAVE_SHARE */ + return (ENOSYS); } ace_t full_access[] = { @@ -5175,10 +5042,6 @@ _init(void) tsd_create(&zfs_fsyncer_key, NULL); tsd_create(&rrw_tsd_key, NULL); -#ifdef HAVE_SHARE - mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL); -#endif /* HAVE_SHARE */ - printk(KERN_NOTICE "ZFS: Loaded module v%s%s, " "ZFS pool version %s, ZFS filesystem version %s\n", ZFS_META_VERSION, ZFS_DEBUG_STR, @@ -5204,16 +5067,7 @@ _fini(void) zvol_fini(); zfs_fini(); spa_fini(); -#ifdef HAVE_SHARE - if (zfs_nfsshare_inited) - (void) ddi_modclose(nfs_mod); - if (zfs_smbshare_inited) - (void) ddi_modclose(smbsrv_mod); - if (zfs_nfsshare_inited || zfs_smbshare_inited) - (void) ddi_modclose(sharefs_mod); - - mutex_destroy(&zfs_share_lock); -#endif /* HAVE_SHARE */ + tsd_destroy(&zfs_fsyncer_key); tsd_destroy(&rrw_tsd_key); |