summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/Makefile.master1
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/Makefile25
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/common.h13
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/info.c212
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/shares_rap.c143
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/shares_rpc.c83
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/smbutil.c14
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/srvsvc1.ndl177
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/srvsvc1_clnt.c138
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/srvsvc1_clnt.h46
-rw-r--r--usr/src/cmd/fs.d/smbclnt/smbutil/view.c100
-rw-r--r--usr/src/cmd/mdb/common/modules/zfs/zfs.c11
-rw-r--r--usr/src/common/smbsrv/smb_door_legacy.c2
-rw-r--r--usr/src/common/smbsrv/smb_token_xdr.c2
-rw-r--r--usr/src/lib/Makefile5
-rw-r--r--usr/src/lib/libmlrpc/Makefile65
-rw-r--r--usr/src/lib/libmlrpc/Makefile.com (renamed from usr/src/lib/smbsrv/libmlrpc/Makefile.com)41
-rw-r--r--usr/src/lib/libmlrpc/amd64/Makefile (renamed from usr/src/lib/smbsrv/libmlrpc/amd64/Makefile)6
-rw-r--r--usr/src/lib/libmlrpc/common/libmlrpc.h (renamed from usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h)53
-rw-r--r--usr/src/lib/libmlrpc/common/llib-lmlrpc (renamed from usr/src/lib/smbsrv/libmlrpc/common/llib-lmlrpc)6
-rw-r--r--usr/src/lib/libmlrpc/common/mapfile-vers (renamed from usr/src/lib/smbsrv/libmlrpc/common/mapfile-vers)89
-rw-r--r--usr/src/lib/libmlrpc/common/mlrpc_clh.c578
-rw-r--r--usr/src/lib/libmlrpc/common/ndr.h (renamed from usr/src/uts/common/smbsrv/ndr.h)15
-rw-r--r--usr/src/lib/libmlrpc/common/ndr_client.c (renamed from usr/src/lib/smbsrv/libmlrpc/common/ndr_client.c)18
-rw-r--r--usr/src/lib/libmlrpc/common/ndr_heap.c (renamed from usr/src/lib/smbsrv/libmlrpc/common/ndr_heap.c)83
-rw-r--r--usr/src/lib/libmlrpc/common/ndr_marshal.c (renamed from usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c)4
-rw-r--r--usr/src/lib/libmlrpc/common/ndr_ops.c (renamed from usr/src/lib/smbsrv/libmlrpc/common/ndr_ops.c)3
-rw-r--r--usr/src/lib/libmlrpc/common/ndr_process.c (renamed from usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c)212
-rw-r--r--usr/src/lib/libmlrpc/common/ndr_server.c (renamed from usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c)40
-rw-r--r--usr/src/lib/libmlrpc/common/ndr_svc.c (renamed from usr/src/lib/smbsrv/libmlrpc/common/ndr_svc.c)3
-rw-r--r--usr/src/lib/libmlrpc/common/ndr_wchar.c162
-rw-r--r--usr/src/lib/libmlrpc/common/ndr_wchar.h46
-rw-r--r--usr/src/lib/libmlrpc/common/ndrtypes.ndl (renamed from usr/src/uts/common/smbsrv/ndl/ndrtypes.ndl)43
-rw-r--r--usr/src/lib/libmlrpc/common/rpcpdu.ndl (renamed from usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl)0
-rw-r--r--usr/src/lib/libmlrpc/i386/Makefile (renamed from usr/src/lib/smbsrv/libmlrpc/i386/Makefile)4
-rw-r--r--usr/src/lib/libmlrpc/sparc/Makefile (renamed from usr/src/lib/smbsrv/libmlrpc/sparc/Makefile)4
-rw-r--r--usr/src/lib/libmlrpc/sparcv9/Makefile (renamed from usr/src/lib/smbsrv/libmlrpc/sparcv9/Makefile)6
-rw-r--r--usr/src/lib/libsmbfs/Makefile.com1
-rw-r--r--usr/src/lib/libsmbfs/netsmb/smb_netshareenum.h18
-rw-r--r--usr/src/lib/libsmbfs/netsmb/smbfs_api.h4
-rw-r--r--usr/src/lib/libsmbfs/smb/file.c4
-rw-r--r--usr/src/lib/libsmbfs/smb/llib-lsmbfs1
-rw-r--r--usr/src/lib/libsmbfs/smb/mapfile-vers1
-rw-r--r--usr/src/lib/libsmbfs/smb/netshareenum.c378
-rw-r--r--usr/src/lib/smbsrv/Makefile4
-rw-r--r--usr/src/lib/smbsrv/Makefile.targ7
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/Makefile30
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c2
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/dssetup_svc.c3
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/eventlog_svc.c3
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h55
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/lsar_clnt.c46
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/lsar_svc.c2
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h4
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c534
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c2
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c40
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/msgsvc_svc.c3
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c9
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c2
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/samr_clnt.c2
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c2
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c2
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/srvsvc_clnt.c120
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/libsmb.h7
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_doorclnt.c2
-rw-r--r--usr/src/pkg/manifests/driver-storage-mpt_sas.mf21
-rw-r--r--usr/src/pkg/manifests/service-file-system-smb.mf5
-rw-r--r--usr/src/pkg/manifests/system-file-system-smb.mf1
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_rewind_config_changed.ksh7
-rw-r--r--usr/src/test/zfs-tests/tests/functional/slog/slog_014_pos.ksh14
-rw-r--r--usr/src/tools/ndrgen/ndrgen.sh126
-rwxr-xr-xusr/src/tools/quick/make-smbclnt304
-rwxr-xr-xusr/src/tools/quick/make-smbsrv8
-rw-r--r--usr/src/uts/common/fs/zfs/metaslab.c512
-rw-r--r--usr/src/uts/common/fs/zfs/spa.c37
-rw-r--r--usr/src/uts/common/fs/zfs/spa_misc.c28
-rw-r--r--usr/src/uts/common/fs/zfs/sys/metaslab.h18
-rw-r--r--usr/src/uts/common/fs/zfs/sys/metaslab_impl.h79
-rw-r--r--usr/src/uts/common/fs/zfs/sys/spa_impl.h12
-rw-r--r--usr/src/uts/common/fs/zfs/sys/vdev_impl.h3
-rw-r--r--usr/src/uts/common/fs/zfs/sys/zio.h7
-rw-r--r--usr/src/uts/common/fs/zfs/vdev.c4
-rw-r--r--usr/src/uts/common/fs/zfs/vdev_queue.c11
-rw-r--r--usr/src/uts/common/fs/zfs/vdev_removal.c9
-rw-r--r--usr/src/uts/common/fs/zfs/zil.c8
-rw-r--r--usr/src/uts/common/fs/zfs/zio.c86
-rw-r--r--usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_impl.c4
-rw-r--r--usr/src/uts/common/smb/Makefile4
-rw-r--r--usr/src/uts/common/smb/wintypes.h (renamed from usr/src/uts/common/smbsrv/wintypes.h)37
-rw-r--r--usr/src/uts/common/smbsrv/Makefile6
-rw-r--r--usr/src/uts/common/smbsrv/ndl/dssetup.ndl4
-rw-r--r--usr/src/uts/common/smbsrv/ndl/eventlog.ndl4
-rw-r--r--usr/src/uts/common/smbsrv/ndl/llsrpc.ndl4
-rw-r--r--usr/src/uts/common/smbsrv/ndl/lsarpc.ndl3
-rw-r--r--usr/src/uts/common/smbsrv/ndl/msgsvc.ndl4
-rw-r--r--usr/src/uts/common/smbsrv/ndl/netdfs.ndl4
-rw-r--r--usr/src/uts/common/smbsrv/ndl/netlogon.ndl2
-rw-r--r--usr/src/uts/common/smbsrv/ndl/samrpc.ndl4
-rw-r--r--usr/src/uts/common/smbsrv/ndl/spoolss.ndl3
-rw-r--r--usr/src/uts/common/smbsrv/ndl/srvsvc.ndl4
-rw-r--r--usr/src/uts/common/smbsrv/ndl/svcctl.ndl4
-rw-r--r--usr/src/uts/common/smbsrv/ndl/winreg.ndl4
-rw-r--r--usr/src/uts/common/smbsrv/netrauth.h2
-rw-r--r--usr/src/uts/common/smbsrv/smb_door.h2
-rw-r--r--usr/src/uts/common/smbsrv/smb_privilege.h2
-rw-r--r--usr/src/uts/common/smbsrv/smb_share.h4
-rw-r--r--usr/src/uts/common/smbsrv/smb_sid.h2
-rw-r--r--usr/src/uts/common/smbsrv/smb_xdr.h3
-rw-r--r--usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/THIRDPARTYLICENSE7
-rw-r--r--usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/THIRDPARTYLICENSE.descrip2
111 files changed, 3328 insertions, 1832 deletions
diff --git a/usr/src/Makefile.master b/usr/src/Makefile.master
index 2e5fd4b51b..70faac9962 100644
--- a/usr/src/Makefile.master
+++ b/usr/src/Makefile.master
@@ -178,6 +178,7 @@ FLEX= /usr/bin/flex
YACC= /usr/ccs/bin/yacc
BISON= /usr/bin/bison
CPP= /usr/lib/cpp
+ANSI_CPP= $(GCC_ROOT)/bin/cpp
JAVAC= $(JAVA_ROOT)/bin/javac
JAVAH= $(JAVA_ROOT)/bin/javah
JAVADOC= $(JAVA_ROOT)/bin/javadoc
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/Makefile b/usr/src/cmd/fs.d/smbclnt/smbutil/Makefile
index 5b751cce22..e20054c772 100644
--- a/usr/src/cmd/fs.d/smbclnt/smbutil/Makefile
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/Makefile
@@ -23,6 +23,8 @@
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
+# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+#
#
# cmd/fs.d/smbclnt/smbutil/Makefile
@@ -30,18 +32,22 @@
PROG= smbutil
-include $(SRC)/cmd/Makefile.cmd
-
-OBJS= smbutil.o login.o lookup.o print.o status.o view.o
+OBJS= smbutil.o info.o login.o lookup.o print.o status.o view.o \
+ shares_rap.o shares_rpc.o srvsvc1_clnt.o srvsvc1_ndr.o
SRCS= $(OBJS:%.o=%.c)
+
+include $(SRC)/cmd/Makefile.cmd
+
POFILE= smbutil_all.po
POFILES= $(OBJS:%.o=%.po)
+
+CLEANFILES += srvsvc1_ndr.c
CLOBBERFILES+= $(POFILE) $(POFILES)
CSTD= $(CSTD_GNU99)
-LDLIBS += -lsmbfs -lnsl
+LDLIBS += -lmlrpc -lsmbfs -lnsl
CPPFLAGS += -I$(SRC)/lib/libsmbfs \
-I$(SRC)/uts/common/smbclnt -I$(SRC)/uts/common
@@ -78,9 +84,12 @@ $(POFILE): $(POFILES)
lint: lint_SRCS
-clean :
- $(RM) $(OBJS)
-
-.KEEP_STATE:
+clean:
+ $(RM) $(OBJS) $(CLEANFILES)
include ../../../Makefile.targ
+
+srvsvc1_ndr.c : srvsvc1.ndl
+ $(NDRGEN) -Y $(ANSI_CPP) $(CPPFLAGS) srvsvc1.ndl
+
+.KEEP_STATE:
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/common.h b/usr/src/cmd/fs.d/smbclnt/smbutil/common.h
index 24cb1436a0..aea093c0ea 100644
--- a/usr/src/cmd/fs.d/smbclnt/smbutil/common.h
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/common.h
@@ -30,6 +30,10 @@
* SUCH DAMAGE.
*/
+/*
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ */
+
#ifndef _SMBUTIL_COMMON_H
#define _SMBUTIL_COMMON_H
@@ -42,6 +46,7 @@ extern "C" {
int cmd_crypt(int argc, char *argv[]);
int cmd_help(int argc, char *argv[]);
+int cmd_info(int argc, char *argv[]);
int cmd_login(int argc, char *argv[]);
int cmd_logout(int argc, char *argv[]);
int cmd_logoutall(int argc, char *argv[]);
@@ -50,8 +55,9 @@ int cmd_print(int argc, char *argv[]);
int cmd_status(int argc, char *argv[]);
int cmd_view(int argc, char *argv[]);
-/* No crypt_usage? */
+void crypt_usage(void);
void help_usage(void);
+void info_usage(void);
void login_usage(void);
void logout_usage(void);
void logoutall_usage(void);
@@ -60,7 +66,10 @@ void print_usage(void);
void status_usage(void);
void view_usage(void);
-extern int loadsmbvfs();
+/* See view.c */
+int share_enum_rap(struct smb_ctx *ctx);
+int share_enum_rpc(struct smb_ctx *ctx, char *server);
+void view_print_share(char *share, int type, char *comment);
#ifdef __cplusplus
}
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/info.c b/usr/src/cmd/fs.d/smbclnt/smbutil/info.c
new file mode 100644
index 0000000000..600df1c1b9
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/info.c
@@ -0,0 +1,212 @@
+/*
+ * 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 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * Show information about the remote server, as offered by
+ * NetServerGetInfo with SERVER_INFO_101
+ */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libintl.h>
+
+#include <libmlrpc/libmlrpc.h>
+#include <netsmb/smb_lib.h>
+#include "srvsvc1_clnt.h"
+#include "common.h"
+
+
+static int get_info(smb_ctx_t *);
+
+void
+info_usage(void)
+{
+ printf(gettext("usage: smbutil info [connection options] //"
+ "[workgroup;][user[:password]@]server\n"));
+ exit(1);
+}
+
+int
+cmd_info(int argc, char *argv[])
+{
+ struct smb_ctx *ctx;
+ int error, err2, opt;
+
+ if (argc < 2)
+ info_usage();
+
+ error = smb_ctx_alloc(&ctx);
+ if (error)
+ return (error);
+
+ error = smb_ctx_scan_argv(ctx, argc, argv,
+ SMBL_SERVER, SMBL_SERVER, USE_WILDCARD);
+ if (error)
+ goto out;
+
+ error = smb_ctx_readrc(ctx);
+ if (error)
+ goto out;
+
+ while ((opt = getopt(argc, argv, STDPARAM_OPT)) != EOF) {
+ if (opt == '?')
+ info_usage();
+ error = smb_ctx_opt(ctx, opt, optarg);
+ if (error)
+ goto out;
+ }
+
+ smb_ctx_setshare(ctx, "IPC$", USE_IPC);
+
+ /*
+ * Resolve the server address,
+ * setup derived defaults.
+ */
+ error = smb_ctx_resolve(ctx);
+ if (error)
+ goto out;
+
+ /*
+ * Have server, share, etc. from above:
+ * smb_ctx_scan_argv, option settings.
+ * Get the session and tree.
+ */
+again:
+ error = smb_ctx_get_ssn(ctx);
+ if (error == EAUTH) {
+ err2 = smb_get_authentication(ctx);
+ if (err2 == 0)
+ goto again;
+ }
+ if (error) {
+ smb_error(gettext("//%s: login failed"),
+ error, ctx->ct_fullserver);
+ goto out;
+ }
+
+ error = smb_ctx_get_tree(ctx);
+ if (error) {
+ smb_error(gettext("//%s/%s: tree connect failed"),
+ error, ctx->ct_fullserver, ctx->ct_origshare);
+ goto out;
+ }
+
+ /*
+ * Have IPC$ tcon. Get the server info.
+ */
+ error = get_info(ctx);
+ if (error)
+ smb_error("cannot get server info.", error);
+
+out:
+ smb_ctx_free(ctx);
+ return (error);
+}
+
+int
+get_info(smb_ctx_t *ctx)
+{
+ char pf_unk[32];
+ mlrpc_handle_t handle;
+ ndr_service_t *svc;
+ union mslm_NetServerGetInfo_ru res;
+ struct mslm_SERVER_INFO_101 *sv101;
+ char *platform_name;
+ int err;
+
+ /*
+ * Create an RPC handle using the smb_ctx we already have.
+ * Just local allocation and initialization.
+ */
+ srvsvc1_initialize();
+ svc = ndr_svc_lookup_name("srvsvc");
+ if (svc == NULL)
+ return (ENOENT);
+
+ err = mlrpc_clh_create(&handle, ctx);
+ if (err)
+ return (err);
+
+ /*
+ * Try to bind to the RPC service. If it fails,
+ * just return the error and the caller will
+ * fall back to RAP.
+ */
+ err = mlrpc_clh_bind(&handle, svc);
+ if (err)
+ goto out;
+
+ err = srvsvc_net_server_getinfo(&handle,
+ ctx->ct_fullserver, 101, &res);
+ if (err)
+ goto out;
+
+ sv101 = res.info101;
+
+ switch (sv101->sv101_platform_id) {
+ case SV_PLATFORM_ID_DOS:
+ platform_name = "DOS";
+ break;
+ case SV_PLATFORM_ID_OS2:
+ platform_name = "OS2";
+ break;
+ case SV_PLATFORM_ID_NT:
+ platform_name = "NT";
+ break;
+ case SV_PLATFORM_ID_OSF:
+ platform_name = "OSF";
+ break;
+ case SV_PLATFORM_ID_VMS:
+ platform_name = "VMS";
+ break;
+ default:
+ platform_name = pf_unk;
+ snprintf(pf_unk, sizeof (pf_unk), "(%d)",
+ sv101->sv101_platform_id);
+ break;
+ }
+
+ printf("server info:\n");
+ printf(" platform_id %s\n", platform_name);
+ printf(" vers.major %d\n", sv101->sv101_version_major);
+ printf(" vers.minor %d\n", sv101->sv101_version_minor);
+
+ if (smb_verbose)
+ printf(" type_flags 0x%x\n", sv101->sv101_type);
+
+ printf(" name \"%s\"\n", sv101->sv101_name);
+ printf(" comment \"%s\"\n", sv101->sv101_comment);
+
+out:
+ (void) mlrpc_clh_free(&handle);
+ return (err);
+}
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/shares_rap.c b/usr/src/cmd/fs.d/smbclnt/smbutil/shares_rap.c
new file mode 100644
index 0000000000..f2235e2880
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/shares_rap.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2000-2002, Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Id: view.c,v 1.9 2002/02/20 09:26:42 bp Exp
+ */
+
+/*
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netsmb/mchain.h> /* letohs, etc. */
+#include <netsmb/smb.h>
+#include <netsmb/smb_lib.h>
+#include <netsmb/smb_rap.h>
+
+#include "common.h"
+
+/*
+ * Enumerate shares using Remote Administration Protocol (RAP)
+ * Was in libsmbfs netshareenum.c
+ */
+
+struct smb_share_info_1 {
+ char shi1_netname[13];
+ char shi1_pad;
+ uint16_t shi1_type;
+ uint32_t shi1_remark; /* char * */
+};
+
+static int
+smb_rap_NetShareEnum(struct smb_ctx *ctx, int sLevel, void *pbBuffer,
+ int *cbBuffer, int *pcEntriesRead, int *pcTotalAvail)
+{
+ struct smb_rap *rap;
+ long lval = -1;
+ int error;
+
+ error = smb_rap_create(0, "WrLeh", "B13BWz", &rap);
+ if (error)
+ return (error);
+ smb_rap_setNparam(rap, sLevel); /* W - sLevel */
+ smb_rap_setPparam(rap, pbBuffer); /* r - pbBuffer */
+ smb_rap_setNparam(rap, *cbBuffer); /* L - cbBuffer */
+ error = smb_rap_request(rap, ctx);
+ if (error == 0) {
+ *pcEntriesRead = rap->r_entries;
+ error = smb_rap_getNparam(rap, &lval);
+ *pcTotalAvail = lval;
+ /* Copy the data length into the IN/OUT variable. */
+ *cbBuffer = rap->r_rcvbuflen;
+ }
+ error = smb_rap_error(rap, error);
+ smb_rap_done(rap);
+ return (error);
+}
+
+int
+share_enum_rap(smb_ctx_t *ctx)
+{
+ struct smb_share_info_1 *shi;
+ void *rpbuf;
+ char *cp;
+ int error, bufsize, i, rcnt, total;
+ int lbound, rbound;
+ uint16_t type;
+
+ bufsize = 0xffe0; /* samba notes win2k bug for 65535 */
+ rpbuf = malloc(bufsize);
+ if (rpbuf == NULL)
+ return (errno);
+
+ error = smb_rap_NetShareEnum(ctx, 1, rpbuf, &bufsize, &rcnt, &total);
+ if (error &&
+ error != (ERROR_MORE_DATA | SMB_RAP_ERROR))
+ goto out;
+
+ /*
+ * Bounds for offsets to comments strings.
+ * After the array, and before the end.
+ */
+ lbound = rcnt * (sizeof (struct smb_share_info_1));
+ rbound = bufsize;
+
+ /* Print the header line. */
+ view_print_share(NULL, 0, NULL);
+
+ for (shi = rpbuf, i = 0; i < rcnt; i++, shi++) {
+ type = letohs(shi->shi1_type);
+
+ shi->shi1_pad = '\0'; /* ensure null termination */
+
+ /*
+ * Offsets to comment strings can be trash.
+ * Only print when the offset is valid.
+ */
+ if (shi->shi1_remark >= lbound &&
+ shi->shi1_remark < rbound) {
+ cp = (char *)rpbuf + shi->shi1_remark;
+ } else
+ cp = NULL;
+
+ /* Convert from OEM to local codeset? */
+ view_print_share(shi->shi1_netname, type, cp);
+ }
+ error = 0;
+
+out:
+ free(rpbuf);
+ return (error);
+}
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/shares_rpc.c b/usr/src/cmd/fs.d/smbclnt/smbutil/shares_rpc.c
new file mode 100644
index 0000000000..221d6f077b
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/shares_rpc.c
@@ -0,0 +1,83 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * Share enumeration using Remote Procedure Call (RPC)
+ */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libmlrpc/libmlrpc.h>
+#include <netsmb/smbfs_api.h>
+#include "srvsvc1_clnt.h"
+#include "common.h"
+
+int
+share_enum_rpc(struct smb_ctx *ctx, char *server)
+{
+ mlrpc_handle_t handle;
+ ndr_service_t *svc;
+ union mslm_NetShareEnum_ru res;
+ struct mslm_NetShareInfo_1 *nsi1;
+ int err, i, count;
+
+ /*
+ * Create an RPC handle using the smb_ctx we already have.
+ * Just local allocation and initialization.
+ */
+ srvsvc1_initialize();
+ svc = ndr_svc_lookup_name("srvsvc");
+ if (svc == NULL)
+ return (ENOENT);
+
+ err = mlrpc_clh_create(&handle, ctx);
+ if (err)
+ return (err);
+
+ /*
+ * Try to bind to the RPC service. If it fails,
+ * just return the error and the caller will
+ * fall back to RAP.
+ */
+ err = mlrpc_clh_bind(&handle, svc);
+ if (err)
+ goto out;
+
+ err = srvsvc_net_share_enum(&handle, server, 1, &res);
+ if (err)
+ goto out;
+
+ /* Print the header line. */
+ view_print_share(NULL, 0, NULL);
+
+ /* Print the share list. */
+ count = res.bufptr1->entriesread;
+ i = 0, nsi1 = res.bufptr1->entries;
+ while (i < count) {
+ /* Convert UTF-8 to local code set? */
+ view_print_share((char *)nsi1->shi1_netname,
+ nsi1->shi1_type, (char *)nsi1->shi1_comment);
+ i++, nsi1++;
+ }
+
+out:
+ (void) mlrpc_clh_free(&handle);
+ return (err);
+}
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/smbutil.c b/usr/src/cmd/fs.d/smbclnt/smbutil/smbutil.c
index 20cb3a2c86..9b09b87d64 100644
--- a/usr/src/cmd/fs.d/smbclnt/smbutil/smbutil.c
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/smbutil.c
@@ -33,6 +33,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/param.h>
@@ -65,10 +67,11 @@ static struct commands {
const char *name;
cmd_fn_t *fn;
cmd_usage_t *usage;
- int flags;
+ int flags;
} commands[] = {
{"crypt", cmd_crypt, NULL, CMDFL_NO_KMOD},
{"help", cmd_help, help_usage, CMDFL_NO_KMOD},
+ {"info", cmd_info, info_usage, 0},
{"login", cmd_login, login_usage, 0},
{"logout", cmd_logout, logout_usage, 0},
{"logoutall", cmd_logoutall, logoutall_usage, 0},
@@ -187,13 +190,14 @@ help(void) {
printf(gettext("where subcommands are:\n"
" crypt slightly obscure password\n"
" help display help on specified subcommand\n"
- /* " lc display active connections\n" */
+ /* " lc display active connections\n" */
+ " info display server type and version\n"
" login login to specified host\n"
- " logout logout from specified host\n"
+ " logout logout from specified host\n"
" logoutall logout all users (requires privilege)\n"
- " lookup resolve NetBIOS name to IP address\n"
+ " lookup resolve NetBIOS name to IP address\n"
" print print file to the specified remote printer\n"
- " status resolve IP address or DNS name to NetBIOS names\n"
+ " status resolve IP address or DNS name to NetBIOS names\n"
" view list resources on specified host\n"
"\n"));
exit(1);
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/srvsvc1.ndl b/usr/src/cmd/fs.d/smbclnt/smbutil/srvsvc1.ndl
new file mode 100644
index 0000000000..6712f05020
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/srvsvc1.ndl
@@ -0,0 +1,177 @@
+/*
+ * 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 2013 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * SRVSVC - Server Service (partial)
+ *
+ * This module needs only NetShareEnum (levels 0, 1)
+ * and NetServerGetInfo (levels 100, 101)
+ */
+
+#include <libmlrpc/ndrtypes.ndl>
+
+/*
+ * SRVSVC - Server Service
+ */
+
+#define SRVSVC_OPNUM_NetShareEnum 0x0f
+#define SRVSVC_OPNUM_NetServerGetInfo 0x15
+
+/*
+ * SRVSVC NetShareEnum (
+ * IN LPTSTR servername,
+ * IN DWORD level;
+ * OUT union switch(level) {
+ * case 0: struct {
+ * DWORD entriesread;
+ * [size_is(entriesread)]
+ * _SHARE_INFO_0 *entries;
+ * } *bufptr0;
+ * case 1: struct {
+ * DWORD entriesread;
+ * [size_is(entriesread)]
+ * _SHARE_INFO_1 *entries;
+ * } *bufptr1;
+ * ...
+ * } bufptr,
+ * IN DWORD prefmaxlen,
+ * OUT DWORD totalentries,
+ * IN OUT DWORD ?* resume_handle,
+ * OUT DWORD status
+ * )
+ */
+
+struct mslm_NetShareInfo_0 {
+ LPTSTR shi0_netname;
+};
+struct mslm_NetShareInfo_0_result {
+ DWORD entriesread;
+ SIZE_IS(entriesread)
+ struct mslm_NetShareInfo_0 *entries;
+};
+
+struct mslm_NetShareInfo_1 {
+ LPTSTR shi1_netname;
+ DWORD shi1_type; /* type of resource such as IPC$ */
+ LPTSTR shi1_comment;
+};
+struct mslm_NetShareInfo_1_result {
+ DWORD entriesread;
+ SIZE_IS(entriesread)
+ struct mslm_NetShareInfo_1 *entries;
+};
+
+union mslm_NetShareEnum_ru {
+ CASE(0) struct mslm_NetShareInfo_0_result *bufptr0;
+ CASE(1) struct mslm_NetShareInfo_1_result *bufptr1;
+ DEFAULT char *nullptr;
+};
+struct mslm_NetShareEnum_result {
+ DWORD level;
+ SWITCH(level)
+ union mslm_NetShareEnum_ru ru;
+};
+
+
+OPERATION(SRVSVC_OPNUM_NetShareEnum)
+struct mslm_NetShareEnum {
+ IN LPTSTR servername;
+ INOUT DWORD level;
+ INOUT struct mslm_NetShareEnum_result result;
+ IN DWORD prefmaxlen;
+ OUT DWORD totalentries;
+ INOUT DWORD *resume_handle;
+ OUT DWORD status;
+};
+
+
+/*
+ * SRVSVC NetServerGetInfo (
+ * IN LPTSTR servername,
+ * IN DWORD level,
+ * OUT union switch(level) {
+ * case 100: _SERVER_INFO_100 * p100;
+ * case 101: _SERVER_INFO_101 * p101;
+ * case 102: _SERVER_INFO_102 * p102;
+ * } bufptr,
+ * OUT DWORD status
+ * )
+ */
+
+/* for svX_platform (note: decimal!) */
+#define SV_PLATFORM_ID_DOS 300
+#define SV_PLATFORM_ID_OS2 400
+#define SV_PLATFORM_ID_NT 500
+#define SV_PLATFORM_ID_OSF 600
+#define SV_PLATFORM_ID_VMS 700
+
+struct mslm_SERVER_INFO_100 {
+ DWORD sv100_platform_id;
+ LPTSTR sv100_name;
+};
+
+struct mslm_SERVER_INFO_101 {
+ DWORD sv101_platform_id;
+ LPTSTR sv101_name;
+ DWORD sv101_version_major;
+ DWORD sv101_version_minor;
+ DWORD sv101_type;
+ LPTSTR sv101_comment;
+};
+
+union mslm_NetServerGetInfo_ru {
+ CASE(100) struct mslm_SERVER_INFO_100 *info100;
+ CASE(101) struct mslm_SERVER_INFO_101 *info101;
+ DEFAULT char *nullptr;
+};
+
+struct mslm_NetServerGetInfo_result {
+ DWORD level;
+ SWITCH(level)
+ union mslm_NetServerGetInfo_ru ru;
+};
+
+
+OPERATION(SRVSVC_OPNUM_NetServerGetInfo)
+struct mslm_NetServerGetInfo {
+ IN LPTSTR servername;
+ IN DWORD level;
+ OUT struct mslm_NetServerGetInfo_result result;
+ OUT DWORD status;
+};
+
+
+/*
+ * The SRVSVC interface
+ */
+INTERFACE(0)
+union srvsvc_interface {
+ CASE(SRVSVC_OPNUM_NetShareEnum)
+ struct mslm_NetShareEnum NetShareEnum;
+ CASE(SRVSVC_OPNUM_NetServerGetInfo)
+ struct mslm_NetServerGetInfo NetServerGetInfo;
+};
+typedef union srvsvc_interface srvsvc_interface_t;
+EXTERNTYPEINFO(srvsvc_interface)
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/srvsvc1_clnt.c b/usr/src/cmd/fs.d/smbclnt/smbutil/srvsvc1_clnt.c
new file mode 100644
index 0000000000..7ebe614ab6
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/srvsvc1_clnt.c
@@ -0,0 +1,138 @@
+/*
+ * 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 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * A few excerpts from lib/smbsrv/libmlsvc
+ * See longer comment in srvsvc1.ndl
+ */
+
+#include <sys/errno.h>
+#include <stdio.h>
+#include <time.h>
+#include <strings.h>
+#include <time.h>
+
+#include <libmlrpc/libmlrpc.h>
+#include "srvsvc1_clnt.h"
+
+static ndr_service_t srvsvc_service = {
+ "SRVSVC", /* name */
+ "Server services", /* desc */
+ "\\srvsvc", /* endpoint */
+ "\\PIPE\\ntsvcs", /* sec_addr_port */
+ "4b324fc8-1670-01d3-1278-5a47bf6ee188", 3, /* abstract */
+ NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */
+ 0, /* no bind_instance_size */
+ 0, /* no bind_req() */
+ 0, /* no unbind_and_close() */
+ 0, /* use generic_call_stub() */
+ &TYPEINFO(srvsvc_interface), /* interface_ti */
+ NULL /* stub_table */
+};
+
+/*
+ * srvsvc_initialize
+ *
+ * This function registers the SRVSVC RPC interface with the RPC runtime
+ * library. It must be called in order to use either the client side
+ * or the server side functions.
+ */
+void
+srvsvc1_initialize(void)
+{
+ static int init_done;
+ if (init_done)
+ return;
+ init_done = 1;
+ (void) ndr_svc_register(&srvsvc_service);
+}
+
+/*
+ * Client-side stub for NetServerGetInfo
+ */
+int
+srvsvc_net_server_getinfo(mlrpc_handle_t *handle, char *server,
+ int level, union mslm_NetServerGetInfo_ru *resp)
+{
+ struct mslm_NetServerGetInfo arg;
+ int len, opnum, rc;
+
+ opnum = SRVSVC_OPNUM_NetServerGetInfo;
+ bzero(&arg, sizeof (arg));
+
+ len = strlen(server) + 4;
+ arg.servername = ndr_rpc_malloc(handle, len);
+ if (arg.servername == NULL)
+ return (ENOMEM);
+
+ (void) snprintf((char *)arg.servername, len, "\\\\%s", server);
+ arg.level = level;
+
+ rc = ndr_rpc_call(handle, opnum, &arg);
+ if ((rc != 0) || (arg.status != 0))
+ return (EIO);
+
+ *resp = arg.result.ru;
+ return (0);
+}
+
+/*
+ * Client-side stub for NetShareEnum
+ */
+int
+srvsvc_net_share_enum(mlrpc_handle_t *handle, char *server,
+ int level, union mslm_NetShareEnum_ru *resp)
+{
+ /* Any enum result type is OK for nres. */
+ struct mslm_NetShareInfo_0_result nres;
+ struct mslm_NetShareEnum arg;
+ int len, opnum, rc;
+
+ opnum = SRVSVC_OPNUM_NetShareEnum;
+ bzero(&nres, sizeof (nres));
+ bzero(&arg, sizeof (arg));
+
+ len = strlen(server) + 4;
+ arg.servername = ndr_rpc_malloc(handle, len);
+ if (arg.servername == NULL)
+ return (ENOMEM);
+
+ (void) snprintf((char *)arg.servername, len, "\\\\%s", server);
+ arg.level = level;
+ arg.result.level = level;
+ arg.result.ru.bufptr0 = &nres;
+ arg.prefmaxlen = 0xFFFFFFFF;
+ arg.resume_handle = NULL;
+
+ rc = ndr_rpc_call(handle, opnum, &arg);
+ if ((rc != 0) || (arg.status != 0))
+ return (EIO);
+
+ *resp = arg.result.ru;
+ return (0);
+}
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/srvsvc1_clnt.h b/usr/src/cmd/fs.d/smbclnt/smbutil/srvsvc1_clnt.h
new file mode 100644
index 0000000000..66e50a8ab5
--- /dev/null
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/srvsvc1_clnt.h
@@ -0,0 +1,46 @@
+/*
+ * 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 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ */
+
+#ifndef _SRVSVC1_CLNT_H
+#define _SRVSVC1_CLNT_H
+
+/*
+ * Excerpts from lib/smbsrv/libmlsvc
+ * Just enough for share enumeration.
+ */
+
+#include <libmlrpc/libmlrpc.h>
+#include "srvsvc1.ndl"
+
+void srvsvc1_initialize(void);
+int srvsvc_net_share_enum(mlrpc_handle_t *handle, char *server,
+ int level, union mslm_NetShareEnum_ru *resp);
+int srvsvc_net_server_getinfo(mlrpc_handle_t *handle, char *server,
+ int level, union mslm_NetServerGetInfo_ru *resp);
+
+#endif /* _SRVSVC1_CLNT_H */
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/view.c b/usr/src/cmd/fs.d/smbclnt/smbutil/view.c
index baad53b00c..8622fb14be 100644
--- a/usr/src/cmd/fs.d/smbclnt/smbutil/view.c
+++ b/usr/src/cmd/fs.d/smbclnt/smbutil/view.c
@@ -34,6 +34,7 @@
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
@@ -48,12 +49,9 @@
#include <netsmb/smb.h>
#include <netsmb/smb_lib.h>
-#include <netsmb/smb_netshareenum.h>
-
#include "common.h"
-int enum_shares(smb_ctx_t *);
-void print_shares(int, int, struct share_info *);
+static int use_rap;
void
view_usage(void)
@@ -79,18 +77,27 @@ cmd_view(int argc, char *argv[])
error = smb_ctx_scan_argv(ctx, argc, argv,
SMBL_SERVER, SMBL_SERVER, USE_WILDCARD);
if (error)
- return (error);
+ goto out;
error = smb_ctx_readrc(ctx);
if (error)
- return (error);
+ goto out;
while ((opt = getopt(argc, argv, STDPARAM_OPT)) != EOF) {
if (opt == '?')
view_usage();
+ /*
+ * This is an undocumented option, just for testing.
+ * Use the old LanMan Remote API Protocol (RAP) for
+ * enumerating shares.
+ */
+ if (opt == 'B') {
+ use_rap++;
+ continue;
+ }
error = smb_ctx_opt(ctx, opt, optarg);
if (error)
- return (error);
+ goto out;
}
smb_ctx_setshare(ctx, "IPC$", USE_IPC);
@@ -101,7 +108,7 @@ cmd_view(int argc, char *argv[])
*/
error = smb_ctx_resolve(ctx);
if (error)
- return (error);
+ goto out;
/*
* Have server, share, etc. from above:
@@ -118,24 +125,26 @@ again:
if (error) {
smb_error(gettext("//%s: login failed"),
error, ctx->ct_fullserver);
- return (error);
+ goto out;
}
error = smb_ctx_get_tree(ctx);
if (error) {
smb_error(gettext("//%s/%s: tree connect failed"),
error, ctx->ct_fullserver, ctx->ct_origshare);
- return (error);
+ goto out;
}
/*
* Have IPC$ tcon, now list shares.
- * This prints its own errors.
+ * Try RPC; if that fails, do RAP.
*/
- error = enum_shares(ctx);
- if (error)
- return (error);
+ if (!use_rap)
+ error = share_enum_rpc(ctx, ctx->ct_fullserver);
+ if (error || use_rap)
+ error = share_enum_rap(ctx);
+out:
smb_ctx_free(ctx);
return (0);
}
@@ -145,7 +154,7 @@ static char *shtype[] = {
gettext("disk"),
gettext("printer"),
gettext("device"), /* Communications device */
- gettext("IPC"), /* Inter process communication */
+ gettext("IPC"), /* Inter process communication */
gettext("unknown")
};
#else
@@ -153,53 +162,34 @@ static char *shtype[] = {
"disk",
"printer",
"device", /* Communications device */
- "IPC", /* IPC Inter process communication */
+ "IPC", /* IPC Inter process communication */
"unknown"
};
#endif
-int
-enum_shares(smb_ctx_t *ctx)
+/*
+ * Print one line of the share list, or
+ * if SHARE is null, print the header line.
+ */
+void
+view_print_share(char *share, int type, char *comment)
{
- struct share_info *share_info;
- int error, entries, total;
+ char *stname;
+ int stindex;
- /*
- * XXX: Later, try RPC first,
- * then fall back to RAP...
- */
- error = smb_netshareenum(ctx, &entries, &total, &share_info);
- if (error) {
- smb_error(gettext("//%s failed to list shares"),
- error, ctx->ct_fullserver);
- return (error);
+ if (share == NULL) {
+ printf(gettext("Share Type Comment\n"));
+ printf("-------------------------------\n");
+ return;
}
- print_shares(entries, total, share_info);
- return (0);
-}
-void
-print_shares(int entries, int total,
- struct share_info *share_info)
-{
- struct share_info *ep;
- int i;
-
- printf(gettext("Share Type Comment\n"));
- printf("-------------------------------\n");
-
- for (ep = share_info, i = 0; i < entries; i++, ep++) {
- int sti = ep->type & STYPE_MASK;
- if (sti > STYPE_UNKNOWN)
- sti = STYPE_UNKNOWN;
- printf("%-12s %-10s %s\n", ep->netname,
- gettext(shtype[sti]),
- ep->remark ? ep->remark : "");
- free(ep->netname);
- free(ep->remark);
- }
- printf(gettext("\n%d shares listed from %d available\n"),
- entries, total);
+ stindex = type & STYPE_MASK;
+ if (stindex > STYPE_UNKNOWN)
+ stindex = STYPE_UNKNOWN;
+ stname = gettext(shtype[stindex]);
+
+ if (comment == NULL)
+ comment = "";
- free(share_info);
+ printf("%-12s %-10s %s\n", share, stname, comment);
}
diff --git a/usr/src/cmd/mdb/common/modules/zfs/zfs.c b/usr/src/cmd/mdb/common/modules/zfs/zfs.c
index 5d3af7ff3c..ad66d688ea 100644
--- a/usr/src/cmd/mdb/common/modules/zfs/zfs.c
+++ b/usr/src/cmd/mdb/common/modules/zfs/zfs.c
@@ -21,8 +21,8 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
* Copyright (c) 2017, Joyent, Inc. All rights reserved.
- * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
*/
/* Portions Copyright 2010 Robert Milkowski */
@@ -1727,6 +1727,7 @@ typedef struct mdb_metaslab_alloc_trace {
uint64_t mat_weight;
uint64_t mat_offset;
uint32_t mat_dva_id;
+ int mat_allocator;
} mdb_metaslab_alloc_trace_t;
static void
@@ -1799,8 +1800,9 @@ metaslab_trace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
}
if (!(flags & DCMD_PIPE_OUT) && DCMD_HDRSPEC(flags)) {
- mdb_printf("%<u>%6s %6s %8s %11s %18s %18s%</u>\n",
- "MSID", "DVA", "ASIZE", "WEIGHT", "RESULT", "VDEV");
+ mdb_printf("%<u>%6s %6s %8s %11s %11s %18s %18s%</u>\n",
+ "MSID", "DVA", "ASIZE", "ALLOCATOR", "WEIGHT", "RESULT",
+ "VDEV");
}
if (mat.mat_msp != NULL) {
@@ -1815,7 +1817,8 @@ metaslab_trace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
mdb_printf("%6s ", "-");
}
- mdb_printf("%6d %8llx ", mat.mat_dva_id, mat.mat_size);
+ mdb_printf("%6d %8llx %11llx ", mat.mat_dva_id, mat.mat_size,
+ mat.mat_allocator);
metaslab_print_weight(mat.mat_weight);
diff --git a/usr/src/common/smbsrv/smb_door_legacy.c b/usr/src/common/smbsrv/smb_door_legacy.c
index 985b83eb7a..ae1e557db8 100644
--- a/usr/src/common/smbsrv/smb_door_legacy.c
+++ b/usr/src/common/smbsrv/smb_door_legacy.c
@@ -39,7 +39,7 @@
#include <sys/errno.h>
#endif
-#include <smbsrv/wintypes.h>
+#include <smb/wintypes.h>
#include <smbsrv/smb_share.h>
#include <smbsrv/smb_door.h>
#include <smbsrv/alloc.h>
diff --git a/usr/src/common/smbsrv/smb_token_xdr.c b/usr/src/common/smbsrv/smb_token_xdr.c
index fdad7ed5ca..b2f5a92352 100644
--- a/usr/src/common/smbsrv/smb_token_xdr.c
+++ b/usr/src/common/smbsrv/smb_token_xdr.c
@@ -32,7 +32,7 @@
#if !defined(_KERNEL) && !defined(_FAKE_KERNEL)
#include <stdlib.h>
#endif /* !_KERNEL */
-#include <smbsrv/wintypes.h>
+#include <smb/wintypes.h>
#include <smbsrv/smb_sid.h>
#include <smbsrv/smb_xdr.h>
#include <smbsrv/smb_token.h>
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile
index 0054c41e6d..445238f973 100644
--- a/usr/src/lib/Makefile
+++ b/usr/src/lib/Makefile
@@ -166,6 +166,7 @@ SUBDIRS += \
libmapid \
libmapmalloc \
libmd5 \
+ libmlrpc \
libmtmalloc \
libmvec \
libndmp \
@@ -432,6 +433,7 @@ HDRSUBDIRS= \
libmail \
libmapid \
libmd \
+ libmlrpc \
libmtmalloc \
libndmp \
libnsctl \
@@ -642,6 +644,7 @@ libkmf: libcryptoutil pkcs11
libkvm: ../cmd/sgs/libelf
libldap5: libsasl
libmapid: libresolv2 libscf
+libmlrpc: libsmbfs libuuid
libndmp: libscf
libnisdb: libldap5
libnwam: libscf libbsm libdladm libipadm
@@ -714,7 +717,7 @@ sasl_plugins: pkcs11 libgss libsasl
scsi: libfru libumem libdevid libdevinfo
smbsrv: libxnet libpthread librt libshare libidmap pkcs11 libsqlite \
libcryptoutil libreparse libcmdutils libresolv2 libsmbfs \
- libuuid libfakekernel libads libgss libldap5 krb5
+ libuuid libfakekernel libads libgss libldap5 krb5 libmlrpc
storage: libdevice libdevinfo libdevid
sun_fc: libdevinfo libsysevent
sun_sas: libdevinfo libsysevent libkstat libdevid
diff --git a/usr/src/lib/libmlrpc/Makefile b/usr/src/lib/libmlrpc/Makefile
new file mode 100644
index 0000000000..ae458ebc7a
--- /dev/null
+++ b/usr/src/lib/libmlrpc/Makefile
@@ -0,0 +1,65 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+#
+
+include $(SRC)/lib/Makefile.lib
+
+HDRS= libmlrpc.h ndr.h ndrtypes.ndl rpcpdu.ndl
+HDRDIR= common
+
+ROOTHDRDIR= $(ROOT)/usr/include/libmlrpc
+ROOTHDRS= $(HDRS:%=$(ROOTHDRDIR)/%)
+
+# ISA targets
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+all := TARGET = all
+install := TARGET = install
+clean := TARGET = clean
+clobber := TARGET = clobber
+lint := TARGET = lint
+
+.KEEP_STATE:
+
+all install clean clobber lint: $(SUBDIRS)
+
+install_h: $(ROOTHDRDIR) $(ROOTHDRS)
+
+check: $(CHECKHDRS)
+
+$(ROOTHDRDIR)/%: %
+ $(INS.file)
+
+$(ROOTHDRDIR):
+ $(INS.dir)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; VERSION='$(VERSION)' $(MAKE) $(TARGET)
+
+FRC:
+
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/lib/smbsrv/libmlrpc/Makefile.com b/usr/src/lib/libmlrpc/Makefile.com
index fa45211464..1a2ecb4ddd 100644
--- a/usr/src/lib/smbsrv/libmlrpc/Makefile.com
+++ b/usr/src/lib/libmlrpc/Makefile.com
@@ -18,39 +18,58 @@
#
# CDDL HEADER END
#
+
#
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
+# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+#
LIBRARY = libmlrpc.a
-VERS = .1
+VERS = .2
-OBJS_COMMON = \
+OBJS_COMMON = \
+ mlrpc_clh.o \
ndr_client.o \
ndr_heap.o \
ndr_marshal.o \
ndr_ops.o \
ndr_process.o \
ndr_server.o \
- ndr_svc.o
+ ndr_svc.o \
+ ndr_wchar.o
NDLLIST = rpcpdu
-OBJECTS= $(OBJS_COMMON) $(OBJS_SHARED) $(NDLLIST:%=%_ndr.o)
+OBJECTS= $(OBJS_COMMON) $(NDLLIST:%=%_ndr.o)
+CLEANFILES += $(NDLLIST:%=%_ndr.c)
-include ../../../Makefile.lib
include ../../Makefile.lib
-INCS += -I$(SRC)/common/smbsrv
+LIBS= $(DYNLIB) $(LINTLIB)
+
+LDLIBS += -lsmbfs -luuid -lc
+
+SRCDIR= ../common
+SRCS= $(OBJS_COMMON:%.o=$(SRCDIR)/%.c)
+$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
-LDLIBS += $(MACH_LDLIBS)
-LDLIBS += -lsmb -luuid -lc
+NDLDIR = $(SRCDIR)
+CFLAGS += $(CCVERBOSE)
+INCS = -I. -I$(SRCDIR)
CPPFLAGS += $(INCS) -D_REENTRANT
-SRCS= $(OBJS_COMMON:%.o=$(SRCDIR)/%.c) \
- $(OBJS_SHARED:%.o=$(SRC)/common/smbsrv/%.c)
+all: $(LIBS)
+
+lint: lintcheck
include ../../Makefile.targ
-include ../../../Makefile.targ
+
+objs/%_ndr.o pics/%_ndr.o : %_ndr.c
+
+%_ndr.c : $(NDLDIR)/%.ndl
+ $(NDRGEN) -Y $(ANSI_CPP) $(CPPFLAGS) $<
+
+.KEEP_STATE:
diff --git a/usr/src/lib/smbsrv/libmlrpc/amd64/Makefile b/usr/src/lib/libmlrpc/amd64/Makefile
index b3c4916b0c..087f0e1107 100644
--- a/usr/src/lib/smbsrv/libmlrpc/amd64/Makefile
+++ b/usr/src/lib/libmlrpc/amd64/Makefile
@@ -22,14 +22,10 @@
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
MACH_LDLIBS += -L$(ROOT)/usr/lib/smbsrv/$(MACH64)
include ../Makefile.com
-include ../../../Makefile.lib.64
-
-DYNFLAGS += -R/usr/lib/smbsrv/$(MACH64)
+include ../../Makefile.lib.64
install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h b/usr/src/lib/libmlrpc/common/libmlrpc.h
index 5b55ce4c54..d020532cbe 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h
+++ b/usr/src/lib/libmlrpc/common/libmlrpc.h
@@ -28,10 +28,9 @@
#include <sys/types.h>
#include <sys/uio.h>
-#include <smbsrv/wintypes.h>
-#include <smbsrv/ndr.h>
-#include <smbsrv/smb_sid.h>
-#include <smbsrv/smb_xdr.h>
+
+#include <smb/wintypes.h>
+#include <libmlrpc/ndr.h>
#ifdef __cplusplus
extern "C" {
@@ -247,9 +246,9 @@ typedef struct ndr_binding {
#define NDR_N_BINDING_POOL 2
typedef struct ndr_pipe {
- void *np_listener;
+ void *np_listener;
const char *np_endpoint;
- smb_netuserinfo_t *np_user;
+ struct smb_netuserinfo *np_user;
int (*np_send)(struct ndr_pipe *, void *, size_t);
int (*np_recv)(struct ndr_pipe *, void *, size_t);
int np_fid;
@@ -402,12 +401,12 @@ typedef struct ndr_vcbuf {
ndr_heap_t *ndr_heap_create(void);
void ndr_heap_destroy(ndr_heap_t *);
+void *ndr_heap_dupmem(ndr_heap_t *, const void *, size_t);
void *ndr_heap_malloc(ndr_heap_t *, unsigned);
void *ndr_heap_strdup(ndr_heap_t *, const char *);
int ndr_heap_mstring(ndr_heap_t *, const char *, ndr_mstring_t *);
void ndr_heap_mkvcs(ndr_heap_t *, char *, ndr_vcstr_t *);
void ndr_heap_mkvcb(ndr_heap_t *, uint8_t *, uint32_t, ndr_vcbuf_t *);
-smb_sid_t *ndr_heap_siddup(ndr_heap_t *, smb_sid_t *);
int ndr_heap_used(ndr_heap_t *);
int ndr_heap_avail(ndr_heap_t *);
@@ -416,7 +415,7 @@ int ndr_heap_avail(ndr_heap_t *);
#define NDR_NEWN(XA, T, N) ndr_heap_malloc((XA)->heap, sizeof (T)*(N))
#define NDR_STRDUP(XA, S) ndr_heap_strdup((XA)->heap, (S))
#define NDR_MSTRING(XA, S, OUT) ndr_heap_mstring((XA)->heap, (S), (OUT))
-#define NDR_SIDDUP(XA, S) ndr_heap_siddup((XA)->heap, (S))
+#define NDR_SIDDUP(XA, S) ndr_heap_dupmem((XA)->heap, (S), smb_sid_len(S))
typedef struct ndr_xa {
unsigned short ptype; /* high bits special */
@@ -488,7 +487,7 @@ void nds_destruct(ndr_stream_t *);
void nds_show_state(ndr_stream_t *);
/* ndr_client.c */
-int ndr_clnt_bind(ndr_client_t *, const char *, ndr_binding_t **);
+int ndr_clnt_bind(ndr_client_t *, ndr_service_t *, ndr_binding_t **);
int ndr_clnt_call(ndr_binding_t *, int, void *);
void ndr_clnt_free_heap(ndr_client_t *);
@@ -514,10 +513,6 @@ void ndr_pipe_worker(ndr_pipe_t *);
int ndr_generic_call_stub(ndr_xa_t *);
-boolean_t ndr_is_admin(ndr_xa_t *);
-boolean_t ndr_is_poweruser(ndr_xa_t *);
-int32_t ndr_native_os(ndr_xa_t *);
-
/* ndr_svc.c */
ndr_stub_table_t *ndr_svc_find_stub(ndr_service_t *, int);
ndr_service_t *ndr_svc_lookup_name(const char *);
@@ -538,6 +533,38 @@ void ndr_hdclose(ndr_pipe_t *);
ssize_t ndr_uiomove(caddr_t, size_t, enum uio_rw, struct uio *);
+/*
+ * An ndr_client_t is created while binding a client connection to hold
+ * the context for calls made using that connection.
+ *
+ * Handles are RPC call specific and we use an inheritance mechanism to
+ * ensure that each handle has a pointer to the client_t. When the top
+ * level (bind) handle is released, we close the connection.
+ *
+ * There are some places in libmlsvc where the code assumes that the
+ * handle member is first in this struct. careful
+ */
+typedef struct mlrpc_handle {
+ ndr_hdid_t handle; /* keep first */
+ ndr_client_t *clnt;
+} mlrpc_handle_t;
+
+int mlrpc_clh_create(mlrpc_handle_t *, void *);
+uint32_t mlrpc_clh_bind(mlrpc_handle_t *, ndr_service_t *);
+void mlrpc_clh_unbind(mlrpc_handle_t *);
+void *mlrpc_clh_free(mlrpc_handle_t *);
+
+int ndr_rpc_call(mlrpc_handle_t *, int, void *);
+int ndr_rpc_get_ssnkey(mlrpc_handle_t *, unsigned char *, size_t);
+void *ndr_rpc_malloc(mlrpc_handle_t *, size_t);
+ndr_heap_t *ndr_rpc_get_heap(mlrpc_handle_t *);
+void ndr_rpc_release(mlrpc_handle_t *);
+void ndr_rpc_set_nonull(mlrpc_handle_t *);
+
+boolean_t ndr_is_null_handle(mlrpc_handle_t *);
+boolean_t ndr_is_bind_handle(mlrpc_handle_t *);
+void ndr_inherit_handle(mlrpc_handle_t *, mlrpc_handle_t *);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/llib-lmlrpc b/usr/src/lib/libmlrpc/common/llib-lmlrpc
index 1621e3c2f6..3345e6129a 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/llib-lmlrpc
+++ b/usr/src/lib/libmlrpc/common/llib-lmlrpc
@@ -21,11 +21,11 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*LINTLIBRARY*/
/*PROTOLIB1*/
-#include <smbsrv/libmlrpc.h>
+#include <libmlrpc.h>
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/mapfile-vers b/usr/src/lib/libmlrpc/common/mapfile-vers
index 5822d32711..241d8309d0 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/mapfile-vers
+++ b/usr/src/lib/libmlrpc/common/mapfile-vers
@@ -42,47 +42,74 @@ $mapfile_version 2
SYMBOL_VERSION SUNWprivate {
global:
- ndr_buf_decode;
- ndr_buf_fini;
- ndr_buf_init;
- ndr_clnt_bind;
- ndr_clnt_call;
- ndr_clnt_free_heap;
+ mlrpc_clh_bind;
+ mlrpc_clh_create;
+ mlrpc_clh_free;
+ mlrpc_clh_unbind;
+
+ # Allow debug/test programs to provide these.
+ ndo_printf { FLAGS = NODIRECT };
+ ndo_trace { FLAGS = NODIRECT };
+
+ ndr_buf_decode;
+ ndr_buf_fini;
+ ndr_buf_init;
+ ndr_clnt_bind;
+ ndr_clnt_call;
+ ndr_clnt_free_heap;
ndr_generic_call_stub;
- ndr_heap_avail;
- ndr_heap_create;
- ndr_heap_destroy;
- ndr_heap_malloc;
- ndr_heap_mkvcb;
- ndr_heap_mkvcs;
+ ndr_heap_avail;
+ ndr_heap_create;
+ ndr_heap_destroy;
+ ndr_heap_dupmem;
+ ndr_heap_malloc;
+ ndr_heap_mkvcb;
+ ndr_heap_mkvcs;
ndr_heap_mstring;
- ndr_heap_siddup;
- ndr_heap_strdup;
- ndr_heap_used;
+ ndr_heap_strdup;
+ ndr_heap_used;
ndr_hdalloc;
+ ndr_hdclose;
ndr_hdfree;
ndr_hdlookup;
- ndr_inner;
- ndr_is_admin;
- ndr_is_poweruser;
+ ndr_inherit_handle;
+ ndr_inner;
+ ndr_is_bind_handle;
+ ndr_is_null_handle;
ndr_mbstowcs;
- ndr_mbtowc;
- ndr_native_os;
- ndr_params;
+ ndr_params;
ndr_pipe_worker;
- ndr_svc_binding_pool_init;
+ ndr_rpc_call;
+ ndr_rpc_get_heap;
+ ndr_rpc_get_ssnkey;
+ ndr_rpc_malloc;
+ ndr_rpc_release;
+ ndr_rpc_set_nonull;
+ ndr_svc_binding_pool_init;
ndr_svc_lookup_name;
- ndr_svc_register;
- ndr_topmost;
+ ndr_svc_register;
+ ndr_topmost;
ndr_uuid_parse;
ndr_uuid_unparse;
- nds_destruct;
- nds_initialize;
- ndt__char;
- ndt_s_wchar;
- ndt__uchar;
- ndt__ulong;
- ndt__ushort;
+
+ nds_destruct;
+ nds_initialize;
+
+ ndt__char;
+ ndt_s_char;
+ ndt__uchar;
+ ndt_s_uchar;
+ ndt__wchar;
+ ndt_s_wchar;
+ ndt__short;
+ ndt_s_short;
+ ndt__ushort;
+ ndt_s_ushort;
+ ndt__long;
+ ndt_s_long;
+ ndt__ulong;
+ ndt_s_ulong;
+
local:
*;
};
diff --git a/usr/src/lib/libmlrpc/common/mlrpc_clh.c b/usr/src/lib/libmlrpc/common/mlrpc_clh.c
new file mode 100644
index 0000000000..72c051d675
--- /dev/null
+++ b/usr/src/lib/libmlrpc/common/mlrpc_clh.c
@@ -0,0 +1,578 @@
+/*
+ * 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 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * ML-RPC Client handle interface and support functions.
+ */
+
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/poll.h>
+
+#include <errno.h>
+#include <strings.h>
+#include <unistd.h>
+
+#include <netsmb/smbfs_api.h>
+#include <smb/ntstatus.h>
+#include <libmlrpc.h>
+
+#include <assert.h>
+
+static int ndr_xa_init(ndr_client_t *, ndr_xa_t *);
+static int ndr_xa_exchange(ndr_client_t *, ndr_xa_t *);
+static int ndr_xa_read(ndr_client_t *, ndr_xa_t *);
+static void ndr_xa_preserve(ndr_client_t *, ndr_xa_t *);
+static void ndr_xa_destruct(ndr_client_t *, ndr_xa_t *);
+static void ndr_xa_release(ndr_client_t *);
+
+/* See notes in mlrpc_clh_bind */
+int rpc_pipe_open_retries = 10;
+
+/*
+ * Create an RPC client binding handle using the given smb_ctx.
+ * That context must already have a session and tree connected.
+ *
+ * Returns zero or an errno value.
+ */
+int
+mlrpc_clh_create(mlrpc_handle_t *handle, void *ctx)
+{
+ ndr_client_t *clnt = NULL;
+
+ if (ctx == NULL)
+ return (EINVAL);
+
+ /*
+ * Allocate...
+ */
+ if ((clnt = malloc(sizeof (*clnt))) == NULL)
+ return (ENOMEM);
+ bzero(clnt, sizeof (*clnt));
+
+ clnt->xa_fd = -1;
+
+ /*
+ * Setup the transport functions.
+ * Always a named pipe (for now).
+ */
+ clnt->xa_private = ctx;
+ clnt->xa_init = ndr_xa_init;
+ clnt->xa_exchange = ndr_xa_exchange;
+ clnt->xa_read = ndr_xa_read;
+ clnt->xa_preserve = ndr_xa_preserve;
+ clnt->xa_destruct = ndr_xa_destruct;
+ clnt->xa_release = ndr_xa_release;
+
+ /* See _is_bind_handle */
+ clnt->handle = &handle->handle;
+
+ ndr_svc_binding_pool_init(&clnt->binding_list,
+ clnt->binding_pool, NDR_N_BINDING_POOL);
+
+ if ((clnt->heap = ndr_heap_create()) == NULL)
+ goto nomem;
+
+ /* success! */
+ bzero(handle, sizeof (*handle));
+ handle->clnt = clnt;
+ return (0);
+
+nomem:
+ free(clnt);
+ return (ENOMEM);
+}
+
+
+/*
+ * This call must be made to initialize an RPC client structure and bind
+ * to the remote service before any RPCs can be exchanged with that service.
+ *
+ * The mlrpc_handle_t is a wrapper that is used to associate an RPC handle
+ * with the client context for an instance of the interface. The handle
+ * is zeroed to ensure that it doesn't look like a valid handle -
+ * handle content is provided by the remove service.
+ *
+ * The client points to this top-level handle so that we know when to
+ * unbind and teardown the connection. As each handle is initialized it
+ * will inherit a reference to the client context.
+ *
+ *
+ * Similar to MSRPC RpcBindingBind()
+ *
+ * Returns 0 or an NT_STATUS: (failed in...)
+ *
+ * RPC_NT_SERVER_TOO_BUSY (open pipe)
+ * RPC_NT_SERVER_UNAVAILABLE (open pipe)
+ * NT_STATUS_ACCESS_DENIED (open pipe)
+ * NT_STATUS_INVALID_PARAMETER (rpc bind)
+ * NT_STATUS_INTERNAL_ERROR (bad args etc)
+ * NT_STATUS_NO_MEMORY
+ */
+uint32_t
+mlrpc_clh_bind(mlrpc_handle_t *handle, ndr_service_t *svc)
+{
+ ndr_client_t *clnt = NULL;
+ struct smb_ctx *ctx = NULL;
+ uint32_t status = 0;
+ int fd = -1;
+ int rc, retries;
+
+ if ((clnt = handle->clnt) == NULL)
+ return (NT_STATUS_INTERNAL_ERROR);
+ if ((ctx = clnt->xa_private) == NULL)
+ return (NT_STATUS_INTERNAL_ERROR);
+ if (clnt->xa_fd != -1)
+ return (NT_STATUS_INTERNAL_ERROR);
+
+ /*
+ * Open the named pipe.
+ *
+ * Sometimes a DC may return NT_STATUS_PIPE_NOT_AVAILABLE for
+ * the first few seconds during service auto-start. The client
+ * translates that to EBUSY, so when we see that, wait a bit
+ * and retry the open for up to rpc_pipe_open_retries. If we
+ * fail even after retries, return RPC_NT_SERVER_TOO_BUSY,
+ * which is how callers of this layer expect that reported.
+ * We try up to 10 times, with a 0.5 sec. wait after each
+ * BUSY failure, giving a total wait here of 5 sec.
+ */
+ retries = rpc_pipe_open_retries;
+retry_open:
+ fd = smb_fh_open(ctx, svc->endpoint, O_RDWR);
+ if (fd < 0) {
+ rc = errno;
+ switch (rc) {
+ case EBUSY:
+ if (--retries > 0) {
+ (void) poll(NULL, 0, 500);
+ goto retry_open;
+ }
+ status = RPC_NT_SERVER_TOO_BUSY;
+ break;
+ case EACCES:
+ status = NT_STATUS_ACCESS_DENIED;
+ break;
+ default:
+ status = RPC_NT_SERVER_UNAVAILABLE;
+ break;
+ }
+ return (status);
+ }
+
+ clnt->xa_fd = fd;
+
+ /* Paranoia, in case of re-bind. */
+ bzero(&handle->handle, sizeof (ndr_hdid_t));
+
+ /*
+ * Do the OtW RPC bind.
+ */
+ rc = ndr_clnt_bind(clnt, svc, &clnt->binding);
+ switch (rc) {
+ case NDR_DRC_FAULT_OUT_OF_MEMORY:
+ status = NT_STATUS_NO_MEMORY;
+ break;
+ case NDR_DRC_FAULT_API_SERVICE_INVALID:
+ /* svc->..._uuid parse errors */
+ status = NT_STATUS_INTERNAL_ERROR;
+ break;
+ default:
+ if (NDR_DRC_IS_FAULT(rc)) {
+ status = RPC_NT_PROTOCOL_ERROR;
+ break;
+ }
+ /* FALLTHROUGH */
+ case NDR_DRC_OK:
+ status = NT_STATUS_SUCCESS;
+ }
+
+ if (status != 0) {
+ if (fd != -1)
+ (void) smb_fh_close(fd);
+ clnt->xa_fd = -1;
+ }
+
+ return (status);
+}
+
+/*
+ * Unbind and close the pipe to an RPC service.
+ *
+ * Similar to MSRPC RpcBindingUnbind()
+ * This should be called after a dropped connection.
+ */
+void
+mlrpc_clh_unbind(mlrpc_handle_t *handle)
+{
+ ndr_client_t *clnt = handle->clnt;
+
+ if (clnt->xa_fd != -1) {
+ (void) smb_fh_close(clnt->xa_fd);
+ clnt->xa_fd = -1;
+ }
+}
+
+/*
+ * If the heap has been preserved we need to go through an xa release.
+ * The heap is preserved during an RPC call because that's where data
+ * returned from the server is stored.
+ *
+ * Otherwise we destroy the heap directly.
+ *
+ * Returns the xa_private pointer (if non-NULL) to inform the caller
+ * that it can now be destroyed.
+ */
+void *
+mlrpc_clh_free(mlrpc_handle_t *handle)
+{
+ ndr_client_t *clnt = handle->clnt;
+ void *private;
+
+ if (clnt == NULL)
+ return (NULL);
+
+ /*
+ * Should never get an unbind on inherited handles.
+ * Callers of ndr_inherit_handle() check handles
+ * with ndr_is_bind_handle() before calling this.
+ *
+ * Maybe make this function more tolerant?
+ */
+ assert(handle->clnt->handle == &handle->handle);
+
+ mlrpc_clh_unbind(handle);
+
+ if (clnt->heap_preserved)
+ ndr_clnt_free_heap(clnt); /* xa_release */
+ else
+ ndr_heap_destroy(clnt->heap);
+
+ /*
+ * Note: Caller will free the smb_ctx stored in
+ * clnt->xa_private (or possibly reuse it).
+ */
+ private = clnt->xa_private;
+ free(clnt);
+ bzero(handle, sizeof (*handle));
+ return (private);
+}
+
+/*
+ * Call the RPC function identified by opnum. The remote service is
+ * identified by the handle, which should have been initialized by
+ * ndr_rpc_bind.
+ *
+ * If the RPC call is successful (returns 0), the caller must call
+ * ndr_rpc_release to release the heap. Otherwise, we release the
+ * heap here.
+ */
+int
+ndr_rpc_call(mlrpc_handle_t *handle, int opnum, void *params)
+{
+ ndr_client_t *clnt = handle->clnt;
+ int rc;
+
+ if (ndr_rpc_get_heap(handle) == NULL)
+ return (-1);
+
+ rc = ndr_clnt_call(clnt->binding, opnum, params);
+
+ /*
+ * Always clear the nonull flag to ensure
+ * it is not applied to subsequent calls.
+ */
+ clnt->nonull = B_FALSE;
+
+ if (NDR_DRC_IS_FAULT(rc)) {
+ ndr_rpc_release(handle);
+ return (-1);
+ }
+
+ return (0);
+}
+
+/*
+ * Outgoing strings should not be null terminated.
+ */
+void
+ndr_rpc_set_nonull(mlrpc_handle_t *handle)
+{
+ handle->clnt->nonull = B_TRUE;
+}
+
+/*
+ * Get the session key from a bound RPC client handle.
+ *
+ * The key returned is the 16-byte "user session key"
+ * established by the underlying authentication protocol
+ * (either Kerberos or NTLM). This key is needed for
+ * SAM RPC calls such as SamrSetInformationUser, etc.
+ * See [MS-SAMR] sections: 2.2.3.3, 2.2.7.21, 2.2.7.25.
+ *
+ * Returns zero (success) or an errno.
+ */
+int
+ndr_rpc_get_ssnkey(mlrpc_handle_t *handle, uchar_t *key, size_t len)
+{
+ ndr_client_t *clnt = handle->clnt;
+
+ if (clnt == NULL || clnt->xa_fd == -1)
+ return (EINVAL);
+
+ return (smb_fh_getssnkey(clnt->xa_fd, key, len));
+}
+
+void *
+ndr_rpc_malloc(mlrpc_handle_t *handle, size_t size)
+{
+ ndr_heap_t *heap;
+
+ if ((heap = ndr_rpc_get_heap(handle)) == NULL)
+ return (NULL);
+
+ return (ndr_heap_malloc(heap, size));
+}
+
+ndr_heap_t *
+ndr_rpc_get_heap(mlrpc_handle_t *handle)
+{
+ ndr_client_t *clnt = handle->clnt;
+
+ if (clnt->heap == NULL)
+ clnt->heap = ndr_heap_create();
+
+ return (clnt->heap);
+}
+
+/*
+ * Must be called by RPC clients to free the heap after a successful RPC
+ * call, i.e. ndr_rpc_call returned 0. The caller should take a copy
+ * of any data returned by the RPC prior to calling this function because
+ * returned data is in the heap.
+ */
+void
+ndr_rpc_release(mlrpc_handle_t *handle)
+{
+ ndr_client_t *clnt = handle->clnt;
+
+ if (clnt->heap_preserved)
+ ndr_clnt_free_heap(clnt);
+ else
+ ndr_heap_destroy(clnt->heap);
+
+ clnt->heap = NULL;
+}
+
+/*
+ * Returns true if the handle is null.
+ * Otherwise returns false.
+ */
+boolean_t
+ndr_is_null_handle(mlrpc_handle_t *handle)
+{
+ static const ndr_hdid_t hdid0 = {0};
+
+ if (handle == NULL || handle->clnt == NULL)
+ return (B_TRUE);
+
+ if (!memcmp(&handle->handle, &hdid0, sizeof (hdid0)))
+ return (B_TRUE);
+
+ return (B_FALSE);
+}
+
+/*
+ * Returns true if the handle is the top level bind handle.
+ * Otherwise returns false.
+ */
+boolean_t
+ndr_is_bind_handle(mlrpc_handle_t *handle)
+{
+ return (handle->clnt->handle == &handle->handle);
+}
+
+/*
+ * Pass the client reference from parent to child.
+ */
+void
+ndr_inherit_handle(mlrpc_handle_t *child, mlrpc_handle_t *parent)
+{
+ child->clnt = parent->clnt;
+}
+
+/*
+ * ndr_rpc_status remains in libmlsvc mlsvc_client.c
+ */
+
+/*
+ * The following functions provide the client callback interface.
+ * If the caller hasn't provided a heap, create one here.
+ */
+static int
+ndr_xa_init(ndr_client_t *clnt, ndr_xa_t *mxa)
+{
+ ndr_stream_t *recv_nds = &mxa->recv_nds;
+ ndr_stream_t *send_nds = &mxa->send_nds;
+ ndr_heap_t *heap = clnt->heap;
+ int rc;
+
+ if (heap == NULL) {
+ if ((heap = ndr_heap_create()) == NULL)
+ return (-1);
+
+ clnt->heap = heap;
+ }
+
+ mxa->heap = heap;
+
+ rc = nds_initialize(send_nds, 0, NDR_MODE_CALL_SEND, heap);
+ if (rc == 0)
+ rc = nds_initialize(recv_nds, NDR_PDU_SIZE_HINT_DEFAULT,
+ NDR_MODE_RETURN_RECV, heap);
+
+ if (rc != 0) {
+ nds_destruct(&mxa->recv_nds);
+ nds_destruct(&mxa->send_nds);
+ ndr_heap_destroy(mxa->heap);
+ mxa->heap = NULL;
+ clnt->heap = NULL;
+ return (-1);
+ }
+
+ if (clnt->nonull)
+ NDS_SETF(send_nds, NDS_F_NONULL);
+
+ return (0);
+}
+
+/*
+ * This is the entry pointy for an RPC client call exchange with
+ * a server, which will result in an smbrdr SmbTransact request.
+ *
+ * SmbTransact should return the number of bytes received, which
+ * we record as the PDU size, or a negative error code.
+ */
+static int
+ndr_xa_exchange(ndr_client_t *clnt, ndr_xa_t *mxa)
+{
+ ndr_stream_t *recv_nds = &mxa->recv_nds;
+ ndr_stream_t *send_nds = &mxa->send_nds;
+ int err, more, nbytes;
+
+ nbytes = recv_nds->pdu_max_size;
+ err = smb_fh_xactnp(clnt->xa_fd,
+ send_nds->pdu_size, (char *)send_nds->pdu_base_offset,
+ &nbytes, (char *)recv_nds->pdu_base_offset, &more);
+ if (err) {
+ recv_nds->pdu_size = 0;
+ return (-1);
+ }
+
+ recv_nds->pdu_size = nbytes;
+ return (0);
+}
+
+/*
+ * This entry point will be invoked if the xa-exchange response contained
+ * only the first fragment of a multi-fragment response. The RPC client
+ * code will then make repeated xa-read requests to obtain the remaining
+ * fragments, which will result in smbrdr SmbReadX requests.
+ *
+ * SmbReadX should return the number of bytes received, in which case we
+ * expand the PDU size to include the received data, or a negative error
+ * code.
+ */
+static int
+ndr_xa_read(ndr_client_t *clnt, ndr_xa_t *mxa)
+{
+ ndr_stream_t *nds = &mxa->recv_nds;
+ int len;
+ int nbytes;
+
+ if ((len = (nds->pdu_max_size - nds->pdu_size)) < 0)
+ return (-1);
+
+ nbytes = smb_fh_read(clnt->xa_fd, 0, len,
+ (char *)nds->pdu_base_offset + nds->pdu_size);
+
+ if (nbytes < 0)
+ return (-1);
+
+ nds->pdu_size += nbytes;
+
+ if (nds->pdu_size > nds->pdu_max_size) {
+ nds->pdu_size = nds->pdu_max_size;
+ return (-1);
+ }
+
+ return (nbytes);
+}
+
+/*
+ * Preserve the heap so that the client application has access to data
+ * returned from the server after an RPC call.
+ */
+static void
+ndr_xa_preserve(ndr_client_t *clnt, ndr_xa_t *mxa)
+{
+ assert(clnt->heap == mxa->heap);
+
+ clnt->heap_preserved = B_TRUE;
+ mxa->heap = NULL;
+}
+
+/*
+ * Dispose of the transaction streams. If the heap has not been
+ * preserved, we can destroy it here.
+ */
+static void
+ndr_xa_destruct(ndr_client_t *clnt, ndr_xa_t *mxa)
+{
+ nds_destruct(&mxa->recv_nds);
+ nds_destruct(&mxa->send_nds);
+
+ if (!clnt->heap_preserved) {
+ ndr_heap_destroy(mxa->heap);
+ mxa->heap = NULL;
+ clnt->heap = NULL;
+ }
+}
+
+/*
+ * Dispose of a preserved heap.
+ */
+static void
+ndr_xa_release(ndr_client_t *clnt)
+{
+ if (clnt->heap_preserved) {
+ ndr_heap_destroy(clnt->heap);
+ clnt->heap = NULL;
+ clnt->heap_preserved = B_FALSE;
+ }
+}
diff --git a/usr/src/uts/common/smbsrv/ndr.h b/usr/src/lib/libmlrpc/common/ndr.h
index 584c0798e4..f6af9a22cf 100644
--- a/usr/src/uts/common/smbsrv/ndr.h
+++ b/usr/src/lib/libmlrpc/common/ndr.h
@@ -40,18 +40,14 @@
* ogspecs@opengroup.org
*/
-#if defined(_KERNEL) || defined(_FAKE_KERNEL)
-#error "not used in kernel code"
-#else /* _KERNEL */
#include <sys/types.h>
#include <sys/uio.h>
-#include <syslog.h>
#include <stdlib.h>
#include <string.h>
-#include <smbsrv/wintypes.h>
-#include <smbsrv/ndl/rpcpdu.ndl>
-#include <smbsrv/string.h>
-#endif /* _KERNEL */
+
+#include <smb/wintypes.h>
+#include <libmlrpc/ndrtypes.ndl>
+#include <libmlrpc/rpcpdu.ndl>
#ifdef __cplusplus
extern "C" {
@@ -455,8 +451,7 @@ int ndr_inner_pointer(ndr_ref_t *);
int ndr_inner_reference(ndr_ref_t *);
int ndr_inner_array(ndr_ref_t *);
-size_t ndr_mbstowcs(struct ndr_stream *, smb_wchar_t *, const char *, size_t);
-int ndr_mbtowc(struct ndr_stream *, smb_wchar_t *, const char *, size_t);
+size_t ndr_mbstowcs(struct ndr_stream *, ndr_wchar_t *, const char *, size_t);
void nds_bswap(void *src, void *dst, size_t len);
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_client.c b/usr/src/lib/libmlrpc/common/ndr_client.c
index 7aaa35e6b5..56cc1847ef 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_client.c
+++ b/usr/src/lib/libmlrpc/common/ndr_client.c
@@ -21,14 +21,15 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/errno.h>
#include <string.h>
#include <strings.h>
-#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
+#include <libmlrpc.h>
#define NDR_DEFAULT_FRAGSZ 8192
#define NDR_MULTI_FRAGSZ (60 * 1024)
@@ -38,24 +39,19 @@ static int ndr_clnt_get_frags(ndr_client_t *, ndr_xa_t *);
static int ndr_clnt_get_frag(ndr_client_t *, ndr_xa_t *, ndr_common_header_t *);
int
-ndr_clnt_bind(ndr_client_t *clnt, const char *service_name,
+ndr_clnt_bind(ndr_client_t *clnt, ndr_service_t *msvc,
ndr_binding_t **ret_binding_p)
{
- ndr_service_t *msvc;
ndr_binding_t *mbind;
ndr_xa_t mxa;
ndr_bind_hdr_t *bhdr;
- ndr_p_cont_elem_t *pce;
+ ndr_p_cont_elem_t *pce;
ndr_bind_ack_hdr_t *bahdr;
ndr_p_result_t *pre;
int rc;
bzero(&mxa, sizeof (mxa));
- msvc = ndr_svc_lookup_name(service_name);
- if (msvc == NULL)
- return (NDR_DRC_FAULT_API_SERVICE_INVALID);
-
mxa.binding_list = clnt->binding_list;
if ((mbind = ndr_svc_new_binding(&mxa)) == NULL)
return (NDR_DRC_FAULT_API_BIND_NO_SLOTS);
@@ -140,16 +136,12 @@ int
ndr_clnt_call(ndr_binding_t *mbind, int opnum, void *params)
{
ndr_client_t *clnt = mbind->clnt;
- ndr_service_t *msvc = mbind->service;
ndr_xa_t mxa;
ndr_request_hdr_t *reqhdr;
ndr_common_header_t *rsphdr;
unsigned long recv_pdu_scan_offset;
int rc;
- if (ndr_svc_lookup_name(msvc->name) == NULL)
- return (NDR_DRC_FAULT_API_SERVICE_INVALID);
-
bzero(&mxa, sizeof (mxa));
mxa.ptype = NDR_PTYPE_REQUEST;
mxa.opnum = opnum;
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_heap.c b/usr/src/lib/libmlrpc/common/ndr_heap.c
index 73a453b00e..5ec8a5aa77 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_heap.c
+++ b/usr/src/lib/libmlrpc/common/ndr_heap.c
@@ -21,6 +21,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -46,9 +48,8 @@
#include <strings.h>
#include <sys/uio.h>
-#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
-#include <smbsrv/smb_sid.h>
+#include <libmlrpc.h>
+#include <ndr_wchar.h>
/*
* Allocate a heap structure and the first heap block. For many RPC
@@ -154,6 +155,23 @@ ndr_heap_malloc(ndr_heap_t *heap, unsigned size)
}
/*
+ * Convenience function to copy some memory into the heap.
+ */
+void *
+ndr_heap_dupmem(ndr_heap_t *heap, const void *mem, size_t len)
+{
+ void *p;
+
+ if (mem == NULL)
+ return (NULL);
+
+ if ((p = ndr_heap_malloc(heap, len)) != NULL)
+ (void) memcpy(p, mem, len);
+
+ return (p);
+}
+
+/*
* Convenience function to do heap strdup.
*/
void *
@@ -171,8 +189,7 @@ ndr_heap_strdup(ndr_heap_t *heap, const char *s)
if ((len = strlen(s)) == 0)
return ("");
- if ((p = ndr_heap_malloc(heap, len+1)) != NULL)
- (void) strcpy((char *)p, s);
+ p = ndr_heap_dupmem(heap, s, len+1);
return (p);
}
@@ -183,11 +200,21 @@ ndr_heap_strdup(ndr_heap_t *heap, const char *s)
int
ndr_heap_mstring(ndr_heap_t *heap, const char *s, ndr_mstring_t *out)
{
+ size_t slen;
+
if (s == NULL || out == NULL)
return (-1);
- out->length = smb_wcequiv_strlen(s);
- out->allosize = out->length + sizeof (smb_wchar_t);
+ /*
+ * Determine the WC strlen of s
+ * Was ndr__wcequiv_strlen(s)
+ */
+ slen = ndr__mbstowcs(NULL, s, NDR_STRING_MAX);
+ if (slen == (size_t)-1)
+ return (-1);
+
+ out->length = slen * sizeof (ndr_wchar_t);
+ out->allosize = out->length + sizeof (ndr_wchar_t);
if ((out->str = ndr_heap_strdup(heap, s)) == NULL)
return (-1);
@@ -207,20 +234,31 @@ ndr_heap_mstring(ndr_heap_t *heap, const char *s, ndr_mstring_t *out)
void
ndr_heap_mkvcs(ndr_heap_t *heap, char *s, ndr_vcstr_t *vc)
{
+ size_t slen;
int mlen;
- vc->wclen = smb_wcequiv_strlen(s);
- vc->wcsize = vc->wclen;
+ /*
+ * Determine the WC strlen of s
+ * Was ndr__wcequiv_strlen(s)
+ */
+ slen = ndr__mbstowcs(NULL, s, NDR_STRING_MAX);
+ if (slen == (size_t)-1)
+ slen = 0;
- mlen = sizeof (ndr_vcs_t) + vc->wcsize + sizeof (smb_wchar_t);
+ vc->wclen = slen * sizeof (ndr_wchar_t);
+ vc->wcsize = vc->wclen;
+ /*
+ * alloc one extra wchar for a null
+ * See slen + 1 arg for mbstowcs
+ */
+ mlen = sizeof (ndr_vcs_t) + vc->wcsize + sizeof (ndr_wchar_t);
vc->vcs = ndr_heap_malloc(heap, mlen);
if (vc->vcs) {
vc->vcs->vc_first_is = 0;
- vc->vcs->vc_length_is = vc->wclen / sizeof (smb_wchar_t);
- (void) smb_mbstowcs((smb_wchar_t *)vc->vcs->buffer, s,
- vc->vcs->vc_length_is);
+ vc->vcs->vc_length_is = slen;
+ (void) ndr__mbstowcs(vc->vcs->buffer, s, slen + 1);
}
}
@@ -250,25 +288,8 @@ ndr_heap_mkvcb(ndr_heap_t *heap, uint8_t *data, uint32_t datalen,
}
/*
- * Duplcate a SID in the heap.
+ * Removed ndr_heap_siddup(), now using ndr_heap_dupmem().
*/
-smb_sid_t *
-ndr_heap_siddup(ndr_heap_t *heap, smb_sid_t *sid)
-{
- smb_sid_t *new_sid;
- unsigned size;
-
- if (sid == NULL)
- return (NULL);
-
- size = smb_sid_len(sid);
-
- if ((new_sid = ndr_heap_malloc(heap, size)) == NULL)
- return (NULL);
-
- bcopy(sid, new_sid, size);
- return (new_sid);
-}
int
ndr_heap_used(ndr_heap_t *heap)
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c b/usr/src/lib/libmlrpc/common/ndr_marshal.c
index a690dfb2e9..4d34030d2a 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c
+++ b/usr/src/lib/libmlrpc/common/ndr_marshal.c
@@ -20,14 +20,14 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#include <assert.h>
#include <strings.h>
#include <sys/param.h>
-#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
+#include <libmlrpc.h>
#ifdef _BIG_ENDIAN
static const int ndr_native_byte_order = NDR_REPLAB_INTG_BIG_ENDIAN;
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_ops.c b/usr/src/lib/libmlrpc/common/ndr_ops.c
index 0cbcdc6e90..4ca1cb6295 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_ops.c
+++ b/usr/src/lib/libmlrpc/common/ndr_ops.c
@@ -49,8 +49,7 @@
#include <string.h>
#include <assert.h>
-#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
+#include <libmlrpc.h>
#define NDOBUFSZ 128
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c b/usr/src/lib/libmlrpc/common/ndr_process.c
index 945b02e699..3188500a8b 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c
+++ b/usr/src/lib/libmlrpc/common/ndr_process.c
@@ -22,6 +22,7 @@
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright 2012 Milan Jurik. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -34,13 +35,11 @@
#include <strings.h>
#include <assert.h>
#include <string.h>
+#include <stdio.h>
#include <stdlib.h>
-#include <smbsrv/libsmb.h>
-#include <smbsrv/string.h>
-#include <smbsrv/libmlrpc.h>
-
-#define NDR_STRING_MAX 4096
+#include <libmlrpc.h>
+#include <ndr_wchar.h>
#define NDR_IS_UNION(T) \
(((T)->type_flags & NDR_F_TYPEOP_MASK) == NDR_F_UNION)
@@ -1210,17 +1209,22 @@ ndr_outer_string(ndr_ref_t *outer_ref)
/*
* size_is is the number of characters in the
* (multibyte) string, including the null.
+ * In other words, symbols, not bytes.
*/
- size_is = smb_wcequiv_strlen(valp) /
- sizeof (smb_wchar_t);
-
- if (!(nds->flags & NDS_F_NONULL))
- ++size_is;
-
- if (size_is > NDR_STRING_MAX) {
+ size_t wlen;
+ wlen = ndr__mbstowcs(NULL, valp, NDR_STRING_MAX);
+ if (wlen == (size_t)-1) {
+ /* illegal sequence error? */
NDR_SET_ERROR(outer_ref, NDR_ERR_STRLEN);
return (0);
}
+ if ((nds->flags & NDS_F_NONULL) == 0)
+ wlen++;
+ if (wlen > NDR_STRING_MAX) {
+ NDR_SET_ERROR(outer_ref, NDR_ERR_STRLEN);
+ return (0);
+ }
+ size_is = wlen;
} else {
valp = outer_ref->datum;
n_zeroes = 0;
@@ -1288,7 +1292,7 @@ ndr_outer_string(ndr_ref_t *outer_ref)
* be nice to use mbequiv_strlen but the string
* may not be null terminated.
*/
- n_alloc = (size_is + 1) * MTS_MB_CHAR_MAX;
+ n_alloc = (size_is + 1) * NDR_MB_CHAR_MAX;
} else {
n_alloc = (size_is + 1) * is_varlen;
}
@@ -1741,7 +1745,7 @@ ndr_inner_array(ndr_ref_t *encl_ref)
myref.inner_flags = NDR_F_NONE;
for (i = 0; i < n_elem; i++) {
- (void) sprintf(name, "[%lu]", i);
+ (void) snprintf(name, sizeof (name), "[%lu]", i);
myref.name = name;
myref.pdu_offset = pdu_offset + i * ti->pdu_size_fixed_part;
myref.datum = encl_ref->datum + i * ti->c_size_fixed_part;
@@ -1796,20 +1800,20 @@ ndr_inner_array(ndr_ref_t *encl_ref)
int ndr_basic_integer(ndr_ref_t *, unsigned);
int ndr_string_basic_integer(ndr_ref_t *, ndr_typeinfo_t *);
+/* Comments to be nice to those searching for these types. */
+MAKE_BASIC_TYPE(_char, 1) /* ndt__char, ndt_s_char */
+MAKE_BASIC_TYPE(_uchar, 1) /* ndt__uchar, ndt_s_uchar */
+MAKE_BASIC_TYPE(_short, 2) /* ndt__short, ndt_s_short */
+MAKE_BASIC_TYPE(_ushort, 2) /* ndt__ushort, ndt_s_ushort */
+MAKE_BASIC_TYPE(_long, 4) /* ndt__long, ndt_s_long */
+MAKE_BASIC_TYPE(_ulong, 4) /* ndt__ulong, ndt_s_ulong */
-MAKE_BASIC_TYPE(_char, 1)
-MAKE_BASIC_TYPE(_uchar, 1)
-MAKE_BASIC_TYPE(_short, 2)
-MAKE_BASIC_TYPE(_ushort, 2)
-MAKE_BASIC_TYPE(_long, 4)
-MAKE_BASIC_TYPE(_ulong, 4)
-
-MAKE_BASIC_TYPE_BASE(_wchar, 2)
+MAKE_BASIC_TYPE_BASE(_wchar, 2) /* ndt__wchar, ndt_s_wchar */
int
ndr_basic_integer(ndr_ref_t *ref, unsigned size)
{
- ndr_stream_t *nds = ref->stream;
+ ndr_stream_t *nds = ref->stream;
char *valp = (char *)ref->datum;
int rc;
@@ -1854,7 +1858,7 @@ ndr_string_basic_integer(ndr_ref_t *encl_ref, ndr_typeinfo_t *type_under)
myref.name = name;
for (i = 0; i < NDR_STRING_MAX; i++) {
- (void) sprintf(name, "[%lu]", i);
+ (void) snprintf(name, sizeof (name), "[%lu]", i);
myref.pdu_offset = pdu_offset + i * size;
valp = encl_ref->datum + i * size;
myref.datum = valp;
@@ -1897,27 +1901,27 @@ ndr_typeinfo_t ndt_s_wchar = {
* multi-byte to wide characters. During NDR_M_OP_UNMARSHALL, we
* convert from wide characters to multi-byte.
*
- * It appeared that NT would sometimes leave a spurious character
- * in the data stream before the null wide_char, which would get
- * included in the string decode because we processed until the
- * null character. It now looks like NT does not always terminate
- * RPC Unicode strings and the terminating null is a side effect
- * of field alignment. So now we rely on the strlen_is (set up in
- * ndr_outer_string) of the enclosing reference. This may or may
- * not include the null but it doesn't matter, the algorithm will
- * get it right.
+ * The most critical thing to get right in this function is to
+ * marshall or unmarshall _exactly_ the number of elements the
+ * OtW length specifies, as saved by the caller in: strlen_is.
+ * Doing otherwise would leave us positioned at the wrong place
+ * in the data stream for whatever follows this. Note that the
+ * string data covered by strlen_is may or may not include any
+ * null termination, but the converted string provided by the
+ * caller or returned always has a null terminator.
*/
int
ndr_s_wchar(ndr_ref_t *encl_ref)
{
ndr_stream_t *nds = encl_ref->stream;
- unsigned short wide_char;
- char *valp;
+ char *valp = encl_ref->datum;
ndr_ref_t myref;
- unsigned long i;
char name[30];
- int count;
- int char_count = 0;
+ ndr_wchar_t wcs[NDR_STRING_MAX+1];
+ size_t i, slen, wlen;
+
+ /* This is enforced in ndr_outer_string() */
+ assert(encl_ref->strlen_is <= NDR_STRING_MAX);
if (nds->m_op == NDR_M_OP_UNMARSHALL) {
/*
@@ -1930,59 +1934,60 @@ ndr_s_wchar(ndr_ref_t *encl_ref)
}
}
+ /*
+ * If we're marshalling, convert the given string
+ * from UTF-8 into a local UCS-2 string.
+ */
+ if (nds->m_op == NDR_M_OP_MARSHALL) {
+ wlen = ndr__mbstowcs(wcs, valp, NDR_STRING_MAX);
+ if (wlen == (size_t)-1)
+ return (0);
+ /*
+ * Add a nulls to make strlen_is.
+ * (always zero or one of them)
+ * Then null terminate at wlen,
+ * just for debug convenience.
+ */
+ while (wlen < encl_ref->strlen_is)
+ wcs[wlen++] = 0;
+ wcs[wlen] = 0;
+ }
+
+ /*
+ * Copy wire data to or from the local wc string.
+ * Always exactly strlen_is elements.
+ */
bzero(&myref, sizeof (myref));
myref.enclosing = encl_ref;
myref.stream = encl_ref->stream;
myref.packed_alignment = 0;
myref.ti = &ndt__wchar;
myref.inner_flags = NDR_F_NONE;
- myref.datum = (char *)&wide_char;
myref.name = name;
myref.pdu_offset = encl_ref->pdu_offset;
+ myref.datum = (char *)wcs;
+ wlen = encl_ref->strlen_is;
- valp = encl_ref->datum;
- count = 0;
-
- for (i = 0; i < NDR_STRING_MAX; i++) {
- (void) sprintf(name, "[%lu]", i);
-
- if (nds->m_op == NDR_M_OP_MARSHALL) {
- count = smb_mbtowc((smb_wchar_t *)&wide_char, valp,
- MTS_MB_CHAR_MAX);
- if (count < 0) {
- return (0);
- } else if (count == 0) {
- if (encl_ref->strlen_is != encl_ref->size_is)
- break;
-
- /*
- * If the input char is 0, mbtowc
- * returns 0 without setting wide_char.
- * Set wide_char to 0 and a count of 1.
- */
- wide_char = *valp;
- count = 1;
- }
- }
-
+ for (i = 0; i < wlen; i++) {
+ (void) snprintf(name, sizeof (name), "[%lu]", i);
if (!ndr_inner(&myref))
return (0);
+ myref.pdu_offset += sizeof (ndr_wchar_t);
+ myref.datum += sizeof (ndr_wchar_t);
+ }
- if (nds->m_op == NDR_M_OP_UNMARSHALL) {
- count = smb_wctomb(valp, wide_char);
-
- if ((++char_count) == encl_ref->strlen_is) {
- valp += count;
- *valp = '\0';
- break;
- }
- }
-
- if (!wide_char)
- break;
-
- myref.pdu_offset += sizeof (wide_char);
- valp += count;
+ /*
+ * If this is unmarshall, convert the local UCS-2 string
+ * into a UTF-8 string in the caller's buffer. The caller
+ * previously determined the space required and provides a
+ * buffer of sufficient size.
+ */
+ if (nds->m_op == NDR_M_OP_UNMARSHALL) {
+ wcs[wlen] = 0;
+ slen = ndr__wcstombs(valp, wcs, wlen);
+ if (slen == (size_t)-1)
+ return (0);
+ valp[slen] = '\0';
}
return (1);
@@ -1997,51 +2002,20 @@ ndr_s_wchar(ndr_ref_t *encl_ref)
* any terminating null wide character. Returns -1 if an invalid
* multibyte character is encountered.
*/
+/* ARGSUSED */
size_t
-ndr_mbstowcs(ndr_stream_t *nds, smb_wchar_t *wcs, const char *mbs,
+ndr_mbstowcs(ndr_stream_t *nds, ndr_wchar_t *wcs, const char *mbs,
size_t nwchars)
{
- smb_wchar_t *start = wcs;
- int nbytes;
-
- while (nwchars--) {
- nbytes = ndr_mbtowc(nds, wcs, mbs, MTS_MB_CHAR_MAX);
- if (nbytes < 0) {
- *wcs = 0;
- return ((size_t)-1);
- }
-
- if (*mbs == 0)
- break;
-
- ++wcs;
- mbs += nbytes;
- }
-
- return (wcs - start);
-}
-
-/*
- * Converts a multibyte character to a little-endian, wide-char, which
- * is stored in wcharp. Up to nbytes bytes are examined.
- *
- * If mbchar is valid, returns the number of bytes processed in mbchar.
- * If mbchar is invalid, returns -1. See also smb_mbtowc().
- */
-/*ARGSUSED*/
-int
-ndr_mbtowc(ndr_stream_t *nds, smb_wchar_t *wcharp, const char *mbchar,
- size_t nbytes)
-{
- int rc;
-
- if ((rc = smb_mbtowc(wcharp, mbchar, nbytes)) < 0)
- return (rc);
+ size_t len;
#ifdef _BIG_ENDIAN
- if (nds == NULL || NDR_MODE_MATCH(nds, NDR_MODE_RETURN_SEND))
- *wcharp = BSWAP_16(*wcharp);
+ if (nds == NULL || NDR_MODE_MATCH(nds, NDR_MODE_RETURN_SEND)) {
+ /* Make WC string in LE order. */
+ len = ndr__mbstowcs_le(wcs, mbs, nwchars);
+ } else
#endif
+ len = ndr__mbstowcs(wcs, mbs, nwchars);
- return (rc);
+ return (len);
}
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c b/usr/src/lib/libmlrpc/common/ndr_server.c
index 198daa7d55..4a1e2c177a 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c
+++ b/usr/src/lib/libmlrpc/common/ndr_server.c
@@ -36,9 +36,7 @@
#include <string.h>
#include <thread.h>
-#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
-#include <smbsrv/ntaccess.h>
+#include <libmlrpc.h>
#define NDR_PIPE_SEND(np, buf, len) \
((np)->np_send)((np), (buf), (len))
@@ -132,42 +130,6 @@ out1:
}
/*
- * Check whether or not the specified user has administrator privileges,
- * i.e. is a member of Domain Admins or Administrators.
- * Returns true if the user is an administrator, otherwise returns false.
- */
-boolean_t
-ndr_is_admin(ndr_xa_t *xa)
-{
- smb_netuserinfo_t *ctx = xa->pipe->np_user;
-
- return (ctx->ui_flags & SMB_ATF_ADMIN);
-}
-
-/*
- * Check whether or not the specified user has power-user privileges,
- * i.e. is a member of Domain Admins, Administrators or Power Users.
- * This is typically required for operations such as managing shares.
- * Returns true if the user is a power user, otherwise returns false.
- */
-boolean_t
-ndr_is_poweruser(ndr_xa_t *xa)
-{
- smb_netuserinfo_t *ctx = xa->pipe->np_user;
-
- return ((ctx->ui_flags & SMB_ATF_ADMIN) ||
- (ctx->ui_flags & SMB_ATF_POWERUSER));
-}
-
-int32_t
-ndr_native_os(ndr_xa_t *xa)
-{
- smb_netuserinfo_t *ctx = xa->pipe->np_user;
-
- return (ctx->ui_native_os);
-}
-
-/*
* Receive an entire RPC request (all fragments)
* Returns zero or an NDR fault code.
*/
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_svc.c b/usr/src/lib/libmlrpc/common/ndr_svc.c
index d5c5f95f01..1e000a27f1 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_svc.c
+++ b/usr/src/lib/libmlrpc/common/ndr_svc.c
@@ -34,8 +34,7 @@
#include <strings.h>
#include <assert.h>
-#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
+#include <libmlrpc.h>
/*
diff --git a/usr/src/lib/libmlrpc/common/ndr_wchar.c b/usr/src/lib/libmlrpc/common/ndr_wchar.c
new file mode 100644
index 0000000000..81886f3250
--- /dev/null
+++ b/usr/src/lib/libmlrpc/common/ndr_wchar.c
@@ -0,0 +1,162 @@
+/*
+ * 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 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * Some wchar support functions used by this library.
+ * Mostlly just wrappers that call sys/u8_textprep.h
+ * functions: uconv_u8tou16, uconv_u16tou8.
+ */
+
+#include <sys/types.h>
+#include <sys/u8_textprep.h>
+#include <string.h>
+
+#include "ndr_wchar.h"
+
+/*
+ * When we just want lengths, we need an output buffer to pass to the
+ * uconv_... functions. Nothing ever reads this output, so we can
+ * use shared space for the unwanted output.
+ */
+static uint16_t junk_wcs[NDR_STRING_MAX];
+static char junk_mbs[NDR_MB_CUR_MAX * NDR_STRING_MAX];
+
+static size_t
+ndr__mbstowcs_x(uint16_t *, const char *, size_t, int);
+
+/*
+ * Like mbstowcs(3C), but with UCS-2 wchar_t
+ */
+size_t
+ndr__mbstowcs(uint16_t *wcs, const char *mbs, size_t nwchars)
+{
+ return (ndr__mbstowcs_x(wcs, mbs, nwchars,
+ UCONV_OUT_SYSTEM_ENDIAN));
+}
+
+/*
+ * Like above, but put UCS-2 little-endian.
+ */
+size_t
+ndr__mbstowcs_le(uint16_t *wcs, const char *mbs, size_t nwchars)
+{
+ return (ndr__mbstowcs_x(wcs, mbs, nwchars,
+ UCONV_OUT_LITTLE_ENDIAN));
+}
+
+/*
+ * Like mbstowcs(3C), but with UCS-2 wchar_t, and
+ * one extra arg for the byte order flags.
+ */
+static size_t
+ndr__mbstowcs_x(uint16_t *wcs, const char *mbs, size_t nwchars, int flags)
+{
+ size_t obytes, mbslen, wcslen;
+ int err;
+
+ /* NULL or empty input is allowed. */
+ if (mbs == NULL || *mbs == '\0') {
+ if (wcs != NULL && nwchars > 0)
+ *wcs = 0;
+ return (0);
+ }
+
+ /*
+ * If wcs == NULL, caller just wants the length.
+ * Convert into some throw-away space.
+ */
+ obytes = nwchars * 2;
+ if (wcs == NULL) {
+ if (obytes > sizeof (junk_wcs))
+ return ((size_t)-1);
+ wcs = junk_wcs;
+ }
+
+ mbslen = strlen(mbs);
+ wcslen = nwchars;
+ err = uconv_u8tou16((const uchar_t *)mbs, &mbslen,
+ wcs, &wcslen, flags);
+ if (err != 0)
+ return ((size_t)-1);
+
+ if (wcslen < nwchars)
+ wcs[wcslen] = 0;
+
+ return (wcslen);
+}
+
+/*
+ * Like wcstombs(3C), but with UCS-2 wchar_t.
+ */
+size_t
+ndr__wcstombs(char *mbs, const uint16_t *wcs, size_t nbytes)
+{
+ size_t mbslen, wcslen;
+ int err;
+
+ /* NULL or empty input is allowed. */
+ if (wcs == NULL || *wcs == 0) {
+ if (mbs != NULL && nbytes > 0)
+ *mbs = '\0';
+ return (0);
+ }
+
+ /*
+ * If mbs == NULL, caller just wants the length.
+ * Convert into some throw-away space.
+ */
+ if (mbs == NULL) {
+ if (nbytes > sizeof (junk_mbs))
+ return ((size_t)-1);
+ mbs = junk_mbs;
+ }
+
+ wcslen = ndr__wcslen(wcs);
+ mbslen = nbytes;
+ err = uconv_u16tou8(wcs, &wcslen,
+ (uchar_t *)mbs, &mbslen, UCONV_IN_SYSTEM_ENDIAN);
+ if (err != 0)
+ return ((size_t)-1);
+
+ if (mbslen < nbytes)
+ mbs[mbslen] = '\0';
+
+ return (mbslen);
+}
+
+/*
+ * Like wcslen(3C), but with UCS-2 wchar_t.
+ */
+size_t
+ndr__wcslen(const uint16_t *wc)
+{
+ size_t len = 0;
+ while (*wc++)
+ len++;
+ return (len);
+}
diff --git a/usr/src/lib/libmlrpc/common/ndr_wchar.h b/usr/src/lib/libmlrpc/common/ndr_wchar.h
new file mode 100644
index 0000000000..e5fe8a1054
--- /dev/null
+++ b/usr/src/lib/libmlrpc/common/ndr_wchar.h
@@ -0,0 +1,46 @@
+/*
+ * 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 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ */
+
+#ifndef _NDR_WCHAR_H
+#define _NDR_WCHAR_H
+
+/*
+ * Some ndr_wchar_t support stuff.
+ */
+
+#define NDR_MB_CUR_MAX 3
+#define NDR_MB_CHAR_MAX NDR_MB_CUR_MAX
+#define NDR_STRING_MAX 4096
+
+size_t ndr__mbstowcs(uint16_t *, const char *, size_t);
+size_t ndr__mbstowcs_le(uint16_t *, const char *, size_t);
+
+size_t ndr__wcslen(const uint16_t *);
+size_t ndr__wcstombs(char *, const uint16_t *, size_t);
+
+#endif /* _NDR_WCHAR_H */
diff --git a/usr/src/uts/common/smbsrv/ndl/ndrtypes.ndl b/usr/src/lib/libmlrpc/common/ndrtypes.ndl
index 16bb4b8135..b7d5fdb716 100644
--- a/usr/src/uts/common/smbsrv/ndl/ndrtypes.ndl
+++ b/usr/src/lib/libmlrpc/common/ndrtypes.ndl
@@ -21,10 +21,17 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
-#ifndef _NDR_TYPES_NDL_
-#define _NDR_TYPES_NDL_
+#ifndef _NDRTYPES_NDL_
+#define _NDRTYPES_NDL_
+
+/*
+ * Type definitions (and related) used in NDL files and the
+ * NDL run-time support libraries. See also: libmlrpc.h
+ */
#define TYPEINFO(TYPE) ndt__##TYPE
@@ -69,20 +76,6 @@
#define LPWORD ushort *
#define LPDWORD ulong *
-/*
- * Opaque context handle.
- */
-#ifndef CONTEXT_HANDLE
-#define CONTEXT_HANDLE(NAME) \
- struct NAME { \
- DWORD data1; \
- DWORD data2; \
- WORD data3[2]; \
- BYTE data4[8]; \
- }; \
- typedef struct NAME
-#endif /* CONTEXT_HANDLE */
-
#define EXTERNTYPEINFO(TYPE)
#else /* NDRGEN */
@@ -116,7 +109,7 @@
/*
* When not using ndrgen, get BYTE, WORD, DWORD definitions from wintypes.h.
*/
-#include <smbsrv/wintypes.h>
+#include <smb/wintypes.h>
#define EXTERNTYPEINFO(TYPE) extern struct ndr_typeinfo TYPEINFO(TYPE);
@@ -167,4 +160,18 @@
#define UNION_INFO_ENT(N,NAME) CASE(N) struct NAME##N info##N
#define UNION_INFO_PTR(N,NAME) CASE(N) struct NAME##N *info##N
-#endif /* _NDR_TYPES_NDL_ */
+/*
+ * Opaque context handle.
+ */
+#ifndef CONTEXT_HANDLE
+#define CONTEXT_HANDLE(NAME) \
+ struct NAME { \
+ DWORD data1; \
+ DWORD data2; \
+ WORD data3[2]; \
+ BYTE data4[8]; \
+ }; \
+ typedef struct NAME
+#endif /* CONTEXT_HANDLE */
+
+#endif /* _NDRTYPES_NDL_ */
diff --git a/usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl b/usr/src/lib/libmlrpc/common/rpcpdu.ndl
index f1ea15cf00..f1ea15cf00 100644
--- a/usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl
+++ b/usr/src/lib/libmlrpc/common/rpcpdu.ndl
diff --git a/usr/src/lib/smbsrv/libmlrpc/i386/Makefile b/usr/src/lib/libmlrpc/i386/Makefile
index 710c9eb3dd..6589e9941a 100644
--- a/usr/src/lib/smbsrv/libmlrpc/i386/Makefile
+++ b/usr/src/lib/libmlrpc/i386/Makefile
@@ -22,11 +22,7 @@
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
include ../Makefile.com
-DYNFLAGS += -R/usr/lib/smbsrv
-
install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
diff --git a/usr/src/lib/smbsrv/libmlrpc/sparc/Makefile b/usr/src/lib/libmlrpc/sparc/Makefile
index 710c9eb3dd..6589e9941a 100644
--- a/usr/src/lib/smbsrv/libmlrpc/sparc/Makefile
+++ b/usr/src/lib/libmlrpc/sparc/Makefile
@@ -22,11 +22,7 @@
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
include ../Makefile.com
-DYNFLAGS += -R/usr/lib/smbsrv
-
install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
diff --git a/usr/src/lib/smbsrv/libmlrpc/sparcv9/Makefile b/usr/src/lib/libmlrpc/sparcv9/Makefile
index b3c4916b0c..087f0e1107 100644
--- a/usr/src/lib/smbsrv/libmlrpc/sparcv9/Makefile
+++ b/usr/src/lib/libmlrpc/sparcv9/Makefile
@@ -22,14 +22,10 @@
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
MACH_LDLIBS += -L$(ROOT)/usr/lib/smbsrv/$(MACH64)
include ../Makefile.com
-include ../../../Makefile.lib.64
-
-DYNFLAGS += -R/usr/lib/smbsrv/$(MACH64)
+include ../../Makefile.lib.64
install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
diff --git a/usr/src/lib/libsmbfs/Makefile.com b/usr/src/lib/libsmbfs/Makefile.com
index 0521eba951..8f8b118128 100644
--- a/usr/src/lib/libsmbfs/Makefile.com
+++ b/usr/src/lib/libsmbfs/Makefile.com
@@ -59,7 +59,6 @@ OBJ_LIB=\
nb_ssn.o \
nbns_rq.o \
negprot.o \
- netshareenum.o \
newvc.o \
nls.o \
ntlm.o \
diff --git a/usr/src/lib/libsmbfs/netsmb/smb_netshareenum.h b/usr/src/lib/libsmbfs/netsmb/smb_netshareenum.h
deleted file mode 100644
index 14f2594df7..0000000000
--- a/usr/src/lib/libsmbfs/netsmb/smb_netshareenum.h
+++ /dev/null
@@ -1,18 +0,0 @@
-
-#ifndef _NETSMB_SMB_NETSHAREENUM_H_
-#define _NETSMB_SMB_NETSHAREENUM_H_
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/* This is from Apple. See ../smb/netshareenum.c */
-
-struct share_info {
- uint16_t type;
- char *netname;
- char *remark;
-};
-typedef struct share_info share_info_t;
-
-int smb_netshareenum(struct smb_ctx *, int *, int *, struct share_info **);
-
-#endif /* _NETSMB_SMB_NETSHAREENUM_H_ */
diff --git a/usr/src/lib/libsmbfs/netsmb/smbfs_api.h b/usr/src/lib/libsmbfs/netsmb/smbfs_api.h
index 8436318b4c..b1f4b1e198 100644
--- a/usr/src/lib/libsmbfs/netsmb/smbfs_api.h
+++ b/usr/src/lib/libsmbfs/netsmb/smbfs_api.h
@@ -140,8 +140,8 @@ typedef void (*smb_ctx_close_hook_t)(struct smb_ctx *);
void smb_ctx_set_close_hook(smb_ctx_close_hook_t);
int smb_fh_close(int);
int smb_fh_open(struct smb_ctx *ctx, const char *, int);
-int smb_fh_read(int, off_t, size_t, char *);
-int smb_fh_write(int, off_t, size_t, const char *);
+int smb_fh_read(int, off64_t, size_t, char *);
+int smb_fh_write(int, off64_t, size_t, const char *);
int smb_fh_xactnp(int, int, const char *,
int *, char *, int *);
int smb_fh_getssnkey(int, uchar_t *, size_t);
diff --git a/usr/src/lib/libsmbfs/smb/file.c b/usr/src/lib/libsmbfs/smb/file.c
index 1c09532d61..8ca9d2cee1 100644
--- a/usr/src/lib/libsmbfs/smb/file.c
+++ b/usr/src/lib/libsmbfs/smb/file.c
@@ -204,7 +204,7 @@ smb_fh_open(struct smb_ctx *ctx, const char *path, int oflag)
}
int
-smb_fh_read(int fd, off_t offset, size_t count,
+smb_fh_read(int fd, off64_t offset, size_t count,
char *dst)
{
struct smbioc_rw rwrq;
@@ -221,7 +221,7 @@ smb_fh_read(int fd, off_t offset, size_t count,
}
int
-smb_fh_write(int fd, off_t offset, size_t count,
+smb_fh_write(int fd, off64_t offset, size_t count,
const char *src)
{
struct smbioc_rw rwrq;
diff --git a/usr/src/lib/libsmbfs/smb/llib-lsmbfs b/usr/src/lib/libsmbfs/smb/llib-lsmbfs
index 1096482541..7459db63be 100644
--- a/usr/src/lib/libsmbfs/smb/llib-lsmbfs
+++ b/usr/src/lib/libsmbfs/smb/llib-lsmbfs
@@ -34,7 +34,6 @@
#include <netsmb/smb_lib.h>
#include <netsmb/smb_keychain.h>
-#include <netsmb/smb_netshareenum.h>
#include <netsmb/smb_rap.h>
#include <netsmb/spnego.h>
diff --git a/usr/src/lib/libsmbfs/smb/mapfile-vers b/usr/src/lib/libsmbfs/smb/mapfile-vers
index 24bffec63d..68b38f46ed 100644
--- a/usr/src/lib/libsmbfs/smb/mapfile-vers
+++ b/usr/src/lib/libsmbfs/smb/mapfile-vers
@@ -111,7 +111,6 @@ SYMBOL_VERSION SUNWprivate {
smb_iod_start;
smb_iod_work;
smb_lib_init;
- smb_netshareenum; # will move to libnetapi
smb_open_printer;
smb_open_rcfile;
smb_simplecrypt;
diff --git a/usr/src/lib/libsmbfs/smb/netshareenum.c b/usr/src/lib/libsmbfs/smb/netshareenum.c
deleted file mode 100644
index af5a0bb9bd..0000000000
--- a/usr/src/lib/libsmbfs/smb/netshareenum.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
- * Reserved. This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License'). You may not use this file
- * except in compliance with the License. Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/* BEGIN CSTYLED */
-/*
- * @(#)ui.c *
- * (c) 2004 Apple Computer, Inc. All Rights Reserved
- *
- *
- * netshareenum.c -- Routines for getting a list of share information
- * from a server.
- *
- * MODIFICATION HISTORY:
- * 27-Nov-2004 Guy Harris New today
- */
-/* END CSTYLED */
-
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include <netsmb/mchain.h>
-#include <netsmb/smb.h>
-#include <netsmb/smb_lib.h>
-#include <netsmb/smb_rap.h>
-#include <netsmb/smb_netshareenum.h>
-#include <smb/charsets.h>
-
-#if 0 /* XXX see below */
-#include <dce/exc_handling.h>
-#include <rpc/attrb.h>
-#include "srvsvc.h"
-#endif
-
-/*
- * Don't want RPC client-side code in here.
- * It's good code; just doesn't belong here.
- *
- * The API provided by this library should be
- * just files and pipes (and not much more).
- * It MAY be useful to provide some of the
- * RAP (remote API) functions functions like
- * rap_netshareenum below...
- *
- * XXX: Not sure this file belongs here at all.
- * smb_rap.h looks like a reasonable API
- * for this library to export.
- */
-#if 0 /* XXX */
-
-static int
-rpc_netshareenum(struct smb_ctx *ctx, int *entriesp, int *totalp,
- struct share_info **entries_listp)
-{
- char ctx_string[2+16+1]; /* enough for 64-bit pointer, in hex */
- unsigned_char_p_t binding;
- unsigned32 binding_status;
- rpc_binding_handle_t binding_h;
- int error, i, entries;
- char *addrstr, *srvnamestr;
- unsigned short *usrvnamestr;
- unsigned32 level;
- SHARE_ENUM_STRUCT share_info;
- SHARE_INFO_1_CONTAINER share_info_1_container;
- SHARE_INFO_1 *shares, *share;
- unsigned32 total_entries;
- unsigned32 status, free_status;
- struct share_info *entry_list, *elp;
- static EXCEPTION rpc_x_connect_rejected;
- static int exceptions_initialized;
-
- sprintf(ctx_string, "%p", ctx);
- rpc_string_binding_compose(NULL, "ncacn_np", ctx_string,
- "srvsvc", NULL, &binding, &binding_status);
- if (binding_status != rpc_s_ok) {
- smb_error(dgettext(TEXT_DOMAIN,
- "rpc_string_binding_compose failed with %d"),
- 0, binding_status);
- return (EINVAL);
- }
- rpc_binding_from_string_binding(binding, &binding_h, &status);
- rpc_string_free(&binding, (unsigned32 *)&free_status);
- if (binding_status != rpc_s_ok) {
- smb_error(dgettext(TEXT_DOMAIN,
- "rpc_binding_from_string_binding failed with %d"), 0,
- binding_status);
- return (EINVAL);
- }
- level = 1;
- share_info.share_union.level = 1;
- share_info.share_union.tagged_union.share1 = &share_info_1_container;
- share_info_1_container.share_count = 0;
- share_info_1_container.shares = NULL;
- /*
- * Convert the server IP address to a string, and send that as
- * the "server name" - that's what Windows appears to do, and
- * that avoids problems with NetBIOS names containing
- * non-ASCII characters.
- */
- addrstr = inet_ntoa(ctx->ct_srvinaddr.sin_addr);
- srvnamestr = malloc(strlen(addrstr) + 3);
- if (srvnamestr == NULL) {
- status = errno;
- smb_error(dgettext(TEXT_DOMAIN,
- "can't allocate string for server address"), status);
- rpc_binding_free(&binding_h, &free_status);
- return (status);
- }
- strcpy(srvnamestr, "\\\\");
- strcat(srvnamestr, addrstr);
- usrvnamestr = convert_utf8_to_leunicode(srvnamestr);
- if (usrvnamestr == NULL) {
- smb_error(dgettext(TEXT_DOMAIN,
- "can't convert string for server address to Unicode"), 0);
- rpc_binding_free(&binding_h, &free_status);
- free(srvnamestr);
- return (EINVAL);
- }
- if (!exceptions_initialized) {
- EXCEPTION_INIT(rpc_x_connect_rejected);
- exc_set_status(&rpc_x_connect_rejected, rpc_s_connect_rejected);
- exceptions_initialized = 1;
- }
- /* printf("Calling NetrShareEnum.."); XXX */
- TRY
- status = NetrShareEnum(binding_h, usrvnamestr, &level,
- &share_info, 4294967295U, &total_entries, NULL);
- if (status != 0)
- smb_error(dgettext(TEXT_DOMAIN,
- "error from NetrShareEnum call: status = 0x%08x"),
- 0, status);
- /*CSTYLED*/
- CATCH (rpc_x_connect_rejected)
- /*
- * This is what we get if we can't open the pipe.
- * That's a normal occurrence when we're talking
- * to a system that (presumably) doesn't support
- * DCE RPC on the server side, such as Windows 95/98/Me,
- * so we don't log an error.
- */
- /*CSTYLED*/
- status = ENOTSUP;
- CATCH_ALL
- /*
- * XXX - should we handle some exceptions differently,
- * returning different errors, and try RAP only for
- * ENOTSUP?
- */
- smb_error(dgettext(TEXT_DOMAIN,
- "error from NetrShareEnum call: exception = %u"),
- 0, THIS_CATCH->match.value);
- status = ENOTSUP;
- ENDTRY
- rpc_binding_free(&binding_h, &free_status);
- free(srvnamestr);
- free(usrvnamestr);
- if (status != 0)
- return (ENOTSUP);
-
- /*
- * XXX - if the IDL is correct, it's not clear whether the
- * unmarshalling code will properly handle the case where
- * a packet where "share_count" and the max count for the
- * array of shares don't match; a valid DCE RPC implementation
- * won't marshal something like that, but there's no guarantee
- * that the server we're talking to has a valid implementation
- * (which could be a *malicious* implementation!).
- */
- entries = share_info.share_union.tagged_union.share1->share_count;
- shares = share_info.share_union.tagged_union.share1->shares;
- entry_list = calloc(entries, sizeof (struct share_info));
- if (entry_list == NULL) {
- error = errno;
- goto cleanup_and_return;
- }
- for (share = shares, elp = entry_list, i = 0; i < entries;
- i++, share++) {
- elp->type = share->shi1_type;
- elp->netname = convert_unicode_to_utf8(share->shi1_share);
- if (elp->netname == NULL)
- goto fail;
- elp->remark = convert_unicode_to_utf8(share->shi1_remark);
- if (elp->remark == NULL)
- goto fail;
- elp++;
- }
- *entriesp = entries;
- *totalp = total_entries;
- *entries_listp = entry_list;
- error = 0;
- goto cleanup_and_return;
-
-fail:
- error = errno;
- for (elp = entry_list, i = 0; i < entries; i++, elp++) {
- /*
- * elp->netname is set before elp->remark, so if
- * elp->netname is null, elp->remark is also null.
- * If either of them is null, we haven't done anything
- * to any entries after this one.
- */
- if (elp->netname == NULL)
- break;
- free(elp->netname);
- if (elp->remark == NULL)
- break;
- free(elp->remark);
- }
- free(entry_list);
-
-cleanup_and_return:
- for (share = shares, i = 0; i < entries; i++, share++) {
- free(share->shi1_share);
- free(share->shi1_remark);
- }
- free(shares);
- /*
- * XXX - "share1" should be a unique pointer, but we haven't
- * changed the marshalling code to support non-full pointers
- * in unions, so we leave it as a full pointer.
- *
- * That means that this might, or might not, be changed from
- * pointing to "share_info_1_container" to pointing to a
- * mallocated structure, according to the DCE RPC 1.1 IDL spec;
- * we free it only if it's changed.
- */
- if (share_info.share_union.tagged_union.share1 !=
- &share_info_1_container)
- free(share_info.share_union.tagged_union.share1);
- return (error);
-}
-#endif /* XXX */
-
-/*
- * Enumerate shares using RAP
- */
-
-struct smb_share_info_1 {
- char shi1_netname[13];
- char shi1_pad;
- uint16_t shi1_type;
- uint32_t shi1_remark; /* char * */
-};
-
-static int
-smb_rap_NetShareEnum(struct smb_ctx *ctx, int sLevel, void *pbBuffer,
- int *cbBuffer, int *pcEntriesRead, int *pcTotalAvail)
-{
- struct smb_rap *rap;
- long lval = -1;
- int error;
-
- error = smb_rap_create(0, "WrLeh", "B13BWz", &rap);
- if (error)
- return (error);
- (void) smb_rap_setNparam(rap, sLevel); /* W - sLevel */
- (void) smb_rap_setPparam(rap, pbBuffer); /* r - pbBuffer */
- (void) smb_rap_setNparam(rap, *cbBuffer); /* L - cbBuffer */
- error = smb_rap_request(rap, ctx);
- if (error == 0) {
- *pcEntriesRead = rap->r_entries;
- error = smb_rap_getNparam(rap, &lval);
- *pcTotalAvail = lval;
- /* Copy the data length into the IN/OUT variable. */
- *cbBuffer = rap->r_rcvbuflen;
- }
- error = smb_rap_error(rap, error);
- smb_rap_done(rap);
- return (error);
-}
-
-static int
-rap_netshareenum(struct smb_ctx *ctx, int *entriesp, int *totalp,
- struct share_info **entries_listp)
-{
- int error, bufsize, i, entries, total, nreturned;
- struct smb_share_info_1 *rpbuf, *ep;
- struct share_info *entry_list, *elp;
- char *cp;
- int lbound, rbound;
-
- bufsize = 0xffe0; /* samba notes win2k bug for 65535 */
- rpbuf = malloc(bufsize);
- if (rpbuf == NULL)
- return (errno);
-
- error = smb_rap_NetShareEnum(ctx, 1, rpbuf, &bufsize, &entries, &total);
- if (error &&
- error != (ERROR_MORE_DATA | SMB_RAP_ERROR)) {
- free(rpbuf);
- return (error);
- }
- entry_list = malloc(entries * sizeof (struct share_info));
- if (entry_list == NULL) {
- error = errno;
- free(rpbuf);
- return (error);
- }
- lbound = entries * (sizeof (struct smb_share_info_1));
- rbound = bufsize;
- for (ep = rpbuf, elp = entry_list, i = 0, nreturned = 0; i < entries;
- i++, ep++) {
- elp->type = letohs(ep->shi1_type);
- ep->shi1_pad = '\0'; /* ensure null termination */
- elp->netname = convert_wincs_to_utf8(ep->shi1_netname);
- if (elp->netname == NULL)
- continue; /* punt on this entry */
- /*
- * Check for validity of offset.
- */
- if (ep->shi1_remark >= lbound && ep->shi1_remark < rbound) {
- cp = (char *)rpbuf + ep->shi1_remark;
- elp->remark = convert_wincs_to_utf8(cp);
- } else
- elp->remark = NULL;
- elp++;
- nreturned++;
- }
- *entriesp = nreturned;
- *totalp = total;
- *entries_listp = entry_list;
- free(rpbuf);
- return (0);
-}
-
-/*
- * First we try the RPC-based NetrShareEnum, and, if that fails, we fall
- * back on the RAP-based NetShareEnum.
- */
-int
-smb_netshareenum(struct smb_ctx *ctx, int *entriesp, int *totalp,
- struct share_info **entry_listp)
-{
- int error;
-
-#ifdef NOTYETDEFINED
- /*
- * Try getting a list of shares with the SRVSVC RPC service.
- */
- error = rpc_netshareenum(ctx, entriesp, totalp, entry_listp);
- if (error == 0)
- return (0);
-#endif
-
- /*
- * OK, that didn't work - try RAP.
- * XXX - do so only if it failed because we couldn't open
- * the pipe?
- */
- error = rap_netshareenum(ctx, entriesp, totalp, entry_listp);
- return (error);
-}
diff --git a/usr/src/lib/smbsrv/Makefile b/usr/src/lib/smbsrv/Makefile
index 4213133a56..68353f10fe 100644
--- a/usr/src/lib/smbsrv/Makefile
+++ b/usr/src/lib/smbsrv/Makefile
@@ -29,14 +29,12 @@ include ../Makefile.lib
SUBDIRS = \
libfksmbsrv \
libmlsvc \
- libmlrpc \
libsmb \
libsmbns \
libsmbrp
include ./Makefile.subdirs
-libmlrpc: libsmb
libsmbns: libsmb
-libmlsvc: libsmb libmlrpc libsmbns
+libmlsvc: libsmb libsmbns
libfksmbsrv: libsmb
diff --git a/usr/src/lib/smbsrv/Makefile.targ b/usr/src/lib/smbsrv/Makefile.targ
index 92a05ef243..9305212b3c 100644
--- a/usr/src/lib/smbsrv/Makefile.targ
+++ b/usr/src/lib/smbsrv/Makefile.targ
@@ -22,19 +22,22 @@
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
+# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+#
#
# Common targets for smbsrv Makefiles
#
%_ndr.c: $(NDLDIR)/%.ndl
- $(NDRGEN) -Y $(CC) $<
+ $(NDRGEN) -Y $(ANSI_CPP) $(CPPFLAGS) $<
pics/%.o: $(SRC)/common/smbsrv/%.c
$(COMPILE.c) -o $@ $<
$(POST_PROCESS_O)
+pics/%.o := CPPFLAGS += -I$(ROOTSMBHDRDIR)/ndl
+
.KEEP_STATE:
all: $(LIBS)
diff --git a/usr/src/lib/smbsrv/libmlrpc/Makefile b/usr/src/lib/smbsrv/libmlrpc/Makefile
deleted file mode 100644
index c5a61203cd..0000000000
--- a/usr/src/lib/smbsrv/libmlrpc/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# 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 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-#
-
-HDRS= libmlrpc.h
-
-include ../Makefile.smbsrv
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c b/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c
index 02b57b9328..f77c0bdf01 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c
@@ -29,7 +29,7 @@
#include <string.h>
#include <strings.h>
-#include <smbsrv/wintypes.h>
+#include <smb/wintypes.h>
#include <smbsrv/libsmb.h>
#include <smbsrv/ndl/dssetup.ndl>
#include <smbsrv/libmlsvc.h>
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/dssetup_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/dssetup_svc.c
index 07986c2c93..24b999e7c3 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/dssetup_svc.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/dssetup_svc.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -32,8 +33,8 @@
#include <stdlib.h>
#include <netdb.h>
+#include <libmlrpc/libmlrpc.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/ndl/dssetup.ndl>
#include <smbsrv/smbinfo.h>
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/eventlog_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/eventlog_svc.c
index 34438c6cae..35f9c856e9 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/eventlog_svc.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/eventlog_svc.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -29,8 +30,8 @@
#include <sys/utsname.h>
#include <unistd.h>
#include <strings.h>
+#include <libmlrpc/libmlrpc.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
#include <smbsrv/nmpipes.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/ndl/eventlog.ndl>
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h
index 381a2ea98c..838353b8e9 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h
+++ b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h
@@ -26,17 +26,22 @@
#ifndef _LIBMLSVC_H
#define _LIBMLSVC_H
-#include <uuid/uuid.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/ksynch.h>
+#include <uuid/uuid.h>
+
#include <time.h>
#include <stdio.h>
#include <string.h>
+#include <syslog.h>
#include <netdb.h>
#include <libuutil.h>
-#include <smbsrv/wintypes.h>
+
+#include <smb/wintypes.h>
+#include <libmlrpc/libmlrpc.h>
+
#include <smbsrv/hash_table.h>
#include <smbsrv/smb_token.h>
#include <smbsrv/smb_privilege.h>
@@ -44,8 +49,6 @@
#include <smbsrv/smb_xdr.h>
#include <smbsrv/smb_dfs.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
-#include <smbsrv/ndl/lsarpc.ndl>
#ifdef __cplusplus
extern "C" {
@@ -128,24 +131,6 @@ typedef struct ms_luid {
} ms_luid_t;
/*
- * Information about a server as reported by NetServerGetInfo.
- * The SV_PLATFORM and SV_TYPE definitions are in srvsvc.ndl.
- */
-typedef struct srvsvc_server_info {
- uint32_t sv_platform_id;
- char *sv_name;
- uint32_t sv_version_major;
- uint32_t sv_version_minor;
- uint32_t sv_type;
- char *sv_comment;
- uint32_t sv_os;
-} srvsvc_server_info_t;
-
-int srvsvc_net_server_getinfo(char *, char *, srvsvc_server_info_t *);
-int srvsvc_net_remote_tod(char *, char *, struct timeval *, struct tm *);
-
-
-/*
* A client_t is created while binding a client connection to hold the
* context for calls made using that connection.
*
@@ -153,29 +138,23 @@ int srvsvc_net_remote_tod(char *, char *, struct timeval *, struct tm *);
* ensure that each handle has a pointer to the client_t. When the top
* level (bind) handle is released, we close the connection.
*/
-typedef struct mlsvc_handle {
- ndr_hdid_t handle;
- ndr_client_t *clnt;
- srvsvc_server_info_t svinfo;
-} mlsvc_handle_t;
+typedef struct mlrpc_handle mlsvc_handle_t;
+/* mlsvc_client.c */
void ndr_rpc_init(void);
void ndr_rpc_fini(void);
uint32_t ndr_rpc_bind(mlsvc_handle_t *, char *, char *, char *, const char *);
void ndr_rpc_unbind(mlsvc_handle_t *);
-int ndr_rpc_call(mlsvc_handle_t *, int, void *);
-void ndr_rpc_set_nonull(mlsvc_handle_t *);
-const srvsvc_server_info_t *ndr_rpc_server_info(mlsvc_handle_t *);
-uint32_t ndr_rpc_server_os(mlsvc_handle_t *);
-int ndr_rpc_get_ssnkey(mlsvc_handle_t *, unsigned char *, size_t);
-void *ndr_rpc_malloc(mlsvc_handle_t *, size_t);
-ndr_heap_t *ndr_rpc_get_heap(mlsvc_handle_t *);
-void ndr_rpc_release(mlsvc_handle_t *);
-boolean_t ndr_is_null_handle(mlsvc_handle_t *);
-boolean_t ndr_is_bind_handle(mlsvc_handle_t *);
-void ndr_inherit_handle(mlsvc_handle_t *, mlsvc_handle_t *);
void ndr_rpc_status(mlsvc_handle_t *, int, uint32_t);
+/* These three get info about the connected client. */
+boolean_t ndr_is_admin(ndr_xa_t *);
+boolean_t ndr_is_poweruser(ndr_xa_t *);
+int32_t ndr_native_os(ndr_xa_t *);
+
+/* SRVSVC */
+int srvsvc_net_remote_tod(char *, char *, struct timeval *, struct tm *);
+
/* SVCCTL service */
/*
* Calculate the wide-char equivalent string length required to
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/lsar_clnt.c b/usr/src/lib/smbsrv/libmlsvc/common/lsar_clnt.c
index eeab7745f2..7524e2db55 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/lsar_clnt.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/lsar_clnt.c
@@ -383,7 +383,6 @@ lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name, smb_account_t *info)
lsar_lookup_names1
};
- const srvsvc_server_info_t *svinfo;
lsa_names_t names;
char *p;
uint32_t length;
@@ -396,20 +395,15 @@ lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name, smb_account_t *info)
bzero(info, sizeof (smb_account_t));
- svinfo = ndr_rpc_server_info(lsa_handle);
- if (svinfo->sv_os == NATIVE_OS_WIN2000 &&
- svinfo->sv_version_major == 5 && svinfo->sv_version_minor == 0) {
- /*
- * Windows 2000 doesn't like an LSA lookup for
- * DOMAIN\Administrator.
- */
- if ((p = strchr(name, '\\')) != 0) {
- ++p;
-
- if (strcasecmp(p, "administrator") == 0)
- name = p;
- }
+ /*
+ * Windows 2000 (or later) doesn't like an LSA lookup for
+ * DOMAIN\Administrator.
+ */
+ if ((p = strchr(name, '\\')) != 0) {
+ ++p;
+ if (strcasecmp(p, "administrator") == 0)
+ name = p;
}
length = smb_wcequiv_strlen(name);
@@ -418,17 +412,12 @@ lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name, smb_account_t *info)
names.name[0].str = (unsigned char *)name;
names.n_entry = 1;
- if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) {
- for (i = 0; i < n_op; ++i) {
- ndr_rpc_set_nonull(lsa_handle);
- status = (*ops[i])(lsa_handle, &names, info);
-
- if (status != NT_STATUS_INVALID_PARAMETER)
- break;
- }
- } else {
+ for (i = 0; i < n_op; ++i) {
ndr_rpc_set_nonull(lsa_handle);
- status = lsar_lookup_names1(lsa_handle, &names, info);
+ status = (*ops[i])(lsa_handle, &names, info);
+
+ if (status != NT_STATUS_INVALID_PARAMETER)
+ break;
}
if (status == NT_STATUS_SUCCESS) {
@@ -726,10 +715,8 @@ lsar_lookup_sids(mlsvc_handle_t *lsa_handle, smb_sid_t *sid,
smb_sid_tostr(sid, sidbuf);
smb_tracef("%s", sidbuf);
- if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000)
- status = lsar_lookup_sids2(lsa_handle, (lsa_sid_t *)sid,
- account);
- else
+ status = lsar_lookup_sids2(lsa_handle, (lsa_sid_t *)sid, account);
+ if (status == RPC_NT_PROCNUM_OUT_OF_RANGE)
status = lsar_lookup_sids1(lsa_handle, (lsa_sid_t *)sid,
account);
@@ -1167,8 +1154,7 @@ lsar_lookup_priv_value(mlsvc_handle_t *lsa_handle, char *name,
(void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
length = smb_wcequiv_strlen(name);
- if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000)
- length += sizeof (smb_wchar_t);
+ length += sizeof (smb_wchar_t);
arg.name.length = length;
arg.name.allosize = length;
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/lsar_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/lsar_svc.c
index 3864260e2c..28d5e73948 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/lsar_svc.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/lsar_svc.c
@@ -33,8 +33,8 @@
#include <pwd.h>
#include <grp.h>
+#include <libmlrpc/libmlrpc.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/ndl/lsarpc.ndl>
#include <lsalib.h>
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h
index dcf2c5f0e7..2afc62a02d 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h
@@ -46,7 +46,6 @@ void netr_initialize(void);
void samr_initialize(void);
void svcctl_initialize(void);
void winreg_initialize(void);
-int srvsvc_gettime(unsigned long *);
void msgsvcsend_initialize(void);
void spoolss_initialize(void);
void netdfs_initialize(void);
@@ -64,7 +63,8 @@ int netr_setup_authenticator(struct netr_info *, struct netr_authenticator *,
struct netr_authenticator *);
DWORD netr_validate_chain(struct netr_info *, struct netr_authenticator *);
-void ndr_srvsvc_timecheck(char *, char *);
+int srvsvc_gettime(unsigned long *);
+void srvsvc_timecheck(char *, char *);
/* Generic functions to get/set windows Security Descriptors */
uint32_t srvsvc_sd_get(smb_share_t *, uint8_t *, uint32_t *);
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c
index ef3ca34bcd..c8879837b1 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c
@@ -31,32 +31,22 @@
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/fcntl.h>
-#include <sys/tzfile.h>
#include <time.h>
#include <strings.h>
#include <assert.h>
#include <errno.h>
#include <thread.h>
-#include <unistd.h>
#include <syslog.h>
#include <synch.h>
+#include <libmlrpc/libmlrpc.h>
#include <netsmb/smbfs_api.h>
+
#include <smbsrv/libsmb.h>
-#include <smbsrv/libsmbns.h>
-#include <smbsrv/libmlrpc.h>
#include <smbsrv/libmlsvc.h>
-#include <smbsrv/ndl/srvsvc.ndl>
#include <libsmbrdr.h>
#include <mlsvc.h>
-static int ndr_xa_init(ndr_client_t *, ndr_xa_t *);
-static int ndr_xa_exchange(ndr_client_t *, ndr_xa_t *);
-static int ndr_xa_read(ndr_client_t *, ndr_xa_t *);
-static void ndr_xa_preserve(ndr_client_t *, ndr_xa_t *);
-static void ndr_xa_destruct(ndr_client_t *, ndr_xa_t *);
-static void ndr_xa_release(ndr_client_t *);
-
/*
* This call must be made to initialize an RPC client structure and bind
@@ -71,13 +61,15 @@ static void ndr_xa_release(ndr_client_t *);
* unbind and teardown the connection. As each handle is initialized it
* will inherit a reference to the client context.
*
- * Returns 0 or an NT_STATUS:
+ * Returns 0 or an NT_STATUS: (failed in...)
+ *
* NT_STATUS_BAD_NETWORK_PATH (get server addr)
* NT_STATUS_NETWORK_ACCESS_DENIED (connect, auth)
- * NT_STATUS_BAD_NETWORK_NAME (tcon, open)
+ * NT_STATUS_BAD_NETWORK_NAME (tcon)
+ * RPC_NT_SERVER_TOO_BUSY (open pipe)
+ * RPC_NT_SERVER_UNAVAILABLE (open pipe)
* NT_STATUS_ACCESS_DENIED (open pipe)
* NT_STATUS_INVALID_PARAMETER (rpc bind)
- *
* NT_STATUS_INTERNAL_ERROR (bad args etc)
* NT_STATUS_NO_MEMORY
*/
@@ -86,11 +78,8 @@ ndr_rpc_bind(mlsvc_handle_t *handle, char *server, char *domain,
char *username, const char *service)
{
struct smb_ctx *ctx = NULL;
- ndr_client_t *clnt = NULL;
ndr_service_t *svc;
- srvsvc_server_info_t svinfo;
DWORD status;
- int fd = -1;
int rc;
if (handle == NULL || server == NULL || server[0] == '\0' ||
@@ -102,19 +91,6 @@ ndr_rpc_bind(mlsvc_handle_t *handle, char *server, char *domain,
return (NT_STATUS_INTERNAL_ERROR);
/*
- * Set the default based on the assumption that most
- * servers will be Windows 2000 or later. This used to
- * try to get the actual server version, but that RPC
- * is not necessarily allowed anymore, so don't bother.
- */
- bzero(&svinfo, sizeof (srvsvc_server_info_t));
- svinfo.sv_platform_id = SV_PLATFORM_ID_NT;
- svinfo.sv_version_major = 5;
- svinfo.sv_version_minor = 0;
- svinfo.sv_type = SV_TYPE_DEFAULT;
- svinfo.sv_os = NATIVE_OS_WIN2000;
-
- /*
* Some callers pass this when they want a NULL session.
* Todo: have callers pass an empty string for that.
*/
@@ -136,296 +112,82 @@ ndr_rpc_bind(mlsvc_handle_t *handle, char *server, char *domain,
"(Srv=%s Dom=%s User=%s), %s (0x%x)",
server, domain, username,
xlate_nt_status(status), status);
- /* Tell the DC Locator this DC failed. */
- smb_ddiscover_bad_dc(server);
- goto errout;
- }
-
- /*
- * Open the named pipe.
- */
- fd = smb_fh_open(ctx, svc->endpoint, O_RDWR);
- if (fd < 0) {
- rc = errno;
- syslog(LOG_DEBUG, "ndr_rpc_bind: "
- "smb_fh_open (%s) err=%d",
- svc->endpoint, rc);
- switch (rc) {
- case EACCES:
- status = NT_STATUS_ACCESS_DENIED;
- break;
+ /*
+ * If the error is one where changing to a new DC
+ * might help, try looking for a different DC.
+ */
+ switch (status) {
+ case NT_STATUS_BAD_NETWORK_PATH:
+ case NT_STATUS_BAD_NETWORK_NAME:
+ /* Look for a new DC */
+ smb_ddiscover_bad_dc(server);
default:
- status = NT_STATUS_BAD_NETWORK_NAME;
break;
}
- goto errout;
+ return (status);
}
/*
* Setup the RPC client handle.
*/
- if ((clnt = malloc(sizeof (ndr_client_t))) == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto errout;
- }
- bzero(clnt, sizeof (ndr_client_t));
-
- clnt->handle = &handle->handle;
- clnt->xa_init = ndr_xa_init;
- clnt->xa_exchange = ndr_xa_exchange;
- clnt->xa_read = ndr_xa_read;
- clnt->xa_preserve = ndr_xa_preserve;
- clnt->xa_destruct = ndr_xa_destruct;
- clnt->xa_release = ndr_xa_release;
- clnt->xa_private = ctx;
- clnt->xa_fd = fd;
-
- ndr_svc_binding_pool_init(&clnt->binding_list,
- clnt->binding_pool, NDR_N_BINDING_POOL);
-
- if ((clnt->heap = ndr_heap_create()) == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto errout;
+ rc = mlrpc_clh_create(handle, ctx);
+ if (rc != 0) {
+ syslog(LOG_ERR, "ndr_rpc_bind: mlrpc_clh_create: rc=%d", rc);
+ smbrdr_ctx_free(ctx);
+ switch (rc) {
+ case ENOMEM:
+ return (NT_STATUS_NO_MEMORY);
+ case EINVAL:
+ return (NT_STATUS_INVALID_PARAMETER);
+ default:
+ return (NT_STATUS_INTERNAL_ERROR);
+ }
}
/*
- * Fill in the caller's handle.
+ * This does the pipe open and OtW RPC bind.
+ * Handles pipe open retries.
*/
- bzero(&handle->handle, sizeof (ndr_hdid_t));
- handle->clnt = clnt;
- bcopy(&svinfo, &handle->svinfo, sizeof (srvsvc_server_info_t));
-
- /*
- * Do the OtW RPC bind.
- */
- rc = ndr_clnt_bind(clnt, service, &clnt->binding);
- switch (rc) {
- case NDR_DRC_FAULT_OUT_OF_MEMORY:
- status = NT_STATUS_NO_MEMORY;
- break;
- case NDR_DRC_FAULT_API_SERVICE_INVALID: /* not registered */
- status = NT_STATUS_INTERNAL_ERROR;
- break;
- default:
- if (NDR_DRC_IS_FAULT(rc)) {
- status = NT_STATUS_INVALID_PARAMETER;
+ status = mlrpc_clh_bind(handle, svc);
+ if (status != 0) {
+ syslog(LOG_DEBUG, "ndr_rpc_bind: "
+ "mlrpc_clh_bind, %s (0x%x)",
+ xlate_nt_status(status), status);
+ switch (status) {
+ case RPC_NT_SERVER_TOO_BUSY:
+ /* Look for a new DC */
+ smb_ddiscover_bad_dc(server);
+ break;
+ default:
break;
}
- /* FALLTHROUGH */
- case NDR_DRC_OK:
- return (NT_STATUS_SUCCESS);
- }
-
- syslog(LOG_DEBUG, "ndr_rpc_bind: "
- "ndr_clnt_bind, %s (0x%x)",
- xlate_nt_status(status), status);
-
-errout:
- handle->clnt = NULL;
- if (clnt != NULL) {
- ndr_heap_destroy(clnt->heap);
- free(clnt);
- }
- if (ctx != NULL) {
- if (fd != -1)
- (void) smb_fh_close(fd);
- smbrdr_ctx_free(ctx);
+ ctx = mlrpc_clh_free(handle);
+ if (ctx != NULL) {
+ smbrdr_ctx_free(ctx);
+ }
}
return (status);
}
/*
- * Unbind and close the pipe to an RPC service.
- *
- * If the heap has been preserved we need to go through an xa release.
- * The heap is preserved during an RPC call because that's where data
- * returned from the server is stored.
+ * Unbind and close the pipe to an RPC service
+ * and cleanup the smb_ctx.
*
- * Otherwise we destroy the heap directly.
+ * The heap may or may not be destroyed (see mlrpc_clh_free)
*/
void
ndr_rpc_unbind(mlsvc_handle_t *handle)
{
- ndr_client_t *clnt = handle->clnt;
- struct smb_ctx *ctx = clnt->xa_private;
+ struct smb_ctx *ctx;
- if (clnt->heap_preserved)
- ndr_clnt_free_heap(clnt);
- else
- ndr_heap_destroy(clnt->heap);
+ ctx = mlrpc_clh_free(handle);
+ if (ctx != NULL)
+ smbrdr_ctx_free(ctx);
- (void) smb_fh_close(clnt->xa_fd);
- smbrdr_ctx_free(ctx);
- free(clnt);
bzero(handle, sizeof (mlsvc_handle_t));
}
-/*
- * Call the RPC function identified by opnum. The remote service is
- * identified by the handle, which should have been initialized by
- * ndr_rpc_bind.
- *
- * If the RPC call is successful (returns 0), the caller must call
- * ndr_rpc_release to release the heap. Otherwise, we release the
- * heap here.
- */
-int
-ndr_rpc_call(mlsvc_handle_t *handle, int opnum, void *params)
-{
- ndr_client_t *clnt = handle->clnt;
- int rc;
-
- if (ndr_rpc_get_heap(handle) == NULL)
- return (-1);
-
- rc = ndr_clnt_call(clnt->binding, opnum, params);
-
- /*
- * Always clear the nonull flag to ensure
- * it is not applied to subsequent calls.
- */
- clnt->nonull = B_FALSE;
-
- if (NDR_DRC_IS_FAULT(rc)) {
- ndr_rpc_release(handle);
- return (-1);
- }
-
- return (0);
-}
-
-/*
- * Outgoing strings should not be null terminated.
- */
-void
-ndr_rpc_set_nonull(mlsvc_handle_t *handle)
-{
- handle->clnt->nonull = B_TRUE;
-}
-
-/*
- * Return a reference to the server info.
- */
-const srvsvc_server_info_t *
-ndr_rpc_server_info(mlsvc_handle_t *handle)
-{
- return (&handle->svinfo);
-}
-
-/*
- * Return the RPC server OS level.
- */
-uint32_t
-ndr_rpc_server_os(mlsvc_handle_t *handle)
-{
- return (handle->svinfo.sv_os);
-}
-
-/*
- * Get the session key from a bound RPC client handle.
- *
- * The key returned is the 16-byte "user session key"
- * established by the underlying authentication protocol
- * (either Kerberos or NTLM). This key is needed for
- * SAM RPC calls such as SamrSetInformationUser, etc.
- * See [MS-SAMR] sections: 2.2.3.3, 2.2.7.21, 2.2.7.25.
- *
- * Returns zero (success) or an errno.
- */
-int
-ndr_rpc_get_ssnkey(mlsvc_handle_t *handle,
- unsigned char *ssn_key, size_t len)
-{
- ndr_client_t *clnt = handle->clnt;
- int rc;
-
- if (clnt == NULL)
- return (EINVAL);
-
- rc = smb_fh_getssnkey(clnt->xa_fd, ssn_key, len);
- return (rc);
-}
-
-void *
-ndr_rpc_malloc(mlsvc_handle_t *handle, size_t size)
-{
- ndr_heap_t *heap;
-
- if ((heap = ndr_rpc_get_heap(handle)) == NULL)
- return (NULL);
-
- return (ndr_heap_malloc(heap, size));
-}
-
-ndr_heap_t *
-ndr_rpc_get_heap(mlsvc_handle_t *handle)
-{
- ndr_client_t *clnt = handle->clnt;
-
- if (clnt->heap == NULL)
- clnt->heap = ndr_heap_create();
-
- return (clnt->heap);
-}
-
-/*
- * Must be called by RPC clients to free the heap after a successful RPC
- * call, i.e. ndr_rpc_call returned 0. The caller should take a copy
- * of any data returned by the RPC prior to calling this function because
- * returned data is in the heap.
- */
-void
-ndr_rpc_release(mlsvc_handle_t *handle)
-{
- ndr_client_t *clnt = handle->clnt;
-
- if (clnt->heap_preserved)
- ndr_clnt_free_heap(clnt);
- else
- ndr_heap_destroy(clnt->heap);
-
- clnt->heap = NULL;
-}
-
-/*
- * Returns true if the handle is null.
- * Otherwise returns false.
- */
-boolean_t
-ndr_is_null_handle(mlsvc_handle_t *handle)
-{
- static ndr_hdid_t zero_handle;
-
- if (handle == NULL || handle->clnt == NULL)
- return (B_TRUE);
-
- if (!memcmp(&handle->handle, &zero_handle, sizeof (ndr_hdid_t)))
- return (B_TRUE);
-
- return (B_FALSE);
-}
-
-/*
- * Returns true if the handle is the top level bind handle.
- * Otherwise returns false.
- */
-boolean_t
-ndr_is_bind_handle(mlsvc_handle_t *handle)
-{
- return (handle->clnt->handle == &handle->handle);
-}
-
-/*
- * Pass the client reference from parent to child.
- */
-void
-ndr_inherit_handle(mlsvc_handle_t *child, mlsvc_handle_t *parent)
-{
- child->clnt = parent->clnt;
- bcopy(&parent->svinfo, &child->svinfo, sizeof (srvsvc_server_info_t));
-}
-
void
ndr_rpc_status(mlsvc_handle_t *handle, int opnum, DWORD status)
{
@@ -456,193 +218,3 @@ ndr_rpc_status(mlsvc_handle_t *handle, int opnum, DWORD status)
smb_tracef("%s[0x%02x]: %s: %s (0x%08x)",
name, opnum, s, xlate_nt_status(status), status);
}
-
-/*
- * The following functions provide the client callback interface.
- * If the caller hasn't provided a heap, create one here.
- */
-static int
-ndr_xa_init(ndr_client_t *clnt, ndr_xa_t *mxa)
-{
- ndr_stream_t *recv_nds = &mxa->recv_nds;
- ndr_stream_t *send_nds = &mxa->send_nds;
- ndr_heap_t *heap = clnt->heap;
- int rc;
-
- if (heap == NULL) {
- if ((heap = ndr_heap_create()) == NULL)
- return (-1);
-
- clnt->heap = heap;
- }
-
- mxa->heap = heap;
-
- rc = nds_initialize(send_nds, 0, NDR_MODE_CALL_SEND, heap);
- if (rc == 0)
- rc = nds_initialize(recv_nds, NDR_PDU_SIZE_HINT_DEFAULT,
- NDR_MODE_RETURN_RECV, heap);
-
- if (rc != 0) {
- nds_destruct(&mxa->recv_nds);
- nds_destruct(&mxa->send_nds);
- ndr_heap_destroy(mxa->heap);
- mxa->heap = NULL;
- clnt->heap = NULL;
- return (-1);
- }
-
- if (clnt->nonull)
- NDS_SETF(send_nds, NDS_F_NONULL);
-
- return (0);
-}
-
-/*
- * This is the entry pointy for an RPC client call exchange with
- * a server, which will result in an smbrdr SmbTransact request.
- *
- * SmbTransact should return the number of bytes received, which
- * we record as the PDU size, or a negative error code.
- */
-static int
-ndr_xa_exchange(ndr_client_t *clnt, ndr_xa_t *mxa)
-{
- ndr_stream_t *recv_nds = &mxa->recv_nds;
- ndr_stream_t *send_nds = &mxa->send_nds;
- int err, more, nbytes;
-
- nbytes = recv_nds->pdu_max_size;
- err = smb_fh_xactnp(clnt->xa_fd,
- send_nds->pdu_size, (char *)send_nds->pdu_base_offset,
- &nbytes, (char *)recv_nds->pdu_base_offset, &more);
- if (err) {
- recv_nds->pdu_size = 0;
- return (-1);
- }
-
- recv_nds->pdu_size = nbytes;
- return (0);
-}
-
-/*
- * This entry point will be invoked if the xa-exchange response contained
- * only the first fragment of a multi-fragment response. The RPC client
- * code will then make repeated xa-read requests to obtain the remaining
- * fragments, which will result in smbrdr SmbReadX requests.
- *
- * SmbReadX should return the number of bytes received, in which case we
- * expand the PDU size to include the received data, or a negative error
- * code.
- */
-static int
-ndr_xa_read(ndr_client_t *clnt, ndr_xa_t *mxa)
-{
- ndr_stream_t *nds = &mxa->recv_nds;
- int len;
- int nbytes;
-
- if ((len = (nds->pdu_max_size - nds->pdu_size)) < 0)
- return (-1);
-
- nbytes = smb_fh_read(clnt->xa_fd, 0, len,
- (char *)nds->pdu_base_offset + nds->pdu_size);
-
- if (nbytes < 0)
- return (-1);
-
- nds->pdu_size += nbytes;
-
- if (nds->pdu_size > nds->pdu_max_size) {
- nds->pdu_size = nds->pdu_max_size;
- return (-1);
- }
-
- return (nbytes);
-}
-
-/*
- * Preserve the heap so that the client application has access to data
- * returned from the server after an RPC call.
- */
-static void
-ndr_xa_preserve(ndr_client_t *clnt, ndr_xa_t *mxa)
-{
- assert(clnt->heap == mxa->heap);
-
- clnt->heap_preserved = B_TRUE;
- mxa->heap = NULL;
-}
-
-/*
- * Dispose of the transaction streams. If the heap has not been
- * preserved, we can destroy it here.
- */
-static void
-ndr_xa_destruct(ndr_client_t *clnt, ndr_xa_t *mxa)
-{
- nds_destruct(&mxa->recv_nds);
- nds_destruct(&mxa->send_nds);
-
- if (!clnt->heap_preserved) {
- ndr_heap_destroy(mxa->heap);
- mxa->heap = NULL;
- clnt->heap = NULL;
- }
-}
-
-/*
- * Dispose of a preserved heap.
- */
-static void
-ndr_xa_release(ndr_client_t *clnt)
-{
- if (clnt->heap_preserved) {
- ndr_heap_destroy(clnt->heap);
- clnt->heap = NULL;
- clnt->heap_preserved = B_FALSE;
- }
-}
-
-
-/*
- * Compare the time here with the remote time on the server
- * and report clock skew.
- */
-void
-ndr_srvsvc_timecheck(char *server, char *domain)
-{
- char hostname[MAXHOSTNAMELEN];
- struct timeval dc_tv;
- struct tm dc_tm;
- struct tm *tm;
- time_t tnow;
- time_t tdiff;
- int priority;
-
- if (srvsvc_net_remote_tod(server, domain, &dc_tv, &dc_tm) < 0) {
- syslog(LOG_DEBUG, "srvsvc_net_remote_tod failed");
- return;
- }
-
- tnow = time(NULL);
-
- if (tnow > dc_tv.tv_sec)
- tdiff = (tnow - dc_tv.tv_sec) / SECSPERMIN;
- else
- tdiff = (dc_tv.tv_sec - tnow) / SECSPERMIN;
-
- if (tdiff != 0) {
- (void) strlcpy(hostname, "localhost", MAXHOSTNAMELEN);
- (void) gethostname(hostname, MAXHOSTNAMELEN);
-
- priority = (tdiff > 2) ? LOG_NOTICE : LOG_DEBUG;
- syslog(priority, "DC [%s] clock skew detected: %u minutes",
- server, tdiff);
-
- tm = gmtime(&dc_tv.tv_sec);
- syslog(priority, "%-8s UTC: %s", server, asctime(tm));
- tm = gmtime(&tnow);
- syslog(priority, "%-8s UTC: %s", hostname, asctime(tm));
- }
-}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c
index 794e6c9576..cdb6478f5b 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c
@@ -111,7 +111,7 @@ mlsvc_timecheck(void *arg)
if (!smb_domain_getinfo(&di))
continue;
- ndr_srvsvc_timecheck(di.d_dci.dc_name,
+ srvsvc_timecheck(di.d_dci.dc_name,
di.d_primary.di_nbname);
}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c
index ad3565699b..b46cf99f87 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c
@@ -425,3 +425,43 @@ mlsvc_disconnect(const char *server)
{
smbrdr_disconnect(server);
}
+
+/*
+ * A few more helper functions for RPC services.
+ */
+
+/*
+ * Check whether or not the specified user has administrator privileges,
+ * i.e. is a member of Domain Admins or Administrators.
+ * Returns true if the user is an administrator, otherwise returns false.
+ */
+boolean_t
+ndr_is_admin(ndr_xa_t *xa)
+{
+ smb_netuserinfo_t *ctx = xa->pipe->np_user;
+
+ return (ctx->ui_flags & SMB_ATF_ADMIN);
+}
+
+/*
+ * Check whether or not the specified user has power-user privileges,
+ * i.e. is a member of Domain Admins, Administrators or Power Users.
+ * This is typically required for operations such as managing shares.
+ * Returns true if the user is a power user, otherwise returns false.
+ */
+boolean_t
+ndr_is_poweruser(ndr_xa_t *xa)
+{
+ smb_netuserinfo_t *ctx = xa->pipe->np_user;
+
+ return ((ctx->ui_flags & SMB_ATF_ADMIN) ||
+ (ctx->ui_flags & SMB_ATF_POWERUSER));
+}
+
+int32_t
+ndr_native_os(ndr_xa_t *xa)
+{
+ smb_netuserinfo_t *ctx = xa->pipe->np_user;
+
+ return (ctx->ui_native_os);
+}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/msgsvc_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/msgsvc_svc.c
index 78538e6291..b49a3946ad 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/msgsvc_svc.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/msgsvc_svc.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -30,8 +31,8 @@
#include <syslog.h>
#include <stdlib.h>
+#include <libmlrpc/libmlrpc.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/ndl/msgsvc.ndl>
#include <smbsrv/smbinfo.h>
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c b/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c
index ea31c935ed..2b22744304 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c
@@ -191,6 +191,10 @@ netr_server_req_challenge(mlsvc_handle_t *netr_handle, netr_info_t *netr_info)
return (0);
}
+uint32_t netr_server_auth2_flags =
+ NETR_NEGOTIATE_BASE_FLAGS |
+ NETR_NEGOTIATE_STRONGKEY_FLAG;
+
/*
* netr_server_authenticate2
*/
@@ -216,10 +220,9 @@ netr_server_authenticate2(mlsvc_handle_t *netr_handle, netr_info_t *netr_info)
arg.account_name = (unsigned char *)account_name;
arg.account_type = NETR_WKSTA_TRUST_ACCOUNT_TYPE;
arg.hostname = (unsigned char *)netr_info->hostname;
- arg.negotiate_flags = NETR_NEGOTIATE_BASE_FLAGS;
+ arg.negotiate_flags = netr_server_auth2_flags;
- if (ndr_rpc_server_os(netr_handle) == NATIVE_OS_WIN2000) {
- arg.negotiate_flags |= NETR_NEGOTIATE_STRONGKEY_FLAG;
+ if (arg.negotiate_flags & NETR_NEGOTIATE_STRONGKEY_FLAG) {
if (netr_gen_skey128(netr_info) != SMBAUTH_SUCCESS)
return (-1);
} else {
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c
index ab99db75f8..6fdd3a9ca4 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c
@@ -37,8 +37,8 @@
#include <netdb.h>
#include <thread.h>
+#include <libmlrpc/libmlrpc.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/ndl/netlogon.ndl>
#include <smbsrv/netrauth.h>
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samr_clnt.c b/usr/src/lib/smbsrv/libmlsvc/common/samr_clnt.c
index 289e8470cf..dd15469c15 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/samr_clnt.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/samr_clnt.c
@@ -44,8 +44,8 @@
#include <netdb.h>
#include <sys/param.h>
+#include <libmlrpc/libmlrpc.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/smbinfo.h>
#include <smbsrv/ntaccess.h>
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c
index 8835a8e00f..43ae0568e9 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c
@@ -39,8 +39,8 @@
#include <netdb.h>
#include <assert.h>
#include <grp.h>
+#include <libmlrpc/libmlrpc.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/smbinfo.h>
#include <smbsrv/nmpipes.h>
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c
index ba1c9caece..302c7fb278 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c
@@ -35,8 +35,8 @@
#include <strings.h>
#include <fcntl.h>
#include <errno.h>
+#include <libmlrpc/libmlrpc.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlrpc.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/smb.h>
#include <smbsrv/ndl/spoolss.ndl>
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_clnt.c b/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_clnt.c
index def8ced54a..c7e5d60a6b 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_clnt.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_clnt.c
@@ -34,9 +34,11 @@
*/
#include <sys/errno.h>
+#include <sys/tzfile.h>
#include <stdio.h>
#include <time.h>
#include <strings.h>
+#include <unistd.h>
#include <smbsrv/libsmb.h>
#include <smbsrv/libmlsvc.h>
@@ -348,65 +350,45 @@ srvsvc_net_connect_enum(char *server, char *domain, char *netname, int level)
}
/*
- * Windows 95+ and Windows NT4.0 both report the version as 4.0.
- * Windows 2000+ reports the version as 5.x.
+ * Compare the time here with the remote time on the server
+ * and report clock skew.
*/
-int
-srvsvc_net_server_getinfo(char *server, char *domain,
- srvsvc_server_info_t *svinfo)
+void
+srvsvc_timecheck(char *server, char *domain)
{
- mlsvc_handle_t handle;
- struct mslm_NetServerGetInfo arg;
- struct mslm_SERVER_INFO_101 *sv101;
- int len, opnum, rc;
- char user[SMB_USERNAME_MAXLEN];
+ char hostname[MAXHOSTNAMELEN];
+ struct timeval dc_tv;
+ struct tm dc_tm;
+ struct tm *tm;
+ time_t tnow;
+ time_t tdiff;
+ int priority;
+
+ if (srvsvc_net_remote_tod(server, domain, &dc_tv, &dc_tm) < 0) {
+ syslog(LOG_DEBUG, "srvsvc_net_remote_tod failed");
+ return;
+ }
- smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
+ tnow = time(NULL);
- if (srvsvc_open(server, domain, user, &handle) != 0)
- return (-1);
+ if (tnow > dc_tv.tv_sec)
+ tdiff = (tnow - dc_tv.tv_sec) / SECSPERMIN;
+ else
+ tdiff = (dc_tv.tv_sec - tnow) / SECSPERMIN;
- opnum = SRVSVC_OPNUM_NetServerGetInfo;
- bzero(&arg, sizeof (arg));
+ if (tdiff != 0) {
+ (void) strlcpy(hostname, "localhost", MAXHOSTNAMELEN);
+ (void) gethostname(hostname, MAXHOSTNAMELEN);
- len = strlen(server) + 4;
- arg.servername = ndr_rpc_malloc(&handle, len);
- if (arg.servername == NULL)
- return (-1);
+ priority = (tdiff > 2) ? LOG_NOTICE : LOG_DEBUG;
+ syslog(priority, "DC [%s] clock skew detected: %u minutes",
+ server, tdiff);
- (void) snprintf((char *)arg.servername, len, "\\\\%s", server);
- arg.level = 101;
-
- rc = ndr_rpc_call(&handle, opnum, &arg);
- if ((rc != 0) || (arg.status != 0)) {
- srvsvc_close(&handle);
- return (-1);
+ tm = gmtime(&dc_tv.tv_sec);
+ syslog(priority, "%-8s UTC: %s", server, asctime(tm));
+ tm = gmtime(&tnow);
+ syslog(priority, "%-8s UTC: %s", hostname, asctime(tm));
}
-
- sv101 = arg.result.bufptr.bufptr101;
-
- bzero(svinfo, sizeof (srvsvc_server_info_t));
- svinfo->sv_platform_id = sv101->sv101_platform_id;
- svinfo->sv_version_major = sv101->sv101_version_major;
- svinfo->sv_version_minor = sv101->sv101_version_minor;
- svinfo->sv_type = sv101->sv101_type;
- if (sv101->sv101_name)
- svinfo->sv_name = strdup((char *)sv101->sv101_name);
- if (sv101->sv101_comment)
- svinfo->sv_comment = strdup((char *)sv101->sv101_comment);
-
- if (svinfo->sv_type & SV_TYPE_WFW)
- svinfo->sv_os = NATIVE_OS_WIN95;
- if (svinfo->sv_type & SV_TYPE_WINDOWS)
- svinfo->sv_os = NATIVE_OS_WIN95;
- if ((svinfo->sv_type & SV_TYPE_NT) ||
- (svinfo->sv_type & SV_TYPE_SERVER_NT))
- svinfo->sv_os = NATIVE_OS_WINNT;
- if (svinfo->sv_version_major > 4)
- svinfo->sv_os = NATIVE_OS_WIN2000;
-
- srvsvc_close(&handle);
- return (0);
}
/*
@@ -544,39 +526,3 @@ srvsvc_net_remote_tod(char *server, char *domain, struct timeval *tv,
srvsvc_close(&handle);
return (0);
}
-
-void
-srvsvc_net_test(char *server, char *domain, char *netname)
-{
- smb_domainex_t di;
- srvsvc_server_info_t svinfo;
-
- (void) smb_tracef("%s %s %s", server, domain, netname);
-
- if (smb_domain_getinfo(&di)) {
- server = di.d_dci.dc_name;
- domain = di.d_primary.di_nbname;
- }
-
- if (srvsvc_net_server_getinfo(server, domain, &svinfo) == 0) {
- smb_tracef("NetServerGetInfo: %s %s (%d.%d) id=%d type=0x%08x",
- svinfo.sv_name ? svinfo.sv_name : "NULL",
- svinfo.sv_comment ? svinfo.sv_comment : "NULL",
- svinfo.sv_version_major, svinfo.sv_version_minor,
- svinfo.sv_platform_id, svinfo.sv_type);
-
- free(svinfo.sv_name);
- free(svinfo.sv_comment);
- }
-
- (void) srvsvc_net_share_get_info(server, domain, netname);
-#if 0
- /*
- * The NetSessionEnum server-side definition was updated.
- * Disabled until the client-side has been updated.
- */
- (void) srvsvc_net_session_enum(server, domain, netname);
-#endif
- (void) srvsvc_net_connect_enum(server, domain, netname, 0);
- (void) srvsvc_net_connect_enum(server, domain, netname, 1);
-}
diff --git a/usr/src/lib/smbsrv/libsmb/common/libsmb.h b/usr/src/lib/smbsrv/libsmb/common/libsmb.h
index fdda80dc2a..82d6bc1cc3 100644
--- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h
+++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h
@@ -44,17 +44,18 @@ extern "C" {
#include <synch.h>
#include <stdarg.h>
+#include <smb/nterror.h>
+#include <smb/ntstatus.h>
+#include <smb/wintypes.h>
+
#include <smbsrv/string.h>
#include <smbsrv/smb_idmap.h>
#include <smbsrv/netbios.h>
#include <smbsrv/smb_share.h>
-#include <smb/nterror.h>
-#include <smb/ntstatus.h>
#include <smbsrv/smb_door.h>
#include <smbsrv/alloc.h>
#include <smbsrv/hash_table.h>
#include <smbsrv/msgbuf.h>
-#include <smbsrv/wintypes.h>
#include <smbsrv/smb_xdr.h>
#include <smbsrv/smbinfo.h>
#include <smbsrv/ntifs.h>
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_doorclnt.c b/usr/src/lib/smbsrv/libsmb/common/smb_doorclnt.c
index e51f8bbca1..dfbbfd0483 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_doorclnt.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_doorclnt.c
@@ -33,8 +33,8 @@
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
+#include <smb/wintypes.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/wintypes.h>
#include <smbsrv/smb_door.h>
static int smb_door_call(uint32_t, void *, xdrproc_t, void *, xdrproc_t);
diff --git a/usr/src/pkg/manifests/driver-storage-mpt_sas.mf b/usr/src/pkg/manifests/driver-storage-mpt_sas.mf
index ae55dc9422..c0506e3307 100644
--- a/usr/src/pkg/manifests/driver-storage-mpt_sas.mf
+++ b/usr/src/pkg/manifests/driver-storage-mpt_sas.mf
@@ -71,8 +71,25 @@ driver name=mpt_sas class=scsi-self-identifying \
alias=pciex1000,95 \
alias=pciex1000,96 \
alias=pciex1000,97 \
+ alias=pciex1000,aa \
+ alias=pciex1000,ab \
+ alias=pciex1000,ac \
+ alias=pciex1000,ad \
+ alias=pciex1000,ae \
+ alias=pciex1000,af \
+ alias=pciex1000,c0 \
+ alias=pciex1000,c1 \
+ alias=pciex1000,c2 \
+ alias=pciex1000,c3 \
alias=pciex1000,c4 \
- alias=pciex1000,c9
+ alias=pciex1000,c5 \
+ alias=pciex1000,c6 \
+ alias=pciex1000,c7 \
+ alias=pciex1000,c8 \
+ alias=pciex1000,c9 \
+ alias=pciex1000,d0 \
+ alias=pciex1000,d1 \
+ alias=pciex1000,d2
file path=kernel/drv/$(ARCH64)/mpt_sas group=sys
file path=kernel/drv/mpt_sas.conf group=sys \
original_name=SUNWmptsas:kernel/drv/mpt_sas.conf preserve=true
@@ -81,3 +98,5 @@ legacy pkg=SUNWmptsas desc="LSI MPT SAS 2.0/2.5 Controller HBA Driver" \
name="LSI MPT SAS 2.0/2.5 Controller HBA Driver"
license cr_Sun license=cr_Sun
license lic_CDDL license=lic_CDDL
+license usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/THIRDPARTYLICENSE \
+ license=usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/THIRDPARTYLICENSE
diff --git a/usr/src/pkg/manifests/service-file-system-smb.mf b/usr/src/pkg/manifests/service-file-system-smb.mf
index 4b349a26bc..ba5dedcd6d 100644
--- a/usr/src/pkg/manifests/service-file-system-smb.mf
+++ b/usr/src/pkg/manifests/service-file-system-smb.mf
@@ -83,7 +83,6 @@ file path=usr/lib/smbsrv/dtrace/smbd-pipesvc.d mode=0555
file path=usr/lib/smbsrv/dtrace/smbnode.d mode=0555
file path=usr/lib/smbsrv/dtrace/smbsrv.d mode=0555
file path=usr/lib/smbsrv/dtrace/smbvfs.d mode=0555
-file path=usr/lib/smbsrv/libmlrpc.so.1
file path=usr/lib/smbsrv/libmlsvc.so.1
file path=usr/lib/smbsrv/libsmb.so.1
file path=usr/lib/smbsrv/libsmbns.so.1
@@ -109,7 +108,3 @@ license cr_Sun license=cr_Sun
license lic_CDDL license=lic_CDDL
link path=usr/lib/reparse/libreparse_smb.so target=libreparse_smb.so.1
link path=usr/lib/security/pam_smb_passwd.so target=pam_smb_passwd.so.1
-link path=usr/lib/smbsrv/libmlrpc.so target=libmlrpc.so.1
-link path=usr/lib/smbsrv/libmlsvc.so target=libmlsvc.so.1
-link path=usr/lib/smbsrv/libsmb.so target=libsmb.so.1
-link path=usr/lib/smbsrv/libsmbns.so target=libsmbns.so.1
diff --git a/usr/src/pkg/manifests/system-file-system-smb.mf b/usr/src/pkg/manifests/system-file-system-smb.mf
index b68191317a..b5ff30e5ad 100644
--- a/usr/src/pkg/manifests/system-file-system-smb.mf
+++ b/usr/src/pkg/manifests/system-file-system-smb.mf
@@ -79,6 +79,7 @@ file path=usr/lib/fs/smbfs/mount mode=4555
file path=usr/lib/fs/smbfs/share mode=0555
file path=usr/lib/fs/smbfs/umount mode=4555
file path=usr/lib/fs/smbfs/unshare mode=0555
+file path=usr/lib/libmlrpc.so.2
file path=usr/lib/libsmbfs.so.1
file path=usr/lib/mdb/kvm/$(ARCH64)/nsmb.so mode=0555
file path=usr/lib/mdb/kvm/$(ARCH64)/smbfs.so mode=0555
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_rewind_config_changed.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_rewind_config_changed.ksh
index 7b5870b8d6..1e86a66b7c 100644
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_rewind_config_changed.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_rewind_config_changed.ksh
@@ -12,7 +12,7 @@
#
#
-# Copyright (c) 2017 by Delphix. All rights reserved.
+# Copyright (c) 2016, 2018 by Delphix. All rights reserved.
#
. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.kshlib
@@ -49,6 +49,7 @@ function custom_cleanup
set_vdev_validate_skip 0
cleanup
log_must mdb_ctf_set_int vdev_min_ms_count 0t16
+ log_must mdb_ctf_set_int spa_allocators 0t4
}
log_onexit custom_cleanup
@@ -207,6 +208,10 @@ increase_device_sizes $(( FILE_SIZE * 4 ))
# reduce the chance of reusing a metaslab that holds old MOS metadata.
log_must mdb_ctf_set_int vdev_min_ms_count 0t150
+# Decrease the number of allocators for pools created during this test,
+# to increase the odds that metadata survives from old txgs.
+log_must mdb_ctf_set_int spa_allocators 0t1
+
# Part of the rewind test is to see how it reacts to path changes
typeset pathstochange="$VDEV0 $VDEV1 $VDEV2 $VDEV3"
diff --git a/usr/src/test/zfs-tests/tests/functional/slog/slog_014_pos.ksh b/usr/src/test/zfs-tests/tests/functional/slog/slog_014_pos.ksh
index b9dbc6c97e..621ac23aa9 100644
--- a/usr/src/test/zfs-tests/tests/functional/slog/slog_014_pos.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/slog/slog_014_pos.ksh
@@ -26,7 +26,7 @@
#
#
-# Copyright (c) 2013, 2016 by Delphix. All rights reserved.
+# Copyright (c) 2013, 2018 by Delphix. All rights reserved.
#
. $STF_SUITE/tests/functional/slog/slog.kshlib
@@ -52,9 +52,19 @@ do
log_must zpool create $TESTPOOL $type $VDEV $spare $SDEV \
log $LDEV
+ # Create a file to be corrupted
+ dd if=/dev/urandom of=/$TESTPOOL/filler bs=1024k count=50
+
+ #
+ # Ensure the file has been synced out before attempting to
+ # corrupt its contents.
+ #
+ sync
+
+ #
# Corrupt a pool device to make the pool DEGRADED
- dd if=/dev/urandom of=/$TESTPOOL/filler bs=1024k count=50
# The oseek value below is to skip past the vdev label.
+ #
log_must dd if=/dev/urandom of=$VDIR/a bs=1024k oseek=4 \
conv=notrunc count=50
log_must zpool scrub $TESTPOOL
diff --git a/usr/src/tools/ndrgen/ndrgen.sh b/usr/src/tools/ndrgen/ndrgen.sh
index c74253b6d2..19dbb9f8e5 100644
--- a/usr/src/tools/ndrgen/ndrgen.sh
+++ b/usr/src/tools/ndrgen/ndrgen.sh
@@ -19,16 +19,24 @@
#
# CDDL HEADER END
#
+
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
+# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+#
# This is a wrapper script around the ndrgen compiler (ndrgen1).
-# CC must be defined in the environment or on the command line.
-NDRPROG="${0%/*}/ndrgen1"
-INCDIR=${ROOT}/usr/include/smbsrv
+NDRPROG="${0}1"
+
+# Note: most *.ndl files require an ANSI-compatible cpp,
+# so we can NOT use /usr/lib/cpp or /usr/ccs/lib/cpp
+# Wish there was an easier way to get an ANSI cpp.
+CPP="${CC} -E"
+CPPFLAGS="-DNDRGEN"
+V_FLAG=
PROGNAME=`basename $0`
@@ -38,60 +46,61 @@ ndrgen_usage()
print "$PROGNAME: ERROR: $1"
fi
- echo "usage: $PROGNAME [-Y cpp-path] file [file]..."
+ echo "usage: $PROGNAME [options] file.ndl [file.ndl]..."
+ echo " options: -Y cc-path -Ddefine -Iinclude"
exit 1
}
-# Copy header text from the input ndl file to the generated ndr C file.
-ndrgen_copy_header()
+# Process the input ndl file ($1) generating C code on stdout.
+process()
{
- ndl_file=$1
- ndr_file=$2
+ # Put the standard top matter
+ #
+ # Want the include directive to have just
+ # include "file.ndl" (no path) so...
+ inc_ndl=`basename $1`
+ cat - << EOF
+/*
+ * Please do not edit this file.
+ * It was generated using ndrgen.
+ */
+
+#include <strings.h>
+#include <libmlrpc/ndr.h>
+#include "$inc_ndl"
+EOF
+
+ # Put optional custom top matter
nawk 'BEGIN { copy=0; }
/^\/\* NDRGEN_HEADER_BEGIN \*\// { copy=1; next; }
/^\/\* NDRGEN_HEADER_END \*\// { copy=0; next; }
- /./ { if (copy==1) print; }' < $ndl_file > $ndr_file
+ /./ { if (copy==1) print; }' $1
+
+ # now the real ndrgen output
+ [ -n "$V_FLAG" ] &&
+ echo "$CPP $CPPFLAGS $1 | $NDRPROG" >&2
+ $CPP $CPPFLAGS $1 | $NDRPROG
}
-if [[ $# -lt 1 ]] ; then
- ndrgen_usage
-fi
-while getopts "Y" FLAG $*; do
+while getopts "D:I:Y:V" FLAG
+do
case $FLAG in
- Y)
- CC_FLAG="y"
- ;;
- *)
- ndrgen_usage
- ;;
+ D|I) CPPFLAGS="$CPPFLAGS -${FLAG}${OPTARG}";;
+ Y) CPP="$OPTARG";;
+ V) V_FLAG="V";;
+ *) ndrgen_usage;;
esac
done
+shift $(($OPTIND - 1))
-if [[ $CC_FLAG = "y" ]] ; then
- shift $(($OPTIND - 1))
-
- if [[ $# -lt 1 ]] ; then
- ndrgen_usage "C pre-processor path is missing"
- else
- CC=$1
- shift $(($OPTIND - 1))
-
- # Check for cw being invoked with -_cc or -_gcc
- if [[ $1 = "-_cc" || $1 = "-_gcc" ]] ; then
- CC_ARG=$1
- shift $(($OPTIND - 1))
- fi
- fi
-fi
-
-if [[ $CC = "" ]] ; then
- ndrgen_usage "C pre-processor is not defined"
+if [[ $# -lt 1 ]] ; then
+ ndrgen_usage
fi
-if [ ! -f $CC ] || [ ! -x $CC ] ; then
- ndrgen_usage "cannot run $CC"
+if [ ! -x $CPP ] ; then
+ ndrgen_usage "cannot run $CPP"
fi
for i
@@ -101,36 +110,9 @@ do
exit 1
fi
- BASENAME=`basename $i .ndl`
- TMP_NAME=$BASENAME.ndl.c
-
- cp $i $TMP_NAME
-
- if $CC $CC_ARG -E -D__a64 -D__EXTENSIONS__ -D_FILE_OFFSET_BITS=64 \
- -I. -I${INCDIR} -I${INCDIR}/ndl -DNDRGEN $TMP_NAME | \
- $NDRPROG > $BASENAME.raw
- then
- touch ${BASENAME}_ndr.c
- ndrgen_copy_header $i ${BASENAME}_ndr.c
-
- cat - << EOF >> ${BASENAME}_ndr.c
-/*
- * Please do not edit this file.
- * It was generated using ndrgen.
- */
-
-#include <strings.h>
-#include <smbsrv/ndr.h>
-#include <smbsrv/ndl/$BASENAME.ndl>
-EOF
-
- cat $BASENAME.raw >> ${BASENAME}_ndr.c
-
- rm -f $BASENAME.raw
- rm -f $TMP_NAME
- else
- rm -f $BASENAME.raw
- rm -f $TMP_NAME
- exit 1
- fi
+ base=`basename $i .ndl`
+ process $i > ${base}_ndr.c || {
+ echo "ndrgen error";
+ rm ${base}_ndr.c;
+ }
done
diff --git a/usr/src/tools/quick/make-smbclnt b/usr/src/tools/quick/make-smbclnt
new file mode 100755
index 0000000000..1b65f50a71
--- /dev/null
+++ b/usr/src/tools/quick/make-smbclnt
@@ -0,0 +1,304 @@
+#!/bin/ksh
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2014 Nexenta Systems, Inc. All rights reserved.
+#
+
+# Use distributed make (dmake) by default.
+make=${MAKE:-dmake}
+
+CLOSED_IS_PRESENT=no
+export CLOSED_IS_PRESENT
+
+# Do this if you want to use dbx or gdb
+# export SOURCEDEBUG=yes
+
+[ -n "$SRC" ] || {
+ echo "SRC not set. Run 'ws' or 'bldenv' first."
+ exit 1
+}
+
+cpu=`uname -p`
+case $cpu in
+i386)
+ x=intel
+ kmdb_arch="amd64"
+ mdb_arch="ia32 amd64"
+ arch64=amd64
+ ;;
+sparc)
+ x=sparc
+ kmdb_arch=v9
+ mdb_arch="v7 v9"
+ arch64=sparcv9
+ ;;
+*) echo "Huh?" ; exit 1;;
+esac
+
+################################################################
+
+build_tools() {
+ test -f $SRC/tools/proto/root_i386-nd/opt/onbld/bin/genoffsets ||
+ (cd $SRC/tools && $make install)
+ (cd $SRC/common/mapfiles; $make install)
+}
+
+clobber_tools() {
+ (cd $SRC/tools && $make clobber)
+ (cd $SRC/common/mapfiles; $make clobber)
+}
+
+################################################################
+
+do_hdrs() {
+
+targ=$1
+if [ "$targ" = clobber ]
+then
+ (cd $SRC/uts && $make -k clobber_h)
+ (cd $SRC/head && $make clobber)
+fi
+
+if [ "$targ" = install ]
+then
+ targ=install_h
+
+ # Just the parts of "make sgs" we need, and
+ # skip them if they appear to be done.
+ # ... stuff under $SRC
+ test -f $SRC/uts/common/sys/priv_names.h ||
+ (cd $SRC/uts && $make -k all_h)
+
+ test -f $SRC/head/rpcsvc/nispasswd.h ||
+ (cd $SRC/head && $make -k install_h)
+
+ # ... stuff under $ROOT (proto area)
+ test -d $ROOT/usr/include/sys ||
+ (cd $SRC && $make rootdirs)
+ test -f $ROOT/usr/include/sys/types.h ||
+ (cd $SRC/uts && $make -k install_h)
+ test -f $ROOT/usr/include/rpcsvc/daemon_utils.h ||
+ (cd $SRC/head && $make install_h)
+
+ # always update the smb headers to be safe
+ (cd $SRC/uts/common/smb && $make -k install_h)
+
+fi
+
+# Need some library headers too...
+for lib in \
+ libcryptoutil \
+ libmlrpc \
+ libpam \
+ libsec \
+ libshare \
+ libsmbfs \
+ passwdutil
+do
+ (cd $SRC/lib/$lib && $make $targ)
+done
+}
+
+################################################################
+
+do_kern() {
+ case $1 in
+ lint) targ=modlintlib ;;
+ *) targ=$1 ;;
+ esac
+ ( unset SOURCEDEBUG ;
+ (cd $SRC/uts/$x/nsmb && $make $targ) ;
+ (cd $SRC/uts/$x/smbfs && $make $targ) )
+}
+
+################################################################
+
+# Note lib1 builds prerequisite libraries not delivered by the
+# tar file we create below. To accelerate clean/install, we
+# skip these on clean (but still nuke them for clobber)
+
+do_lib1() {
+ :
+}
+
+# lib2 builds stuff we include in the tar file,
+# or that we don't mind rebuilding after clean.
+
+do_lib2() {
+
+(cd $SRC/lib/libsmbfs && $make $1)
+[ "$1" = install ] &&
+ (cd $SRC/lib/libsmbfs && $make _msg)
+(cd $SRC/lib/libmlrpc && $make $1)
+(cd $SRC/lib/libshare && $make $1 PLUGINS=smbfs)
+(cd $SRC/lib/passwdutil && $make $1)
+(cd $SRC/lib/pam_modules/smbfs && $make $1)
+
+}
+
+################################################################
+
+do_cmds() {
+
+case $1 in
+install)
+ # mount programs need fslib.o
+ (cd $SRC/cmd/fs.d && $make fslib.o)
+ (cd $SRC/cmd/fs.d/smbclnt && $make $1 catalog)
+ ;;
+clean|clobber)
+ (cd $SRC/cmd/fs.d/smbclnt && $make $1)
+ (cd $SRC/cmd/fs.d && $make ${1}_local)
+ ;;
+esac
+
+# Build the MDB modules, WITH the linktest
+(cd $SRC/cmd/mdb/tools && $make $1)
+
+# kmdb_arch is 64-bit only
+for a in $kmdb_arch
+do
+ case $1 in
+ install|lint)
+ (cd $SRC/cmd/mdb/$x/$a/kmdb &&
+ $make kmdb_modlinktest.o )
+ ;;
+ clean|clobber)
+ (cd $SRC/cmd/mdb/$x/$a/kmdb &&
+ $make -k $1 )
+ ;;
+ esac
+
+ (cd $SRC/cmd/mdb/$x/$a/nsmb &&
+ $make $1 KMDB_LINKTEST_ENABLE= )
+ (cd $SRC/cmd/mdb/$x/$a/smbfs &&
+ $make $1 KMDB_LINKTEST_ENABLE= )
+done
+}
+
+
+################################################################
+# This builds $SRC/TAGS (and cscope.files) in a helpful order.
+
+do_tags() {
+ (cd $SRC ;
+ find uts/common/sys -name '*.[ch]' -print |sort
+ find uts/common/net -name '*.[ch]' -print |sort
+ find uts/common/netinet -name '*.[ch]' -print |sort
+ find uts/common/smb -name '*.[ch]' -print |sort
+ find uts/common/netsmb -name '*.[ch]' -print |sort
+ find uts/common/fs/smbclnt -name '*.[ch]' -print |sort
+ find head -name '*.h' -print |sort
+ find lib/libsmbfs -name '*.[ch]' -print |sort
+ find cmd/fs.d/smbclnt -name '*.[ch]' -print |sort
+ find common/smbclnt -name '*.[ch]' -print |sort
+ ) > $SRC/cscope.files
+
+ (cd $SRC ;
+ exctags -e --langmap=c:+.ndl -h ndl -L - < cscope.files
+ cscope -b )
+}
+
+################################################################
+# This creates a tarfile one can use to update a test machine.
+
+do_tar() {
+ git_rev=`git rev-parse --short=8 HEAD`
+ files="
+lib/svc/manifest/network/smb/client.xml
+lib/svc/method/smb-client
+opt/smbcl-tests/tests/srvenum
+opt/smbcl-tests/tests/srvinfo
+opt/smbcl-tests/tests/tconn
+usr/bin/smbutil
+usr/kernel/drv/$arch64/nsmb
+usr/kernel/fs/$arch64/smbfs
+usr/kernel/kmdb/$arch64/nsmb
+usr/kernel/kmdb/$arch64/smbfs
+usr/lib/$arch64/libsmbfs.so.1
+usr/lib/fs/smbfs/$arch64/libshare_smbfs.so.1
+usr/lib/fs/smbfs/chacl
+usr/lib/fs/smbfs/dfshares
+usr/lib/fs/smbfs/libshare_smbfs.so.1
+usr/lib/fs/smbfs/lsacl
+usr/lib/fs/smbfs/mount
+usr/lib/fs/smbfs/share
+usr/lib/fs/smbfs/umount
+usr/lib/fs/smbfs/unshare
+usr/lib/libmlrpc.so.2
+usr/lib/libsmbfs.so.1
+usr/lib/mdb/kvm/$arch64/nsmb.so
+usr/lib/mdb/kvm/$arch64/smbfs.so
+usr/lib/mdb/kvm/nsmb.so
+usr/lib/mdb/kvm/smbfs.so
+usr/lib/security/$arch64/pam_smbfs_login.so.1
+usr/lib/security/pam_smbfs_login.so.1
+usr/lib/smbfs/smbiod
+usr/lib/smbfs/smbiod-svc
+"
+
+ (cd $ROOT && tar cfj ../../smbclnt-${git_rev}.tar.bz2 $files)
+}
+
+################################################################
+
+if [ "$1" = "" ]; then
+ set '?' # force usage
+fi
+
+set -x
+
+for arg
+do
+ case "$arg" in
+ install)
+ build_tools
+ set -e
+ do_hdrs $arg
+ do_kern $arg
+ do_lib1 $arg
+ do_lib2 $arg
+ do_cmds $arg
+ ;;
+ lint)
+ do_kern $arg
+ do_lib1 $arg
+ do_lib2 $arg
+ do_cmds $arg
+ ;;
+ clean)
+ # intentionally skip: lib1, hdrs, tools
+ do_cmds $arg
+ do_lib2 $arg
+ do_kern $arg
+ ;;
+ clobber)
+ do_cmds $arg
+ do_lib2 $arg
+ do_lib1 $arg
+ do_kern $arg
+ do_hdrs $arg
+ clobber_tools
+ ;;
+ tags)
+ do_tags
+ ;;
+ tar)
+ do_tar
+ ;;
+ *)
+ echo "Usage: $0 {install|lint|clean|clobber|tags|tar}";
+ exit 1;
+ ;;
+ esac
+done
diff --git a/usr/src/tools/quick/make-smbsrv b/usr/src/tools/quick/make-smbsrv
index e808bffee2..18c1baddcf 100755
--- a/usr/src/tools/quick/make-smbsrv
+++ b/usr/src/tools/quick/make-smbsrv
@@ -107,8 +107,9 @@ for lib in \
libdevid \
libfakekernel \
libgss \
- libkrb5 \
libidmap \
+ libkrb5 \
+ libmlrpc \
libpam \
libsec \
libscf \
@@ -164,7 +165,8 @@ do_lib2() {
for lib in \
libfakekernel \
libads \
- libsmbfs
+ libsmbfs \
+ libmlrpc
do
(cd $SRC/lib/$lib && $make $1)
done
@@ -287,7 +289,7 @@ usr/lib/mdb/kvm/$arch64/smbsrv.so
usr/lib/reparse/libreparse_smb.so.1
usr/lib/security/pam_smb_passwd.so.1
usr/lib/smbsrv/dtrace
-usr/lib/smbsrv/libmlrpc.so.1
+usr/lib/libmlrpc.so.2
usr/lib/smbsrv/libmlsvc.so.1
usr/lib/smbsrv/libsmb.so.1
usr/lib/smbsrv/libsmbns.so.1
diff --git a/usr/src/uts/common/fs/zfs/metaslab.c b/usr/src/uts/common/fs/zfs/metaslab.c
index 82ca2d6cbf..1f5a7fbd26 100644
--- a/usr/src/uts/common/fs/zfs/metaslab.c
+++ b/usr/src/uts/common/fs/zfs/metaslab.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
*/
@@ -217,6 +217,8 @@ static uint64_t metaslab_weight(metaslab_t *);
static void metaslab_set_fragmentation(metaslab_t *);
static void metaslab_free_impl(vdev_t *, uint64_t, uint64_t, boolean_t);
static void metaslab_check_free_impl(vdev_t *, uint64_t, uint64_t);
+static void metaslab_passivate(metaslab_t *msp, uint64_t weight);
+static uint64_t metaslab_weight_from_range_tree(metaslab_t *msp);
kmem_cache_t *metaslab_alloc_trace_cache;
@@ -236,7 +238,12 @@ metaslab_class_create(spa_t *spa, metaslab_ops_t *ops)
mc->mc_rotor = NULL;
mc->mc_ops = ops;
mutex_init(&mc->mc_lock, NULL, MUTEX_DEFAULT, NULL);
- refcount_create_tracked(&mc->mc_alloc_slots);
+ mc->mc_alloc_slots = kmem_zalloc(spa->spa_alloc_count *
+ sizeof (refcount_t), KM_SLEEP);
+ mc->mc_alloc_max_slots = kmem_zalloc(spa->spa_alloc_count *
+ sizeof (uint64_t), KM_SLEEP);
+ for (int i = 0; i < spa->spa_alloc_count; i++)
+ refcount_create_tracked(&mc->mc_alloc_slots[i]);
return (mc);
}
@@ -250,7 +257,12 @@ metaslab_class_destroy(metaslab_class_t *mc)
ASSERT(mc->mc_space == 0);
ASSERT(mc->mc_dspace == 0);
- refcount_destroy(&mc->mc_alloc_slots);
+ for (int i = 0; i < mc->mc_spa->spa_alloc_count; i++)
+ refcount_destroy(&mc->mc_alloc_slots[i]);
+ kmem_free(mc->mc_alloc_slots, mc->mc_spa->spa_alloc_count *
+ sizeof (refcount_t));
+ kmem_free(mc->mc_alloc_max_slots, mc->mc_spa->spa_alloc_count *
+ sizeof (uint64_t));
mutex_destroy(&mc->mc_lock);
kmem_free(mc, sizeof (metaslab_class_t));
}
@@ -447,6 +459,30 @@ metaslab_compare(const void *x1, const void *x2)
const metaslab_t *m1 = x1;
const metaslab_t *m2 = x2;
+ int sort1 = 0;
+ int sort2 = 0;
+ if (m1->ms_allocator != -1 && m1->ms_primary)
+ sort1 = 1;
+ else if (m1->ms_allocator != -1 && !m1->ms_primary)
+ sort1 = 2;
+ if (m2->ms_allocator != -1 && m2->ms_primary)
+ sort2 = 1;
+ else if (m2->ms_allocator != -1 && !m2->ms_primary)
+ sort2 = 2;
+
+ /*
+ * Sort inactive metaslabs first, then primaries, then secondaries. When
+ * selecting a metaslab to allocate from, an allocator first tries its
+ * primary, then secondary active metaslab. If it doesn't have active
+ * metaslabs, or can't allocate from them, it searches for an inactive
+ * metaslab to activate. If it can't find a suitable one, it will steal
+ * a primary or secondary metaslab from another allocator.
+ */
+ if (sort1 < sort2)
+ return (-1);
+ if (sort1 > sort2)
+ return (1);
+
if (m1->ms_weight < m2->ms_weight)
return (1);
if (m1->ms_weight > m2->ms_weight)
@@ -598,12 +634,16 @@ metaslab_group_alloc_update(metaslab_group_t *mg)
}
metaslab_group_t *
-metaslab_group_create(metaslab_class_t *mc, vdev_t *vd)
+metaslab_group_create(metaslab_class_t *mc, vdev_t *vd, int allocators)
{
metaslab_group_t *mg;
mg = kmem_zalloc(sizeof (metaslab_group_t), KM_SLEEP);
mutex_init(&mg->mg_lock, NULL, MUTEX_DEFAULT, NULL);
+ mg->mg_primaries = kmem_zalloc(allocators * sizeof (metaslab_t *),
+ KM_SLEEP);
+ mg->mg_secondaries = kmem_zalloc(allocators * sizeof (metaslab_t *),
+ KM_SLEEP);
avl_create(&mg->mg_metaslab_tree, metaslab_compare,
sizeof (metaslab_t), offsetof(struct metaslab, ms_group_node));
mg->mg_vd = vd;
@@ -611,7 +651,16 @@ metaslab_group_create(metaslab_class_t *mc, vdev_t *vd)
mg->mg_activation_count = 0;
mg->mg_initialized = B_FALSE;
mg->mg_no_free_space = B_TRUE;
- refcount_create_tracked(&mg->mg_alloc_queue_depth);
+ mg->mg_allocators = allocators;
+
+ mg->mg_alloc_queue_depth = kmem_zalloc(allocators * sizeof (refcount_t),
+ KM_SLEEP);
+ mg->mg_cur_max_alloc_queue_depth = kmem_zalloc(allocators *
+ sizeof (uint64_t), KM_SLEEP);
+ for (int i = 0; i < allocators; i++) {
+ refcount_create_tracked(&mg->mg_alloc_queue_depth[i]);
+ mg->mg_cur_max_alloc_queue_depth[i] = 0;
+ }
mg->mg_taskq = taskq_create("metaslab_group_taskq", metaslab_load_pct,
minclsyspri, 10, INT_MAX, TASKQ_THREADS_CPU_PCT);
@@ -633,8 +682,20 @@ metaslab_group_destroy(metaslab_group_t *mg)
taskq_destroy(mg->mg_taskq);
avl_destroy(&mg->mg_metaslab_tree);
+ kmem_free(mg->mg_primaries, mg->mg_allocators * sizeof (metaslab_t *));
+ kmem_free(mg->mg_secondaries, mg->mg_allocators *
+ sizeof (metaslab_t *));
mutex_destroy(&mg->mg_lock);
- refcount_destroy(&mg->mg_alloc_queue_depth);
+
+ for (int i = 0; i < mg->mg_allocators; i++) {
+ refcount_destroy(&mg->mg_alloc_queue_depth[i]);
+ mg->mg_cur_max_alloc_queue_depth[i] = 0;
+ }
+ kmem_free(mg->mg_alloc_queue_depth, mg->mg_allocators *
+ sizeof (refcount_t));
+ kmem_free(mg->mg_cur_max_alloc_queue_depth, mg->mg_allocators *
+ sizeof (uint64_t));
+
kmem_free(mg, sizeof (metaslab_group_t));
}
@@ -713,6 +774,22 @@ metaslab_group_passivate(metaslab_group_t *mg)
taskq_wait(mg->mg_taskq);
spa_config_enter(spa, locks & ~(SCL_ZIO - 1), spa, RW_WRITER);
metaslab_group_alloc_update(mg);
+ for (int i = 0; i < mg->mg_allocators; i++) {
+ metaslab_t *msp = mg->mg_primaries[i];
+ if (msp != NULL) {
+ mutex_enter(&msp->ms_lock);
+ metaslab_passivate(msp,
+ metaslab_weight_from_range_tree(msp));
+ mutex_exit(&msp->ms_lock);
+ }
+ msp = mg->mg_secondaries[i];
+ if (msp != NULL) {
+ mutex_enter(&msp->ms_lock);
+ metaslab_passivate(msp,
+ metaslab_weight_from_range_tree(msp));
+ mutex_exit(&msp->ms_lock);
+ }
+ }
mgprev = mg->mg_prev;
mgnext = mg->mg_next;
@@ -853,6 +930,17 @@ metaslab_group_remove(metaslab_group_t *mg, metaslab_t *msp)
}
static void
+metaslab_group_sort_impl(metaslab_group_t *mg, metaslab_t *msp, uint64_t weight)
+{
+ ASSERT(MUTEX_HELD(&mg->mg_lock));
+ ASSERT(msp->ms_group == mg);
+ avl_remove(&mg->mg_metaslab_tree, msp);
+ msp->ms_weight = weight;
+ avl_add(&mg->mg_metaslab_tree, msp);
+
+}
+
+static void
metaslab_group_sort(metaslab_group_t *mg, metaslab_t *msp, uint64_t weight)
{
/*
@@ -863,10 +951,7 @@ metaslab_group_sort(metaslab_group_t *mg, metaslab_t *msp, uint64_t weight)
ASSERT(MUTEX_HELD(&msp->ms_lock));
mutex_enter(&mg->mg_lock);
- ASSERT(msp->ms_group == mg);
- avl_remove(&mg->mg_metaslab_tree, msp);
- msp->ms_weight = weight;
- avl_add(&mg->mg_metaslab_tree, msp);
+ metaslab_group_sort_impl(mg, msp, weight);
mutex_exit(&mg->mg_lock);
}
@@ -914,7 +999,7 @@ metaslab_group_fragmentation(metaslab_group_t *mg)
*/
static boolean_t
metaslab_group_allocatable(metaslab_group_t *mg, metaslab_group_t *rotor,
- uint64_t psize)
+ uint64_t psize, int allocator)
{
spa_t *spa = mg->mg_vd->vdev_spa;
metaslab_class_t *mc = mg->mg_class;
@@ -943,7 +1028,7 @@ metaslab_group_allocatable(metaslab_group_t *mg, metaslab_group_t *rotor,
if (mg->mg_allocatable) {
metaslab_group_t *mgp;
int64_t qdepth;
- uint64_t qmax = mg->mg_max_alloc_queue_depth;
+ uint64_t qmax = mg->mg_cur_max_alloc_queue_depth[allocator];
if (!mc->mc_alloc_throttle_enabled)
return (B_TRUE);
@@ -955,7 +1040,7 @@ metaslab_group_allocatable(metaslab_group_t *mg, metaslab_group_t *rotor,
if (mg->mg_no_free_space)
return (B_FALSE);
- qdepth = refcount_count(&mg->mg_alloc_queue_depth);
+ qdepth = refcount_count(&mg->mg_alloc_queue_depth[allocator]);
/*
* If this metaslab group is below its qmax or it's
@@ -974,9 +1059,10 @@ metaslab_group_allocatable(metaslab_group_t *mg, metaslab_group_t *rotor,
* groups at the same time when we make this check.
*/
for (mgp = mg->mg_next; mgp != rotor; mgp = mgp->mg_next) {
- qmax = mgp->mg_max_alloc_queue_depth;
+ qmax = mgp->mg_cur_max_alloc_queue_depth[allocator];
- qdepth = refcount_count(&mgp->mg_alloc_queue_depth);
+ qdepth = refcount_count(
+ &mgp->mg_alloc_queue_depth[allocator]);
/*
* If there is another metaslab group that
@@ -1463,6 +1549,8 @@ metaslab_init(metaslab_group_t *mg, uint64_t id, uint64_t object, uint64_t txg,
ms->ms_id = id;
ms->ms_start = id << vd->vdev_ms_shift;
ms->ms_size = 1ULL << vd->vdev_ms_shift;
+ ms->ms_allocator = -1;
+ ms->ms_new = B_TRUE;
/*
* We only open space map objects that already exist. All others
@@ -1558,6 +1646,7 @@ metaslab_fini(metaslab_t *msp)
cv_destroy(&msp->ms_load_cv);
mutex_destroy(&msp->ms_lock);
mutex_destroy(&msp->ms_sync_lock);
+ ASSERT3U(msp->ms_allocator, ==, -1);
kmem_free(msp, sizeof (metaslab_t));
}
@@ -1954,19 +2043,59 @@ metaslab_weight(metaslab_t *msp)
}
static int
-metaslab_activate(metaslab_t *msp, uint64_t activation_weight)
+metaslab_activate_allocator(metaslab_group_t *mg, metaslab_t *msp,
+ int allocator, uint64_t activation_weight)
+{
+ /*
+ * If we're activating for the claim code, we don't want to actually
+ * set the metaslab up for a specific allocator.
+ */
+ if (activation_weight == METASLAB_WEIGHT_CLAIM)
+ return (0);
+ metaslab_t **arr = (activation_weight == METASLAB_WEIGHT_PRIMARY ?
+ mg->mg_primaries : mg->mg_secondaries);
+
+ ASSERT(MUTEX_HELD(&msp->ms_lock));
+ mutex_enter(&mg->mg_lock);
+ if (arr[allocator] != NULL) {
+ mutex_exit(&mg->mg_lock);
+ return (EEXIST);
+ }
+
+ arr[allocator] = msp;
+ ASSERT3S(msp->ms_allocator, ==, -1);
+ msp->ms_allocator = allocator;
+ msp->ms_primary = (activation_weight == METASLAB_WEIGHT_PRIMARY);
+ mutex_exit(&mg->mg_lock);
+
+ return (0);
+}
+
+static int
+metaslab_activate(metaslab_t *msp, int allocator, uint64_t activation_weight)
{
ASSERT(MUTEX_HELD(&msp->ms_lock));
if ((msp->ms_weight & METASLAB_ACTIVE_MASK) == 0) {
+ int error = 0;
metaslab_load_wait(msp);
if (!msp->ms_loaded) {
- int error = metaslab_load(msp);
- if (error) {
+ if ((error = metaslab_load(msp)) != 0) {
metaslab_group_sort(msp->ms_group, msp, 0);
return (error);
}
}
+ if ((msp->ms_weight & METASLAB_ACTIVE_MASK) != 0) {
+ /*
+ * The metaslab was activated for another allocator
+ * while we were waiting, we should reselect.
+ */
+ return (EBUSY);
+ }
+ if ((error = metaslab_activate_allocator(msp->ms_group, msp,
+ allocator, activation_weight)) != 0) {
+ return (error);
+ }
msp->ms_activation_weight = msp->ms_weight;
metaslab_group_sort(msp->ms_group, msp,
@@ -1979,6 +2108,34 @@ metaslab_activate(metaslab_t *msp, uint64_t activation_weight)
}
static void
+metaslab_passivate_allocator(metaslab_group_t *mg, metaslab_t *msp,
+ uint64_t weight)
+{
+ ASSERT(MUTEX_HELD(&msp->ms_lock));
+ if (msp->ms_weight & METASLAB_WEIGHT_CLAIM) {
+ metaslab_group_sort(mg, msp, weight);
+ return;
+ }
+
+ mutex_enter(&mg->mg_lock);
+ ASSERT3P(msp->ms_group, ==, mg);
+ if (msp->ms_primary) {
+ ASSERT3U(0, <=, msp->ms_allocator);
+ ASSERT3U(msp->ms_allocator, <, mg->mg_allocators);
+ ASSERT3P(mg->mg_primaries[msp->ms_allocator], ==, msp);
+ ASSERT(msp->ms_weight & METASLAB_WEIGHT_PRIMARY);
+ mg->mg_primaries[msp->ms_allocator] = NULL;
+ } else {
+ ASSERT(msp->ms_weight & METASLAB_WEIGHT_SECONDARY);
+ ASSERT3P(mg->mg_secondaries[msp->ms_allocator], ==, msp);
+ mg->mg_secondaries[msp->ms_allocator] = NULL;
+ }
+ msp->ms_allocator = -1;
+ metaslab_group_sort_impl(mg, msp, weight);
+ mutex_exit(&mg->mg_lock);
+}
+
+static void
metaslab_passivate(metaslab_t *msp, uint64_t weight)
{
uint64_t size = weight & ~METASLAB_WEIGHT_TYPE;
@@ -1993,7 +2150,7 @@ metaslab_passivate(metaslab_t *msp, uint64_t weight)
ASSERT0(weight & METASLAB_ACTIVE_MASK);
msp->ms_activation_weight = 0;
- metaslab_group_sort(msp->ms_group, msp, weight);
+ metaslab_passivate_allocator(msp->ms_group, msp, weight);
ASSERT((msp->ms_weight & METASLAB_ACTIVE_MASK) == 0);
}
@@ -2550,11 +2707,18 @@ metaslab_sync_done(metaslab_t *msp, uint64_t txg)
vdev_dirty(vd, VDD_METASLAB, msp, txg + 1);
}
+ if (msp->ms_new) {
+ msp->ms_new = B_FALSE;
+ mutex_enter(&mg->mg_lock);
+ mg->mg_ms_ready++;
+ mutex_exit(&mg->mg_lock);
+ }
/*
* Calculate the new weights before unloading any metaslabs.
* This will give us the most accurate weighting.
*/
- metaslab_group_sort(mg, msp, metaslab_weight(msp));
+ metaslab_group_sort(mg, msp, metaslab_weight(msp) |
+ (msp->ms_weight & METASLAB_ACTIVE_MASK));
/*
* If the metaslab is loaded and we've not tried to load or allocate
@@ -2566,6 +2730,10 @@ metaslab_sync_done(metaslab_t *msp, uint64_t txg)
VERIFY0(range_tree_space(
msp->ms_allocating[(txg + t) & TXG_MASK]));
}
+ if (msp->ms_allocator != -1) {
+ metaslab_passivate(msp, msp->ms_weight &
+ ~METASLAB_ACTIVE_MASK);
+ }
if (!metaslab_debug_unload)
metaslab_unload(msp);
@@ -2659,7 +2827,8 @@ metaslab_alloc_trace_fini(void)
*/
static void
metaslab_trace_add(zio_alloc_list_t *zal, metaslab_group_t *mg,
- metaslab_t *msp, uint64_t psize, uint32_t dva_id, uint64_t offset)
+ metaslab_t *msp, uint64_t psize, uint32_t dva_id, uint64_t offset,
+ int allocator)
{
if (!metaslab_trace_enabled)
return;
@@ -2692,6 +2861,7 @@ metaslab_trace_add(zio_alloc_list_t *zal, metaslab_group_t *mg,
mat->mat_dva_id = dva_id;
mat->mat_offset = offset;
mat->mat_weight = 0;
+ mat->mat_allocator = allocator;
if (msp != NULL)
mat->mat_weight = msp->ms_weight;
@@ -2732,35 +2902,56 @@ metaslab_trace_fini(zio_alloc_list_t *zal)
*/
static void
-metaslab_group_alloc_increment(spa_t *spa, uint64_t vdev, void *tag, int flags)
+metaslab_group_alloc_increment(spa_t *spa, uint64_t vdev, void *tag, int flags,
+ int allocator)
{
if (!(flags & METASLAB_ASYNC_ALLOC) ||
- flags & METASLAB_DONT_THROTTLE)
+ (flags & METASLAB_DONT_THROTTLE))
return;
metaslab_group_t *mg = vdev_lookup_top(spa, vdev)->vdev_mg;
if (!mg->mg_class->mc_alloc_throttle_enabled)
return;
- (void) refcount_add(&mg->mg_alloc_queue_depth, tag);
+ (void) refcount_add(&mg->mg_alloc_queue_depth[allocator], tag);
+}
+
+static void
+metaslab_group_increment_qdepth(metaslab_group_t *mg, int allocator)
+{
+ uint64_t max = mg->mg_max_alloc_queue_depth;
+ uint64_t cur = mg->mg_cur_max_alloc_queue_depth[allocator];
+ while (cur < max) {
+ if (atomic_cas_64(&mg->mg_cur_max_alloc_queue_depth[allocator],
+ cur, cur + 1) == cur) {
+ atomic_inc_64(
+ &mg->mg_class->mc_alloc_max_slots[allocator]);
+ return;
+ }
+ cur = mg->mg_cur_max_alloc_queue_depth[allocator];
+ }
}
void
-metaslab_group_alloc_decrement(spa_t *spa, uint64_t vdev, void *tag, int flags)
+metaslab_group_alloc_decrement(spa_t *spa, uint64_t vdev, void *tag, int flags,
+ int allocator, boolean_t io_complete)
{
if (!(flags & METASLAB_ASYNC_ALLOC) ||
- flags & METASLAB_DONT_THROTTLE)
+ (flags & METASLAB_DONT_THROTTLE))
return;
metaslab_group_t *mg = vdev_lookup_top(spa, vdev)->vdev_mg;
if (!mg->mg_class->mc_alloc_throttle_enabled)
return;
- (void) refcount_remove(&mg->mg_alloc_queue_depth, tag);
+ (void) refcount_remove(&mg->mg_alloc_queue_depth[allocator], tag);
+ if (io_complete)
+ metaslab_group_increment_qdepth(mg, allocator);
}
void
-metaslab_group_alloc_verify(spa_t *spa, const blkptr_t *bp, void *tag)
+metaslab_group_alloc_verify(spa_t *spa, const blkptr_t *bp, void *tag,
+ int allocator)
{
#ifdef ZFS_DEBUG
const dva_t *dva = bp->blk_dva;
@@ -2769,7 +2960,8 @@ metaslab_group_alloc_verify(spa_t *spa, const blkptr_t *bp, void *tag)
for (int d = 0; d < ndvas; d++) {
uint64_t vdev = DVA_GET_VDEV(&dva[d]);
metaslab_group_t *mg = vdev_lookup_top(spa, vdev)->vdev_mg;
- VERIFY(refcount_not_held(&mg->mg_alloc_queue_depth, tag));
+ VERIFY(refcount_not_held(&mg->mg_alloc_queue_depth[allocator],
+ tag));
}
#endif
}
@@ -2811,91 +3003,146 @@ metaslab_block_alloc(metaslab_t *msp, uint64_t size, uint64_t txg)
return (start);
}
+/*
+ * Find the metaslab with the highest weight that is less than what we've
+ * already tried. In the common case, this means that we will examine each
+ * metaslab at most once. Note that concurrent callers could reorder metaslabs
+ * by activation/passivation once we have dropped the mg_lock. If a metaslab is
+ * activated by another thread, and we fail to allocate from the metaslab we
+ * have selected, we may not try the newly-activated metaslab, and instead
+ * activate another metaslab. This is not optimal, but generally does not cause
+ * any problems (a possible exception being if every metaslab is completely full
+ * except for the the newly-activated metaslab which we fail to examine).
+ */
+static metaslab_t *
+find_valid_metaslab(metaslab_group_t *mg, uint64_t activation_weight,
+ dva_t *dva, int d, uint64_t min_distance, uint64_t asize, int allocator,
+ zio_alloc_list_t *zal, metaslab_t *search, boolean_t *was_active)
+{
+ avl_index_t idx;
+ avl_tree_t *t = &mg->mg_metaslab_tree;
+ metaslab_t *msp = avl_find(t, search, &idx);
+ if (msp == NULL)
+ msp = avl_nearest(t, idx, AVL_AFTER);
+
+ for (; msp != NULL; msp = AVL_NEXT(t, msp)) {
+ int i;
+ if (!metaslab_should_allocate(msp, asize)) {
+ metaslab_trace_add(zal, mg, msp, asize, d,
+ TRACE_TOO_SMALL, allocator);
+ continue;
+ }
+
+ /*
+ * If the selected metaslab is condensing, skip it.
+ */
+ if (msp->ms_condensing)
+ continue;
+
+ *was_active = msp->ms_allocator != -1;
+ /*
+ * If we're activating as primary, this is our first allocation
+ * from this disk, so we don't need to check how close we are.
+ * If the metaslab under consideration was already active,
+ * we're getting desperate enough to steal another allocator's
+ * metaslab, so we still don't care about distances.
+ */
+ if (activation_weight == METASLAB_WEIGHT_PRIMARY || *was_active)
+ break;
+
+ uint64_t target_distance = min_distance
+ + (space_map_allocated(msp->ms_sm) != 0 ? 0 :
+ min_distance >> 1);
+
+ for (i = 0; i < d; i++) {
+ if (metaslab_distance(msp, &dva[i]) < target_distance)
+ break;
+ }
+ if (i == d)
+ break;
+ }
+
+ if (msp != NULL) {
+ search->ms_weight = msp->ms_weight;
+ search->ms_start = msp->ms_start + 1;
+ search->ms_allocator = msp->ms_allocator;
+ search->ms_primary = msp->ms_primary;
+ }
+ return (msp);
+}
+
+/* ARGSUSED */
static uint64_t
metaslab_group_alloc_normal(metaslab_group_t *mg, zio_alloc_list_t *zal,
- uint64_t asize, uint64_t txg, uint64_t min_distance, dva_t *dva, int d)
+ uint64_t asize, uint64_t txg, uint64_t min_distance, dva_t *dva, int d,
+ int allocator)
{
metaslab_t *msp = NULL;
uint64_t offset = -1ULL;
uint64_t activation_weight;
- uint64_t target_distance;
- int i;
+ boolean_t tertiary = B_FALSE;
activation_weight = METASLAB_WEIGHT_PRIMARY;
- for (i = 0; i < d; i++) {
- if (DVA_GET_VDEV(&dva[i]) == mg->mg_vd->vdev_id) {
+ for (int i = 0; i < d; i++) {
+ if (activation_weight == METASLAB_WEIGHT_PRIMARY &&
+ DVA_GET_VDEV(&dva[i]) == mg->mg_vd->vdev_id) {
activation_weight = METASLAB_WEIGHT_SECONDARY;
+ } else if (activation_weight == METASLAB_WEIGHT_SECONDARY &&
+ DVA_GET_VDEV(&dva[i]) == mg->mg_vd->vdev_id) {
+ tertiary = B_TRUE;
break;
}
}
+ /*
+ * If we don't have enough metaslabs active to fill the entire array, we
+ * just use the 0th slot.
+ */
+ if (mg->mg_ms_ready < mg->mg_allocators * 2) {
+ tertiary = B_FALSE;
+ allocator = 0;
+ }
+
+ ASSERT3U(mg->mg_vd->vdev_ms_count, >=, 2);
+
metaslab_t *search = kmem_alloc(sizeof (*search), KM_SLEEP);
search->ms_weight = UINT64_MAX;
search->ms_start = 0;
+ /*
+ * At the end of the metaslab tree are the already-active metaslabs,
+ * first the primaries, then the secondaries. When we resume searching
+ * through the tree, we need to consider ms_allocator and ms_primary so
+ * we start in the location right after where we left off, and don't
+ * accidentally loop forever considering the same metaslabs.
+ */
+ search->ms_allocator = -1;
+ search->ms_primary = B_TRUE;
for (;;) {
- boolean_t was_active;
- avl_tree_t *t = &mg->mg_metaslab_tree;
- avl_index_t idx;
+ boolean_t was_active = B_FALSE;
mutex_enter(&mg->mg_lock);
- /*
- * Find the metaslab with the highest weight that is less
- * than what we've already tried. In the common case, this
- * means that we will examine each metaslab at most once.
- * Note that concurrent callers could reorder metaslabs
- * by activation/passivation once we have dropped the mg_lock.
- * If a metaslab is activated by another thread, and we fail
- * to allocate from the metaslab we have selected, we may
- * not try the newly-activated metaslab, and instead activate
- * another metaslab. This is not optimal, but generally
- * does not cause any problems (a possible exception being
- * if every metaslab is completely full except for the
- * the newly-activated metaslab which we fail to examine).
- */
- msp = avl_find(t, search, &idx);
- if (msp == NULL)
- msp = avl_nearest(t, idx, AVL_AFTER);
- for (; msp != NULL; msp = AVL_NEXT(t, msp)) {
-
- if (!metaslab_should_allocate(msp, asize)) {
- metaslab_trace_add(zal, mg, msp, asize, d,
- TRACE_TOO_SMALL);
- continue;
- }
-
- /*
- * If the selected metaslab is condensing, skip it.
- */
- if (msp->ms_condensing)
- continue;
-
- was_active = msp->ms_weight & METASLAB_ACTIVE_MASK;
- if (activation_weight == METASLAB_WEIGHT_PRIMARY)
- break;
-
- target_distance = min_distance +
- (space_map_allocated(msp->ms_sm) != 0 ? 0 :
- min_distance >> 1);
-
- for (i = 0; i < d; i++) {
- if (metaslab_distance(msp, &dva[i]) <
- target_distance)
- break;
- }
- if (i == d)
- break;
+ if (activation_weight == METASLAB_WEIGHT_PRIMARY &&
+ mg->mg_primaries[allocator] != NULL) {
+ msp = mg->mg_primaries[allocator];
+ was_active = B_TRUE;
+ } else if (activation_weight == METASLAB_WEIGHT_SECONDARY &&
+ mg->mg_secondaries[allocator] != NULL && !tertiary) {
+ msp = mg->mg_secondaries[allocator];
+ was_active = B_TRUE;
+ } else {
+ msp = find_valid_metaslab(mg, activation_weight, dva, d,
+ min_distance, asize, allocator, zal, search,
+ &was_active);
}
+
mutex_exit(&mg->mg_lock);
if (msp == NULL) {
kmem_free(search, sizeof (*search));
return (-1ULL);
}
- search->ms_weight = msp->ms_weight;
- search->ms_start = msp->ms_start + 1;
mutex_enter(&msp->ms_lock);
-
/*
* Ensure that the metaslab we have selected is still
* capable of handling our request. It's possible that
@@ -2909,18 +3156,32 @@ metaslab_group_alloc_normal(metaslab_group_t *mg, zio_alloc_list_t *zal,
continue;
}
- if ((msp->ms_weight & METASLAB_WEIGHT_SECONDARY) &&
- activation_weight == METASLAB_WEIGHT_PRIMARY) {
- metaslab_passivate(msp,
- msp->ms_weight & ~METASLAB_ACTIVE_MASK);
+ /*
+ * If the metaslab is freshly activated for an allocator that
+ * isn't the one we're allocating from, or if it's a primary and
+ * we're seeking a secondary (or vice versa), we go back and
+ * select a new metaslab.
+ */
+ if (!was_active && (msp->ms_weight & METASLAB_ACTIVE_MASK) &&
+ (msp->ms_allocator != -1) &&
+ (msp->ms_allocator != allocator || ((activation_weight ==
+ METASLAB_WEIGHT_PRIMARY) != msp->ms_primary))) {
mutex_exit(&msp->ms_lock);
continue;
}
- if (metaslab_activate(msp, activation_weight) != 0) {
+ if (msp->ms_weight & METASLAB_WEIGHT_CLAIM) {
+ metaslab_passivate(msp, msp->ms_weight &
+ ~METASLAB_WEIGHT_CLAIM);
mutex_exit(&msp->ms_lock);
continue;
}
+
+ if (metaslab_activate(msp, allocator, activation_weight) != 0) {
+ mutex_exit(&msp->ms_lock);
+ continue;
+ }
+
msp->ms_selected_txg = txg;
/*
@@ -2933,7 +3194,7 @@ metaslab_group_alloc_normal(metaslab_group_t *mg, zio_alloc_list_t *zal,
if (!metaslab_should_allocate(msp, asize)) {
/* Passivate this metaslab and select a new one. */
metaslab_trace_add(zal, mg, msp, asize, d,
- TRACE_TOO_SMALL);
+ TRACE_TOO_SMALL, allocator);
goto next;
}
@@ -2944,13 +3205,15 @@ metaslab_group_alloc_normal(metaslab_group_t *mg, zio_alloc_list_t *zal,
*/
if (msp->ms_condensing) {
metaslab_trace_add(zal, mg, msp, asize, d,
- TRACE_CONDENSING);
+ TRACE_CONDENSING, allocator);
+ metaslab_passivate(msp, msp->ms_weight &
+ ~METASLAB_ACTIVE_MASK);
mutex_exit(&msp->ms_lock);
continue;
}
offset = metaslab_block_alloc(msp, asize, txg);
- metaslab_trace_add(zal, mg, msp, asize, d, offset);
+ metaslab_trace_add(zal, mg, msp, asize, d, offset, allocator);
if (offset != -1ULL) {
/* Proactively passivate the metaslab, if needed */
@@ -3006,19 +3269,20 @@ next:
static uint64_t
metaslab_group_alloc(metaslab_group_t *mg, zio_alloc_list_t *zal,
- uint64_t asize, uint64_t txg, uint64_t min_distance, dva_t *dva, int d)
+ uint64_t asize, uint64_t txg, uint64_t min_distance, dva_t *dva, int d,
+ int allocator)
{
uint64_t offset;
ASSERT(mg->mg_initialized);
offset = metaslab_group_alloc_normal(mg, zal, asize, txg,
- min_distance, dva, d);
+ min_distance, dva, d, allocator);
mutex_enter(&mg->mg_lock);
if (offset == -1ULL) {
mg->mg_failed_allocations++;
metaslab_trace_add(zal, mg, NULL, asize, d,
- TRACE_GROUP_FAILURE);
+ TRACE_GROUP_FAILURE, allocator);
if (asize == SPA_GANGBLOCKSIZE) {
/*
* This metaslab group was unable to allocate
@@ -3053,7 +3317,7 @@ int ditto_same_vdev_distance_shift = 3;
int
metaslab_alloc_dva(spa_t *spa, metaslab_class_t *mc, uint64_t psize,
dva_t *dva, int d, dva_t *hintdva, uint64_t txg, int flags,
- zio_alloc_list_t *zal)
+ zio_alloc_list_t *zal, int allocator)
{
metaslab_group_t *mg, *rotor;
vdev_t *vd;
@@ -3065,7 +3329,8 @@ metaslab_alloc_dva(spa_t *spa, metaslab_class_t *mc, uint64_t psize,
* For testing, make some blocks above a certain size be gang blocks.
*/
if (psize >= metaslab_force_ganging && (ddi_get_lbolt() & 3) == 0) {
- metaslab_trace_add(zal, NULL, NULL, psize, d, TRACE_FORCE_GANG);
+ metaslab_trace_add(zal, NULL, NULL, psize, d, TRACE_FORCE_GANG,
+ allocator);
return (SET_ERROR(ENOSPC));
}
@@ -3151,12 +3416,12 @@ top:
*/
if (allocatable && !GANG_ALLOCATION(flags) && !try_hard) {
allocatable = metaslab_group_allocatable(mg, rotor,
- psize);
+ psize, allocator);
}
if (!allocatable) {
metaslab_trace_add(zal, mg, NULL, psize, d,
- TRACE_NOT_ALLOCATABLE);
+ TRACE_NOT_ALLOCATABLE, allocator);
goto next;
}
@@ -3171,7 +3436,7 @@ top:
vd->vdev_state < VDEV_STATE_HEALTHY) &&
d == 0 && !try_hard && vd->vdev_children == 0) {
metaslab_trace_add(zal, mg, NULL, psize, d,
- TRACE_VDEV_ERROR);
+ TRACE_VDEV_ERROR, allocator);
goto next;
}
@@ -3195,7 +3460,7 @@ top:
ASSERT(P2PHASE(asize, 1ULL << vd->vdev_ashift) == 0);
uint64_t offset = metaslab_group_alloc(mg, zal, asize, txg,
- distance, dva, d);
+ distance, dva, d, allocator);
if (offset != -1ULL) {
/*
@@ -3258,7 +3523,7 @@ next:
bzero(&dva[d], sizeof (dva_t));
- metaslab_trace_add(zal, rotor, NULL, psize, d, TRACE_ENOSPC);
+ metaslab_trace_add(zal, rotor, NULL, psize, d, TRACE_ENOSPC, allocator);
return (SET_ERROR(ENOSPC));
}
@@ -3559,18 +3824,20 @@ metaslab_free_dva(spa_t *spa, const dva_t *dva, boolean_t checkpoint)
* the reservation.
*/
boolean_t
-metaslab_class_throttle_reserve(metaslab_class_t *mc, int slots, zio_t *zio,
- int flags)
+metaslab_class_throttle_reserve(metaslab_class_t *mc, int slots, int allocator,
+ zio_t *zio, int flags)
{
uint64_t available_slots = 0;
boolean_t slot_reserved = B_FALSE;
+ uint64_t max = mc->mc_alloc_max_slots[allocator];
ASSERT(mc->mc_alloc_throttle_enabled);
mutex_enter(&mc->mc_lock);
- uint64_t reserved_slots = refcount_count(&mc->mc_alloc_slots);
- if (reserved_slots < mc->mc_alloc_max_slots)
- available_slots = mc->mc_alloc_max_slots - reserved_slots;
+ uint64_t reserved_slots =
+ refcount_count(&mc->mc_alloc_slots[allocator]);
+ if (reserved_slots < max)
+ available_slots = max - reserved_slots;
if (slots <= available_slots || GANG_ALLOCATION(flags)) {
/*
@@ -3578,7 +3845,9 @@ metaslab_class_throttle_reserve(metaslab_class_t *mc, int slots, zio_t *zio,
* them individually when an I/O completes.
*/
for (int d = 0; d < slots; d++) {
- reserved_slots = refcount_add(&mc->mc_alloc_slots, zio);
+ reserved_slots =
+ refcount_add(&mc->mc_alloc_slots[allocator],
+ zio);
}
zio->io_flags |= ZIO_FLAG_IO_ALLOCATING;
slot_reserved = B_TRUE;
@@ -3589,12 +3858,14 @@ metaslab_class_throttle_reserve(metaslab_class_t *mc, int slots, zio_t *zio,
}
void
-metaslab_class_throttle_unreserve(metaslab_class_t *mc, int slots, zio_t *zio)
+metaslab_class_throttle_unreserve(metaslab_class_t *mc, int slots,
+ int allocator, zio_t *zio)
{
ASSERT(mc->mc_alloc_throttle_enabled);
mutex_enter(&mc->mc_lock);
for (int d = 0; d < slots; d++) {
- (void) refcount_remove(&mc->mc_alloc_slots, zio);
+ (void) refcount_remove(&mc->mc_alloc_slots[allocator],
+ zio);
}
mutex_exit(&mc->mc_lock);
}
@@ -3616,7 +3887,13 @@ metaslab_claim_concrete(vdev_t *vd, uint64_t offset, uint64_t size,
mutex_enter(&msp->ms_lock);
if ((txg != 0 && spa_writeable(spa)) || !msp->ms_loaded)
- error = metaslab_activate(msp, METASLAB_WEIGHT_SECONDARY);
+ error = metaslab_activate(msp, 0, METASLAB_WEIGHT_CLAIM);
+ /*
+ * No need to fail in that case; someone else has activated the
+ * metaslab, but that doesn't preclude us from using it.
+ */
+ if (error == EBUSY)
+ error = 0;
if (error == 0 &&
!range_tree_contains(msp->ms_allocatable, offset, size))
@@ -3721,7 +3998,7 @@ metaslab_claim_dva(spa_t *spa, const dva_t *dva, uint64_t txg)
int
metaslab_alloc(spa_t *spa, metaslab_class_t *mc, uint64_t psize, blkptr_t *bp,
int ndvas, uint64_t txg, blkptr_t *hintbp, int flags,
- zio_alloc_list_t *zal, zio_t *zio)
+ zio_alloc_list_t *zal, zio_t *zio, int allocator)
{
dva_t *dva = bp->blk_dva;
dva_t *hintdva = hintbp->blk_dva;
@@ -3744,12 +4021,13 @@ metaslab_alloc(spa_t *spa, metaslab_class_t *mc, uint64_t psize, blkptr_t *bp,
for (int d = 0; d < ndvas; d++) {
error = metaslab_alloc_dva(spa, mc, psize, dva, d, hintdva,
- txg, flags, zal);
+ txg, flags, zal, allocator);
if (error != 0) {
for (d--; d >= 0; d--) {
metaslab_unalloc_dva(spa, &dva[d], txg);
metaslab_group_alloc_decrement(spa,
- DVA_GET_VDEV(&dva[d]), zio, flags);
+ DVA_GET_VDEV(&dva[d]), zio, flags,
+ allocator, B_FALSE);
bzero(&dva[d], sizeof (dva_t));
}
spa_config_exit(spa, SCL_ALLOC, FTAG);
@@ -3760,7 +4038,7 @@ metaslab_alloc(spa_t *spa, metaslab_class_t *mc, uint64_t psize, blkptr_t *bp,
* based on the newly allocated dva.
*/
metaslab_group_alloc_increment(spa,
- DVA_GET_VDEV(&dva[d]), zio, flags);
+ DVA_GET_VDEV(&dva[d]), zio, flags, allocator);
}
}
diff --git a/usr/src/uts/common/fs/zfs/spa.c b/usr/src/uts/common/fs/zfs/spa.c
index 064e4411db..163f5e054e 100644
--- a/usr/src/uts/common/fs/zfs/spa.c
+++ b/usr/src/uts/common/fs/zfs/spa.c
@@ -7398,9 +7398,11 @@ spa_sync(spa_t *spa, uint64_t txg)
spa->spa_syncing_txg = txg;
spa->spa_sync_pass = 0;
- mutex_enter(&spa->spa_alloc_lock);
- VERIFY0(avl_numnodes(&spa->spa_alloc_tree));
- mutex_exit(&spa->spa_alloc_lock);
+ for (int i = 0; i < spa->spa_alloc_count; i++) {
+ mutex_enter(&spa->spa_alloc_locks[i]);
+ VERIFY0(avl_numnodes(&spa->spa_alloc_trees[i]));
+ mutex_exit(&spa->spa_alloc_locks[i]);
+ }
/*
* If there are any pending vdev state changes, convert them
@@ -7459,7 +7461,7 @@ spa_sync(spa_t *spa, uint64_t txg)
* The max queue depth will not change in the middle of syncing
* out this txg.
*/
- uint64_t queue_depth_total = 0;
+ uint64_t slots_per_allocator = 0;
for (int c = 0; c < rvd->vdev_children; c++) {
vdev_t *tvd = rvd->vdev_child[c];
metaslab_group_t *mg = tvd->vdev_mg;
@@ -7473,18 +7475,23 @@ spa_sync(spa_t *spa, uint64_t txg)
* allocations look at mg_max_alloc_queue_depth, and async
* allocations all happen from spa_sync().
*/
- ASSERT0(refcount_count(&mg->mg_alloc_queue_depth));
+ for (int i = 0; i < spa->spa_alloc_count; i++)
+ ASSERT0(refcount_count(&(mg->mg_alloc_queue_depth[i])));
mg->mg_max_alloc_queue_depth = max_queue_depth;
- queue_depth_total += mg->mg_max_alloc_queue_depth;
+
+ for (int i = 0; i < spa->spa_alloc_count; i++) {
+ mg->mg_cur_max_alloc_queue_depth[i] =
+ zfs_vdev_def_queue_depth;
+ }
+ slots_per_allocator += zfs_vdev_def_queue_depth;
}
metaslab_class_t *mc = spa_normal_class(spa);
- ASSERT0(refcount_count(&mc->mc_alloc_slots));
- mc->mc_alloc_max_slots = queue_depth_total;
+ for (int i = 0; i < spa->spa_alloc_count; i++) {
+ ASSERT0(refcount_count(&mc->mc_alloc_slots[i]));
+ mc->mc_alloc_max_slots[i] = slots_per_allocator;
+ }
mc->mc_alloc_throttle_enabled = zio_dva_throttle_enabled;
- ASSERT3U(mc->mc_alloc_max_slots, <=,
- max_queue_depth * rvd->vdev_children);
-
for (int c = 0; c < rvd->vdev_children; c++) {
vdev_t *vd = rvd->vdev_child[c];
vdev_indirect_state_sync_verify(vd);
@@ -7661,9 +7668,11 @@ spa_sync(spa_t *spa, uint64_t txg)
dsl_pool_sync_done(dp, txg);
- mutex_enter(&spa->spa_alloc_lock);
- VERIFY0(avl_numnodes(&spa->spa_alloc_tree));
- mutex_exit(&spa->spa_alloc_lock);
+ for (int i = 0; i < spa->spa_alloc_count; i++) {
+ mutex_enter(&spa->spa_alloc_locks[i]);
+ VERIFY0(avl_numnodes(&spa->spa_alloc_trees[i]));
+ mutex_exit(&spa->spa_alloc_locks[i]);
+ }
/*
* Update usable space statistics.
diff --git a/usr/src/uts/common/fs/zfs/spa_misc.c b/usr/src/uts/common/fs/zfs/spa_misc.c
index efb4993c0a..fe0971a720 100644
--- a/usr/src/uts/common/fs/zfs/spa_misc.c
+++ b/usr/src/uts/common/fs/zfs/spa_misc.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
* Copyright 2013 Saso Kiselkov. All rights reserved.
@@ -357,6 +357,8 @@ int spa_asize_inflation = 24;
int spa_slop_shift = 5;
uint64_t spa_min_slop = 128 * 1024 * 1024;
+int spa_allocators = 4;
+
/*PRINTFLIKE2*/
void
spa_load_failed(spa_t *spa, const char *fmt, ...)
@@ -607,7 +609,6 @@ spa_add(const char *name, nvlist_t *config, const char *altroot)
mutex_init(&spa->spa_suspend_lock, NULL, MUTEX_DEFAULT, NULL);
mutex_init(&spa->spa_vdev_top_lock, NULL, MUTEX_DEFAULT, NULL);
mutex_init(&spa->spa_iokstat_lock, NULL, MUTEX_DEFAULT, NULL);
- mutex_init(&spa->spa_alloc_lock, NULL, MUTEX_DEFAULT, NULL);
cv_init(&spa->spa_async_cv, NULL, CV_DEFAULT, NULL);
cv_init(&spa->spa_evicting_os_cv, NULL, CV_DEFAULT, NULL);
@@ -658,8 +659,16 @@ spa_add(const char *name, nvlist_t *config, const char *altroot)
spa_active_count++;
}
- avl_create(&spa->spa_alloc_tree, zio_bookmark_compare,
- sizeof (zio_t), offsetof(zio_t, io_alloc_node));
+ spa->spa_alloc_count = spa_allocators;
+ spa->spa_alloc_locks = kmem_zalloc(spa->spa_alloc_count *
+ sizeof (kmutex_t), KM_SLEEP);
+ spa->spa_alloc_trees = kmem_zalloc(spa->spa_alloc_count *
+ sizeof (avl_tree_t), KM_SLEEP);
+ for (int i = 0; i < spa->spa_alloc_count; i++) {
+ mutex_init(&spa->spa_alloc_locks[i], NULL, MUTEX_DEFAULT, NULL);
+ avl_create(&spa->spa_alloc_trees[i], zio_bookmark_compare,
+ sizeof (zio_t), offsetof(zio_t, io_alloc_node));
+ }
/*
* Every pool starts with the default cachefile
@@ -746,7 +755,15 @@ spa_remove(spa_t *spa)
kmem_free(dp, sizeof (spa_config_dirent_t));
}
- avl_destroy(&spa->spa_alloc_tree);
+ for (int i = 0; i < spa->spa_alloc_count; i++) {
+ avl_destroy(&spa->spa_alloc_trees[i]);
+ mutex_destroy(&spa->spa_alloc_locks[i]);
+ }
+ kmem_free(spa->spa_alloc_locks, spa->spa_alloc_count *
+ sizeof (kmutex_t));
+ kmem_free(spa->spa_alloc_trees, spa->spa_alloc_count *
+ sizeof (avl_tree_t));
+
list_destroy(&spa->spa_config_list);
nvlist_free(spa->spa_label_features);
@@ -777,7 +794,6 @@ spa_remove(spa_t *spa)
cv_destroy(&spa->spa_scrub_io_cv);
cv_destroy(&spa->spa_suspend_cv);
- mutex_destroy(&spa->spa_alloc_lock);
mutex_destroy(&spa->spa_async_lock);
mutex_destroy(&spa->spa_errlist_lock);
mutex_destroy(&spa->spa_errlog_lock);
diff --git a/usr/src/uts/common/fs/zfs/sys/metaslab.h b/usr/src/uts/common/fs/zfs/sys/metaslab.h
index a76d344d21..32a19ca645 100644
--- a/usr/src/uts/common/fs/zfs/sys/metaslab.h
+++ b/usr/src/uts/common/fs/zfs/sys/metaslab.h
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
*/
#ifndef _SYS_METASLAB_H
@@ -65,9 +65,10 @@ uint64_t metaslab_block_maxsize(metaslab_t *);
#define METASLAB_DONT_THROTTLE 0x10
int metaslab_alloc(spa_t *, metaslab_class_t *, uint64_t,
- blkptr_t *, int, uint64_t, blkptr_t *, int, zio_alloc_list_t *, zio_t *);
+ blkptr_t *, int, uint64_t, blkptr_t *, int, zio_alloc_list_t *, zio_t *,
+ int);
int metaslab_alloc_dva(spa_t *, metaslab_class_t *, uint64_t,
- dva_t *, int, dva_t *, uint64_t, int, zio_alloc_list_t *);
+ dva_t *, int, dva_t *, uint64_t, int, zio_alloc_list_t *, int);
void metaslab_free(spa_t *, const blkptr_t *, uint64_t, boolean_t);
void metaslab_free_concrete(vdev_t *, uint64_t, uint64_t, boolean_t);
void metaslab_free_dva(spa_t *, const dva_t *, boolean_t);
@@ -88,9 +89,9 @@ int metaslab_class_validate(metaslab_class_t *);
void metaslab_class_histogram_verify(metaslab_class_t *);
uint64_t metaslab_class_fragmentation(metaslab_class_t *);
uint64_t metaslab_class_expandable_space(metaslab_class_t *);
-boolean_t metaslab_class_throttle_reserve(metaslab_class_t *, int,
+boolean_t metaslab_class_throttle_reserve(metaslab_class_t *, int, int,
zio_t *, int);
-void metaslab_class_throttle_unreserve(metaslab_class_t *, int, zio_t *);
+void metaslab_class_throttle_unreserve(metaslab_class_t *, int, int, zio_t *);
void metaslab_class_space_update(metaslab_class_t *, int64_t, int64_t,
int64_t, int64_t);
@@ -99,7 +100,7 @@ uint64_t metaslab_class_get_space(metaslab_class_t *);
uint64_t metaslab_class_get_dspace(metaslab_class_t *);
uint64_t metaslab_class_get_deferred(metaslab_class_t *);
-metaslab_group_t *metaslab_group_create(metaslab_class_t *, vdev_t *);
+metaslab_group_t *metaslab_group_create(metaslab_class_t *, vdev_t *, int);
void metaslab_group_destroy(metaslab_group_t *);
void metaslab_group_activate(metaslab_group_t *);
void metaslab_group_passivate(metaslab_group_t *);
@@ -108,8 +109,9 @@ uint64_t metaslab_group_get_space(metaslab_group_t *);
void metaslab_group_histogram_verify(metaslab_group_t *);
uint64_t metaslab_group_fragmentation(metaslab_group_t *);
void metaslab_group_histogram_remove(metaslab_group_t *, metaslab_t *);
-void metaslab_group_alloc_decrement(spa_t *, uint64_t, void *, int);
-void metaslab_group_alloc_verify(spa_t *, const blkptr_t *, void *);
+void metaslab_group_alloc_decrement(spa_t *, uint64_t, void *, int, int,
+ boolean_t);
+void metaslab_group_alloc_verify(spa_t *, const blkptr_t *, void *, int);
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/fs/zfs/sys/metaslab_impl.h b/usr/src/uts/common/fs/zfs/sys/metaslab_impl.h
index a6673fbe06..6a02f7c800 100644
--- a/usr/src/uts/common/fs/zfs/sys/metaslab_impl.h
+++ b/usr/src/uts/common/fs/zfs/sys/metaslab_impl.h
@@ -24,7 +24,7 @@
*/
/*
- * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
*/
#ifndef _SYS_METASLAB_IMPL_H
@@ -52,6 +52,7 @@ typedef struct metaslab_alloc_trace {
uint64_t mat_weight;
uint32_t mat_dva_id;
uint64_t mat_offset;
+ int mat_allocator;
} metaslab_alloc_trace_t;
/*
@@ -72,9 +73,11 @@ typedef enum trace_alloc_type {
#define METASLAB_WEIGHT_PRIMARY (1ULL << 63)
#define METASLAB_WEIGHT_SECONDARY (1ULL << 62)
-#define METASLAB_WEIGHT_TYPE (1ULL << 61)
+#define METASLAB_WEIGHT_CLAIM (1ULL << 61)
+#define METASLAB_WEIGHT_TYPE (1ULL << 60)
#define METASLAB_ACTIVE_MASK \
- (METASLAB_WEIGHT_PRIMARY | METASLAB_WEIGHT_SECONDARY)
+ (METASLAB_WEIGHT_PRIMARY | METASLAB_WEIGHT_SECONDARY | \
+ METASLAB_WEIGHT_CLAIM)
/*
* The metaslab weight is used to encode the amount of free space in a
@@ -97,37 +100,39 @@ typedef enum trace_alloc_type {
*
* 64 56 48 40 32 24 16 8 0
* +-------+-------+-------+-------+-------+-------+-------+-------+
- * |PS1| weighted-free space |
+ * |PSC1| weighted-free space |
* +-------+-------+-------+-------+-------+-------+-------+-------+
*
* PS - indicates primary and secondary activation
+ * C - indicates activation for claimed block zio
* space - the fragmentation-weighted space
*
* Segment-based weight:
*
* 64 56 48 40 32 24 16 8 0
* +-------+-------+-------+-------+-------+-------+-------+-------+
- * |PS0| idx| count of segments in region |
+ * |PSC0| idx| count of segments in region |
* +-------+-------+-------+-------+-------+-------+-------+-------+
*
* PS - indicates primary and secondary activation
+ * C - indicates activation for claimed block zio
* idx - index for the highest bucket in the histogram
* count - number of segments in the specified bucket
*/
-#define WEIGHT_GET_ACTIVE(weight) BF64_GET((weight), 62, 2)
-#define WEIGHT_SET_ACTIVE(weight, x) BF64_SET((weight), 62, 2, x)
+#define WEIGHT_GET_ACTIVE(weight) BF64_GET((weight), 61, 3)
+#define WEIGHT_SET_ACTIVE(weight, x) BF64_SET((weight), 61, 3, x)
#define WEIGHT_IS_SPACEBASED(weight) \
- ((weight) == 0 || BF64_GET((weight), 61, 1))
-#define WEIGHT_SET_SPACEBASED(weight) BF64_SET((weight), 61, 1, 1)
+ ((weight) == 0 || BF64_GET((weight), 60, 1))
+#define WEIGHT_SET_SPACEBASED(weight) BF64_SET((weight), 60, 1, 1)
/*
* These macros are only applicable to segment-based weighting.
*/
-#define WEIGHT_GET_INDEX(weight) BF64_GET((weight), 55, 6)
-#define WEIGHT_SET_INDEX(weight, x) BF64_SET((weight), 55, 6, x)
-#define WEIGHT_GET_COUNT(weight) BF64_GET((weight), 0, 55)
-#define WEIGHT_SET_COUNT(weight, x) BF64_SET((weight), 0, 55, x)
+#define WEIGHT_GET_INDEX(weight) BF64_GET((weight), 54, 6)
+#define WEIGHT_SET_INDEX(weight, x) BF64_SET((weight), 54, 6, x)
+#define WEIGHT_GET_COUNT(weight) BF64_GET((weight), 0, 54)
+#define WEIGHT_SET_COUNT(weight, x) BF64_SET((weight), 0, 54, x)
/*
* A metaslab class encompasses a category of allocatable top-level vdevs.
@@ -178,8 +183,8 @@ struct metaslab_class {
* allowed to reserve slots even if we've reached the maximum
* number of allocations allowed.
*/
- uint64_t mc_alloc_max_slots;
- refcount_t mc_alloc_slots;
+ uint64_t *mc_alloc_max_slots;
+ refcount_t *mc_alloc_slots;
uint64_t mc_alloc_groups; /* # of allocatable groups */
@@ -201,9 +206,12 @@ struct metaslab_class {
*/
struct metaslab_group {
kmutex_t mg_lock;
+ metaslab_t **mg_primaries;
+ metaslab_t **mg_secondaries;
avl_tree_t mg_metaslab_tree;
uint64_t mg_aliquot;
boolean_t mg_allocatable; /* can we allocate? */
+ uint64_t mg_ms_ready;
/*
* A metaslab group is considered to be initialized only after
@@ -223,15 +231,33 @@ struct metaslab_group {
metaslab_group_t *mg_next;
/*
- * Each metaslab group can handle mg_max_alloc_queue_depth allocations
- * which are tracked by mg_alloc_queue_depth. It's possible for a
- * metaslab group to handle more allocations than its max. This
- * can occur when gang blocks are required or when other groups
- * are unable to handle their share of allocations.
+ * In order for the allocation throttle to function properly, we cannot
+ * have too many IOs going to each disk by default; the throttle
+ * operates by allocating more work to disks that finish quickly, so
+ * allocating larger chunks to each disk reduces its effectiveness.
+ * However, if the number of IOs going to each allocator is too small,
+ * we will not perform proper aggregation at the vdev_queue layer,
+ * also resulting in decreased performance. Therefore, we will use a
+ * ramp-up strategy.
+ *
+ * Each allocator in each metaslab group has a current queue depth
+ * (mg_alloc_queue_depth[allocator]) and a current max queue depth
+ * (mg_cur_max_alloc_queue_depth[allocator]), and each metaslab group
+ * has an absolute max queue depth (mg_max_alloc_queue_depth). We
+ * add IOs to an allocator until the mg_alloc_queue_depth for that
+ * allocator hits the cur_max. Every time an IO completes for a given
+ * allocator on a given metaslab group, we increment its cur_max until
+ * it reaches mg_max_alloc_queue_depth. The cur_max resets every txg to
+ * help protect against disks that decrease in performance over time.
+ *
+ * It's possible for an allocator to handle more allocations than
+ * its max. This can occur when gang blocks are required or when other
+ * groups are unable to handle their share of allocations.
*/
uint64_t mg_max_alloc_queue_depth;
- refcount_t mg_alloc_queue_depth;
-
+ uint64_t *mg_cur_max_alloc_queue_depth;
+ refcount_t *mg_alloc_queue_depth;
+ int mg_allocators;
/*
* A metalab group that can no longer allocate the minimum block
* size will set mg_no_free_space. Once a metaslab group is out
@@ -356,6 +382,13 @@ struct metaslab {
uint64_t ms_max_size; /* maximum allocatable size */
/*
+ * -1 if it's not active in an allocator, otherwise set to the allocator
+ * this metaslab is active for.
+ */
+ int ms_allocator;
+ boolean_t ms_primary; /* Only valid if ms_allocator is not -1 */
+
+ /*
* The metaslab block allocators can optionally use a size-ordered
* range tree and/or an array of LBAs. Not all allocators use
* this functionality. The ms_allocatable_by_size should always
@@ -369,6 +402,8 @@ struct metaslab {
metaslab_group_t *ms_group; /* metaslab group */
avl_node_t ms_group_node; /* node in metaslab group tree */
txg_node_t ms_txg_node; /* per-txg dirty metaslab links */
+
+ boolean_t ms_new;
};
#ifdef __cplusplus
diff --git a/usr/src/uts/common/fs/zfs/sys/spa_impl.h b/usr/src/uts/common/fs/zfs/sys/spa_impl.h
index a23f9b8c4f..a6da04b67b 100644
--- a/usr/src/uts/common/fs/zfs/sys/spa_impl.h
+++ b/usr/src/uts/common/fs/zfs/sys/spa_impl.h
@@ -237,8 +237,16 @@ struct spa {
uint64_t spa_last_synced_guid; /* last synced guid */
list_t spa_config_dirty_list; /* vdevs with dirty config */
list_t spa_state_dirty_list; /* vdevs with dirty state */
- kmutex_t spa_alloc_lock;
- avl_tree_t spa_alloc_tree;
+ /*
+ * spa_alloc_locks and spa_alloc_trees are arrays, whose lengths are
+ * stored in spa_alloc_count. There is one tree and one lock for each
+ * allocator, to help improve allocation performance in write-heavy
+ * workloads.
+ */
+ kmutex_t *spa_alloc_locks;
+ avl_tree_t *spa_alloc_trees;
+ int spa_alloc_count;
+
spa_aux_vdev_t spa_spares; /* hot spares */
spa_aux_vdev_t spa_l2cache; /* L2ARC cache devices */
nvlist_t *spa_label_features; /* Features for reading MOS */
diff --git a/usr/src/uts/common/fs/zfs/sys/vdev_impl.h b/usr/src/uts/common/fs/zfs/sys/vdev_impl.h
index 4327f61af9..252069c5a4 100644
--- a/usr/src/uts/common/fs/zfs/sys/vdev_impl.h
+++ b/usr/src/uts/common/fs/zfs/sys/vdev_impl.h
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
*/
#ifndef _SYS_VDEV_IMPL_H
@@ -59,6 +59,7 @@ typedef struct vdev_cache_entry vdev_cache_entry_t;
struct abd;
extern int zfs_vdev_queue_depth_pct;
+extern int zfs_vdev_def_queue_depth;
extern uint32_t zfs_vdev_async_write_max_active;
/*
diff --git a/usr/src/uts/common/fs/zfs/sys/zio.h b/usr/src/uts/common/fs/zfs/sys/zio.h
index 1520216c8f..273e5fcb0b 100644
--- a/usr/src/uts/common/fs/zfs/sys/zio.h
+++ b/usr/src/uts/common/fs/zfs/sys/zio.h
@@ -22,7 +22,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright 2016 Toomas Soome <tsoome@me.com>
@@ -459,6 +459,7 @@ struct zio {
void *io_waiter;
kmutex_t io_lock;
kcondvar_t io_cv;
+ int io_allocator;
/* FMA state */
zio_cksum_report_t *io_cksum_report;
@@ -517,8 +518,8 @@ extern zio_t *zio_write_phys(zio_t *pio, vdev_t *vd, uint64_t offset,
extern zio_t *zio_free_sync(zio_t *pio, spa_t *spa, uint64_t txg,
const blkptr_t *bp, enum zio_flag flags);
-extern int zio_alloc_zil(spa_t *spa, uint64_t txg, blkptr_t *new_bp,
- blkptr_t *old_bp, uint64_t size, boolean_t *slog);
+extern int zio_alloc_zil(spa_t *spa, uint64_t objset, uint64_t txg,
+ blkptr_t *new_bp, blkptr_t *old_bp, uint64_t size, boolean_t *slog);
extern void zio_flush(zio_t *zio, vdev_t *vd);
extern void zio_shrink(zio_t *zio, uint64_t size);
diff --git a/usr/src/uts/common/fs/zfs/vdev.c b/usr/src/uts/common/fs/zfs/vdev.c
index ae7f4b501c..e761ee4b39 100644
--- a/usr/src/uts/common/fs/zfs/vdev.c
+++ b/usr/src/uts/common/fs/zfs/vdev.c
@@ -644,7 +644,8 @@ vdev_alloc(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, uint_t id,
alloctype == VDEV_ALLOC_SPLIT ||
alloctype == VDEV_ALLOC_ROOTPOOL);
vd->vdev_mg = metaslab_group_create(islog ?
- spa_log_class(spa) : spa_normal_class(spa), vd);
+ spa_log_class(spa) : spa_normal_class(spa), vd,
+ spa->spa_alloc_count);
}
if (vd->vdev_ops->vdev_op_leaf &&
@@ -1013,7 +1014,6 @@ vdev_metaslab_init(vdev_t *vd, uint64_t txg)
vd->vdev_ms = mspp;
vd->vdev_ms_count = newc;
-
for (m = oldc; m < newc; m++) {
uint64_t object = 0;
diff --git a/usr/src/uts/common/fs/zfs/vdev_queue.c b/usr/src/uts/common/fs/zfs/vdev_queue.c
index 3a6644a51f..9f962350db 100644
--- a/usr/src/uts/common/fs/zfs/vdev_queue.c
+++ b/usr/src/uts/common/fs/zfs/vdev_queue.c
@@ -25,7 +25,7 @@
*/
/*
- * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
*/
@@ -189,6 +189,15 @@ int zfs_vdev_queue_depth_pct = 1000;
int zfs_vdev_queue_depth_pct = 300;
#endif
+/*
+ * When performing allocations for a given metaslab, we want to make sure that
+ * there are enough IOs to aggregate together to improve throughput. We want to
+ * ensure that there are at least 128k worth of IOs that can be aggregated, and
+ * we assume that the average allocation size is 4k, so we need the queue depth
+ * to be 32 per allocator to get good aggregation of sequential writes.
+ */
+int zfs_vdev_def_queue_depth = 32;
+
int
vdev_queue_offset_compare(const void *x1, const void *x2)
diff --git a/usr/src/uts/common/fs/zfs/vdev_removal.c b/usr/src/uts/common/fs/zfs/vdev_removal.c
index f8d149fc11..d00b5b35f7 100644
--- a/usr/src/uts/common/fs/zfs/vdev_removal.c
+++ b/usr/src/uts/common/fs/zfs/vdev_removal.c
@@ -806,8 +806,15 @@ spa_vdev_copy_segment(vdev_t *vd, uint64_t start, uint64_t size, uint64_t txg,
ASSERT3U(size, <=, SPA_MAXBLOCKSIZE);
+ /*
+ * We use allocator 0 for this I/O because we don't expect device remap
+ * to be the steady state of the system, so parallelizing is not as
+ * critical as it is for other allocation types. We also want to ensure
+ * that the IOs are allocated together as much as possible, to reduce
+ * mapping sizes.
+ */
int error = metaslab_alloc_dva(spa, mg->mg_class, size,
- &dst, 0, NULL, txg, 0, zal);
+ &dst, 0, NULL, txg, 0, zal, 0);
if (error != 0)
return (error);
diff --git a/usr/src/uts/common/fs/zfs/zil.c b/usr/src/uts/common/fs/zfs/zil.c
index 4711c7150f..0e02377de5 100644
--- a/usr/src/uts/common/fs/zfs/zil.c
+++ b/usr/src/uts/common/fs/zfs/zil.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Joyent, Inc. All rights reserved.
- * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
*/
@@ -657,7 +657,8 @@ zil_create(zilog_t *zilog)
BP_ZERO(&blk);
}
- error = zio_alloc_zil(zilog->zl_spa, txg, &blk, NULL,
+ error = zio_alloc_zil(zilog->zl_spa,
+ zilog->zl_os->os_dsl_dataset->ds_object, txg, &blk, NULL,
ZIL_MIN_BLKSZ, &slog);
if (error == 0)
@@ -1334,7 +1335,8 @@ zil_lwb_write_issue(zilog_t *zilog, lwb_t *lwb)
BP_ZERO(bp);
/* pass the old blkptr in order to spread log blocks across devs */
- error = zio_alloc_zil(spa, txg, bp, &lwb->lwb_blk, zil_blksz, &slog);
+ error = zio_alloc_zil(spa, zilog->zl_os->os_dsl_dataset->ds_object,
+ txg, bp, &lwb->lwb_blk, zil_blksz, &slog);
if (error == 0) {
ASSERT3U(bp->blk_birth, ==, txg);
bp->blk_cksum = lwb->lwb_blk.blk_cksum;
diff --git a/usr/src/uts/common/fs/zfs/zio.c b/usr/src/uts/common/fs/zfs/zio.c
index d43adabb5b..f2c511ef77 100644
--- a/usr/src/uts/common/fs/zfs/zio.c
+++ b/usr/src/uts/common/fs/zfs/zio.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
* Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
@@ -44,6 +44,7 @@
#include <sys/zfs_zone.h>
#include <sys/metaslab_impl.h>
#include <sys/abd.h>
+#include <sys/cityhash.h>
/*
* ==========================================================================
@@ -2235,7 +2236,8 @@ zio_write_gang_block(zio_t *pio)
ASSERT(!(pio->io_flags & ZIO_FLAG_NODATA));
flags |= METASLAB_ASYNC_ALLOC;
- VERIFY(refcount_held(&mc->mc_alloc_slots, pio));
+ VERIFY(refcount_held(&mc->mc_alloc_slots[pio->io_allocator],
+ pio));
/*
* The logical zio has already placed a reservation for
@@ -2246,12 +2248,12 @@ zio_write_gang_block(zio_t *pio)
* additional reservations for gang blocks.
*/
VERIFY(metaslab_class_throttle_reserve(mc, gbh_copies - copies,
- pio, flags));
+ pio->io_allocator, pio, flags));
}
error = metaslab_alloc(spa, mc, SPA_GANGBLOCKSIZE,
bp, gbh_copies, txg, pio == gio ? NULL : gio->io_bp, flags,
- &pio->io_alloc_list, pio);
+ &pio->io_alloc_list, pio, pio->io_allocator);
if (error) {
if (pio->io_flags & ZIO_FLAG_IO_ALLOCATING) {
ASSERT(pio->io_priority == ZIO_PRIORITY_ASYNC_WRITE);
@@ -2265,7 +2267,7 @@ zio_write_gang_block(zio_t *pio)
* stage.
*/
metaslab_class_throttle_unreserve(mc,
- gbh_copies - copies, pio);
+ gbh_copies - copies, pio->io_allocator, pio);
}
pio->io_error = error;
return (ZIO_PIPELINE_CONTINUE);
@@ -2323,7 +2325,7 @@ zio_write_gang_block(zio_t *pio)
* slot for them here.
*/
VERIFY(metaslab_class_throttle_reserve(mc,
- zp.zp_copies, cio, flags));
+ zp.zp_copies, cio->io_allocator, cio, flags));
}
zio_nowait(cio);
}
@@ -2813,13 +2815,13 @@ zio_ddt_free(zio_t *zio)
*/
static zio_t *
-zio_io_to_allocate(spa_t *spa)
+zio_io_to_allocate(spa_t *spa, int allocator)
{
zio_t *zio;
- ASSERT(MUTEX_HELD(&spa->spa_alloc_lock));
+ ASSERT(MUTEX_HELD(&spa->spa_alloc_locks[allocator]));
- zio = avl_first(&spa->spa_alloc_tree);
+ zio = avl_first(&spa->spa_alloc_trees[allocator]);
if (zio == NULL)
return (NULL);
@@ -2829,12 +2831,13 @@ zio_io_to_allocate(spa_t *spa)
* Try to place a reservation for this zio. If we're unable to
* reserve then we throttle.
*/
+ ASSERT3U(zio->io_allocator, ==, allocator);
if (!metaslab_class_throttle_reserve(spa_normal_class(spa),
- zio->io_prop.zp_copies, zio, 0)) {
+ zio->io_prop.zp_copies, zio->io_allocator, zio, 0)) {
return (NULL);
}
- avl_remove(&spa->spa_alloc_tree, zio);
+ avl_remove(&spa->spa_alloc_trees[allocator], zio);
ASSERT3U(zio->io_stage, <, ZIO_STAGE_DVA_ALLOCATE);
return (zio);
@@ -2858,13 +2861,23 @@ zio_dva_throttle(zio_t *zio)
ASSERT3U(zio->io_queued_timestamp, >, 0);
ASSERT(zio->io_stage == ZIO_STAGE_DVA_THROTTLE);
- mutex_enter(&spa->spa_alloc_lock);
+ zbookmark_phys_t *bm = &zio->io_bookmark;
+ /*
+ * We want to try to use as many allocators as possible to help improve
+ * performance, but we also want logically adjacent IOs to be physically
+ * adjacent to improve sequential read performance. We chunk each object
+ * into 2^20 block regions, and then hash based on the objset, object,
+ * level, and region to accomplish both of these goals.
+ */
+ zio->io_allocator = cityhash4(bm->zb_objset, bm->zb_object,
+ bm->zb_level, bm->zb_blkid >> 20) % spa->spa_alloc_count;
+ mutex_enter(&spa->spa_alloc_locks[zio->io_allocator]);
ASSERT(zio->io_type == ZIO_TYPE_WRITE);
- avl_add(&spa->spa_alloc_tree, zio);
+ avl_add(&spa->spa_alloc_trees[zio->io_allocator], zio);
- nio = zio_io_to_allocate(zio->io_spa);
- mutex_exit(&spa->spa_alloc_lock);
+ nio = zio_io_to_allocate(zio->io_spa, zio->io_allocator);
+ mutex_exit(&spa->spa_alloc_locks[zio->io_allocator]);
if (nio == zio)
return (ZIO_PIPELINE_CONTINUE);
@@ -2885,13 +2898,13 @@ zio_dva_throttle(zio_t *zio)
}
void
-zio_allocate_dispatch(spa_t *spa)
+zio_allocate_dispatch(spa_t *spa, int allocator)
{
zio_t *zio;
- mutex_enter(&spa->spa_alloc_lock);
- zio = zio_io_to_allocate(spa);
- mutex_exit(&spa->spa_alloc_lock);
+ mutex_enter(&spa->spa_alloc_locks[allocator]);
+ zio = zio_io_to_allocate(spa, allocator);
+ mutex_exit(&spa->spa_alloc_locks[allocator]);
if (zio == NULL)
return;
@@ -2932,7 +2945,7 @@ zio_dva_allocate(zio_t *zio)
error = metaslab_alloc(spa, mc, zio->io_size, bp,
zio->io_prop.zp_copies, zio->io_txg, NULL, flags,
- &zio->io_alloc_list, zio);
+ &zio->io_alloc_list, zio, zio->io_allocator);
if (error != 0) {
spa_dbgmsg(spa, "%s: metaslab allocation failure: zio %p, "
@@ -2992,8 +3005,8 @@ zio_dva_unallocate(zio_t *zio, zio_gang_node_t *gn, blkptr_t *bp)
* Try to allocate an intent log block. Return 0 on success, errno on failure.
*/
int
-zio_alloc_zil(spa_t *spa, uint64_t txg, blkptr_t *new_bp, blkptr_t *old_bp,
- uint64_t size, boolean_t *slog)
+zio_alloc_zil(spa_t *spa, uint64_t objset, uint64_t txg, blkptr_t *new_bp,
+ blkptr_t *old_bp, uint64_t size, boolean_t *slog)
{
int error = 1;
zio_alloc_list_t io_alloc_list;
@@ -3001,14 +3014,22 @@ zio_alloc_zil(spa_t *spa, uint64_t txg, blkptr_t *new_bp, blkptr_t *old_bp,
ASSERT(txg > spa_syncing_txg(spa));
metaslab_trace_init(&io_alloc_list);
+ /*
+ * When allocating a zil block, we don't have information about
+ * the final destination of the block except the objset it's part
+ * of, so we just hash the objset ID to pick the allocator to get
+ * some parallelism.
+ */
error = metaslab_alloc(spa, spa_log_class(spa), size, new_bp, 1,
- txg, old_bp, METASLAB_HINTBP_AVOID, &io_alloc_list, NULL);
+ txg, old_bp, METASLAB_HINTBP_AVOID, &io_alloc_list, NULL,
+ cityhash4(0, 0, 0, objset) % spa->spa_alloc_count);
if (error == 0) {
*slog = TRUE;
} else {
error = metaslab_alloc(spa, spa_normal_class(spa), size,
new_bp, 1, txg, old_bp, METASLAB_HINTBP_AVOID,
- &io_alloc_list, NULL);
+ &io_alloc_list, NULL, cityhash4(0, 0, 0, objset) %
+ spa->spa_alloc_count);
if (error == 0)
*slog = FALSE;
}
@@ -3498,8 +3519,8 @@ zio_ready(zio_t *zio)
*/
metaslab_class_throttle_unreserve(
spa_normal_class(zio->io_spa),
- zio->io_prop.zp_copies, zio);
- zio_allocate_dispatch(zio->io_spa);
+ zio->io_prop.zp_copies, zio->io_allocator, zio);
+ zio_allocate_dispatch(zio->io_spa, zio->io_allocator);
}
}
@@ -3582,18 +3603,19 @@ zio_dva_throttle_done(zio_t *zio)
ASSERT0(zio->io_flags & ZIO_FLAG_NOPWRITE);
mutex_enter(&pio->io_lock);
- metaslab_group_alloc_decrement(zio->io_spa, vd->vdev_id, pio, flags);
+ metaslab_group_alloc_decrement(zio->io_spa, vd->vdev_id, pio, flags,
+ pio->io_allocator, B_TRUE);
mutex_exit(&pio->io_lock);
metaslab_class_throttle_unreserve(spa_normal_class(zio->io_spa),
- 1, pio);
+ 1, pio->io_allocator, pio);
/*
* Call into the pipeline to see if there is more work that
* needs to be done. If there is work to be done it will be
* dispatched to another taskq thread.
*/
- zio_allocate_dispatch(zio->io_spa);
+ zio_allocate_dispatch(zio->io_spa, pio->io_allocator);
}
static int
@@ -3636,8 +3658,10 @@ zio_done(zio_t *zio)
ASSERT(zio->io_type == ZIO_TYPE_WRITE);
ASSERT(zio->io_priority == ZIO_PRIORITY_ASYNC_WRITE);
ASSERT(bp != NULL);
- metaslab_group_alloc_verify(spa, zio->io_bp, zio);
- VERIFY(refcount_not_held(&mc->mc_alloc_slots, zio));
+ metaslab_group_alloc_verify(spa, zio->io_bp, zio,
+ zio->io_allocator);
+ VERIFY(refcount_not_held(&mc->mc_alloc_slots[zio->io_allocator],
+ zio));
}
for (int c = 0; c < ZIO_CHILD_TYPES; c++)
diff --git a/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_impl.c b/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_impl.c
index 370c39ccc1..34014a5768 100644
--- a/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_impl.c
+++ b/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas_impl.c
@@ -2143,7 +2143,7 @@ mptsas_get_sas_io_unit_page_hndshk(mptsas_t *mpt)
"manufacturing information (%u). Driver "
"will not attach. Please contact the "
"firmware vendor about this.", num_phys,
- mpt->m_num_phys, mpt->m_num_phys);
+ mpt->m_num_phys);
rval = DDI_FAILURE;
goto cleanup;
}
@@ -2243,7 +2243,7 @@ mptsas_get_sas_io_unit_page_hndshk(mptsas_t *mpt)
"manufacturing information (%u). Driver "
"will not attach. Please contact the "
"firmware vendor about this.", num_phys,
- mpt->m_num_phys, mpt->m_num_phys);
+ mpt->m_num_phys);
rval = DDI_FAILURE;
goto cleanup;
}
diff --git a/usr/src/uts/common/smb/Makefile b/usr/src/uts/common/smb/Makefile
index 2efb11c19c..74ac618565 100644
--- a/usr/src/uts/common/smb/Makefile
+++ b/usr/src/uts/common/smb/Makefile
@@ -21,6 +21,7 @@
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
#
include ../../../Makefile.master
@@ -29,7 +30,8 @@ HDRS= \
doserror.h \
lmerr.h \
nterror.h \
- ntstatus.h
+ ntstatus.h \
+ wintypes.h
ROOTDIR= $(ROOT)/usr/include/smb
diff --git a/usr/src/uts/common/smbsrv/wintypes.h b/usr/src/uts/common/smb/wintypes.h
index 1dc3e1515a..61e48016b4 100644
--- a/usr/src/uts/common/smbsrv/wintypes.h
+++ b/usr/src/uts/common/smb/wintypes.h
@@ -18,13 +18,16 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
-#ifndef _SMBSRV_WINTYPES_H
-#define _SMBSRV_WINTYPES_H
+#ifndef _SMB_WINTYPES_H
+#define _SMB_WINTYPES_H
#include <sys/types.h>
@@ -42,36 +45,26 @@ extern "C" {
typedef uint8_t BYTE;
typedef uint16_t WORD;
typedef uint32_t DWORD;
-typedef uint32_t ntstatus_t;
+typedef DWORD ntstatus_t;
+
+/* pointers to those types */
+typedef BYTE *LPBYTE;
+typedef WORD *LPWORD;
+typedef DWORD *LPDWORD;
+
+/* Note: Internally, this is always a UTF-8 string. */
typedef uint8_t *LPTSTR;
-typedef uint8_t *LPBYTE;
-typedef uint16_t *LPWORD;
-typedef uint32_t *LPDWORD;
#endif /* UNSIGNED_TYPES_DEFINED */
-
#ifndef ANY_SIZE_ARRAY
#define ANY_SIZE_ARRAY 1
#endif /* ANY_SIZE_ARRAY */
-/*
- * Opaque context handle.
- */
-#ifndef CONTEXT_HANDLE
-#define CONTEXT_HANDLE(NAME) \
- struct NAME { \
- DWORD data1; \
- DWORD data2; \
- WORD data3[2]; \
- BYTE data4[8]; \
- }; \
- typedef struct NAME
-#endif /* CONTEXT_HANDLE */
-
+/* CONTEXT_HANDLE now in ndrtypes.ndl */
#ifdef __cplusplus
}
#endif
-#endif /* _SMBSRV_WINTYPES_H */
+#endif /* _SMB_WINTYPES_H */
diff --git a/usr/src/uts/common/smbsrv/Makefile b/usr/src/uts/common/smbsrv/Makefile
index f48dc89acb..4664c09cfb 100644
--- a/usr/src/uts/common/smbsrv/Makefile
+++ b/usr/src/uts/common/smbsrv/Makefile
@@ -33,7 +33,6 @@ HDRS= alloc.h \
mailslot.h \
mbuf.h \
msgbuf.h \
- ndr.h \
netbios.h \
netrauth.h \
nmpipes.h \
@@ -63,18 +62,15 @@ HDRS= alloc.h \
string.h \
svrapi.h \
winioctl.h \
- winsvc.h \
- wintypes.h
+ winsvc.h
NDLHDRS= dssetup.ndl \
eventlog.ndl \
llsrpc.ndl \
lsarpc.ndl \
msgsvc.ndl \
- ndrtypes.ndl \
netdfs.ndl \
netlogon.ndl \
- rpcpdu.ndl \
samrpc.ndl \
security.ndl \
spoolss.ndl \
diff --git a/usr/src/uts/common/smbsrv/ndl/dssetup.ndl b/usr/src/uts/common/smbsrv/ndl/dssetup.ndl
index b70a81bb5e..8f1d718e94 100644
--- a/usr/src/uts/common/smbsrv/ndl/dssetup.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/dssetup.ndl
@@ -21,6 +21,8 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _DSSETUP_NDL_
@@ -34,7 +36,7 @@
* except DsRoleGetPrimaryDomainInfo have been deprecated (MS04-011).
*/
-#include "ndrtypes.ndl"
+#include <libmlrpc/ndrtypes.ndl>
#define DSSETUP_OPNUM_DsRoleGetPrimaryDomainInfo 0x00
diff --git a/usr/src/uts/common/smbsrv/ndl/eventlog.ndl b/usr/src/uts/common/smbsrv/ndl/eventlog.ndl
index df56f8837a..c0e579c4d6 100644
--- a/usr/src/uts/common/smbsrv/ndl/eventlog.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/eventlog.ndl
@@ -21,6 +21,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _MLSVC_LOGR_NDL_
@@ -34,7 +36,7 @@
***********************************************************************
*/
-#include "ndrtypes.ndl"
+#include <libmlrpc/ndrtypes.ndl>
#define LOGR_OPNUM_EventLogClose 0x02
#define LOGR_OPNUM_EventLogQueryCount 0x04
diff --git a/usr/src/uts/common/smbsrv/ndl/llsrpc.ndl b/usr/src/uts/common/smbsrv/ndl/llsrpc.ndl
index 3710b32e47..62c276873e 100644
--- a/usr/src/uts/common/smbsrv/ndl/llsrpc.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/llsrpc.ndl
@@ -21,6 +21,8 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _MLSVC_LLSR_NDL_
@@ -41,7 +43,7 @@
* 0x3b closes the handle obtained via 0x3a
*/
-#include "ndrtypes.ndl"
+#include <libmlrpc/ndrtypes.ndl>
#define LLSR_OPNUM_Open 0x00
#define LLSR_OPNUM_Close 0x01
diff --git a/usr/src/uts/common/smbsrv/ndl/lsarpc.ndl b/usr/src/uts/common/smbsrv/ndl/lsarpc.ndl
index 2d89687a6a..e93324b419 100644
--- a/usr/src/uts/common/smbsrv/ndl/lsarpc.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/lsarpc.ndl
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _MLSVC_LSA_NDL_
@@ -38,7 +39,7 @@
* user principal name (UPN) form, such as john@example.com.
*/
-#include "ndrtypes.ndl"
+#include <libmlrpc/ndrtypes.ndl>
#define LSARPC_OPNUM_CloseHandle 0x00
diff --git a/usr/src/uts/common/smbsrv/ndl/msgsvc.ndl b/usr/src/uts/common/smbsrv/ndl/msgsvc.ndl
index 28ab3b6437..f804f32685 100644
--- a/usr/src/uts/common/smbsrv/ndl/msgsvc.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/msgsvc.ndl
@@ -21,6 +21,8 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _MSGSVC_NDL_
@@ -30,7 +32,7 @@
* Message Service
*/
-#include "ndrtypes.ndl"
+#include <libmlrpc/ndrtypes.ndl>
#define MSGSVCSEND_OPNUM_NetrSendMessage 0x00
diff --git a/usr/src/uts/common/smbsrv/ndl/netdfs.ndl b/usr/src/uts/common/smbsrv/ndl/netdfs.ndl
index afc4c88385..7e9a0a42d1 100644
--- a/usr/src/uts/common/smbsrv/ndl/netdfs.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/netdfs.ndl
@@ -21,6 +21,8 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _NETDFS_NDL_
@@ -30,7 +32,7 @@
* NT Distributed File Service (NETDFS) RPC interface definition.
*/
-#include "ndrtypes.ndl"
+#include <libmlrpc/ndrtypes.ndl>
#define NETDFS_ABSTRACT_UUID "4fc742e0-4a10-11cf-8273-00aa004ae673"
diff --git a/usr/src/uts/common/smbsrv/ndl/netlogon.ndl b/usr/src/uts/common/smbsrv/ndl/netlogon.ndl
index 26df6a902a..907d52ec72 100644
--- a/usr/src/uts/common/smbsrv/ndl/netlogon.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/netlogon.ndl
@@ -36,7 +36,7 @@
***********************************************************************
*/
-#include "ndrtypes.ndl"
+#include <libmlrpc/ndrtypes.ndl>
#define NETR_OPNUM_UasLogon 0x00
diff --git a/usr/src/uts/common/smbsrv/ndl/samrpc.ndl b/usr/src/uts/common/smbsrv/ndl/samrpc.ndl
index f5ccfd75b8..ef47fff452 100644
--- a/usr/src/uts/common/smbsrv/ndl/samrpc.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/samrpc.ndl
@@ -31,7 +31,7 @@
* Security Accounts Manager RPC (SAMR) interface definition.
*/
-#include "ndrtypes.ndl"
+#include <libmlrpc/ndrtypes.ndl>
/* Windows NT */
#define SAMR_OPNUM_Connect 0x00 /* SamrConnect */
@@ -363,7 +363,7 @@ struct samr_logon_hours_all {
#ifndef NDRGEN
#define SAMR_USER_PWLEN 256
struct samr_user_password {
- smb_wchar_t Buffer[SAMR_USER_PWLEN];
+ ndr_wchar_t Buffer[SAMR_USER_PWLEN];
DWORD Length;
};
#endif /* NDRGEN */
diff --git a/usr/src/uts/common/smbsrv/ndl/spoolss.ndl b/usr/src/uts/common/smbsrv/ndl/spoolss.ndl
index a467b5638c..ef923797d4 100644
--- a/usr/src/uts/common/smbsrv/ndl/spoolss.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/spoolss.ndl
@@ -20,12 +20,13 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _SPOOLSS_NDL_
#define _SPOOLSS_NDL_
-#include "ndrtypes.ndl"
+#include <libmlrpc/ndrtypes.ndl>
#include "security.ndl"
#define TABLE_STRING 1
diff --git a/usr/src/uts/common/smbsrv/ndl/srvsvc.ndl b/usr/src/uts/common/smbsrv/ndl/srvsvc.ndl
index dbc42578d1..5e345a9585 100644
--- a/usr/src/uts/common/smbsrv/ndl/srvsvc.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/srvsvc.ndl
@@ -21,6 +21,8 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _MLSVC_LANMAN_NDL_
@@ -30,7 +32,7 @@
* LanMan RPC (WKSSVC and SRVSVC) interface definitions.
*/
-#include "ndrtypes.ndl"
+#include <libmlrpc/ndrtypes.ndl>
/*
* WARNING: The cpp(1) macros in this file are not understood by
diff --git a/usr/src/uts/common/smbsrv/ndl/svcctl.ndl b/usr/src/uts/common/smbsrv/ndl/svcctl.ndl
index 5a6a9d034e..2509f62b52 100644
--- a/usr/src/uts/common/smbsrv/ndl/svcctl.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/svcctl.ndl
@@ -21,6 +21,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _MLSVC_SVCCTL_NDL_
@@ -32,7 +34,7 @@
* stop services.
*/
-#include "ndrtypes.ndl"
+#include <libmlrpc/ndrtypes.ndl>
/* Windows NT */
#define SVCCTL_OPNUM_Close 0x00
diff --git a/usr/src/uts/common/smbsrv/ndl/winreg.ndl b/usr/src/uts/common/smbsrv/ndl/winreg.ndl
index d09cc32ed2..5789a63e91 100644
--- a/usr/src/uts/common/smbsrv/ndl/winreg.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/winreg.ndl
@@ -21,6 +21,8 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _MLSVC_WINREG_NDL_
@@ -43,7 +45,7 @@
* HKEY_PERFORMANCE_NLS (HKPN) Runtime performance information.
*/
-#include "ndrtypes.ndl"
+#include <libmlrpc/ndrtypes.ndl>
/* Windows NT */
#define WINREG_OPNUM_OpenHKCR 0x00
diff --git a/usr/src/uts/common/smbsrv/netrauth.h b/usr/src/uts/common/smbsrv/netrauth.h
index bc11d81e8c..b621e2da1a 100644
--- a/usr/src/uts/common/smbsrv/netrauth.h
+++ b/usr/src/uts/common/smbsrv/netrauth.h
@@ -33,7 +33,7 @@
*/
#include <sys/types.h>
-#include <smbsrv/wintypes.h>
+#include <smb/wintypes.h>
#include <smbsrv/netbios.h>
#include <smbsrv/smbinfo.h>
#include <netdb.h>
diff --git a/usr/src/uts/common/smbsrv/smb_door.h b/usr/src/uts/common/smbsrv/smb_door.h
index 31d32794eb..a59040ecdf 100644
--- a/usr/src/uts/common/smbsrv/smb_door.h
+++ b/usr/src/uts/common/smbsrv/smb_door.h
@@ -27,7 +27,7 @@
#define _SMBSRV_SMB_DOOR_H
#include <sys/door.h>
-#include <smbsrv/wintypes.h>
+#include <smb/wintypes.h>
#include <smbsrv/smb_xdr.h>
#include <smbsrv/smb_token.h>
diff --git a/usr/src/uts/common/smbsrv/smb_privilege.h b/usr/src/uts/common/smbsrv/smb_privilege.h
index 1a1ee196c1..cbca27107f 100644
--- a/usr/src/uts/common/smbsrv/smb_privilege.h
+++ b/usr/src/uts/common/smbsrv/smb_privilege.h
@@ -28,7 +28,7 @@
#ifndef _SMB_PRIVILEGE_H
#define _SMB_PRIVILEGE_H
-#include <smbsrv/wintypes.h>
+#include <smb/wintypes.h>
#ifdef __cplusplus
extern "C" {
diff --git a/usr/src/uts/common/smbsrv/smb_share.h b/usr/src/uts/common/smbsrv/smb_share.h
index cfb7551dec..b8cfba779a 100644
--- a/usr/src/uts/common/smbsrv/smb_share.h
+++ b/usr/src/uts/common/smbsrv/smb_share.h
@@ -29,11 +29,11 @@
#define _SMB_SHARE_H
#include <sys/param.h>
+#include <smb/lmerr.h>
+#include <smb/wintypes.h>
#include <smbsrv/string.h>
#include <smbsrv/smb_inet.h>
#include <smbsrv/hash_table.h>
-#include <smbsrv/wintypes.h>
-#include <smb/lmerr.h>
#if !defined(_KERNEL) && !defined(_FAKE_KERNEL)
#include <libshare.h>
diff --git a/usr/src/uts/common/smbsrv/smb_sid.h b/usr/src/uts/common/smbsrv/smb_sid.h
index 5091f419a4..d6c749e8c1 100644
--- a/usr/src/uts/common/smbsrv/smb_sid.h
+++ b/usr/src/uts/common/smbsrv/smb_sid.h
@@ -29,7 +29,7 @@
/*
* Security Identifier (SID) interface definition.
*/
-#include <smbsrv/wintypes.h>
+#include <smb/wintypes.h>
#ifdef __cplusplus
extern "C" {
diff --git a/usr/src/uts/common/smbsrv/smb_xdr.h b/usr/src/uts/common/smbsrv/smb_xdr.h
index 51bf3b57e2..aaf0ff070f 100644
--- a/usr/src/uts/common/smbsrv/smb_xdr.h
+++ b/usr/src/uts/common/smbsrv/smb_xdr.h
@@ -34,14 +34,13 @@ extern "C" {
#include <sys/param.h>
#include <sys/avl.h>
#include <sys/list.h>
-#include <smbsrv/wintypes.h>
+#include <smb/wintypes.h>
#include <smbsrv/smb_sid.h>
#include <smbsrv/smbinfo.h>
#include <smbsrv/smb_ioctl.h>
#include <smbsrv/smb_sid.h>
#include <smbsrv/smb_share.h>
#include <smbsrv/smb_dfs.h>
-#include <smbsrv/wintypes.h>
#if defined(_KERNEL) || defined(_FAKE_KERNEL)
#include <sys/sysmacros.h>
diff --git a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/THIRDPARTYLICENSE b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/THIRDPARTYLICENSE
index f8cd22f7df..7741eb3a6b 100644
--- a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/THIRDPARTYLICENSE
+++ b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/THIRDPARTYLICENSE
@@ -1,6 +1,7 @@
-Copyright (c) 2013 LSI Corp.
+Copyright (c) 2012-2015 LSI Corp.
+Copyright (c) 2013-2016 Avago Technologies
All rights reserved.
-
+
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
@@ -12,7 +13,7 @@ are met:
3. Neither the name of the author nor the names of any co-contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
-
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
diff --git a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/THIRDPARTYLICENSE.descrip b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/THIRDPARTYLICENSE.descrip
index 88aaf438dc..3d80aca794 100644
--- a/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/THIRDPARTYLICENSE.descrip
+++ b/usr/src/uts/common/sys/scsi/adapters/mpt_sas/mpi/THIRDPARTYLICENSE.descrip
@@ -1 +1 @@
-LSI Fusion-MPT MPI 2.0 / 2.5 Header Files
+LSI Fusion-MPT MPI 2.0 / 2.5 / 2.6 Header Files