changeset 21467:f890323e6a74

Merge pull request #480 from citrus-it/upstream_merge/2019060301 Upstream merge upstream_merge/2019060301
author Dominik Hassler <hadfl@omniosce.org>
date Mon, 03 Jun 2019 18:18:53 +0200
parents b3f2b52f6be6 (current diff) e749519345d9 (diff)
children 06173b94a905
files usr/src/lib/libsldap/common/ns_connmgmt.c usr/src/lib/libsldap/common/ns_connmgmt.h usr/src/test/zfs-tests/tests/functional/cli_root/zpool_reopen/Makefile usr/src/test/zfs-tests/tests/functional/cli_root/zpool_resilver/Makefile usr/src/test/zfs-tests/tests/functional/cli_root/zpool_resilver/cleanup.ksh usr/src/test/zfs-tests/tests/functional/cli_root/zpool_resilver/setup.ksh usr/src/test/zfs-tests/tests/functional/cli_root/zpool_resilver/zpool_resilver.cfg
diffstat 112 files changed, 3285 insertions(+), 489 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/boot/lib/libstand/zfs/zfsimpl.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/boot/lib/libstand/zfs/zfsimpl.c	Mon Jun 03 18:18:53 2019 +0200
@@ -106,8 +106,7 @@
 	char *ptr;
 
 	if (zfs_temp_ptr + size > zfs_temp_end) {
-		printf("ZFS: out of temporary buffer space\n");
-		for (;;) ;
+		panic("ZFS: out of temporary buffer space");
 	}
 	ptr = zfs_temp_ptr;
 	zfs_temp_ptr += size;
@@ -121,8 +120,7 @@
 
 	zfs_temp_ptr -= size;
 	if (zfs_temp_ptr != ptr) {
-		printf("ZFS: zfs_alloc()/zfs_free() mismatch\n");
-		for (;;) ;
+		panic("ZFS: zfs_alloc()/zfs_free() mismatch");
 	}
 }
 
@@ -760,9 +758,8 @@
 {
 	spa_t *spa;
 
-	if ((spa = malloc(sizeof(spa_t))) == NULL)
+	if ((spa = calloc(1, sizeof (spa_t))) == NULL)
 		return (NULL);
-	memset(spa, 0, sizeof(spa_t));
 	if ((spa->spa_name = strdup(name)) == NULL) {
 		free(spa);
 		return (NULL);
--- a/usr/src/cmd/idmap/idmapd/adutils.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/cmd/idmap/idmapd/adutils.c	Mon Jun 03 18:18:53 2019 +0200
@@ -21,6 +21,8 @@
 
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
@@ -59,7 +61,7 @@
 #define	UIDNUMBERFILTER	"(&(objectclass=user)(uidNumber=%u))"
 #define	GIDNUMBERFILTER	"(&(objectclass=group)(gidNumber=%u))"
 #define	SANFILTER	"(sAMAccountName=%s)"
-#define	OBJSIDFILTER	"(objectSid=%s)"
+#define	OBJSIDFILTER	"(|(objectSid=%s)(sIDHistory=%s))"
 
 void	idmap_ldap_res_search_cb(LDAP *ld, LDAPMessage **res, int rc,
 		int qid, void *argp);
@@ -792,7 +794,7 @@
 		return (IDMAP_ERR_SID);
 
 	/* Assemble filter */
-	(void) asprintf(&filter, OBJSIDFILTER, cbinsid);
+	(void) asprintf(&filter, OBJSIDFILTER, cbinsid, cbinsid);
 	if (filter == NULL)
 		return (IDMAP_ERR_MEMORY);
 
--- a/usr/src/cmd/lp/include/printers.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/cmd/lp/include/printers.h	Mon Jun 03 18:18:53 2019 +0200
@@ -32,16 +32,6 @@
 #define	_LP_PRINTERS_H
 
 /*
- * The following conflicts are also defined in sys/processor.h.
- */
-#if defined PS_FAULTED
-#undef  PS_FAULTED
-#endif
-#if defined PS_DISABLED
-#undef  PS_DISABLED
-#endif
-
-/*
  * Define the following to support administrator configurable
  * streams modules:
  */
--- a/usr/src/cmd/ptools/Makefile.amd64	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/cmd/ptools/Makefile.amd64	Mon Jun 03 18:18:53 2019 +0200
@@ -23,8 +23,6 @@
 # Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-# ident	"%Z%%M%	%I%	%E% SMI"
-#
 
 include ../../../Makefile.cmd
 include ../../../Makefile.cmd.64
@@ -33,6 +31,7 @@
 CFLAGS64 += $(CCVERBOSE)
 
 ROOTISAPROG=$(ROOTBIN64)/$(PROG)
+ROOTISALN=$(LN_$(PROG):%=$(ROOTBIN64)/%)
 
 include ../../Makefile.bld
 
--- a/usr/src/cmd/ptools/Makefile.bld	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/cmd/ptools/Makefile.bld	Mon Jun 03 18:18:53 2019 +0200
@@ -22,11 +22,14 @@
 #
 # Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
+# Copyright 2015 Joyent, Inc.
 #
 # Copyright (c) 2018, Joyent, Inc.
 
 PROG:sh = basename `cd ..; pwd`
 
+include ../../../Makefile.ctf
+
 OBJS = $(PROG).o
 
 SRCS = ../$(PROG).c
@@ -119,16 +122,12 @@
 CPPFLAGS_pwdx =		$(CINC)
 OBJS_pwdx =		$(COBJS)
 
+LN_pargs =		penv pauxv
+
 CPPFLAGS +=	$(CPPFLAGS_$(PROG))
 OBJS +=		$(OBJS_$(PROG))
 SRCS +=		$(SRCS_$(PROG))
 
-# For lint, always include ptools_common.c, but suppress the "defined but
-# not used" error, in case a given ptool doesn't need it.
-SRCS +=		../../common/ptools_common.c
-LINTFLAGS +=	-xerroff=E_NAME_DEF_NOT_USED2
-LINTFLAGS64 +=	-xerroff=E_NAME_DEF_NOT_USED2
-
 INSTALL_NEW=
 INSTALL_LEGACY=$(RM) $(ROOTPROCBINSYMLINK) ; \
 	$(LN) -s ../../bin/$(PROG) $(ROOTPROCBINSYMLINK)
@@ -137,19 +136,23 @@
 
 elfcap.o:	$(ELFCAP)/elfcap.c
 		$(COMPILE.c) -o $@ $(ELFCAP)/elfcap.c
+		$(POST_PROCESS_O)
 
 pmap_common.o:	$(PMAP)/pmap_common.c
 		$(COMPILE.c) -o $@ $(PMAP)/pmap_common.c
+		$(POST_PROCESS_O)
 
 %.o:	../%.c
 	$(COMPILE.c) $<
+	$(POST_PROCESS_O)
 
 %.o:	../../common/%.c
 	$(COMPILE.c) $<
 	$(POST_PROCESS_O)
 
-all:	$(PROG)
+all:	$(PROG) $(LN_$(PROG))
 
+ROOTBINLN=$(LN_$(PROG):%=$(ROOTBIN)/%)
 ROOTBINPROG=$(ROOTBIN)/$(PROG)
 ROOTPROCBINSYMLINK=$(ROOT)/usr/proc/bin/$(PROG)
 
@@ -161,11 +164,23 @@
 # Install the ptool, symlinking it into /usr/proc/bin if PTOOL_TYPE is set
 # to LEGACY.
 #
-install: all $(ROOTISAPROG)
+install: all $(ROOTISAPROG) $(ROOTISALN) $(ROOTBINLN)
 	-$(RM) $(ROOTBINPROG)
 	-$(LN) $(ISAEXEC) $(ROOTBINPROG)
 	-$(INSTALL_$(PTOOL_TYPE))
 
+$(ROOTBINLN):
+	-$(RM) $@
+	-$(LN) $(ISAEXEC) $@
+
+$(ROOTISALN): $(ROOTISAPROG)
+	-$(RM) $@
+	-$(LN) $(ROOTISAPROG) $@
+
+$(LN_$(PROG)): $(PROG)
+	-$(RM) $@
+	-$(LN) $(PROG) $@
+
 clean:
 	$(RM) $(OBJS)
 
--- a/usr/src/cmd/ptools/Makefile.i386	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/cmd/ptools/Makefile.i386	Mon Jun 03 18:18:53 2019 +0200
@@ -20,8 +20,6 @@
 # CDDL HEADER END
 #
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
-#
 # Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
@@ -31,6 +29,7 @@
 CFLAGS += $(CCVERBOSE)
 
 ROOTISAPROG=$(ROOTBIN32)/$(PROG)
+ROOTISALN=$(LN_$(PROG):%=$(ROOTBIN32)/%)
 
 include ../../Makefile.bld
 
--- a/usr/src/cmd/ptools/Makefile.ptool	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/cmd/ptools/Makefile.ptool	Mon Jun 03 18:18:53 2019 +0200
@@ -20,8 +20,6 @@
 # CDDL HEADER END
 #
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
-#
 # Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
--- a/usr/src/cmd/ptools/Makefile.sparcv9	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/cmd/ptools/Makefile.sparcv9	Mon Jun 03 18:18:53 2019 +0200
@@ -23,8 +23,6 @@
 # Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-# ident	"%Z%%M%	%I%	%E% SMI"
-#
 
 include ../../../Makefile.cmd
 include ../../../Makefile.cmd.64
@@ -33,6 +31,7 @@
 CFLAGS64 += $(CCVERBOSE)
 
 ROOTISAPROG=$(ROOTBIN64)/$(PROG)
+ROOTISALN=$(LN_$(PROG):%=$(ROOTBIN64)/%)
 
 include ../../Makefile.bld
 
--- a/usr/src/cmd/ptools/pargs/pargs.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/cmd/ptools/pargs/pargs.c	Mon Jun 03 18:18:53 2019 +0200
@@ -73,6 +73,13 @@
 #include <wctype.h>
 #include <widec.h>
 #include <elfcap.h>
+#include <libgen.h>
+
+typedef enum pargs_cmd {
+	PARGS_ARGV,
+	PARGS_ENV,
+	PARGS_AUXV
+} pargs_cmd_t;
 
 typedef struct pargs_data {
 	struct ps_prochandle *pd_proc;	/* target proc handle */
@@ -1291,19 +1298,24 @@
 	int opt;
 	int error = 1;
 	core_content_t content = 0;
+	pargs_cmd_t cmd = PARGS_ARGV;
 
 	(void) setlocale(LC_ALL, "");
 
-	if ((command = strrchr(argv[0], '/')) != NULL)
-		command++;
-	else
-		command = argv[0];
+	command = basename(argv[0]);
+
+	if (strcmp(command, "penv") == 0)
+		cmd = PARGS_ENV;
+	else if (strcmp(command, "pauxv") == 0)
+		cmd = PARGS_AUXV;
 
 	while ((opt = getopt(argc, argv, "acelxF")) != EOF) {
 		switch (opt) {
 		case 'a':		/* show process arguments */
 			content |= CC_CONTENT_STACK;
 			aflag++;
+			if (cmd != PARGS_ARGV)
+				errflg++;
 			break;
 		case 'c':		/* force 7-bit ascii */
 			cflag++;
@@ -1311,13 +1323,19 @@
 		case 'e':		/* show environment variables */
 			content |= CC_CONTENT_STACK;
 			eflag++;
+			if (cmd != PARGS_ARGV)
+				errflg++;
 			break;
 		case 'l':
 			lflag++;
 			aflag++;	/* -l implies -a */
+			if (cmd != PARGS_ARGV)
+				errflg++;
 			break;
 		case 'x':		/* show aux vector entries */
 			xflag++;
+			if (cmd != PARGS_ARGV)
+				errflg++;
 			break;
 		case 'F':
 			/*
@@ -1334,8 +1352,19 @@
 
 	/* -a is the default if no options are specified */
 	if ((aflag + eflag + xflag + lflag) == 0) {
-		aflag++;
-		content |= CC_CONTENT_STACK;
+		switch (cmd) {
+		case PARGS_ARGV:
+			aflag++;
+			content |= CC_CONTENT_STACK;
+			break;
+		case PARGS_ENV:
+			content |= CC_CONTENT_STACK;
+			eflag++;
+			break;
+		case PARGS_AUXV:
+			xflag++;
+			break;
+		}
 	}
 
 	/* -l cannot be used with the -x or -e flags */
--- a/usr/src/cmd/sgs/libld/common/entry.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/cmd/sgs/libld/common/entry.c	Mon Jun 03 18:18:53 2019 +0200
@@ -472,7 +472,7 @@
 		    AL_CNT_SEGMENTS)) == NULL)
 			return (S_ERROR);
 
-#ifdef NDEBUG			/* assert() is enabled */
+#ifndef NDEBUG			/* assert() is enabled */
 		/*
 		 * Enforce the segment name rule: Any segment that can
 		 * be referenced by an entrance descriptor must have
--- a/usr/src/cmd/sgs/libld/common/machrel.amd.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/cmd/sgs/libld/common/machrel.amd.c	Mon Jun 03 18:18:53 2019 +0200
@@ -435,7 +435,20 @@
 	if (orsp->rel_rtype == R_AMD64_DTPMOD64)
 		raddend = 0;
 
-	relbits = (char *)relosp->os_outdata->d_buf;
+	if ((orsp->rel_rtype != M_R_NONE) &&
+	    (orsp->rel_rtype != M_R_RELATIVE)) {
+		if (ndx == 0) {
+			Conv_inv_buf_t	inv_buf;
+			Is_desc *isp = orsp->rel_isdesc;
+
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_NOSYMBOL),
+			    conv_reloc_type(ofl->ofl_nehdr->e_machine,
+			    orsp->rel_rtype, 0, &inv_buf),
+			    isp->is_file->ifl_name, EC_WORD(isp->is_scnndx),
+			    isp->is_name, EC_XWORD(roffset));
+			return (S_ERROR);
+		}
+	}
 
 	rea.r_info = ELF_R_INFO(ndx, orsp->rel_rtype);
 	rea.r_offset = roffset;
@@ -448,6 +461,8 @@
 	 */
 	assert(relosp->os_szoutrels <= relosp->os_shdr->sh_size);
 
+	relbits = (char *)relosp->os_outdata->d_buf;
+
 	(void) memcpy((relbits + relosp->os_szoutrels),
 	    (char *)&rea, sizeof (Rela));
 	relosp->os_szoutrels += (Xword)sizeof (Rela);
@@ -1135,6 +1150,19 @@
 		return (1);
 
 	/*
+	 * If the symbol will be reduced, we can't leave outstanding
+	 * relocations against it, as nothing will ever be able to satisfy them
+	 * (and the symbol won't be in .dynsym
+	 */
+	if ((sdp != NULL) &&
+	    (sdp->sd_sym->st_shndx == SHN_UNDEF) &&
+	    (rsp->rel_rtype != M_R_NONE) &&
+	    (rsp->rel_rtype != M_R_RELATIVE)) {
+		if (ld_sym_reducable(ofl, sdp))
+			return (1);
+	}
+
+	/*
 	 * If we are adding a output relocation against a section
 	 * symbol (non-RELATIVE) then mark that section.  These sections
 	 * will be added to the .dynsym symbol table.
--- a/usr/src/cmd/sgs/libld/common/machrel.intel.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/cmd/sgs/libld/common/machrel.intel.c	Mon Jun 03 18:18:53 2019 +0200
@@ -355,7 +355,20 @@
 			return (S_ERROR);
 	}
 
-	relbits = (char *)relosp->os_outdata->d_buf;
+	if ((orsp->rel_rtype != M_R_NONE) &&
+	    (orsp->rel_rtype != M_R_RELATIVE)) {
+		if (ndx == 0) {
+			Conv_inv_buf_t	inv_buf;
+			Is_desc *isp = orsp->rel_isdesc;
+
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_NOSYMBOL),
+			    conv_reloc_type(ofl->ofl_nehdr->e_machine,
+			    orsp->rel_rtype, 0, &inv_buf),
+			    isp->is_file->ifl_name, EC_WORD(isp->is_scnndx),
+			    isp->is_name, EC_XWORD(roffset));
+			return (S_ERROR);
+		}
+	}
 
 	rea.r_info = ELF_R_INFO(ndx, orsp->rel_rtype);
 	rea.r_offset = roffset;
@@ -367,6 +380,8 @@
 	 */
 	assert(relosp->os_szoutrels <= relosp->os_shdr->sh_size);
 
+	relbits = (char *)relosp->os_outdata->d_buf;
+
 	(void) memcpy((relbits + relosp->os_szoutrels),
 	    (char *)&rea, sizeof (Rel));
 	relosp->os_szoutrels += sizeof (Rel);
@@ -1136,6 +1151,19 @@
 		return (1);
 
 	/*
+	 * If the symbol will be reduced, we can't leave outstanding
+	 * relocations against it, as nothing will ever be able to satisfy them
+	 * (and the symbol won't be in .dynsym
+	 */
+	if ((sdp != NULL) &&
+	    (sdp->sd_sym->st_shndx == SHN_UNDEF) &&
+	    (rsp->rel_rtype != M_R_NONE) &&
+	    (rsp->rel_rtype != M_R_RELATIVE)) {
+		if (ld_sym_reducable(ofl, sdp))
+			return (1);
+	}
+
+	/*
 	 * If we are adding a output relocation against a section
 	 * symbol (non-RELATIVE) then mark that section.  These sections
 	 * will be added to the .dynsym symbol table.
--- a/usr/src/cmd/sgs/libld/common/machrel.sparc.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/cmd/sgs/libld/common/machrel.sparc.c	Mon Jun 03 18:18:53 2019 +0200
@@ -145,7 +145,7 @@
 	 * Determine which memory model to mark the binary with.  The options
 	 * are (most restrictive to least):
 	 *
-	 *	EF_SPARCV9_TSO		0x0 	Total Store Order
+	 *	EF_SPARCV9_TSO		0x0	Total Store Order
 	 *	EF_SPARCV9_PSO		0x1	Partial Store Order
 	 *	EF_SPARCV9_RMO		0x2	Relaxed Memory Order
 	 *
@@ -779,7 +779,25 @@
 	if (orsp->rel_rtype == M_R_DTPMOD)
 		raddend = 0;
 
-	relbits = (char *)relosp->os_outdata->d_buf;
+	/*
+	 * Note that the other case which writes out the relocation, above, is
+	 * M_R_REGISTER specific and so does not need this check.
+	 */
+	if ((orsp->rel_rtype != M_R_NONE) &&
+	    (orsp->rel_rtype != M_R_REGISTER) &&
+	    (orsp->rel_rtype != M_R_RELATIVE)) {
+		if (ndx == 0) {
+			Conv_inv_buf_t	inv_buf;
+			Is_desc *isp = orsp->rel_isdesc;
+
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_NOSYMBOL),
+			    conv_reloc_type(ofl->ofl_nehdr->e_machine,
+			    orsp->rel_rtype, 0, &inv_buf),
+			    isp->is_file->ifl_name, EC_WORD(isp->is_scnndx),
+			    isp->is_name, EC_XWORD(roffset));
+			return (S_ERROR);
+		}
+	}
 
 	rea.r_info = ELF_R_INFO(ndx,
 	    ELF_R_TYPE_INFO(RELAUX_GET_TYPEDATA(orsp), orsp->rel_rtype));
@@ -793,6 +811,8 @@
 	 */
 	assert(relosp->os_szoutrels <= relosp->os_shdr->sh_size);
 
+	relbits = (char *)relosp->os_outdata->d_buf;
+
 	(void) memcpy((relbits + relosp->os_szoutrels),
 	    (char *)&rea, sizeof (Rela));
 	relosp->os_szoutrels += (Xword)sizeof (Rela);
@@ -927,7 +947,7 @@
 	case R_SPARC_TLS_IE_LDX:
 		/*
 		 * Current instruction:
-		 * 	ld{x}	[r1 + r2], r3
+		 *	ld{x}	[r1 + r2], r3
 		 *
 		 * Need to update this to:
 		 *
@@ -1009,7 +1029,7 @@
 	case R_SPARC_GOTDATA_OP:
 		/*
 		 * Current instruction:
-		 * 	ld{x}	[r1 + r2], r3
+		 *	ld{x}	[r1 + r2], r3
 		 *
 		 * Need to update this to:
 		 *
@@ -1411,6 +1431,20 @@
 		return (1);
 
 	/*
+	 * If the symbol will be reduced, we can't leave outstanding
+	 * relocations against it, as nothing will ever be able to satisfy them
+	 * (and the symbol won't be in .dynsym
+	 */
+	if ((sdp != NULL) &&
+	    (sdp->sd_sym->st_shndx == SHN_UNDEF) &&
+	    (rsp->rel_rtype != M_R_NONE) &&
+	    (rsp->rel_rtype != M_R_REGISTER) &&
+	    (rsp->rel_rtype != M_R_RELATIVE)) {
+		if (ld_sym_reducable(ofl, sdp))
+			return (1);
+	}
+
+	/*
 	 * Certain relocations do not make sense in a 64bit shared object,
 	 * if building a shared object do a sanity check on the output
 	 * relocations being created.
--- a/usr/src/cmd/sgs/liblddbg/common/statistics.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/cmd/sgs/liblddbg/common/statistics.c	Mon Jun 03 18:18:53 2019 +0200
@@ -184,7 +184,7 @@
 
 		arsym = adp->ad_start;
 		aux = adp->ad_aux;
-		while (arsym->as_off) {
+		while ((arsym != NULL) && (arsym->as_off != NULL)) {
 			/*
 			 * Assume that symbols from the same member file are
 			 * adjacent within the archive symbol table.
@@ -199,10 +199,9 @@
 		}
 		if ((count == 0) || (used == 0))
 			continue;
-#ifndef	UDIV_NOT_SUPPORTED
+
 		dbg_print(lml, MSG_INTL(MSG_STATS_AR), adp->ad_name, count,
 		    used, ((used * 100) / count));
-#endif
 	}
 	Dbg_util_nl(lml, DBG_NL_STD);
 }
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README	Mon Jun 03 18:18:53 2019 +0200
@@ -1667,3 +1667,5 @@
 	producing relocatable objects
 10366	ld(1) should support GNU-style linker sets
 10581	ld(1) should know kernel modules are a thing
+11057	hidden undefined weak symbols should not leave relocations
+11067	debug statistics crash ld(1) when -z allextract
--- a/usr/src/cmd/smbsrv/smbstat/smbstat.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/cmd/smbsrv/smbstat/smbstat.c	Mon Jun 03 18:18:53 2019 +0200
@@ -102,6 +102,7 @@
 #include <math.h>
 #include <umem.h>
 #include <locale.h>
+#include <sys/processor.h>
 #include <smbsrv/smb_kstat.h>
 
 #if !defined(TEXT_DOMAIN)
--- a/usr/src/cmd/zpool/zpool_main.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/cmd/zpool/zpool_main.c	Mon Jun 03 18:18:53 2019 +0200
@@ -89,6 +89,7 @@
 
 static int zpool_do_initialize(int, char **);
 static int zpool_do_scrub(int, char **);
+static int zpool_do_resilver(int, char **);
 
 static int zpool_do_import(int, char **);
 static int zpool_do_export(int, char **);
@@ -141,6 +142,7 @@
 	HELP_REMOVE,
 	HELP_INITIALIZE,
 	HELP_SCRUB,
+	HELP_RESILVER,
 	HELP_STATUS,
 	HELP_UPGRADE,
 	HELP_GET,
@@ -193,6 +195,7 @@
 	{ "split",	zpool_do_split,		HELP_SPLIT		},
 	{ NULL },
 	{ "initialize",	zpool_do_initialize,	HELP_INITIALIZE		},
+	{ "resilver",	zpool_do_resilver,	HELP_RESILVER		},
 	{ "scrub",	zpool_do_scrub,		HELP_SCRUB		},
 	{ NULL },
 	{ "import",	zpool_do_import,	HELP_IMPORT		},
@@ -274,6 +277,8 @@
 		return (gettext("\tinitialize [-cs] <pool> [<device> ...]\n"));
 	case HELP_SCRUB:
 		return (gettext("\tscrub [-s | -p] <pool> ...\n"));
+	case HELP_RESILVER:
+		return (gettext("\tresilver <pool> ...\n"));
 	case HELP_STATUS:
 		return (gettext("\tstatus [-DgLPvx] [-T d|u] [pool] ... "
 		    "[interval [count]]\n"));
@@ -1692,11 +1697,14 @@
 	(void) nvlist_lookup_uint64_array(root, ZPOOL_CONFIG_SCAN_STATS,
 	    (uint64_t **)&ps, &c);
 
-	if (ps != NULL && ps->pss_state == DSS_SCANNING &&
-	    vs->vs_scan_processed != 0 && children == 0) {
-		(void) printf(gettext("  (%s)"),
-		    (ps->pss_func == POOL_SCAN_RESILVER) ?
-		    "resilvering" : "repairing");
+	if (ps != NULL && ps->pss_state == DSS_SCANNING && children == 0) {
+		if (vs->vs_scan_processed != 0) {
+			(void) printf(gettext("  (%s)"),
+			    (ps->pss_func == POOL_SCAN_RESILVER) ?
+			    "resilvering" : "repairing");
+		} else if (vs->vs_resilver_deferred) {
+			(void) printf(gettext("  (awaiting resilver)"));
+		}
 	}
 
 	if ((vs->vs_initialize_state == VDEV_INITIALIZE_ACTIVE ||
@@ -4519,7 +4527,7 @@
 	 * Ignore faulted pools.
 	 */
 	if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
-		(void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
+		(void) fprintf(stderr, gettext("cannot scan '%s': pool is "
 		    "currently unavailable\n"), zpool_get_name(zhp));
 		return (1);
 	}
@@ -4587,6 +4595,43 @@
 	return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
 }
 
+/*
+ * zpool resilver <pool> ...
+ *
+ *	Restarts any in-progress resilver
+ */
+int
+zpool_do_resilver(int argc, char **argv)
+{
+	int c;
+	scrub_cbdata_t cb;
+
+	cb.cb_type = POOL_SCAN_RESILVER;
+	cb.cb_scrub_cmd = POOL_SCRUB_NORMAL;
+	cb.cb_argc = argc;
+	cb.cb_argv = argv;
+
+	/* check options */
+	while ((c = getopt(argc, argv, "")) != -1) {
+		switch (c) {
+		case '?':
+			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
+			    optopt);
+			usage(B_FALSE);
+		}
+	}
+
+	argc -= optind;
+	argv += optind;
+
+	if (argc < 1) {
+		(void) fprintf(stderr, gettext("missing pool name argument\n"));
+		usage(B_FALSE);
+	}
+
+	return (for_each_pool(argc, argv, B_TRUE, NULL, scrub_callback, &cb));
+}
+
 static void
 zpool_collect_leaves(zpool_handle_t *zhp, nvlist_t *nvroot, nvlist_t *res)
 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/sha1/amd64/THIRDPARTYLICENSE.sha1-ni	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,31 @@
+Intel SHA Extensions optimized implementation of a SHA-1 update function
+
+BSD LICENSE
+
+Copyright(c) 2015 Intel Corporation.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+	* Redistributions of source code must retain the above copyright
+	  notice, this list of conditions and the following disclaimer.
+	* 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.
+	* Neither the name of Intel Corporation nor the names of its
+	  contributors may be used to endorse or promote products derived
+	  from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+OWNER 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.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/sha1/amd64/THIRDPARTYLICENSE.sha1-ni.descrip	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,1 @@
+PORTIONS OF SHA1 FUNCTIONALITY
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/sha1/amd64/sha1-ni.s	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,319 @@
+/*
+ * Intel SHA Extensions optimized implementation of a SHA-1 update function
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2015 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * Contact Information:
+ * 	Sean Gulley <sean.m.gulley@intel.com>
+ * 	Tim Chen <tim.c.chen@linux.intel.com>
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2015 Intel Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 	* Redistributions of source code must retain the above copyright
+ * 	  notice, this list of conditions and the following disclaimer.
+ * 	* 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.
+ * 	* Neither the name of Intel Corporation nor the names of its
+ * 	  contributors may be used to endorse or promote products derived
+ * 	  from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+ * OWNER 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.
+ *
+ */
+
+/*
+ * Copyright (c) 2018, Joyent, Inc.
+ */
+
+/*
+ * illumos uses this file under the terms of the BSD license.
+ *
+ * The following are a series of changes that we have made to this code:
+ *
+ *  o Changed the include to be sys/asm_linkage.h
+ *  o Use the sys/asm_linkage.h prototypes for assembly functions
+ *  o Renamed the function from sha1_ni_transform to sha1_block_data_order to
+ *    match the illumos name for the function
+ */
+
+#include <sys/asm_linkage.h>
+
+#define DIGEST_PTR	%rdi	/* 1st arg */
+#define DATA_PTR	%rsi	/* 2nd arg */
+#define NUM_BLKS	%rdx	/* 3rd arg */
+
+#define RSPSAVE		%rax
+
+/* gcc conversion */
+#define FRAME_SIZE	32	/* space for 2x16 bytes */
+
+#define ABCD		%xmm0
+#define E0		%xmm1	/* Need two E's b/c they ping pong */
+#define E1		%xmm2
+#define MSG0		%xmm3
+#define MSG1		%xmm4
+#define MSG2		%xmm5
+#define MSG3		%xmm6
+#define SHUF_MASK	%xmm7
+
+
+/*
+ * Intel SHA Extensions optimized implementation of a SHA-1 update function
+ *
+ * The function takes a pointer to the current hash values, a pointer to the
+ * input data, and a number of 64 byte blocks to process.  Once all blocks have
+ * been processed, the digest pointer is  updated with the resulting hash value.
+ * The function only processes complete blocks, there is no functionality to
+ * store partial blocks. All message padding and hash value initialization must
+ * be done outside the update function.
+ *
+ * The indented lines in the loop are instructions related to rounds processing.
+ * The non-indented lines are instructions related to the message schedule.
+ *
+ * void sha1_block_data_order(uint32_t *digest, const void *data,
+		uint32_t numBlocks)
+ * digest : pointer to digest
+ * data: pointer to input data
+ * numBlocks: Number of blocks to process
+ */
+.text
+.align 32
+ENTRY_NP(sha1_block_data_order)
+	mov		%rsp, RSPSAVE
+	sub		$FRAME_SIZE, %rsp
+	and		$~0xF, %rsp
+
+	shl		$6, NUM_BLKS		/* convert to bytes */
+	jz		.Ldone_hash
+	add		DATA_PTR, NUM_BLKS	/* pointer to end of data */
+
+	/* load initial hash values */
+	pinsrd		$3, 1*16(DIGEST_PTR), E0
+	movdqu		0*16(DIGEST_PTR), ABCD
+	pand		UPPER_WORD_MASK(%rip), E0
+	pshufd		$0x1B, ABCD, ABCD
+
+	movdqa		PSHUFFLE_BYTE_FLIP_MASK(%rip), SHUF_MASK
+
+.Lloop0:
+	/* Save hash values for addition after rounds */
+	movdqa		E0, (0*16)(%rsp)
+	movdqa		ABCD, (1*16)(%rsp)
+
+	/* Rounds 0-3 */
+	movdqu		0*16(DATA_PTR), MSG0
+	pshufb		SHUF_MASK, MSG0
+		paddd		MSG0, E0
+		movdqa		ABCD, E1
+		sha1rnds4	$0, E0, ABCD
+
+	/* Rounds 4-7 */
+	movdqu		1*16(DATA_PTR), MSG1
+	pshufb		SHUF_MASK, MSG1
+		sha1nexte	MSG1, E1
+		movdqa		ABCD, E0
+		sha1rnds4	$0, E1, ABCD
+	sha1msg1	MSG1, MSG0
+
+	/* Rounds 8-11 */
+	movdqu		2*16(DATA_PTR), MSG2
+	pshufb		SHUF_MASK, MSG2
+		sha1nexte	MSG2, E0
+		movdqa		ABCD, E1
+		sha1rnds4	$0, E0, ABCD
+	sha1msg1	MSG2, MSG1
+	pxor		MSG2, MSG0
+
+	/* Rounds 12-15 */
+	movdqu		3*16(DATA_PTR), MSG3
+	pshufb		SHUF_MASK, MSG3
+		sha1nexte	MSG3, E1
+		movdqa		ABCD, E0
+	sha1msg2	MSG3, MSG0
+		sha1rnds4	$0, E1, ABCD
+	sha1msg1	MSG3, MSG2
+	pxor		MSG3, MSG1
+
+	/* Rounds 16-19 */
+		sha1nexte	MSG0, E0
+		movdqa		ABCD, E1
+	sha1msg2	MSG0, MSG1
+		sha1rnds4	$0, E0, ABCD
+	sha1msg1	MSG0, MSG3
+	pxor		MSG0, MSG2
+
+	/* Rounds 20-23 */
+		sha1nexte	MSG1, E1
+		movdqa		ABCD, E0
+	sha1msg2	MSG1, MSG2
+		sha1rnds4	$1, E1, ABCD
+	sha1msg1	MSG1, MSG0
+	pxor		MSG1, MSG3
+
+	/* Rounds 24-27 */
+		sha1nexte	MSG2, E0
+		movdqa		ABCD, E1
+	sha1msg2	MSG2, MSG3
+		sha1rnds4	$1, E0, ABCD
+	sha1msg1	MSG2, MSG1
+	pxor		MSG2, MSG0
+
+	/* Rounds 28-31 */
+		sha1nexte	MSG3, E1
+		movdqa		ABCD, E0
+	sha1msg2	MSG3, MSG0
+		sha1rnds4	$1, E1, ABCD
+	sha1msg1	MSG3, MSG2
+	pxor		MSG3, MSG1
+
+	/* Rounds 32-35 */
+		sha1nexte	MSG0, E0
+		movdqa		ABCD, E1
+	sha1msg2	MSG0, MSG1
+		sha1rnds4	$1, E0, ABCD
+	sha1msg1	MSG0, MSG3
+	pxor		MSG0, MSG2
+
+	/* Rounds 36-39 */
+		sha1nexte	MSG1, E1
+		movdqa		ABCD, E0
+	sha1msg2	MSG1, MSG2
+		sha1rnds4	$1, E1, ABCD
+	sha1msg1	MSG1, MSG0
+	pxor		MSG1, MSG3
+
+	/* Rounds 40-43 */
+		sha1nexte	MSG2, E0
+		movdqa		ABCD, E1
+	sha1msg2	MSG2, MSG3
+		sha1rnds4	$2, E0, ABCD
+	sha1msg1	MSG2, MSG1
+	pxor		MSG2, MSG0
+
+	/* Rounds 44-47 */
+		sha1nexte	MSG3, E1
+		movdqa		ABCD, E0
+	sha1msg2	MSG3, MSG0
+		sha1rnds4	$2, E1, ABCD
+	sha1msg1	MSG3, MSG2
+	pxor		MSG3, MSG1
+
+	/* Rounds 48-51 */
+		sha1nexte	MSG0, E0
+		movdqa		ABCD, E1
+	sha1msg2	MSG0, MSG1
+		sha1rnds4	$2, E0, ABCD
+	sha1msg1	MSG0, MSG3
+	pxor		MSG0, MSG2
+
+	/* Rounds 52-55 */
+		sha1nexte	MSG1, E1
+		movdqa		ABCD, E0
+	sha1msg2	MSG1, MSG2
+		sha1rnds4	$2, E1, ABCD
+	sha1msg1	MSG1, MSG0
+	pxor		MSG1, MSG3
+
+	/* Rounds 56-59 */
+		sha1nexte	MSG2, E0
+		movdqa		ABCD, E1
+	sha1msg2	MSG2, MSG3
+		sha1rnds4	$2, E0, ABCD
+	sha1msg1	MSG2, MSG1
+	pxor		MSG2, MSG0
+
+	/* Rounds 60-63 */
+		sha1nexte	MSG3, E1
+		movdqa		ABCD, E0
+	sha1msg2	MSG3, MSG0
+		sha1rnds4	$3, E1, ABCD
+	sha1msg1	MSG3, MSG2
+	pxor		MSG3, MSG1
+
+	/* Rounds 64-67 */
+		sha1nexte	MSG0, E0
+		movdqa		ABCD, E1
+	sha1msg2	MSG0, MSG1
+		sha1rnds4	$3, E0, ABCD
+	sha1msg1	MSG0, MSG3
+	pxor		MSG0, MSG2
+
+	/* Rounds 68-71 */
+		sha1nexte	MSG1, E1
+		movdqa		ABCD, E0
+	sha1msg2	MSG1, MSG2
+		sha1rnds4	$3, E1, ABCD
+	pxor		MSG1, MSG3
+
+	/* Rounds 72-75 */
+		sha1nexte	MSG2, E0
+		movdqa		ABCD, E1
+	sha1msg2	MSG2, MSG3
+		sha1rnds4	$3, E0, ABCD
+
+	/* Rounds 76-79 */
+		sha1nexte	MSG3, E1
+		movdqa		ABCD, E0
+		sha1rnds4	$3, E1, ABCD
+
+	/* Add current hash values with previously saved */
+	sha1nexte	(0*16)(%rsp), E0
+	paddd		(1*16)(%rsp), ABCD
+
+	/* Increment data pointer and loop if more to process */
+	add		$64, DATA_PTR
+	cmp		NUM_BLKS, DATA_PTR
+	jne		.Lloop0
+
+	/* Write hash values back in the correct order */
+	pshufd		$0x1B, ABCD, ABCD
+	movdqu		ABCD, 0*16(DIGEST_PTR)
+	pextrd		$3, E0, 1*16(DIGEST_PTR)
+
+.Ldone_hash:
+	mov		RSPSAVE, %rsp
+
+	ret
+SET_SIZE(sha1_block_data_order)
+
+.section	.rodata.cst16.PSHUFFLE_BYTE_FLIP_MASK, "aM", @progbits, 16
+.align 16
+PSHUFFLE_BYTE_FLIP_MASK:
+	.octa 0x000102030405060708090a0b0c0d0e0f
+
+.section	.rodata.cst16.UPPER_WORD_MASK, "aM", @progbits, 16
+.align 16
+UPPER_WORD_MASK:
+	.octa 0xFFFFFFFF000000000000000000000000
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/sha2/amd64/THIRDPARTYLICENSE.sha256-ni	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,32 @@
+Intel SHA Extensions optimized implementation of a SHA-256 update function
+
+BSD LICENSE
+
+Copyright(c) 2015 Intel Corporation.
+Copyright (c) 2018, Joyent, Inc.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+	* Redistributions of source code must retain the above copyright
+	  notice, this list of conditions and the following disclaimer.
+	* 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.
+	* Neither the name of Intel Corporation nor the names of its
+	  contributors may be used to endorse or promote products derived
+	  from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+OWNER 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.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/sha2/amd64/THIRDPARTYLICENSE.sha256-ni.descrip	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,1 @@
+PORTIONS OF SHA2 FUNCTIONALITY
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/sha2/amd64/sha256-ni.s	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,378 @@
+/*
+ * Intel SHA Extensions optimized implementation of a SHA-256 update function
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2015 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * Contact Information:
+ * 	Sean Gulley <sean.m.gulley@intel.com>
+ * 	Tim Chen <tim.c.chen@linux.intel.com>
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2015 Intel Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 	* Redistributions of source code must retain the above copyright
+ * 	  notice, this list of conditions and the following disclaimer.
+ * 	* 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.
+ * 	* Neither the name of Intel Corporation nor the names of its
+ * 	  contributors may be used to endorse or promote products derived
+ * 	  from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+ * OWNER 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.
+ *
+ */
+
+/*
+ * Copyright (c) 2018, Joyent, Inc.
+ */
+
+/*
+ * illumos uses this file under the terms of the BSD license.
+ *
+ * The following are a series of changes that we have made to this code:
+ *
+ *  o Changed the include to be sys/asm_linkage.h.
+ *  o Use the sys/asm_linkage.h prototypes for assembly functions.
+ *  o Renamed the function from sha256_ni_transform to SHA256TransformBlocks to
+ *    match the illumos name for the function.
+ *  o The illumos SHA256_CTX does not have the digest as the first member of its
+ *    context struct. As such, an offset has to be added to the digest argument
+ *    to make sure that we get to the actual digest.
+ *  o Update the function prototype block comment to reflect that we are
+ *    passing the context and not the direct digest.
+ */
+
+#include <sys/asm_linkage.h>
+
+#define DIGEST_PTR	%rdi	/* 1st arg */
+#define DATA_PTR	%rsi	/* 2nd arg */
+#define NUM_BLKS	%rdx	/* 3rd arg */
+
+#define SHA256CONSTANTS	%rax
+
+#define MSG		%xmm0
+#define STATE0		%xmm1
+#define STATE1		%xmm2
+#define MSGTMP0		%xmm3
+#define MSGTMP1		%xmm4
+#define MSGTMP2		%xmm5
+#define MSGTMP3		%xmm6
+#define MSGTMP4		%xmm7
+
+#define SHUF_MASK	%xmm8
+
+#define ABEF_SAVE	%xmm9
+#define CDGH_SAVE	%xmm10
+
+/*
+ * Intel SHA Extensions optimized implementation of a SHA-256 update function
+ *
+ * The function takes a pointer to the current hash values, a pointer to the
+ * input data, and a number of 64 byte blocks to process.  Once all blocks have
+ * been processed, the digest pointer is  updated with the resulting hash value.
+ * The function only processes complete blocks, there is no functionality to
+ * store partial blocks.  All message padding and hash value initialization must
+ * be done outside the update function.
+ *
+ * The indented lines in the loop are instructions related to rounds processing.
+ * The non-indented lines are instructions related to the message schedule.
+ *
+ * void SHA256TransformBlocks(SHA256_CTX *ctx, const void *data,
+		uint32_t numBlocks);
+ * digest : pointer to digest
+ * data: pointer to input data
+ * numBlocks: Number of blocks to process
+ */
+
+.text
+.align 32
+ENTRY_NP(SHA256TransformBlocks)
+
+	shl		$6, NUM_BLKS		/* convert to bytes */
+	jz		.Ldone_hash
+	add		DATA_PTR, NUM_BLKS	/* pointer to end of data */
+
+	/*
+	 * load initial hash values
+	 * Need to reorder these appropriately
+	 * DCBA, HGFE -> ABEF, CDGH
+	 *
+	 * Offset DIGEST_PTR to account for the algorithm in the context.
+	 */
+	addq		$8, DIGEST_PTR
+	movdqu		0*16(DIGEST_PTR), STATE0
+	movdqu		1*16(DIGEST_PTR), STATE1
+
+	pshufd		$0xB1, STATE0,  STATE0		/* CDAB */
+	pshufd		$0x1B, STATE1,  STATE1		/* EFGH */
+	movdqa		STATE0, MSGTMP4
+	palignr		$8, STATE1,  STATE0		/* ABEF */
+	pblendw		$0xF0, MSGTMP4, STATE1		/* CDGH */
+
+	movdqa		PSHUFFLE_BYTE_FLIP_MASK(%rip), SHUF_MASK
+	lea		K256(%rip), SHA256CONSTANTS
+
+.Lloop0:
+	/* Save hash values for addition after rounds */
+	movdqa		STATE0, ABEF_SAVE
+	movdqa		STATE1, CDGH_SAVE
+
+	/* Rounds 0-3 */
+	movdqu		0*16(DATA_PTR), MSG
+	pshufb		SHUF_MASK, MSG
+	movdqa		MSG, MSGTMP0
+		paddd		0*16(SHA256CONSTANTS), MSG
+		sha256rnds2	STATE0, STATE1
+		pshufd 		$0x0E, MSG, MSG
+		sha256rnds2	STATE1, STATE0
+
+	/* Rounds 4-7 */
+	movdqu		1*16(DATA_PTR), MSG
+	pshufb		SHUF_MASK, MSG
+	movdqa		MSG, MSGTMP1
+		paddd		1*16(SHA256CONSTANTS), MSG
+		sha256rnds2	STATE0, STATE1
+		pshufd 		$0x0E, MSG, MSG
+		sha256rnds2	STATE1, STATE0
+	sha256msg1	MSGTMP1, MSGTMP0
+
+	/* Rounds 8-11 */
+	movdqu		2*16(DATA_PTR), MSG
+	pshufb		SHUF_MASK, MSG
+	movdqa		MSG, MSGTMP2
+		paddd		2*16(SHA256CONSTANTS), MSG
+		sha256rnds2	STATE0, STATE1
+		pshufd 		$0x0E, MSG, MSG
+		sha256rnds2	STATE1, STATE0
+	sha256msg1	MSGTMP2, MSGTMP1
+
+	/* Rounds 12-15 */
+	movdqu		3*16(DATA_PTR), MSG
+	pshufb		SHUF_MASK, MSG
+	movdqa		MSG, MSGTMP3
+		paddd		3*16(SHA256CONSTANTS), MSG
+		sha256rnds2	STATE0, STATE1
+	movdqa		MSGTMP3, MSGTMP4
+	palignr		$4, MSGTMP2, MSGTMP4
+	paddd		MSGTMP4, MSGTMP0
+	sha256msg2	MSGTMP3, MSGTMP0
+		pshufd 		$0x0E, MSG, MSG
+		sha256rnds2	STATE1, STATE0
+	sha256msg1	MSGTMP3, MSGTMP2
+
+	/* Rounds 16-19 */
+	movdqa		MSGTMP0, MSG
+		paddd		4*16(SHA256CONSTANTS), MSG
+		sha256rnds2	STATE0, STATE1
+	movdqa		MSGTMP0, MSGTMP4
+	palignr		$4, MSGTMP3, MSGTMP4
+	paddd		MSGTMP4, MSGTMP1
+	sha256msg2	MSGTMP0, MSGTMP1
+		pshufd 		$0x0E, MSG, MSG
+		sha256rnds2	STATE1, STATE0
+	sha256msg1	MSGTMP0, MSGTMP3
+
+	/* Rounds 20-23 */
+	movdqa		MSGTMP1, MSG
+		paddd		5*16(SHA256CONSTANTS), MSG
+		sha256rnds2	STATE0, STATE1
+	movdqa		MSGTMP1, MSGTMP4
+	palignr		$4, MSGTMP0, MSGTMP4
+	paddd		MSGTMP4, MSGTMP2
+	sha256msg2	MSGTMP1, MSGTMP2
+		pshufd 		$0x0E, MSG, MSG
+		sha256rnds2	STATE1, STATE0
+	sha256msg1	MSGTMP1, MSGTMP0
+
+	/* Rounds 24-27 */
+	movdqa		MSGTMP2, MSG
+		paddd		6*16(SHA256CONSTANTS), MSG
+		sha256rnds2	STATE0, STATE1
+	movdqa		MSGTMP2, MSGTMP4
+	palignr		$4, MSGTMP1, MSGTMP4
+	paddd		MSGTMP4, MSGTMP3
+	sha256msg2	MSGTMP2, MSGTMP3
+		pshufd 		$0x0E, MSG, MSG
+		sha256rnds2	STATE1, STATE0
+	sha256msg1	MSGTMP2, MSGTMP1
+
+	/* Rounds 28-31 */
+	movdqa		MSGTMP3, MSG
+		paddd		7*16(SHA256CONSTANTS), MSG
+		sha256rnds2	STATE0, STATE1
+	movdqa		MSGTMP3, MSGTMP4
+	palignr		$4, MSGTMP2, MSGTMP4
+	paddd		MSGTMP4, MSGTMP0
+	sha256msg2	MSGTMP3, MSGTMP0
+		pshufd 		$0x0E, MSG, MSG
+		sha256rnds2	STATE1, STATE0
+	sha256msg1	MSGTMP3, MSGTMP2
+
+	/* Rounds 32-35 */
+	movdqa		MSGTMP0, MSG
+		paddd		8*16(SHA256CONSTANTS), MSG
+		sha256rnds2	STATE0, STATE1
+	movdqa		MSGTMP0, MSGTMP4
+	palignr		$4, MSGTMP3, MSGTMP4
+	paddd		MSGTMP4, MSGTMP1
+	sha256msg2	MSGTMP0, MSGTMP1
+		pshufd 		$0x0E, MSG, MSG
+		sha256rnds2	STATE1, STATE0
+	sha256msg1	MSGTMP0, MSGTMP3
+
+	/* Rounds 36-39 */
+	movdqa		MSGTMP1, MSG
+		paddd		9*16(SHA256CONSTANTS), MSG
+		sha256rnds2	STATE0, STATE1
+	movdqa		MSGTMP1, MSGTMP4
+	palignr		$4, MSGTMP0, MSGTMP4
+	paddd		MSGTMP4, MSGTMP2
+	sha256msg2	MSGTMP1, MSGTMP2
+		pshufd 		$0x0E, MSG, MSG
+		sha256rnds2	STATE1, STATE0
+	sha256msg1	MSGTMP1, MSGTMP0
+
+	/* Rounds 40-43 */
+	movdqa		MSGTMP2, MSG
+		paddd		10*16(SHA256CONSTANTS), MSG
+		sha256rnds2	STATE0, STATE1
+	movdqa		MSGTMP2, MSGTMP4
+	palignr		$4, MSGTMP1, MSGTMP4
+	paddd		MSGTMP4, MSGTMP3
+	sha256msg2	MSGTMP2, MSGTMP3
+		pshufd 		$0x0E, MSG, MSG
+		sha256rnds2	STATE1, STATE0
+	sha256msg1	MSGTMP2, MSGTMP1
+
+	/* Rounds 44-47 */
+	movdqa		MSGTMP3, MSG
+		paddd		11*16(SHA256CONSTANTS), MSG
+		sha256rnds2	STATE0, STATE1
+	movdqa		MSGTMP3, MSGTMP4
+	palignr		$4, MSGTMP2, MSGTMP4
+	paddd		MSGTMP4, MSGTMP0
+	sha256msg2	MSGTMP3, MSGTMP0
+		pshufd 		$0x0E, MSG, MSG
+		sha256rnds2	STATE1, STATE0
+	sha256msg1	MSGTMP3, MSGTMP2
+
+	/* Rounds 48-51 */
+	movdqa		MSGTMP0, MSG
+		paddd		12*16(SHA256CONSTANTS), MSG
+		sha256rnds2	STATE0, STATE1
+	movdqa		MSGTMP0, MSGTMP4
+	palignr		$4, MSGTMP3, MSGTMP4
+	paddd		MSGTMP4, MSGTMP1
+	sha256msg2	MSGTMP0, MSGTMP1
+		pshufd 		$0x0E, MSG, MSG
+		sha256rnds2	STATE1, STATE0
+	sha256msg1	MSGTMP0, MSGTMP3
+
+	/* Rounds 52-55 */
+	movdqa		MSGTMP1, MSG
+		paddd		13*16(SHA256CONSTANTS), MSG
+		sha256rnds2	STATE0, STATE1
+	movdqa		MSGTMP1, MSGTMP4
+	palignr		$4, MSGTMP0, MSGTMP4
+	paddd		MSGTMP4, MSGTMP2
+	sha256msg2	MSGTMP1, MSGTMP2
+		pshufd 		$0x0E, MSG, MSG
+		sha256rnds2	STATE1, STATE0
+
+	/* Rounds 56-59 */
+	movdqa		MSGTMP2, MSG
+		paddd		14*16(SHA256CONSTANTS), MSG
+		sha256rnds2	STATE0, STATE1
+	movdqa		MSGTMP2, MSGTMP4
+	palignr		$4, MSGTMP1, MSGTMP4
+	paddd		MSGTMP4, MSGTMP3
+	sha256msg2	MSGTMP2, MSGTMP3
+		pshufd 		$0x0E, MSG, MSG
+		sha256rnds2	STATE1, STATE0
+
+	/* Rounds 60-63 */
+	movdqa		MSGTMP3, MSG
+		paddd		15*16(SHA256CONSTANTS), MSG
+		sha256rnds2	STATE0, STATE1
+		pshufd 		$0x0E, MSG, MSG
+		sha256rnds2	STATE1, STATE0
+
+	/* Add current hash values with previously saved */
+	paddd		ABEF_SAVE, STATE0
+	paddd		CDGH_SAVE, STATE1
+
+	/* Increment data pointer and loop if more to process */
+	add		$64, DATA_PTR
+	cmp		NUM_BLKS, DATA_PTR
+	jne		.Lloop0
+
+	/* Write hash values back in the correct order */
+	pshufd		$0x1B, STATE0,  STATE0		/* FEBA */
+	pshufd		$0xB1, STATE1,  STATE1		/* DCHG */
+	movdqa		STATE0, MSGTMP4
+	pblendw		$0xF0, STATE1,  STATE0		/* DCBA */
+	palignr		$8, MSGTMP4, STATE1		/* HGFE */
+
+	movdqu		STATE0, 0*16(DIGEST_PTR)
+	movdqu		STATE1, 1*16(DIGEST_PTR)
+
+.Ldone_hash:
+
+	ret
+SET_SIZE(SHA256TransformBlocks)
+
+.section	.rodata.cst256.K256, "aM", @progbits, 256
+.align 64
+K256:
+	.long	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+	.long	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+	.long	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+	.long	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+	.long	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+	.long	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+	.long	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+	.long	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+	.long	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+	.long	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+	.long	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+	.long	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+	.long	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+	.long	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+	.long	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+	.long	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+
+.section	.rodata.cst16.PSHUFFLE_BYTE_FLIP_MASK, "aM", @progbits, 16
+.align 16
+PSHUFFLE_BYTE_FLIP_MASK:
+	.octa 0x0c0d0e0f08090a0b0405060700010203
--- a/usr/src/common/zfs/zfeature_common.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/common/zfs/zfeature_common.c	Mon Jun 03 18:18:53 2019 +0200
@@ -315,10 +315,13 @@
 	    "freed or remapped.",
 	    ZFEATURE_FLAG_READONLY_COMPAT, obsolete_counts_deps);
 
-	{
 	zfeature_register(SPA_FEATURE_ALLOCATION_CLASSES,
 	    "org.zfsonlinux:allocation_classes", "allocation_classes",
 	    "Support for separate allocation classes.",
 	    ZFEATURE_FLAG_READONLY_COMPAT, NULL);
-	}
+
+	zfeature_register(SPA_FEATURE_RESILVER_DEFER,
+	    "com.datto:resilver_defer", "resilver_defer",
+	    "Support for defering new resilvers when one is already running.",
+	    ZFEATURE_FLAG_READONLY_COMPAT, NULL);
 }
--- a/usr/src/common/zfs/zfeature_common.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/common/zfs/zfeature_common.h	Mon Jun 03 18:18:53 2019 +0200
@@ -63,6 +63,7 @@
 	SPA_FEATURE_POOL_CHECKPOINT,
 	SPA_FEATURE_SPACEMAP_V2,
 	SPA_FEATURE_ALLOCATION_CLASSES,
+	SPA_FEATURE_RESILVER_DEFER,
 	SPA_FEATURES
 } spa_feature_t;
 
--- a/usr/src/head/iso/math_c99.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/head/iso/math_c99.h	Mon Jun 03 18:18:53 2019 +0200
@@ -72,7 +72,7 @@
     FP_SUBNORMAL, FP_ZERO, x)
 #define	isfinite(x)	__builtin_isfinite(x)
 #define	isnormal(x)	__builtin_isnormal(x)
-#define	signbit(x)	__builtin_signbit(x)
+#define	signbit(x)	(__builtin_signbit(x) > 0)
 #else  /* __GNUC__ >= 4 */
 #define	isnan(x)	__extension__( \
 			{ __typeof(x) __x_n = (x); \
--- a/usr/src/lib/libldap5/sources/ldap/common/search.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/libldap5/sources/ldap/common/search.c	Mon Jun 03 18:18:53 2019 +0200
@@ -1,10 +1,10 @@
 /*
  * Copyright 2001-2002 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 
 /*
  * The contents of this file are subject to the Netscape Public
@@ -805,6 +805,16 @@
 	for ( s = d = val; *s; s++ ) {
 		if ( escape ) {
 			/*
+			 * need to leave escaped comma as-is, i.e.
+			 * val="CN=Last\, First,OU=..."
+			 */
+			if (*s == ',') {
+				*d++ = '\\';
+				*d++ = *s;
+				escape = 0;
+				continue;
+			}
+			/*
 			 * first try LDAPv3 escape (hexadecimal) sequence
 			 */
 			if (( ival = hexchar2int( *s )) < 0 ) {
--- a/usr/src/lib/libmd/amd64/Makefile	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/libmd/amd64/Makefile	Mon Jun 03 18:18:53 2019 +0200
@@ -34,13 +34,23 @@
 include		$(SRC)/lib/Makefile.lib.64
 include		../Makefile.com
 
+CAPFILES =	pics/sha1-ni.o \
+		pics/sha256-ni.o
+
 EXTPICS =	pics/md5_amd64.o \
+		pics/sha512-x86_64.o \
+		pics/sha256-x86_64.o \
 		pics/sha1-x86_64.o \
-		pics/sha512-x86_64.o \
-		pics/sha256-x86_64.o
+		$(CAPFILES:%.o=%.o.symcap)
 
 CLEANFILES +=	$(EXTPICS) \
-		$(EXTPICS:pics/%.o=%.s)
+		$(EXTPICS:pics/%.o=%.s) \
+		$(CAPFILES) \
+		$(CAPFILES:%.o=%.o.objcap) \
+		$(CAPFILES:%.o=%.o.symcap)
+
+pics/sha1-ni.o.objcap		:= CAPFILE = capabilities/sha.cap
+pics/sha256-ni.o.objcap		:= CAPFILE = capabilities/sha.cap
 
 # This prevents <sys/asm_linkage.h> from including C source:
 AS_CPPFLAGS += -D_ASM
@@ -57,6 +67,21 @@
 		$(COMPILE.s) -o $@ ${@F:.o=.s}
 		$(POST_PROCESS_O)
 
+pics/%.o: $(SRC)/common/crypto/sha1/amd64/%.s
+		$(COMPILE.s) -o $@ $<
+		$(POST_PROCESS_O)
+
+pics/%.o: $(SRC)/common/crypto/sha2/amd64/%.s
+		$(COMPILE.s) -o $@ $<
+		$(POST_PROCESS_O)
+
+pics/%.o.objcap: pics/%.o
+		$(LD) -r -o $@ -M$(CAPFILE) -Breduce $<
+		$(POST_PROCESS_O)
+
+pics/%.o.symcap: pics/%.o.objcap
+		$(LD) -r -o $@ -z symbolcap $<
+
 md5_amd64.s: $(COMDIR)/md5/amd64/md5_amd64.pl
 		$(PERL) $? $@
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libmd/amd64/capabilities/sha.cap	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,29 @@
+#
+# 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 2018 Joyent, Inc.
+#
+
+$mapfile_version 2
+
+CAPABILITY shani {
+	MACHINE = i86pc;
+	HW_1 = SSE2 SSSE3 SSE4.1;
+	#
+	# To avoid a chicken and egg problem with ld, we refer to the
+	# SHA hardware cap value by its numeric value rather than the name.
+	# This allows us to deal with the fact that we're almost
+	# certainly building this on a system before the capability was
+	# known.
+	#
+	HW_2 = 0x100000;
+};
--- a/usr/src/lib/libmd/common/mapfile-vers	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/libmd/common/mapfile-vers	Mon Jun 03 18:18:53 2019 +0200
@@ -21,6 +21,7 @@
 #
 # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
 # Copyright 2013 Saso Kiselkov. All rights reserved.
+# Copyright (c) 2018, Joyent, Inc.
 #
 
 #
@@ -101,6 +102,24 @@
 	SHA512Final	{ FLAGS = NODYNSORT };
 	SHA512Init;
 	SHA512Update	{ FLAGS = NODYNSORT };
+};
+
+SYMBOL_VERSION ILLUMOSprivate {
+    global:
+$if _ELF64 && _x86
+	#
+	# We use hardware capabilities to define multiple versions of
+	# the block processing functions for some of the SHA functions.
+	# Unfortunately, that requires these to be global symbols, even
+	# though we don't want them to be. As such, they remain in a
+	# private version and hopefully some day will be removed. These
+	# symbols are not exposed in any meaningful way in a header file
+	# so no application should actually end up requiring this
+	# section.
+	#
+	sha1_block_data_order;
+	SHA256TransformBlocks;
+$endif
     local:
 	*;
 };
--- a/usr/src/lib/libsldap/common/mapfile-vers	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/libsldap/common/mapfile-vers	Mon Jun 03 18:18:53 2019 +0200
@@ -20,6 +20,7 @@
 #
 #
 # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
 #
 #
 
@@ -48,6 +49,7 @@
 	__ns_ldap_check_all_preq;
 	__ns_ldap_check_dns_preq;
 	__ns_ldap_check_gssapi_preq;
+	__ns_ldap_dn2uid;
 	__ns_ldap_getAcctMgmt;
 	__ns_ldap_getAttrStruct;
 	__ns_ldap_getConnectionInfoFromDUA;
--- a/usr/src/lib/libsldap/common/ns_connmgmt.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/libsldap/common/ns_connmgmt.c	Mon Jun 03 18:18:53 2019 +0200
@@ -21,10 +21,10 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <string.h>
 #include <errno.h>
 #include <syslog.h>
--- a/usr/src/lib/libsldap/common/ns_connmgmt.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/libsldap/common/ns_connmgmt.h	Mon Jun 03 18:18:53 2019 +0200
@@ -21,14 +21,13 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  */
 
-
 #ifndef	_NS_CONNMGMT_H
 #define	_NS_CONNMGMT_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
--- a/usr/src/lib/libsldap/common/ns_internal.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/libsldap/common/ns_internal.h	Mon Jun 03 18:18:53 2019 +0200
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  */
 
 
@@ -63,9 +64,12 @@
 #define	CREDFILE		0
 #define	CONFIGFILE		1
 #define	UIDNUMFILTER		"(&(objectclass=posixAccount)(uidnumber=%s))"
-#define	UIDNUMFILTER_SSD 	"(&(%%s)(uidnumber=%s))"
+#define	UIDNUMFILTER_SSD	"(&(%%s)(uidnumber=%s))"
 #define	UIDFILTER		"(&(objectclass=posixAccount)(uid=%s))"
 #define	UIDFILTER_SSD		"(&(%%s)(uid=%s))"
+#define	UIDDNFILTER	"(&(objectclass=posixAccount)(distinguishedName=%s))"
+#define	UIDDNFILTER_SSD		"(&(%%s)(distinguishedName=%s))"
+
 #define	HOSTFILTER		"(&(objectclass=ipHost)(cn=%s))"
 #define	HOSTFILTER_SSD		"(&(%%s)(cn=%s))"
 
@@ -455,7 +459,7 @@
 	ns_conftype_t	config_type;	/* CLIENT/SERVER/CREDCONFIG */
 	ns_datatype_t	data_type;	/* ppc,pi,pc,int etc... */
 	int		single_valued;	/* TRUE OR FALSE */
-	ns_version_t 	version;	/* Version # for attribute */
+	ns_version_t	version;	/* Version # for attribute */
 	const char	*profile_name;	/* profile schema attribute name */
 	ns_param_t	defval;		/* config file parameter default */
 	int		(*ns_verify)(ParamIndexType i,
@@ -579,7 +583,7 @@
 	LDAP			*ld;
 	thread_t		threadID;	/* thread ID using it */
 	struct ns_ldap_cookie	*cookieInfo;
-	char 			**controls;		/* from server_info */
+	char			**controls;		/* from server_info */
 	char			**saslMechanisms;	/* from server_info */
 } Connection;
 
@@ -626,7 +630,7 @@
 
 		/* search filter callback */
 	int			use_filtercb;
-	int 	(*init_filter_cb)(const ns_ldap_search_desc_t *desc,
+	int	(*init_filter_cb)(const ns_ldap_search_desc_t *desc,
 			char **realfilter, const void *userdata);
 
 		/* user callback */
@@ -642,7 +646,7 @@
 	const char * const	*i_attr;
 	const char		*i_sortattr;
 	const ns_cred_t		*i_auth;
-	int 			i_flags;
+	int			i_flags;
 
 	/* OUTPUTS */
 	ns_ldap_result_t	*result;
@@ -679,12 +683,12 @@
 	char			**dns;
 	char			*currentdn;
 	int			flag;
-	struct berval   	*ctrlCookie;
+	struct berval		*ctrlCookie;
 
 	/* REFERRALS PROCESSING */
 	/* referralinfo list & position */
-	ns_referral_info_t  	*reflist;
-	ns_referral_info_t  	*refpos;
+	ns_referral_info_t	*reflist;
+	ns_referral_info_t	*refpos;
 	/* search timeout value */
 	struct timeval		search_timeout;
 	/* response control to hold account management information */
@@ -713,7 +717,7 @@
 typedef struct ns_server_info {
 	char	*server;
 	char	*serverFQDN;
-	char 	**controls;
+	char	**controls;
 	char	**saslMechanisms;
 } ns_server_info_t;
 
@@ -873,7 +877,7 @@
 		ns_ldap_error_t **errpp);
 
 /* internal un-exposed APIs */
-ns_cred_t 	*__ns_ldap_dupAuth(const ns_cred_t *authp);
+ns_cred_t	*__ns_ldap_dupAuth(const ns_cred_t *authp);
 boolean_t	__s_api_is_auth_matched(const ns_cred_t *auth1,
 		    const ns_cred_t *auth2);
 int		__s_api_get_SSD_from_SSDtoUse_service(const char *service,
@@ -901,10 +905,10 @@
 void		__s_api_freeConnection(Connection *con);
 
 /* internal referrals APIs */
-int 		__s_api_toFollowReferrals(const int flags,
+int		__s_api_toFollowReferrals(const int flags,
 			int *toFollow,
 			ns_ldap_error_t **errorp);
-int 		__s_api_addRefInfo(ns_referral_info_t **head,
+int		__s_api_addRefInfo(ns_referral_info_t **head,
 			char *url, char *baseDN, int *scope,
 			char *filter, LDAP *ld);
 void		__s_api_deleteRefInfo(ns_referral_info_t *head);
--- a/usr/src/lib/libsldap/common/ns_reads.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/libsldap/common/ns_reads.c	Mon Jun 03 18:18:53 2019 +0200
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include <stdio.h>
@@ -227,7 +228,8 @@
 	if ((rdns = ldap_explode_dn(dn, 0)) == NULL)
 		return (NULL);
 
-	for (nRdn = 0; rdns[nRdn] != NULL; nRdn++);
+	for (nRdn = 0; rdns[nRdn] != NULL; nRdn++)
+		;
 
 	if ((mapped_rdns = (char **)calloc(nRdn, sizeof (char *))) == NULL) {
 		ldap_value_free(rdns);
@@ -4231,6 +4233,85 @@
 	return (NS_LDAP_SUCCESS);
 }
 
+#define	_P_UID	"uid"
+static const char *dn2uid_attrs[] = {
+	_P_CN,
+	_P_UID,
+	(char *)NULL
+};
+
+/*ARGSUSED*/
+int
+__ns_ldap_dn2uid(const char *dn,
+		char **userID,
+		const ns_cred_t *cred,	/* cred is ignored */
+		ns_ldap_error_t **errorp)
+{
+	ns_ldap_result_t	*result = NULL;
+	char		*filter, *userdata;
+	char		errstr[MAXERROR];
+	char		**value;
+	int		rc = 0;
+	size_t		len;
+
+	*errorp = NULL;
+	*userID = NULL;
+	if ((dn == NULL) || (dn[0] == '\0'))
+		return (NS_LDAP_INVALID_PARAM);
+
+	len = strlen(UIDDNFILTER) + strlen(dn) + 1;
+	filter = (char *)malloc(len);
+	if (filter == NULL) {
+		return (NS_LDAP_MEMORY);
+	}
+	(void) snprintf(filter, len, UIDDNFILTER, dn);
+
+	len = strlen(UIDDNFILTER_SSD) + strlen(dn) + 1;
+	userdata = (char *)malloc(len);
+	if (userdata == NULL) {
+		return (NS_LDAP_MEMORY);
+	}
+	(void) snprintf(userdata, len, UIDDNFILTER_SSD, dn);
+
+	/*
+	 * Unlike uid2dn, we DO want attribute mapping, so that
+	 * "uid" is mapped to/from samAccountName, for example.
+	 */
+	rc = __ns_ldap_list("passwd", filter,
+	    __s_api_merge_SSD_filter,
+	    dn2uid_attrs, cred, 0,
+	    &result, errorp, NULL,
+	    userdata);
+	free(filter);
+	filter = NULL;
+	free(userdata);
+	userdata = NULL;
+	if (rc != NS_LDAP_SUCCESS)
+		goto out;
+
+	if (result->entries_count > 1) {
+		(void) sprintf(errstr,
+		    gettext("Too many entries are returned for %s"), dn);
+		MKERROR(LOG_WARNING, *errorp, NS_LDAP_INTERNAL, strdup(errstr),
+		    NULL);
+		rc = NS_LDAP_INTERNAL;
+		goto out;
+	}
+
+	value = __ns_ldap_getAttr(result->entry, _P_UID);
+	if (value == NULL || value[0] == NULL) {
+		rc = NS_LDAP_NOTFOUND;
+		goto out;
+	}
+
+	*userID = strdup(value[0]);
+	rc = NS_LDAP_SUCCESS;
+
+out:
+	(void) __ns_ldap_freeResult(&result);
+	result = NULL;
+	return (rc);
+}
 
 /*ARGSUSED*/
 int
--- a/usr/src/lib/libsldap/common/ns_sldap.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/libsldap/common/ns_sldap.h	Mon Jun 03 18:18:53 2019 +0200
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  */
 
 
@@ -814,6 +815,12 @@
 	const ns_cred_t *cred,
 	ns_ldap_error_t ** errorp);
 
+int  __ns_ldap_dn2uid(
+	const char *dn,
+	char **userID,
+	const ns_cred_t *cred,
+	ns_ldap_error_t ** errorp);
+
 int  __ns_ldap_host2dn(
 	const char *host,
 	const char *domain,
--- a/usr/src/lib/libzfs/common/libzfs.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/libzfs/common/libzfs.h	Mon Jun 03 18:18:53 2019 +0200
@@ -140,6 +140,7 @@
 	EZFS_TOOMANY,		/* argument list too long */
 	EZFS_INITIALIZING,	/* currently initializing */
 	EZFS_NO_INITIALIZE,	/* no active initialize */
+	EZFS_NO_RESILVER_DEFER,	/* pool doesn't support resilver_defer */
 	EZFS_UNKNOWN
 } zfs_error_t;
 
--- a/usr/src/lib/libzfs/common/libzfs_pool.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/libzfs/common/libzfs_pool.c	Mon Jun 03 18:18:53 2019 +0200
@@ -2035,6 +2035,10 @@
 			(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
 			    "cannot scrub %s"), zc.zc_name);
 		}
+	} else if (func == POOL_SCAN_RESILVER) {
+		assert(cmd == POOL_SCRUB_NORMAL);
+		(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
+		    "cannot restart resilver on %s"), zc.zc_name);
 	} else if (func == POOL_SCAN_NONE) {
 		(void) snprintf(msg, sizeof (msg),
 		    dgettext(TEXT_DOMAIN, "cannot cancel scrubbing %s"),
@@ -2062,6 +2066,8 @@
 		}
 	} else if (err == ENOENT) {
 		return (zfs_error(hdl, EZFS_NO_SCRUB, msg));
+	} else if (err == ENOTSUP && func == POOL_SCAN_RESILVER) {
+		return (zfs_error(hdl, EZFS_NO_RESILVER_DEFER, msg));
 	} else {
 		return (zpool_standard_error(hdl, err, msg));
 	}
--- a/usr/src/lib/libzfs/common/libzfs_util.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/libzfs/common/libzfs_util.c	Mon Jun 03 18:18:53 2019 +0200
@@ -260,6 +260,9 @@
 	case EZFS_NO_INITIALIZE:
 		return (dgettext(TEXT_DOMAIN, "there is no active "
 		    "initialization"));
+	case EZFS_NO_RESILVER_DEFER:
+		return (dgettext(TEXT_DOMAIN, "this action requires the "
+		    "resilver_defer feature"));
 	case EZFS_UNKNOWN:
 		return (dgettext(TEXT_DOMAIN, "unknown error"));
 	default:
--- a/usr/src/lib/nsswitch/ldap/common/getgrent.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/nsswitch/ldap/common/getgrent.c	Mon Jun 03 18:18:53 2019 +0200
@@ -37,36 +37,41 @@
 #define	_G_NAME		"cn"
 #define	_G_GID		"gidnumber"
 #define	_G_PASSWD	"userpassword"
-#define	_G_MEM		"memberuid"
+#define	_G_MEMUID	"memberuid"
+#define	_G_MEM_DN	"member"	/* DN */
 
 #define	_F_GETGRNAM	"(&(objectClass=posixGroup)(cn=%s))"
 #define	_F_GETGRNAM_SSD	"(&(%%s)(cn=%s))"
 #define	_F_GETGRGID	"(&(objectClass=posixGroup)(gidNumber=%u))"
 #define	_F_GETGRGID_SSD	"(&(%%s)(gidNumber=%u))"
-/*
- * Group membership can be defined by either username or DN, so when searching
- * for groups by member we need to consider both. The first parameter in the
- * filter is replaced by username, the second by DN.
- */
-#define	_F_GETGRMEM \
-	"(&(objectClass=posixGroup)(|(memberUid=%s)(memberUid=%s)))"
-#define	_F_GETGRMEM_SSD	"(&(%%s)(|(memberUid=%s)(memberUid=%s)))"
 
 /*
- * Copied from getpwnam.c, needed to look up user DN.
- * Would it be better to move to ldap_common.h rather than duplicate?
+ * When searching for groups in which a specified user is a member,
+ * there are a few different membership schema that might be in use.
+ * We'll use a filter that should work with an of the common ones:
+ * "memberUid=NAME", or "member=DN" (try uniquemember too?)
+ * The first parameter in the filter string is replaced by username,
+ * and the remaining ones by the full DN.
  */
-#define	_F_GETPWNAM	"(&(objectClass=posixAccount)(uid=%s))"
-#define	_F_GETPWNAM_SSD	"(&(%%s)(uid=%s))"
+#define	_F_GETGRMEM "(&(objectClass=posixGroup)" \
+	"(|(memberUid=%s)(member=%s)))"
+#define	_F_GETGRMEM_SSD	"(&(%%s)" \
+	"(|(memberUid=%s)(member=%s)))"
 
 static const char *gr_attrs[] = {
 	_G_NAME,
 	_G_GID,
 	_G_PASSWD,
-	_G_MEM,
+	_G_MEMUID,
+	_G_MEM_DN,
 	(char *)NULL
 };
 
+static int
+getmembers_UID(char **bufpp, int *lenp, ns_ldap_attr_t *members);
+static int
+getmembers_DN(char **bufpp, int *lenp, ns_ldap_attr_t *members);
+
 
 /*
  * _nss_ldap_group2str is the data marshaling method for the group getXbyY
@@ -85,13 +90,11 @@
 	int		i;
 	int		nss_result;
 	int		buflen = 0, len;
-	int		firstime = 1;
 	char		*buffer = NULL;
 	ns_ldap_result_t	*result = be->result;
 	char		**gname, **passwd, **gid, *password, *end;
 	char		gid_nobody[NOBODY_STR_LEN];
 	char		*gid_nobody_v[1];
-	char		*member_str, *strtok_state;
 	ns_ldap_attr_t	*members;
 
 	(void) snprintf(gid_nobody, sizeof (gid_nobody), "%u", GID_NOBODY);
@@ -146,48 +149,20 @@
 	len = snprintf(buffer, buflen, "%s:%s:%s:", gname[0], password, gid[0]);
 	TEST_AND_ADJUST(len, buffer, buflen, result_grp2str);
 
-	members = __ns_ldap_getAttrStruct(result->entry, _G_MEM);
-	if (members == NULL || members->attrvalue == NULL) {
-		/* no member is fine, skip processing the member list */
-		goto nomember;
+	members = __ns_ldap_getAttrStruct(result->entry, _G_MEMUID);
+	if (members != NULL && members->attrvalue != NULL) {
+		nss_result = getmembers_UID(&buffer, &buflen, members);
+		if (nss_result != 0)
+			goto result_grp2str;
 	}
 
-	for (i = 0; i < members->value_count; i++) {
-		if (members->attrvalue[i] == NULL) {
-			nss_result = NSS_STR_PARSE_PARSE;
+	members = __ns_ldap_getAttrStruct(result->entry, _G_MEM_DN);
+	if (members != NULL && members->attrvalue != NULL) {
+		nss_result = getmembers_DN(&buffer, &buflen, members);
+		if (nss_result != 0)
 			goto result_grp2str;
-		}
-		/*
-		 * If we find an '=' in the member attribute value, treat it as
-		 * a DN, otherwise as a username.
-		 */
-		if (member_str = strchr(members->attrvalue[i], '=')) {
-			member_str++; /* skip over the '=' */
-			/* Fail if we can't pull a username out of the RDN */
-			if (! (member_str = strtok_r(member_str,
-			    ",", &strtok_state))) {
-				nss_result = NSS_STR_PARSE_PARSE;
-				goto result_grp2str;
-			}
-		} else {
-			member_str = members->attrvalue[i];
-		}
-		if (*member_str != '\0') {
-			if (firstime) {
-				len = snprintf(buffer, buflen, "%s",
-				    member_str);
-				TEST_AND_ADJUST(len, buffer, buflen,
-				    result_grp2str);
-				firstime = 0;
-			} else {
-				len = snprintf(buffer, buflen, ",%s",
-				    member_str);
-				TEST_AND_ADJUST(len, buffer, buflen,
-				    result_grp2str);
-			}
-		}
 	}
-nomember:
+
 	/* The front end marshaller doesn't need the trailing nulls */
 	if (argp->buf.result != NULL)
 		be->buflen = strlen(be->buffer);
@@ -197,6 +172,128 @@
 }
 
 /*
+ * Process the list values from the "memberUid" attribute of the
+ * current group.  Note that this list is often empty, and we
+ * get the real list of members via getmember_DN (see below).
+ */
+static int
+getmembers_UID(char **bufpp, int *lenp, ns_ldap_attr_t *members)
+{
+	char	*member_str, *strtok_state;
+	char	*buffer;
+	int	buflen;
+	int	i, len;
+	int	nss_result = 0;
+	int	firsttime;
+
+	buffer = *bufpp;
+	buflen = *lenp;
+	firsttime = (buffer[-1] == ':');
+
+	for (i = 0; i < members->value_count; i++) {
+		member_str = members->attrvalue[i];
+		if (member_str == NULL)
+			goto out;
+
+#ifdef DEBUG
+		(void) fprintf(stdout, "getmembers_UID: uid=<%s>\n",
+		    member_str);
+#endif
+		/*
+		 * If not a valid Unix user name, or
+		 * not valid in ldap, just skip.
+		 */
+		if (member_str[0] == '\0' ||
+		    strpbrk(member_str, " ,:=") != NULL)
+			continue;
+
+		if (firsttime)
+			len = snprintf(buffer, buflen, "%s", member_str);
+		else
+			len = snprintf(buffer, buflen, ",%s", member_str);
+		TEST_AND_ADJUST(len, buffer, buflen, out);
+	}
+
+out:
+	*bufpp = buffer;
+	*lenp = buflen;
+	return (nss_result);
+}
+
+/*
+ * Process the list values from the "member" attribute of the
+ * current group.  Note that this list is ONLY one that can be
+ * assumed to be non-empty.  The problem here is that this list
+ * contains the list of members as "distinguished names" (DN),
+ * and we want the Unix names (known here as "uid").  We must
+ * lookup the "uid" for each DN in the member list.  Example:
+ * CN=Doe\, John,OU=Users,DC=contoso,DC=com => john.doe
+ */
+static int
+getmembers_DN(char **bufpp, int *lenp, ns_ldap_attr_t *members)
+{
+	ns_ldap_error_t *error = NULL;
+	char	*member_dn, *member_uid;
+	char	*buffer;
+	int	buflen;
+	int	i, len;
+	int	nss_result = 0;
+	int	firsttime;
+
+	buffer = *bufpp;
+	buflen = *lenp;
+	firsttime = (buffer[-1] == ':');
+
+	for (i = 0; i < members->value_count; i++) {
+		member_dn = members->attrvalue[i];
+		if (member_dn == NULL)
+			goto out;
+
+		/*
+		 * The attribute name was "member", so these should be
+		 * full distinguished names (DNs).  We need to loookup
+		 * the Unix UID (name) for each.
+		 */
+#ifdef DEBUG
+		(void) fprintf(stdout, "getmembers_DN: dn=%s\n",
+		    member_dn);
+#endif
+		if (member_dn[0] == '\0')
+			continue;
+
+		nss_result = __ns_ldap_dn2uid(member_dn,
+		    &member_uid, NULL, &error);
+		if (nss_result != NS_LDAP_SUCCESS) {
+			(void) __ns_ldap_freeError(&error);
+			error = NULL;
+			continue;
+		}
+#ifdef DEBUG
+		(void) fprintf(stdout, "getmembers_DN: uid=<%s>\n",
+		    member_uid);
+#endif
+		/* Skip invalid names. */
+		if (member_uid[0] == '\0' ||
+		    strpbrk(member_uid, " ,:=") != NULL) {
+			free(member_uid);
+			continue;
+		}
+
+		if (firsttime)
+			len = snprintf(buffer, buflen, "%s", member_uid);
+		else
+			len = snprintf(buffer, buflen, ",%s", member_uid);
+		free(member_uid);
+		TEST_AND_ADJUST(len, buffer, buflen, out);
+	}
+
+out:
+	*bufpp = buffer;
+	*lenp = buflen;
+	return (nss_result);
+}
+
+/*
  * getbynam gets a group entry by name. This function constructs an ldap
  * search filter using the name invocation parameter and the getgrnam search
  * filter defined. Once the filter is constructed, we searche for a matching
@@ -267,6 +364,18 @@
 
 
 /*
+ * Use a custom attributes list for getbymember, because the LDAP
+ * query for this requests a list of groups, and the result can be
+ * very large if it includes the list of members with each group.
+ * We don't need or want the list of members in this case.
+ */
+static const char *grbymem_attrs[] = {
+	_G_NAME,	/* cn */
+	_G_GID,		/* gidnumber */
+	(char *)NULL
+};
+
+/*
  * getbymember returns all groups a user is defined in. This function
  * uses different architectural procedures than the other group backend
  * system calls because it's a private interface. This function constructs
@@ -284,20 +393,21 @@
 static nss_status_t
 getbymember(ldap_backend_ptr be, void *a)
 {
+	ns_ldap_error_t		*error = NULL;
 	int			i, j, k;
 	int			gcnt = (int)0;
-	char			**groupvalue, **membervalue, *member_str;
-	char			*strtok_state;
+	char			**groupvalue;
 	nss_status_t		lstat;
 	struct nss_groupsbymem	*argp = (struct nss_groupsbymem *)a;
 	char			searchfilter[SEARCHFILTERLEN];
 	char			userdata[SEARCHFILTERLEN];
 	char			name[SEARCHFILTERLEN];
+	char			escdn[SEARCHFILTERLEN];
 	ns_ldap_result_t	*result;
 	ns_ldap_entry_t		*curEntry;
-	char			*username, **dn_attr, *dn;
+	char			*dn;
 	gid_t			gid;
-	int			ret;
+	int			ret1, ret2;
 
 	if (strcmp(argp->username, "") == 0 ||
 	    strcmp(argp->username, "root") == 0)
@@ -306,101 +416,82 @@
 	if (_ldap_filter_name(name, argp->username, sizeof (name)) != 0)
 		return ((nss_status_t)NSS_NOTFOUND);
 
-	ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETPWNAM, name);
-	if (ret >= sizeof (searchfilter) || ret < 0)
-		return ((nss_status_t)NSS_NOTFOUND);
-
-	ret = snprintf(userdata, sizeof (userdata), _F_GETPWNAM_SSD, name);
-	if (ret >= sizeof (userdata) || ret < 0)
-		return ((nss_status_t)NSS_NOTFOUND);
-
 	/*
 	 * Look up the user DN in ldap. If it's not found, search solely by
 	 * username.
 	 */
-	lstat = (nss_status_t)_nss_ldap_nocb_lookup(be, NULL,
-	    _PASSWD, searchfilter, NULL, _merge_SSD_filter, userdata);
-	if (lstat != (nss_status_t)NS_LDAP_SUCCESS)
-		return ((nss_status_t)lstat);
-
-	if (be->result == NULL ||
-	    !(dn_attr = __ns_ldap_getAttr(be->result->entry, "dn")))
+	lstat = __ns_ldap_uid2dn(name, &dn, NULL, &error);
+	if (lstat != (nss_status_t)NS_LDAP_SUCCESS) {
+		/* Can't get DN.  Use bare name */
+		(void) __ns_ldap_freeError(&error);
 		dn = name;
-	else
-		dn = dn_attr[0];
+	}
+	/* Note: must free dn if != name */
 
-	ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETGRMEM, name,
-	    dn);
-	if (ret >= sizeof (searchfilter) || ret < 0)
+	/*
+	 * Compose filter patterns
+	 */
+	ret1 = snprintf(searchfilter, sizeof (searchfilter),
+	    _F_GETGRMEM, name, dn);
+	ret2 = snprintf(userdata, sizeof (userdata),
+	    _F_GETGRMEM_SSD, name, dn);
+	if (dn != name)
+		free(dn);
+	if (ret1 >= sizeof (searchfilter) || ret1 < 0)
 		return ((nss_status_t)NSS_NOTFOUND);
-
-	ret = snprintf(userdata, sizeof (userdata), _F_GETGRMEM_SSD, name,
-	    dn);
-	if (ret >= sizeof (userdata) || ret < 0)
+	if (ret2 >= sizeof (userdata) || ret2 < 0)
 		return ((nss_status_t)NSS_NOTFOUND);
 
 	/*
-	 * Free up resources from user DN search before performing group
-	 * search.
+	 * Query for groups matching the filter.
 	 */
-	(void) __ns_ldap_freeResult((ns_ldap_result_t **)&be->result);
-
-	gcnt = (int)argp->numgids;
 	lstat = (nss_status_t)_nss_ldap_nocb_lookup(be, NULL,
-	    _GROUP, searchfilter, NULL, _merge_SSD_filter, userdata);
+	    _GROUP, searchfilter, grbymem_attrs,
+	    _merge_SSD_filter, userdata);
 	if (lstat != (nss_status_t)NS_LDAP_SUCCESS)
 		return ((nss_status_t)lstat);
 	if (be->result == NULL)
 		return (NSS_NOTFOUND);
-	username = (char *)argp->username;
+
+	/*
+	 * Walk the query result, collecting GIDs.
+	 */
 	result = (ns_ldap_result_t *)be->result;
 	curEntry = (ns_ldap_entry_t *)result->entry;
-	for (i = 0; i < result->entries_count && curEntry != NULL; i++) {
-		membervalue = __ns_ldap_getAttr(curEntry, "memberUid");
-		if (membervalue == NULL) {
-			curEntry = curEntry->next;
-			continue;
+	gcnt = (int)argp->numgids;
+	for (i = 0; i < result->entries_count; i++) {
+
+		/*
+		 * Does this group have a gidNumber attr?
+		 */
+		groupvalue = __ns_ldap_getAttr(curEntry, _G_GID);
+		if (groupvalue == NULL || groupvalue[0] == NULL) {
+			/* Drop this group from the list */
+			goto next_group;
 		}
-		for (j = 0; membervalue[j]; j++) {
-			/*
-			 * If we find an '=' in the member attribute
-			 * value, treat it as a DN, otherwise as a
-			 * username.
-			 */
-			if (member_str = strchr(membervalue[j], '=')) {
-				member_str++; /* skip over the '=' */
-				member_str = strtok_r(member_str, ",",
-				    &strtok_state);
-			} else {
-				member_str = membervalue[j];
+
+		/*
+		 * Convert it to a numeric GID
+		 */
+		errno = 0;
+		gid = (gid_t)strtol(groupvalue[0], (char **)NULL, 10);
+		if (errno != 0)
+			goto next_group;
+
+		/*
+		 * If we don't already have this GID, add it.
+		 */
+		if (argp->numgids < argp->maxgids) {
+			for (k = 0; k < argp->numgids; k++) {
+				if (argp->gid_array[k] == gid) {
+					/* already have it */
+					goto next_group;
+				}
 			}
-			if (member_str != NULL &&
-			    strcmp(member_str, username) == 0) {
-				groupvalue = __ns_ldap_getAttr(curEntry,
-				    "gidnumber");
-				if (groupvalue == NULL ||
-				    groupvalue[0] == NULL) {
-					/* Drop this group from the list */
-					break;
-				}
-				errno = 0;
-				gid = (gid_t)strtol(groupvalue[0],
-				    (char **)NULL, 10);
+			argp->gid_array[argp->numgids++] = gid;
+		}
 
-				if (errno == 0 &&
-				    argp->numgids < argp->maxgids) {
-					for (k = 0; k < argp->numgids; k++) {
-						if (argp->gid_array[k] == gid)
-							/* already exists */
-							break;
-					}
-					if (k == argp->numgids)
-						argp->gid_array[argp->numgids++]
-						    = gid;
-				}
-				break;
-			}
-		}
+	next_group:
 		curEntry = curEntry->next;
 	}
 
@@ -431,7 +522,7 @@
 /*ARGSUSED0*/
 nss_backend_t *
 _nss_ldap_group_constr(const char *dummy1, const char *dummy2,
-    const char *dummy3)
+			const char *dummy3)
 {
 
 	return ((nss_backend_t *)_nss_ldap_constr(gr_ops,
--- a/usr/src/lib/nsswitch/ldap/common/ldap_common.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/nsswitch/ldap/common/ldap_common.c	Mon Jun 03 18:18:53 2019 +0200
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include "ldap_common.h"
@@ -104,6 +105,7 @@
 		return (NSS_SUCCESS);
 
 	case NS_LDAP_NOTFOUND:
+		errno = 0;
 		return (NSS_NOTFOUND);
 
 	case NS_LDAP_PARTIAL:
@@ -123,10 +125,10 @@
 /* ARGSUSED */
 nss_status_t
 _nss_ldap_lookup(ldap_backend_ptr be, nss_XbyY_args_t *argp,
-		char *database, char *searchfilter, char *domain,
-		int (*init_filter_cb)(const ns_ldap_search_desc_t *desc,
-		char **realfilter, const void *userdata),
-		const void *userdata)
+    char *database, char *searchfilter, char *domain,
+    int (*init_filter_cb)(const ns_ldap_search_desc_t *desc,
+    char **realfilter, const void *userdata),
+    const void *userdata)
 {
 	int		callbackstat = 0;
 	ns_ldap_error_t	*error = NULL;
@@ -246,14 +248,17 @@
 /* ARGSUSED */
 nss_status_t
 _nss_ldap_nocb_lookup(ldap_backend_ptr be, nss_XbyY_args_t *argp,
-		char *database, char *searchfilter, char *domain,
-		int (*init_filter_cb)(const ns_ldap_search_desc_t *desc,
-		char **realfilter, const void *userdata),
-		const void *userdata)
+    char *database, char *searchfilter, const char * const *attrs,
+    int (*init_filter_cb)(const ns_ldap_search_desc_t *desc,
+    char **realfilter, const void *userdata),
+    const void *userdata)
 {
 	ns_ldap_error_t	*error = NULL;
 	int		rc;
 
+	if (attrs == NULL)
+		attrs = be->attrs;
+
 #ifdef	DEBUG
 	(void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_nocb_lookup]\n");
 	(void) fprintf(stdout, "\tsearchfilter: %s\n", searchfilter);
@@ -265,7 +270,7 @@
 	(void) __ns_ldap_freeResult(&be->result);
 
 	if ((rc = __ns_ldap_list(database, searchfilter, init_filter_cb,
-	    be->attrs, NULL, 0, &be->result, &error, NULL,
+	    attrs, NULL, 0, &be->result, &error, NULL,
 	    userdata)) != NS_LDAP_SUCCESS) {
 		if (argp != NULL)
 			argp->returnval = 0;
@@ -531,7 +536,7 @@
 
 nss_backend_t *
 _nss_ldap_constr(ldap_backend_op_t ops[], int nops, char *tablename,
-		const char **attrs, fnf ldapobj2str)
+    const char **attrs, fnf ldapobj2str)
 {
 	ldap_backend_ptr	be;
 
--- a/usr/src/lib/nsswitch/ldap/common/ldap_common.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/nsswitch/ldap/common/ldap_common.h	Mon Jun 03 18:18:53 2019 +0200
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #ifndef	_LDAP_COMMON_H
@@ -139,7 +140,7 @@
 			char *tablename, const char **attrs, fnf ldapobj2str);
 extern nss_status_t	_nss_ldap_nocb_lookup(ldap_backend_ptr be,
 			nss_XbyY_args_t *argp, char *database,
-			char *searchfilter, char *domain,
+			char *searchfilter, const char * const *attrs,
 			int (*init_filter_cb)(
 				const ns_ldap_search_desc_t *desc,
 				char **realfilter, const void *userdata),
--- a/usr/src/lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c	Mon Jun 03 18:18:53 2019 +0200
@@ -20,17 +20,17 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
  * SMB server interface to idmap
  * (smb_idmap_get..., smb_idmap_batch_...)
  *
- * There are three implementations of this interface:
- *	uts/common/fs/smbsrv/smb_idmap.c (smbsrv kmod)
- *	lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c (libfksmbsrv)
- *	lib/smbsrv/libsmb/common/smb_idmap.c (libsmb)
+ * There are three implementations of this interface.
+ * This is the "fake kernel" version of these routines.  See also:
+ * $SRC/lib/smbsrv/libsmb/common/smb_idmap.c
+ * $SRC/uts/common/fs/smbsrv/smb_idmap.c
  *
  * There are enough differences (relative to the code size)
  * that it's more trouble than it's worth to merge them.
@@ -39,6 +39,7 @@
  *	calls idmap interfaces (libidmap)
  *	uses kmem_... interfaces (libfakekernel)
  *	uses cmn_err instead of syslog, etc.
+ * The code in this variant looks a lot like the one in libsmb.
  */
 
 #include <sys/param.h>
@@ -148,8 +149,7 @@
 {
 	idmap_stat	stat;
 
-	if (!sib)
-		return (IDMAP_ERR_ARG);
+	ASSERT(sib != NULL);
 
 	bzero(sib, sizeof (smb_idmap_batch_t));
 	stat = idmap_get_create(&sib->sib_idmaph);
@@ -175,19 +175,17 @@
 void
 smb_idmap_batch_destroy(smb_idmap_batch_t *sib)
 {
+	char *domsid;
 	int i;
 
-	if (sib == NULL)
-		return;
+	ASSERT(sib != NULL);
+	ASSERT(sib->sib_maps != NULL);
 
 	if (sib->sib_idmaph) {
 		idmap_get_destroy(sib->sib_idmaph);
 		sib->sib_idmaph = NULL;
 	}
 
-	if (sib->sib_maps == NULL)
-		return;
-
 	if (sib->sib_flags & SMB_IDMAP_ID2SID) {
 		/*
 		 * SIDs are allocated only when mapping
@@ -198,6 +196,16 @@
 			/* from strdup() in libidmap */
 			free(sib->sib_maps[i].sim_domsid);
 		}
+	} else if (sib->sib_flags & SMB_IDMAP_SID2ID) {
+		/*
+		 * SID prefixes are allocated only when mapping
+		 * SIDs to UID/GID
+		 */
+		for (i = 0; i < sib->sib_nmap; i++) {
+			domsid = sib->sib_maps[i].sim_domsid;
+			if (domsid)
+				smb_mem_free(domsid);
+		}
 	}
 
 	if (sib->sib_size && sib->sib_maps) {
@@ -225,13 +233,15 @@
 	idmap_stat stat;
 	int flag = 0;
 
-	if (idmaph == NULL || sim == NULL || sid == NULL)
-		return (IDMAP_ERR_ARG);
+	ASSERT(idmaph != NULL);
+	ASSERT(sim != NULL);
+	ASSERT(sid != NULL);
 
 	smb_sid_tostr(sid, sidstr);
 	if (smb_sid_splitstr(sidstr, &sim->sim_rid) != 0)
 		return (IDMAP_ERR_SID);
-	sim->sim_domsid = sidstr;
+	/* Note: Free sim_domsid in smb_idmap_batch_destroy */
+	sim->sim_domsid = smb_mem_strdup(sidstr);
 	sim->sim_idtype = idtype;
 
 	switch (idtype) {
@@ -259,9 +269,6 @@
 		break;
 	}
 
-	/* This was copied by idmap_get_Xbysid. */
-	sim->sim_domsid = NULL;
-
 	return (stat);
 }
 
@@ -272,6 +279,8 @@
  *
  * sim->sim_domsid and sim->sim_rid will contain the mapping
  * result upon successful process of the batched request.
+ * Stash the type for error reporting (caller saves the ID).
+ *
  * NB: sim_domsid allocated by strdup, here or in libidmap
  */
 idmap_stat
@@ -284,6 +293,7 @@
 	if (!idmaph || !sim)
 		return (IDMAP_ERR_ARG);
 
+	sim->sim_idtype = idtype;
 	switch (idtype) {
 	case SMB_IDMAP_USER:
 		stat = idmap_get_sidbyuid(idmaph, id, flag,
@@ -322,12 +332,35 @@
 		break;
 
 	default:
+		ASSERT(0);
 		return (IDMAP_ERR_ARG);
 	}
 
 	return (stat);
 }
 
+static void
+smb_idmap_bgm_report(smb_idmap_batch_t *sib, smb_idmap_t *sim)
+{
+
+	if ((sib->sib_flags & SMB_IDMAP_ID2SID) != 0) {
+		/*
+		 * Note: The ID and type we asked idmap to map
+		 * were saved in *sim_id and sim_idtype.
+		 */
+		uint_t id = (sim->sim_id == NULL) ?
+		    0 : (uint_t)*sim->sim_id;
+		cmn_err(CE_WARN, "Can't get SID for "
+		    "ID=%u type=%d, status=%d",
+		    id, sim->sim_idtype, sim->sim_stat);
+	}
+
+	if ((sib->sib_flags & SMB_IDMAP_SID2ID) != 0) {
+		cmn_err(CE_WARN, "Can't get ID for SID %s-%u, status=%d",
+		    sim->sim_domsid, sim->sim_rid, sim->sim_stat);
+	}
+}
+
 /*
  * smb_idmap_batch_getmappings
  *
@@ -353,13 +386,10 @@
 	 */
 	for (i = 0, sim = sib->sib_maps; i < sib->sib_nmap; i++, sim++) {
 		if (sim->sim_stat != IDMAP_SUCCESS) {
-			if (sib->sib_flags == SMB_IDMAP_SID2ID) {
-				cmn_err(CE_NOTE, "[%d] %d (%d)",
-				    sim->sim_idtype,
-				    sim->sim_rid,
-				    sim->sim_stat);
+			smb_idmap_bgm_report(sib, sim);
+			if ((sib->sib_flags & SMB_IDMAP_SKIP_ERRS) == 0) {
+				return (sim->sim_stat);
 			}
-			return (sim->sim_stat);
 		}
 	}
 
@@ -389,6 +419,7 @@
 
 	sim = sib->sib_maps;
 	for (i = 0; i < sib->sib_nmap; sim++, i++) {
+		ASSERT(sim->sim_domsid != NULL);
 		if (sim->sim_domsid == NULL)
 			return (-1);
 
--- a/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c	Mon Jun 03 18:18:53 2019 +0200
@@ -21,7 +21,7 @@
 /*
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2016 by Delphix. All rights reserved.
- * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include <unistd.h>
@@ -129,6 +129,10 @@
  * smb_token_sids2ids
  *
  * This will map all the SIDs of the access token to UIDs/GIDs.
+ * However, if there are some SIDs we can't map to UIDs/GIDs,
+ * we don't want to fail the logon, and instead just log the
+ * SIDs we could not map and continue as best we can.
+ * The flag SMB_IDMAP_SKIP_ERRS below does that.
  *
  * Returns 0 upon success.  Otherwise, returns -1.
  */
@@ -148,7 +152,8 @@
 	else
 		nmaps = token->tkn_win_grps.i_cnt + 3;
 
-	stat = smb_idmap_batch_create(&sib, nmaps, SMB_IDMAP_SID2ID);
+	stat = smb_idmap_batch_create(&sib, nmaps,
+	    SMB_IDMAP_SID2ID | SMB_IDMAP_SKIP_ERRS);
 	if (stat != IDMAP_SUCCESS)
 		return (-1);
 
--- a/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c	Mon Jun 03 18:18:53 2019 +0200
@@ -20,17 +20,17 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
  * SMB server interface to idmap
  * (smb_idmap_get..., smb_idmap_batch_...)
  *
- * There are three implementations of this interface:
- *	uts/common/fs/smbsrv/smb_idmap.c (smbsrv kmod)
- *	lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c (libfksmbsrv)
- *	lib/smbsrv/libsmb/common/smb_idmap.c (libsmb)
+ * There are three implementations of this interface.
+ * This is the libsmb version of these routines.  See also:
+ * $SRC/uts/common/fs/smbsrv/smb_idmap.c
+ * $SRC/lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c
  *
  * There are enough differences (relative to the code size)
  * that it's more trouble than it's worth to merge them.
@@ -197,6 +197,14 @@
 			smb_sid_free(sib->sib_maps[i].sim_sid);
 			free(sib->sib_maps[i].sim_domsid);
 		}
+	} else if (sib->sib_flags & SMB_IDMAP_SID2ID) {
+		/*
+		 * SID prefixes are allocated only when mapping
+		 * SIDs to UID/GID
+		 */
+		for (i = 0; i < sib->sib_nmap; i++) {
+			free(sib->sib_maps[i].sim_domsid);
+		}
 	}
 
 	if (sib->sib_size && sib->sib_maps) {
@@ -230,7 +238,8 @@
 	smb_sid_tostr(sid, sidstr);
 	if (smb_sid_splitstr(sidstr, &sim->sim_rid) != 0)
 		return (IDMAP_ERR_SID);
-	sim->sim_domsid = sidstr;
+	/* Note: Free sim_domsid in smb_idmap_batch_destroy */
+	sim->sim_domsid = strdup(sidstr);
 	sim->sim_idtype = idtype;
 
 	switch (idtype) {
@@ -258,9 +267,6 @@
 		break;
 	}
 
-	/* This was copied by idmap_get_Xbysid. */
-	sim->sim_domsid = NULL;
-
 	return (stat);
 }
 
@@ -271,6 +277,8 @@
  *
  * sim->sim_domsid and sim->sim_rid will contain the mapping
  * result upon successful process of the batched request.
+ * Stash the type for error reporting (caller saves the ID).
+ *
  * NB: sim_domsid allocated by strdup, here or in libidmap
  */
 idmap_stat
@@ -283,6 +291,7 @@
 	if (!idmaph || !sim)
 		return (IDMAP_ERR_ARG);
 
+	sim->sim_idtype = idtype;
 	switch (idtype) {
 	case SMB_IDMAP_USER:
 		stat = idmap_get_sidbyuid(idmaph, id, flag,
@@ -327,6 +336,28 @@
 	return (stat);
 }
 
+static void
+smb_idmap_bgm_report(smb_idmap_batch_t *sib, smb_idmap_t *sim)
+{
+
+	if ((sib->sib_flags & SMB_IDMAP_ID2SID) != 0) {
+		/*
+		 * Note: The ID and type we asked idmap to map
+		 * were saved in *sim_id and sim_idtype.
+		 */
+		uint_t id = (sim->sim_id == NULL) ?
+		    0 : (uint_t)*sim->sim_id;
+		syslog(LOG_ERR, "Can't get SID for "
+		    "ID=%u type=%d, status=%d",
+		    id, sim->sim_idtype, sim->sim_stat);
+	}
+
+	if ((sib->sib_flags & SMB_IDMAP_SID2ID) != 0) {
+		syslog(LOG_ERR, "Can't get ID for SID %s-%u, status=%d",
+		    sim->sim_domsid, sim->sim_rid, sim->sim_stat);
+	}
+}
+
 /*
  * smb_idmap_batch_getmappings
  *
@@ -352,11 +383,10 @@
 	 */
 	for (i = 0, sim = sib->sib_maps; i < sib->sib_nmap; i++, sim++) {
 		if (sim->sim_stat != IDMAP_SUCCESS) {
-			if (sib->sib_flags == SMB_IDMAP_SID2ID) {
-				smb_tracef("[%d] %d (%d)", sim->sim_idtype,
-				    sim->sim_rid, sim->sim_stat);
+			smb_idmap_bgm_report(sib, sim);
+			if ((sib->sib_flags & SMB_IDMAP_SKIP_ERRS) == 0) {
+				return (sim->sim_stat);
 			}
-			return (sim->sim_stat);
 		}
 	}
 
--- a/usr/src/man/man1/Makefile	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/man/man1/Makefile	Mon Jun 03 18:18:53 2019 +0200
@@ -481,8 +481,10 @@
 		notify.1	\
 		onintr.1	\
 		page.1		\
+		pauxv.1		\
 		pcat.1		\
 		pcred.1		\
+		penv.1		\
 		pfcsh.1		\
 		pfiles.1	\
 		pfksh.1		\
@@ -662,6 +664,9 @@
 pcat.1		:= LINKSRC = pack.1
 unpack.1	:= LINKSRC = pack.1
 
+pauxv.1		:= LINKSRC = pargs.1
+penv.1		:= LINKSRC = pargs.1
+
 pfcsh.1		:= LINKSRC = pfexec.1
 pfksh.1		:= LINKSRC = pfexec.1
 pfsh.1		:= LINKSRC = pfexec.1
--- a/usr/src/man/man1/pargs.1	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/man/man1/pargs.1	Mon Jun 03 18:18:53 2019 +0200
@@ -1,20 +1,22 @@
 '\" te
 .\"  Copyright (c) 2006, Sun Microsystems, Inc. All Rights Reserved
+.\"  Copyright 2015 Joyent, Inc.
 .\" 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]
-.TH PARGS 1 "Jun 19, 2006"
+.TH PARGS 1 "Oct 5, 2015"
 .SH NAME
-pargs \- print  process  arguments,  environment  variables,  or auxiliary
+pargs, penv, pauxv \- print  process  arguments,  environment  variables,  or auxiliary
 vector
 .SH SYNOPSIS
 .LP
 .nf
 \fBpargs\fR [\fB-aceFlx\fR] [\fIpid\fR | \fIcore\fR]...
+\fBpauxv\fR [\fB-cF\fR] [\fIpid\fR | \fIcore\fR]...
+\fBpenv\fR [\fB-cF\fR] [\fIpid\fR | \fIcore\fR]...
 .fi
 
 .SH DESCRIPTION
-.sp
 .LP
 The \fBpargs\fR utility examines a target process or process core file and
 prints arguments, environment variables and values, or the process auxiliary
@@ -32,10 +34,18 @@
 encoding, \fBpargs\fR attempts to employ the \fBiconv\fR(3C) facility to
 generate a printable version of the extracted  strings. In the event that such
 a conversion is impossible, strings are displayed as 7-bit \fBASCII\fR.
-.SH OPTIONS
+.sp
+.LP
+The \fBpauxv\fR command is equivalent to running \fBpargs\fR with the
+\fB-x\fR option.
 .sp
 .LP
-The following options are supported:
+The \fBpenv\fR command is equivalent to running \fBpargs\fR with the
+\fB-e\fR option.
+.SH OPTIONS
+.LP
+The following options are supported by \fBpargs\fR. Only the \fB-c\fR
+and \fB-F\fR options are supported by \fBpauxv\fR and \fBpenv\fR:
 .sp
 .ne 2
 .na
@@ -98,7 +108,6 @@
 .RE
 
 .SH OPERANDS
-.sp
 .LP
 The following operands are supported:
 .sp
@@ -120,7 +129,6 @@
 .RE
 
 .SH USAGE
-.sp
 .LP
 Caution should be exercised when using the \fB-F\fR flag. Imposing two
 controlling processes on one victim process can lead to chaos. Safety is
@@ -128,7 +136,6 @@
 stopped the victim process and the primary controlling process is doing nothing
 at the moment of application of the \fBproc\fR tool in question.
 .SH EXIT STATUS
-.sp
 .LP
 The following exit values are returned:
 .sp
@@ -151,7 +158,6 @@
 .RE
 
 .SH FILES
-.sp
 .ne 2
 .na
 \fB\fB/proc/pid/*\fR\fR
@@ -161,7 +167,6 @@
 .RE
 
 .SH ATTRIBUTES
-.sp
 .LP
 See \fBattributes\fR(5) for descriptions of the following attributes:
 .sp
@@ -177,7 +182,6 @@
 .TE
 
 .SH SEE ALSO
-.sp
 .LP
 \fBproc\fR(1), \fBiconv\fR(3C), \fBproc\fR(4), \fBascii\fR(5),
 \fBattributes\fR(5), \fBenviron\fR(5), \fBformats\fR(5)
--- a/usr/src/man/man1/proc.1	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/man/man1/proc.1	Mon Jun 03 18:18:53 2019 +0200
@@ -539,12 +539,12 @@
 The human readable output is Uncommitted. The options are Committed.
 .SH SEE ALSO
 .LP
-\fBgcore\fR(1), \fBldd\fR(1), \fBpargs\fR(1), \fBpgrep\fR(1), \fBpkill\fR(1),
-\fBplimit\fR(1), \fBpmap\fR(1), \fBpreap\fR(1), \fBps\fR(1), \fBptree\fR(1),
-\fBppgsz\fR(1), \fBpwd\fR(1), \fBrlogin\fR(1), \fBtime\fR(1), \fBtruss\fR(1),
-\fBwait\fR(1), \fBfcntl\fR(2), \fBfstat\fR(2), \fBsetuid\fR(2),
-\fBdlopen\fR(3C), \fBsignal.h\fR(3HEAD), \fBcore\fR(4), \fBproc\fR(4),
-\fBprocess\fR(4), \fBattributes\fR(5), \fBzones\fR(5)
+\fBgcore\fR(1), \fBldd\fR(1), \fBpargs\fR(1), \fBpauxv\fR(1), \fBpenv\fR(1),
+\fBpgrep\fR(1), \fBpkill\fR(1), \fBplimit\fR(1), \fBpmap\fR(1), \fBpreap\fR(1),
+\fBps\fR(1), \fBptree\fR(1), \fBppgsz\fR(1), \fBpwd\fR(1), \fBrlogin\fR(1),
+\fBtime\fR(1), \fBtruss\fR(1), \fBwait\fR(1), \fBfcntl\fR(2), \fBfstat\fR(2),
+\fBsetuid\fR(2), \fBdlopen\fR(3C), \fBsignal.h\fR(3HEAD), \fBcore\fR(4),
+\fBproc\fR(4), \fBprocess\fR(4), \fBattributes\fR(5), \fBzones\fR(5)
 .SH WARNINGS
 .LP
 The following \fBproc\fR tools stop their target processes while inspecting
--- a/usr/src/man/man1m/zpool.1m	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/man/man1m/zpool.1m	Mon Jun 03 18:18:53 2019 +0200
@@ -26,7 +26,7 @@
 .\" Copyright (c) 2017 George Melikov. All Rights Reserved.
 .\" Copyright 2019 Joyent, Inc.
 .\"
-.Dd April 27, 2018
+.Dd May 15, 2019
 .Dt ZPOOL 1M
 .Os
 .Sh NAME
@@ -156,6 +156,9 @@
 .Op Fl f
 .Ar pool Ar device Op Ar new_device
 .Nm
+.Cm resilver
+.Ar pool Ns ...
+.Nm
 .Cm scrub
 .Op Fl s | Fl p
 .Ar pool Ns ...
@@ -1776,6 +1779,19 @@
 .El
 .It Xo
 .Nm
+.Cm resilver
+.Ar pool Ns ...
+.Xc
+Starts a resilver.
+If an existing resilver is already running it will be restarted from the
+beginning.
+Any drives that were scheduled for a deferred resilver will be added to the
+new one.
+This requires the
+.Sy resilver_defer
+feature.
+.It Xo
+.Nm
 .Cm scrub
 .Op Fl s | Fl p
 .Ar pool Ns ...
--- a/usr/src/man/man5/zpool-features.5	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/man/man5/zpool-features.5	Mon Jun 03 18:18:53 2019 +0200
@@ -15,7 +15,7 @@
 .\" CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your
 .\" own identifying information:
 .\" Portions Copyright [yyyy] [name of copyright owner]
-.TH ZPOOL-FEATURES 5 "Apr 19, 2019"
+.TH ZPOOL-FEATURES 5 "May 15, 2019"
 .SH NAME
 zpool\-features \- ZFS pool feature descriptions
 .SH DESCRIPTION
@@ -683,5 +683,26 @@
 removal, it can be returned to the \fBenabled\fR state if all the top-level
 vdevs from an allocation class are removed.
 
+.RE
+.sp
+.ne 2
+.na
+\fB\fBresilver_defer\fR\fR
+.ad
+.RS 4n
+.TS
+l l .
+GUID	com.datto:resilver_defer
+READ\-ONLY COMPATIBLE	yes
+DEPENDENCIES	none
+.TE
+
+This feature allows zfs to postpone new resilvers if an existing one is already
+in progress. Without this feature, any new resilvers will cause the currently
+running one to be immediately restarted from the beginning.
+
+This feature becomes \fBactive\fR once a resilver has been deferred, and
+returns to being \fBenabled\fR when the deferred resilver begins.
+
 .SH "SEE ALSO"
 \fBzfs\fR(1M), \fBzpool\fR(1M)
--- a/usr/src/pkg/manifests/system-extended-system-utilities.mf	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/pkg/manifests/system-extended-system-utilities.mf	Mon Jun 03 18:18:53 2019 +0200
@@ -216,9 +216,17 @@
 file path=usr/share/man/man1m/projadd.1m
 file path=usr/share/man/man1m/projdel.1m
 file path=usr/share/man/man1m/projmod.1m
+$(i386_ONLY)hardlink path=usr/bin/$(ARCH32)/pauxv \
+    target=../../../usr/bin/$(ARCH32)/pargs
+$(i386_ONLY)hardlink path=usr/bin/$(ARCH32)/penv \
+    target=../../../usr/bin/$(ARCH32)/pargs
+hardlink path=usr/bin/$(ARCH64)/pauxv target=../../../usr/bin/$(ARCH64)/pargs
+hardlink path=usr/bin/$(ARCH64)/penv target=../../../usr/bin/$(ARCH64)/pargs
 hardlink path=usr/bin/oawk target=../../usr/bin/awk
 hardlink path=usr/bin/pargs target=../../usr/lib/isaexec
+hardlink path=usr/bin/pauxv target=../../usr/lib/isaexec
 hardlink path=usr/bin/pcred target=../../usr/lib/isaexec
+hardlink path=usr/bin/penv target=../../usr/lib/isaexec
 hardlink path=usr/bin/pfiles target=../../usr/lib/isaexec
 hardlink path=usr/bin/pflags target=../../usr/lib/isaexec
 hardlink path=usr/bin/pldd target=../../usr/lib/isaexec
@@ -275,7 +283,9 @@
 link path=usr/proc/bin/pwdx target=../../bin/pwdx
 link path=usr/share/man/man1/hashcheck.1 target=spell.1
 link path=usr/share/man/man1/hashmake.1 target=spell.1
+link path=usr/share/man/man1/pauxv.1 target=pargs.1
 link path=usr/share/man/man1/pcat.1 target=pack.1
+link path=usr/share/man/man1/penv.1 target=pargs.1
 link path=usr/share/man/man1/spellin.1 target=spell.1
 link path=usr/share/man/man1/uncompress.1 target=compress.1
 link path=usr/share/man/man1/unexpand.1 target=expand.1
--- a/usr/src/pkg/manifests/system-library.mf	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/pkg/manifests/system-library.mf	Mon Jun 03 18:18:53 2019 +0200
@@ -577,6 +577,10 @@
     license=usr/src/common/crypto/ecc/THIRDPARTYLICENSE
 license usr/src/common/crypto/md5/amd64/THIRDPARTYLICENSE \
     license=usr/src/common/crypto/md5/amd64/THIRDPARTYLICENSE
+license usr/src/common/crypto/sha1/amd64/THIRDPARTYLICENSE.sha1-ni \
+    license=usr/src/common/crypto/sha1/amd64/THIRDPARTYLICENSE.sha1-ni
+license usr/src/common/crypto/sha2/amd64/THIRDPARTYLICENSE.sha256-ni \
+    license=usr/src/common/crypto/sha2/amd64/THIRDPARTYLICENSE.sha256-ni
 license usr/src/common/mpi/THIRDPARTYLICENSE \
     license=usr/src/common/mpi/THIRDPARTYLICENSE
 license usr/src/lib/libast/THIRDPARTYLICENSE \
--- a/usr/src/pkg/manifests/system-test-zfstest.mf	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/pkg/manifests/system-test-zfstest.mf	Mon Jun 03 18:18:53 2019 +0200
@@ -88,7 +88,9 @@
 dir path=opt/zfs-tests/tests/functional/cli_root/zpool_offline
 dir path=opt/zfs-tests/tests/functional/cli_root/zpool_online
 dir path=opt/zfs-tests/tests/functional/cli_root/zpool_remove
+dir path=opt/zfs-tests/tests/functional/cli_root/zpool_reopen
 dir path=opt/zfs-tests/tests/functional/cli_root/zpool_replace
+dir path=opt/zfs-tests/tests/functional/cli_root/zpool_resilver
 dir path=opt/zfs-tests/tests/functional/cli_root/zpool_scrub
 dir path=opt/zfs-tests/tests/functional/cli_root/zpool_set
 dir path=opt/zfs-tests/tests/functional/cli_root/zpool_status
@@ -1727,6 +1729,36 @@
 file \
     path=opt/zfs-tests/tests/functional/cli_root/zpool_remove/zpool_remove_003_pos \
     mode=0555
+file path=opt/zfs-tests/tests/functional/cli_root/zpool_reopen/cleanup \
+    mode=0555
+file path=opt/zfs-tests/tests/functional/cli_root/zpool_reopen/setup mode=0555
+file \
+    path=opt/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen.cfg \
+    mode=0444
+file \
+    path=opt/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen.shlib \
+    mode=0444
+file \
+    path=opt/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_001_pos \
+    mode=0555
+file \
+    path=opt/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_002_pos \
+    mode=0555
+file \
+    path=opt/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_003_pos \
+    mode=0555
+file \
+    path=opt/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_004_pos \
+    mode=0555
+file \
+    path=opt/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_005_pos \
+    mode=0555
+file \
+    path=opt/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_006_neg \
+    mode=0555
+file \
+    path=opt/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_007_pos \
+    mode=0555
 file path=opt/zfs-tests/tests/functional/cli_root/zpool_replace/cleanup \
     mode=0555
 file path=opt/zfs-tests/tests/functional/cli_root/zpool_replace/setup \
@@ -1734,6 +1766,19 @@
 file \
     path=opt/zfs-tests/tests/functional/cli_root/zpool_replace/zpool_replace_001_neg \
     mode=0555
+file path=opt/zfs-tests/tests/functional/cli_root/zpool_resilver/cleanup \
+    mode=0555
+file path=opt/zfs-tests/tests/functional/cli_root/zpool_resilver/setup \
+    mode=0555
+file \
+    path=opt/zfs-tests/tests/functional/cli_root/zpool_resilver/zpool_resilver.cfg \
+    mode=0444
+file \
+    path=opt/zfs-tests/tests/functional/cli_root/zpool_resilver/zpool_resilver_bad_args \
+    mode=0555
+file \
+    path=opt/zfs-tests/tests/functional/cli_root/zpool_resilver/zpool_resilver_restart \
+    mode=0555
 file path=opt/zfs-tests/tests/functional/cli_root/zpool_scrub/cleanup \
     mode=0555
 file path=opt/zfs-tests/tests/functional/cli_root/zpool_scrub/setup mode=0555
--- a/usr/src/test/zfs-tests/runfiles/delphix.run	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/test/zfs-tests/runfiles/delphix.run	Mon Jun 03 18:18:53 2019 +0200
@@ -339,9 +339,14 @@
 [/opt/zfs-tests/tests/functional/cli_root/zpool_replace]
 tests = ['zpool_replace_001_neg']
 
+[/opt/zfs-tests/tests/functional/cli_root/zpool_resilver]
+tests = ['zpool_resilver_bad_args', 'zpool_resilver_restart']
+tags = ['functional', 'cli_root', 'zpool_resilver']
+
 [/opt/zfs-tests/tests/functional/cli_root/zpool_scrub]
 tests = ['zpool_scrub_001_neg', 'zpool_scrub_002_pos', 'zpool_scrub_003_pos',
-    'zpool_scrub_004_pos', 'zpool_scrub_005_pos', 'zpool_scrub_multiple_copies']
+    'zpool_scrub_004_pos', 'zpool_scrub_005_pos', 'zpool_scrub_print_repairing',
+    'zpool_scrub_offline_device', 'zpool_scrub_multiple_copies']
 
 [/opt/zfs-tests/tests/functional/cli_root/zpool_set]
 tests = ['zpool_set_001_pos', 'zpool_set_002_neg', 'zpool_set_003_neg']
--- a/usr/src/test/zfs-tests/runfiles/omnios.run	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/test/zfs-tests/runfiles/omnios.run	Mon Jun 03 18:18:53 2019 +0200
@@ -340,9 +340,14 @@
 [/opt/zfs-tests/tests/functional/cli_root/zpool_replace]
 tests = ['zpool_replace_001_neg']
 
+[/opt/zfs-tests/tests/functional/cli_root/zpool_resilver]
+tests = ['zpool_resilver_bad_args', 'zpool_resilver_restart']
+tags = ['functional', 'cli_root', 'zpool_resilver']
+
 [/opt/zfs-tests/tests/functional/cli_root/zpool_scrub]
 tests = ['zpool_scrub_001_neg', 'zpool_scrub_002_pos', 'zpool_scrub_003_pos',
-    'zpool_scrub_004_pos', 'zpool_scrub_005_pos', 'zpool_scrub_multiple_copies']
+    'zpool_scrub_004_pos', 'zpool_scrub_005_pos', 'zpool_scrub_print_repairing',
+    'zpool_scrub_offline_device', 'zpool_scrub_multiple_copies']
 
 [/opt/zfs-tests/tests/functional/cli_root/zpool_set]
 tests = ['zpool_set_001_pos', 'zpool_set_002_neg', 'zpool_set_003_neg']
--- a/usr/src/test/zfs-tests/runfiles/openindiana.run	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/test/zfs-tests/runfiles/openindiana.run	Mon Jun 03 18:18:53 2019 +0200
@@ -340,9 +340,14 @@
 [/opt/zfs-tests/tests/functional/cli_root/zpool_replace]
 tests = ['zpool_replace_001_neg']
 
+[/opt/zfs-tests/tests/functional/cli_root/zpool_resilver]
+tests = ['zpool_resilver_bad_args', 'zpool_resilver_restart']
+tags = ['functional', 'cli_root', 'zpool_resilver']
+
 [/opt/zfs-tests/tests/functional/cli_root/zpool_scrub]
 tests = ['zpool_scrub_001_neg', 'zpool_scrub_002_pos', 'zpool_scrub_003_pos',
-    'zpool_scrub_004_pos', 'zpool_scrub_005_pos', 'zpool_scrub_multiple_copies']
+    'zpool_scrub_004_pos', 'zpool_scrub_005_pos', 'zpool_scrub_print_repairing',
+    'zpool_scrub_offline_device', 'zpool_scrub_multiple_copies']
 
 [/opt/zfs-tests/tests/functional/cli_root/zpool_set]
 tests = ['zpool_set_001_pos', 'zpool_set_002_neg', 'zpool_set_003_neg']
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_get/zpool_get.cfg	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_get/zpool_get.cfg	Mon Jun 03 18:18:53 2019 +0200
@@ -78,4 +78,5 @@
     "feature@zpool_checkpoint"
     "feature@spacemap_v2"
     "feature@allocation_classes"
+    "feature@resilver_defer"
 )
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/cleanup.ksh	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/cleanup.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -34,6 +34,8 @@
 
 verify_runnable "global"
 
+log_must set_tunable32 zfs_scan_suspend_progress 0
+
 for pool in "$TESTPOOL" "$TESTPOOL1"; do
 	datasetexists $pool/$TESTFS && \
 		log_must zfs destroy -Rf $pool/$TESTFS
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_device_replaced.ksh	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_cachefile_device_replaced.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -42,10 +42,10 @@
 #	   each sync.
 #	2. Add data to pool
 #	3. Re-import the pool so that data isn't cached
-#	4. Use zinject to slow down device I/O
+#	4. Use zfs_scan_suspend_progress to ensure resilvers don't progress
 #	5. Trigger the resilvering
 #	6. Use spa freeze to stop writing to the pool.
-#	7. Clear zinject events (needed to export the pool)
+#	7. Re-enable scan progress
 #	8. Export the pool
 #
 
@@ -58,7 +58,7 @@
 	# Revert zfs_txg_timeout to defaults
 	[[ -n ZFS_TXG_TIMEOUT ]] &&
 	    log_must set_zfs_txg_timeout $ZFS_TXG_TIMEOUT
-
+	log_must set_tunable32 zfs_scan_suspend_progress 0
 	cleanup
 }
 
@@ -85,22 +85,16 @@
 	log_must zpool export $TESTPOOL1
 	log_must cp $CPATHBKP $CPATH
 	log_must zpool import -c $CPATH -o cachefile=$CPATH $TESTPOOL1
-	typeset device
-	for device in $zinjectdevices ; do
-		log_must zinject -d $device -D 200:1 $TESTPOOL1 > /dev/null
-	done
+	log_must set_tunable32 zfs_scan_suspend_progress 1
 	log_must zpool replace $TESTPOOL1 $replacevdev $replaceby
 
 	# Cachefile: pool in resilvering state
 	log_must cp $CPATH $CPATHBKP2
 
-	# We must disable zinject in order to export the pool, so we freeze
-	# it first to prevent writing out subsequent resilvering progress.
-	log_must zpool freeze $TESTPOOL1
 	# Confirm pool is still replacing
 	log_must pool_is_replacing $TESTPOOL1
-	log_must zinject -c all > /dev/null
 	log_must zpool export $TESTPOOL1
+	log_must set_tunable32 zfs_scan_suspend_progress 0
 
 	( $earlyremove ) && log_must rm $replacevdev
 
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_rewind_device_replaced.ksh	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_import/import_rewind_device_replaced.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -63,6 +63,7 @@
 	[[ -n ZFS_TXG_TIMEOUT ]] &&
 	    log_must set_zfs_txg_timeout $ZFS_TXG_TIMEOUT
 	log_must rm -rf $BACKUP_DEVICE_DIR
+	log_must set_tunable32 zfs_scan_suspend_progress 0
 	cleanup
 }
 
@@ -96,22 +97,17 @@
 	# This should not free original data.
 	log_must overwrite_data $TESTPOOL1 ""
 
-	# Steps to insure resilvering happens very slowly.
 	log_must zpool export $TESTPOOL1
 	log_must zpool import -d $DEVICE_DIR $TESTPOOL1
-	typeset device
-	for device in $zinjectdevices ; do
-		log_must zinject -d $device -D 200:1 $TESTPOOL1 > /dev/null
-	done
+
+	# Ensure resilvering doesn't complete.
+	log_must set_tunable32 zfs_scan_suspend_progress 1
 	log_must zpool replace $TESTPOOL1 $replacevdev $replaceby
 
-	# We must disable zinject in order to export the pool, so we freeze
-	# it first to prevent writing out subsequent resilvering progress.
-	log_must zpool freeze $TESTPOOL1
 	# Confirm pool is still replacing
 	log_must pool_is_replacing $TESTPOOL1
-	log_must zinject -c all > /dev/null
 	log_must zpool export $TESTPOOL1
+	log_must set_tunable32 zfs_scan_suspend_progress 0
 
 	############################################################
 	# Test 1: rewind while device is resilvering.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_reopen/Makefile	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,21 @@
+#
+# 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 2019 Joyent, Inc.
+#
+
+include $(SRC)/Makefile.master
+
+ROOTOPTPKG = $(ROOT)/opt/zfs-tests
+TARGETDIR = $(ROOTOPTPKG)/tests/functional/cli_root/zpool_reopen
+
+include $(SRC)/test/zfs-tests/Makefile.com
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_reopen/cleanup.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,36 @@
+#!/bin/ksh -p
+
+#
+# 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 (c) 2016, 2017 by Intel Corporation. All rights reserved.
+# Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
+# Copyright 2019 Joyent, Inc.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_reopen/zpool_reopen.shlib
+
+verify_runnable "global"
+
+cleanup_devices $DISKS
+
+# Unplug the disk and remove scsi_debug module
+case "$(uname)" in
+Linux)
+	for SDDEVICE in $(get_debug_device); do
+		remove_disk $SDDEVICE
+	done
+	unload_scsi_debug
+	;;
+esac
+
+log_pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_reopen/setup.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,34 @@
+#!/bin/ksh -p
+
+#
+# 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 (c) 2016, 2017 by Intel Corporation. All rights reserved.
+# Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
+# Copyright 2019 Joyent, Inc.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_reopen/zpool_reopen.cfg
+
+verify_runnable "global"
+
+# Create scsi_debug devices for the reopen tests
+case "$(uname)" in
+Linux)
+	load_scsi_debug $SDSIZE $SDHOSTS $SDTGTS $SDLUNS '512b'
+	;;
+SunOS)
+	log_unsupported "scsi debug module unsupported"
+	;;
+esac
+
+log_pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen.cfg	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,49 @@
+#
+# 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 (c) 2016, 2017 by Intel Corporation. All rights reserved.
+# Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
+# Copyright 2019 Joyent, Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+verify_runnable "global"
+
+export DISK_ARRAY_NUM=$(echo ${DISKS} | nawk '{print NF}')
+export DISKSARRAY=$DISKS
+export SMALL_FILE_SIZE=10
+export LARGE_FILE_SIZE=80
+export MAXTIMEOUT=40
+
+export SDSIZE=256
+export SDHOSTS=1
+export SDTGTS=1
+export SDLUNS=1
+
+export DISK1=$(echo $DISKS | nawk '{print $1}')
+export DISK2=$(echo $DISKS | nawk '{print $2}')
+export DISK3=$(echo $DISKS | nawk '{print $3}')
+
+case "$(uname)" in
+Linux)
+	set_slice_prefix
+	set_device_dir
+	devs_id[0]=$(get_persistent_disk_name $DISK1)
+	devs_id[1]=$(get_persistent_disk_name $DISK2)
+	devs_id[2]=$(get_persistent_disk_name $DISK3)
+	export devs_id
+	;;
+SunOS)
+	DEV_DSKDIR="/dev"
+	;;
+esac
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen.shlib	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,124 @@
+#
+# 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 (c) 2017 Open-E, Inc. All Rights Reserved.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_reopen/zpool_reopen.cfg
+
+#
+# Clear labels on the given disks
+#
+function clear_labels #disks
+{
+	for disk in $@; do
+		if ( is_loop_device $disk ) || ( is_mpath_device $disk ); then
+			zpool labelclear -f /dev/$disk
+		else
+			zpool labelclear -f /dev/${disk}1
+		fi
+	done
+}
+
+#
+# Set the REMOVED_DISK and REMOVED_DISK_ID constants for device
+# used for re-plugging. When the disk is loop device use the
+# scsi_debug emulated drive. Otherwise use the real drive.
+#
+function set_removed_disk
+{
+	if is_loop_device $DISK1; then
+		export REMOVED_DISK=$(get_debug_device)
+		export REMOVED_DISK_ID=$(get_persistent_disk_name $REMOVED_DISK)
+	elif ( is_real_device $DISK1 ) || ( is_mpath_device $DISK1 ); then
+		export REMOVED_DISK="$DISK1"
+		export REMOVED_DISK_ID=${devs_id[0]}
+	else
+		log_fail "No drives that supports removal"
+	fi
+}
+
+#
+# Generate random file of the given size in MiB
+#
+function generate_random_file #path size_mb
+{
+	typeset path=$1
+	typeset -i size_mb=$2
+	file_write -o create -f $path -b 1048576 -s0 -c $size_mb -d R
+}
+
+#
+# Wait until specific event or timeout occur.
+#
+# The passed function is executed with pool name as argument
+# with an interval of 1 second until it succeeds or until the
+# timeout occurs.
+# It returns 1 on timeout or 0 otherwise.
+#
+function wait_for_action #pool timeout function
+{
+	typeset pool=$1
+	typeset -i timeout=$2
+	typeset func=$3
+
+	while [ $timeout -gt 0 ]; do
+		(( --timeout ))
+		if ( $func $pool ); then
+			return 0
+		fi
+		sleep 1
+	done
+
+	return 1
+}
+
+#
+# Helpers for wait_for_action function:
+# wait_for_resilver_start - wait until resilver is started
+# wait_for_resilver_end - wait until resilver is finished
+# wait_for_scrub_end - wait until scrub is finished
+#
+function wait_for_resilver_start #pool timeout
+{
+	wait_for_action $1 $2 is_pool_resilvering
+	return $?
+}
+
+function wait_for_resilver_end #pool timeout
+{
+	wait_for_action $1 $2 is_pool_resilvered
+	return $?
+}
+
+function wait_for_scrub_end #pool timeout
+{
+	wait_for_action $1 $2 is_pool_scrubbed
+	return $?
+}
+
+#
+# Check if scan action has been restarted on the given pool
+#
+
+function is_scan_restarted #pool
+{
+	typeset pool=$1
+	zpool history -i $pool | grep -q "scan aborted, restarting"
+	return $?
+}
+
+function is_deferred_scan_started #pool
+{
+	typeset pool=$1
+	zpool history -i $pool | grep -q "starting deferred resilver"
+	return $?
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_001_pos.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,70 @@
+#!/bin/ksh -p
+
+#
+# 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 (c) 2017 Open-E, Inc. All Rights Reserved.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_reopen/zpool_reopen.shlib
+
+#
+# DESCRIPTION:
+# Test if zpool reopen with no arguments works correctly.
+#
+# STRATEGY:
+# 1. Create a pool.
+# 2. Remove a disk.
+# 3. Reopen a pool and verify if removed disk is marked as unavailable.
+# 4. "Plug back" disk.
+# 5. Reopen a pool and verify if removed disk is marked online again.
+# 6. Check if reopen caused resilver start.
+#
+
+verify_runnable "global"
+
+function cleanup
+{
+	# bring back removed disk online for further tests
+	insert_disk $REMOVED_DISK $scsi_host
+	poolexists $TESTPOOL && destroy_pool $TESTPOOL
+	clear_labels $REMOVED_DISK $DISK2
+}
+
+log_assert "Testing zpool reopen with no arguments"
+log_onexit cleanup
+
+set_removed_disk
+scsi_host=$(get_scsi_host $REMOVED_DISK)
+
+# 1. Create a pool.
+default_mirror_setup_noexit $REMOVED_DISK_ID $DISK2
+# 2. Remove a disk.
+remove_disk $REMOVED_DISK
+# 3. Reopen a pool and verify if removed disk is marked as unavailable.
+log_must zpool reopen
+log_must check_state $TESTPOOL "$REMOVED_DISK_ID" "unavail"
+# Write some data to the pool
+log_must generate_random_file /$TESTPOOL/data $SMALL_FILE_SIZE
+# 4. "Plug back" disk.
+insert_disk $REMOVED_DISK $scsi_host
+# 5. Reopen a pool and verify if removed disk is marked online again.
+log_must zpool reopen
+log_must check_state $TESTPOOL "$REMOVED_DISK_ID" "online"
+# 6. Check if reopen caused resilver start.
+log_must wait_for_resilver_end $TESTPOOL $MAXTIMEOUT
+
+# clean up
+log_must zpool destroy $TESTPOOL
+clear_labels $REMOVED_DISK $DISK2
+
+log_pass "Zpool reopen with no arguments test passed"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_002_pos.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,70 @@
+#!/bin/ksh -p
+
+#
+# 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 (c) 2017 Open-E, Inc. All Rights Reserved.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_reopen/zpool_reopen.shlib
+
+#
+# DESCRIPTION:
+# Test if zpool reopen with pool name as argument works correctly.
+#
+# STRATEGY:
+# 1. Create a pool.
+# 2. Remove a disk.
+# 3. Reopen a pool and verify if removed disk is marked as unavailable.
+# 4. "Plug back" disk.
+# 5. Reopen a pool and verify if removed disk is marked online again.
+# 6. Check if reopen caused resilver start.
+#
+
+verify_runnable "global"
+
+function cleanup
+{
+	# bring back removed disk online for further tests
+	insert_disk $REMOVED_DISK $scsi_host
+	poolexists $TESTPOOL && destroy_pool $TESTPOOL
+	clear_labels $REMOVED_DISK $DISK2
+}
+
+log_assert "Testing zpool reopen with no arguments"
+log_onexit cleanup
+
+set_removed_disk
+scsi_host=$(get_scsi_host $REMOVED_DISK)
+
+# 1. Create a pool.
+default_mirror_setup_noexit $REMOVED_DISK_ID $DISK2
+# 2. Remove a disk.
+remove_disk $REMOVED_DISK
+# 3. Reopen a pool and verify if removed disk is marked as unavailable.
+log_must zpool reopen $TESTPOOL
+log_must check_state $TESTPOOL "$REMOVED_DISK_ID" "unavail"
+# Write some data to the pool
+log_must generate_random_file /$TESTPOOL/data $SMALL_FILE_SIZE
+# 4. "Plug back" disk.
+insert_disk $REMOVED_DISK $scsi_host
+# 5. Reopen a pool and verify if removed disk is marked online again.
+log_must zpool reopen $TESTPOOL
+log_must check_state $TESTPOOL "$REMOVED_DISK_ID" "online"
+# 6. Check if reopen caused resilver start.
+log_must wait_for_resilver_end $TESTPOOL $MAXTIMEOUT
+
+# clean up
+log_must zpool destroy $TESTPOOL
+clear_labels $REMOVED_DISK $DISK2
+
+log_pass "Zpool reopen with no arguments test passed"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_003_pos.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,101 @@
+#!/bin/ksh -p
+
+#
+# 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 (c) 2017 Open-E, Inc. All Rights Reserved.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_reopen/zpool_reopen.shlib
+
+#
+# DESCRIPTION:
+# Test zpool reopen while scrub is running.
+# Checks if re-plugged device is fully resilvered.
+#
+# STRATEGY:
+# 1. Create a pool
+# 2. Remove a disk.
+# 3. Write a test file to the pool and calculate its checksum.
+# 4. Execute scrub.
+# 5. "Plug back" disk.
+# 6. Reopen a pool.
+# 7. Check if scrub scan is replaced by resilver.
+# 8. Put another device offline and check if the test file checksum is correct.
+#
+# NOTES:
+#	A 250ms delay is added to make sure that the scrub is running while
+#	the reopen kicks the resilver.
+#
+
+verify_runnable "global"
+
+function cleanup
+{
+	log_must zinject -c all
+	rm -f $TESTFILE_MD5 2>/dev/null
+	# bring back removed disk online for further tests
+	insert_disk $REMOVED_DISK $scsi_host
+	poolexists $TESTPOOL && destroy_pool $TESTPOOL
+}
+
+log_assert "Testing zpool reopen with pool name as argument"
+log_onexit cleanup
+
+set_removed_disk
+scsi_host=$(get_scsi_host $REMOVED_DISK)
+
+# 1. Create a pool
+default_mirror_setup_noexit $REMOVED_DISK_ID $DISK2
+# 2. Remove a disk.
+remove_disk $REMOVED_DISK
+
+log_must zpool reopen $TESTPOOL
+log_must check_state $TESTPOOL "$REMOVED_DISK_ID" "unavail"
+
+# 3. Write a test file to the pool and calculate its checksum.
+TESTFILE=/$TESTPOOL/data
+TESTFILE_MD5=$(mktemp --tmpdir=/var/tmp)
+log_must generate_random_file /$TESTPOOL/data $LARGE_FILE_SIZE
+log_must md5sum $TESTFILE > $TESTFILE_MD5
+
+# 4. Execute scrub.
+# add delay to I/O requests for remaining disk in pool
+log_must zinject -d $DISK2 -D250:1 $TESTPOOL
+log_must zpool scrub $TESTPOOL
+
+# 5. "Plug back" disk.
+insert_disk $REMOVED_DISK $scsi_host
+# 6. Reopen a pool.
+log_must zpool reopen $TESTPOOL
+log_must check_state $TESTPOOL "$REMOVED_DISK_ID" "online"
+# 7. Check if scrub scan is replaced by resilver.
+# the scrub operation has to be running while reopen is executed
+log_must is_pool_scrubbing $TESTPOOL true
+# remove delay from disk
+log_must zinject -c all
+# the scrub will be replaced by resilver, wait until it ends
+log_must wait_for_resilver_end $TESTPOOL $MAXTIMEOUT
+# check if the scrub scan has been interrupted by resilver
+log_must is_scan_restarted $TESTPOOL
+
+# 8. Put another device offline and check if the test file checksum is correct.
+log_must zpool offline $TESTPOOL $DISK2
+log_must md5sum -c $TESTFILE_MD5
+log_must zpool online $TESTPOOL $DISK2
+sleep 1
+
+# clean up
+rm -f $TESTFILE_MD5 2>/dev/null
+log_must zpool destroy $TESTPOOL
+
+log_pass "Zpool reopen test successful"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_004_pos.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,88 @@
+#!/bin/ksh -p
+
+#
+# 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 (c) 2017 Open-E, Inc. All Rights Reserved.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_reopen/zpool_reopen.shlib
+
+#
+# DESCRIPTION:
+# Test zpool reopen -n while scrub is running.
+# Checks if re-plugged device is NOT resilvered.
+#
+# STRATEGY:
+# 1. Create a pool
+# 2. Remove a disk.
+# 3. Write test file to pool.
+# 4. Execute scrub.
+# 5. "Plug back" disk.
+# 6. Reopen a pool with an -n flag.
+# 7. Check if resilver was deferred.
+# 8. Check if trying to put device to offline fails because of no valid
+#    replicas.
+#
+# NOTES:
+#	A 125ms delay is added to make sure that the scrub is running while
+#	the reopen is invoked.
+#
+
+verify_runnable "global"
+
+function cleanup
+{
+	log_must zinject -c all
+	# bring back removed disk online for further tests
+	insert_disk $REMOVED_DISK $scsi_host
+	poolexists $TESTPOOL && destroy_pool $TESTPOOL
+}
+
+log_assert "Testing zpool reopen with pool name as argument"
+log_onexit cleanup
+
+set_removed_disk
+scsi_host=$(get_scsi_host $REMOVED_DISK)
+
+# 1. Create a pool
+default_mirror_setup_noexit $REMOVED_DISK_ID $DISK2
+# 2. Remove a disk.
+remove_disk $REMOVED_DISK
+log_must zpool reopen -n $TESTPOOL
+log_must check_state $TESTPOOL "$REMOVED_DISK_ID" "unavail"
+# 3. Write test file to pool.
+log_must generate_random_file /$TESTPOOL/data $LARGE_FILE_SIZE
+# 4. Execute scrub.
+# add delay to I/O requests for remaining disk in pool
+log_must zinject -d $DISK2 -D125:1 $TESTPOOL
+log_must zpool scrub $TESTPOOL
+# 5. "Plug back" disk.
+insert_disk $REMOVED_DISK $scsi_host
+# 6. Reopen a pool with an -n flag.
+log_must zpool reopen -n $TESTPOOL
+log_must check_state $TESTPOOL "$REMOVED_DISK_ID" "online"
+# remove delay from disk
+log_must zinject -c all
+# 7. Check if scrub scan is NOT replaced by resilver.
+log_must wait_for_scrub_end $TESTPOOL $MAXTIMEOUT
+log_must is_deferred_scan_started $TESTPOOL
+
+# 8. Check if trying to put device to offline fails because of no valid
+#    replicas.
+log_must wait_for_resilver_end $TESTPOOL $MAXTIMEOUT
+log_must zpool offline $TESTPOOL $DISK2
+
+# clean up
+log_must zpool destroy $TESTPOOL
+
+log_pass "Zpool reopen test successful"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_005_pos.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,86 @@
+#!/bin/ksh -p
+
+#
+# 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 (c) 2017 Open-E, Inc. All Rights Reserved.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_reopen/zpool_reopen.shlib
+
+#
+# DESCRIPTION:
+# Test zpool reopen -n while resilver is running.
+# Checks if the resilver is restarted.
+#
+# STRATEGY:
+# 1. Create a pool
+# 2. Remove a disk.
+# 3. Write test file to pool.
+# 4. "Plug back" disk.
+# 5. Reopen a pool and wait until resilvering is started.
+# 6. Reopen a pool again with -n flag.
+# 7. Wait until resilvering is finished and check if it was restarted.
+#
+# NOTES:
+#	A 25ms delay is added to make sure that the resilver is running while
+#	the reopen is invoked.
+#
+
+verify_runnable "global"
+
+function cleanup
+{
+	log_must zinject -c all
+	insert_disk $REMOVED_DISK $scsi_host
+	poolexists $TESTPOOL && destroy_pool $TESTPOOL
+}
+
+log_assert "Testing zpool reopen with pool name as argument"
+log_onexit cleanup
+
+set_removed_disk
+scsi_host=$(get_scsi_host $REMOVED_DISK)
+
+# 1. Create a pool
+default_mirror_setup_noexit $REMOVED_DISK_ID $DISK2
+# 2. Remove a disk.
+remove_disk $REMOVED_DISK
+
+log_must zpool reopen $TESTPOOL
+log_must check_state $TESTPOOL "$REMOVED_DISK_ID" "unavail"
+# 3. Write test file to pool.
+log_must generate_random_file /$TESTPOOL/data $LARGE_FILE_SIZE
+# 4. "Plug back" disk.
+insert_disk $REMOVED_DISK $scsi_host
+
+# 5. Reopen a pool and wait until resilvering is started.
+log_must zpool reopen $TESTPOOL
+log_must check_state $TESTPOOL "$REMOVED_DISK_ID" "online"
+# add delay to I/O requests for the reopened disk
+log_must zinject -d $REMOVED_DISK_ID -D25:1 $TESTPOOL
+# wait until resilver starts
+log_must wait_for_resilver_start $TESTPOOL $MAXTIMEOUT
+
+# 6. Reopen a pool again with -n flag.
+log_must zpool reopen -n $TESTPOOL
+
+# 7. Wait until resilvering is finished and check if it was restarted.
+log_must wait_for_resilver_end $TESTPOOL $MAXTIMEOUT
+# remove delay from disk
+log_must zinject -c all
+log_mustnot is_scan_restarted $TESTPOOL
+
+# clean up
+log_must zpool destroy $TESTPOOL
+
+log_pass "Zpool reopen test successful"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_006_neg.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,43 @@
+#!/bin/ksh -p
+
+#
+# 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 (c) 2017 Open-E, Inc. All Rights Reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# Wrong arguments passed to zpool reopen should cause an error.
+#
+# STRATEGY:
+# 1. Create an array with bad 'zpool reopen' arguments.
+# 2. For each argument execute the 'zpool reopen' command and verify
+#    if it returns an error.
+#
+
+verify_runnable "global"
+
+# 1. Create an array with bad 'zpool reopen' arguments.
+typeset -a args=("!" "1" "-s" "--n" "-1" "-" "-c" "-f" "-d 2" "-abc" "-na")
+
+log_assert "Test 'zpool reopen' with invalid arguments."
+
+# 2. For each argument execute the 'zpool reopen' command and verify
+#    if it returns an error.
+for arg in ${args[@]}; do
+	log_mustnot zpool reopen $arg
+done
+
+log_pass "Passing invalid arguments to 'zpool reopen' failed as expected."
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_reopen/zpool_reopen_007_pos.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,67 @@
+#!/bin/ksh -p
+
+#
+# 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 (c) 2018 by Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/tests/functional/cli_root/zpool_reopen/zpool_reopen.shlib
+
+#
+# DESCRIPTION:
+# Test zpool reopen while performing IO to the pool.
+# Verify that no IO errors of any kind of reported.
+#
+# STRATEGY:
+# 1. Create a non-redundant pool.
+# 2. Repeat:
+#   a. Write files to the pool.
+#   b. Execute 'zpool reopen'.
+# 3. Verify that no errors are reported by 'zpool status'.
+
+verify_runnable "global"
+
+function cleanup
+{
+	poolexists $TESTPOOL && destroy_pool $TESTPOOL
+}
+
+log_assert "Testing zpool reopen with concurrent user IO"
+log_onexit cleanup
+
+set_removed_disk
+scsi_host=$(get_scsi_host $REMOVED_DISK)
+
+# 1. Create a non-redundant pool.
+log_must zpool create $TESTPOOL $DISK1 $DISK2 $DISK3
+
+for i in $(seq 10); do
+	# 3a. Write files in the background to the pool.
+	mkfile 64m /$TESTPOOL/data.$i &
+
+	# 3b. Execute 'zpool reopen'.
+	log_must zpool reopen $TESTPOOL
+
+	for disk in $DISK1 $DISK2 $DISK3; do
+		zpool status -P -v $TESTPOOL | grep $disk | \
+		    read -r name state rd wr cksum
+		log_must [ $state = "ONLINE" ]
+	        log_must [ $rd -eq 0 ]
+	        log_must [ $wr -eq 0 ]
+	        log_must [ $cksum -eq 0 ]
+	done
+done
+
+wait
+
+log_pass "Zpool reopen with concurrent user IO successful"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_resilver/Makefile	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,21 @@
+#
+# 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 2019 Joyent, Inc.
+#
+
+include $(SRC)/Makefile.master
+
+ROOTOPTPKG = $(ROOT)/opt/zfs-tests
+TARGETDIR = $(ROOTOPTPKG)/tests/functional/cli_root/zpool_resilver
+
+include $(SRC)/test/zfs-tests/Makefile.com
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_resilver/cleanup.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,33 @@
+#!/bin/ksh -p
+#
+# 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.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_scrub/zpool_scrub.cfg
+
+verify_runnable "global"
+
+destroy_mirrors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_resilver/setup.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,39 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2018 by Datto. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_resilver/zpool_resilver.cfg
+
+verify_runnable "global"
+verify_disk_count "$DISKS" 3
+
+default_mirror_setup_noexit $DISK1 $DISK2 $DISK3
+
+mntpnt=$(get_prop mountpoint $TESTPOOL/$TESTFS)
+
+# Create 256M of data
+log_must file_write -b 1048576 -c 256 -o create -d 0 -f $mntpnt/bigfile
+log_pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_resilver/zpool_resilver.cfg	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2018 by Datto. All rights reserved.
+#
+
+export DISK1=$(echo $DISKS | nawk '{print $1}')
+export DISK2=$(echo $DISKS | nawk '{print $2}')
+export DISK3=$(echo $DISKS | nawk '{print $3}')
+
+export MAXTIMEOUT=80
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_resilver/zpool_resilver_bad_args.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,71 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2018 by Datto. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# A badly formed parameter passed to 'zpool resilver' should
+# return an error.
+#
+# STRATEGY:
+# 1. Create an array containing bad 'zpool reilver' parameters.
+# 2. For each element, execute the sub-command.
+# 3. Verify it returns an error.
+# 4. Confirm the sub-command returns an error if the resilver_defer
+#    feature isn't active.
+#
+
+verify_runnable "global"
+
+set -A args "" "-?" "blah blah" "-%" "--?" "-*" "-=" \
+    "-a" "-b" "-c" "-d" "-e" "-f" "-g" "-h" "-i" "-j" "-k" "-l" \
+    "-m" "-n" "-o" "-p" "-q" "-r" "-s" "-t" "-u" "-v" "-w" "-x" "-y" "-z" \
+    "-A" "-B" "-C" "-D" "-E" "-F" "-G" "-H" "-I" "-J" "-K" "-L" \
+    "-M" "-N" "-O" "-P" "-Q" "-R" "-S" "-T" "-U" "-V" "-W" "-X" "-W" "-Z"
+
+function cleanup
+{
+	log_must destroy_pool $TESTPOOL2
+	log_must rm -f $TEST_BASE_DIR/zpool_resilver.dat
+}
+
+log_onexit cleanup
+
+log_assert "Execute 'zpool resilver' using invalid parameters."
+
+typeset -i i=0
+while [[ $i -lt ${#args[*]} ]]; do
+	log_mustnot zpool resilver ${args[i]}
+
+	((i = i + 1))
+done
+
+log_must mkfile $MINVDEVSIZE $TEST_BASE_DIR/zpool_resilver.dat
+log_must zpool create -d $TESTPOOL2 $TEST_BASE_DIR/zpool_resilver.dat
+log_mustnot zpool resilver $TESTPOOL2
+
+log_pass "Badly formed 'zpool resilver' parameters fail as expected."
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_resilver/zpool_resilver_restart.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -0,0 +1,86 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2018 Datto Inc.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_reopen/zpool_reopen.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_resilver/zpool_resilver.cfg
+
+#
+# DESCRIPTION:
+#	"Verify 'zpool resilver' restarts in-progress resilvers"
+#
+# STRATEGY:
+#	1. Write some data and detatch the first drive so it has resilver
+#	   work to do
+#	2. Repeat the process with a second disk
+#	3. Reattach the drives, causing the second drive's resilver to be
+#	   deferred
+#	4. Manually restart the resilver with all drives
+#
+
+verify_runnable "global"
+
+function cleanup
+{
+	log_must set_tunable32 zfs_scan_suspend_progress 0
+	log_must rm -f $mntpnt/biggerfile1
+	log_must rm -f $mntpnt/biggerfile2
+}
+
+log_onexit cleanup
+
+log_assert "Verify 'zpool resilver' restarts in-progress resilvers"
+
+mntpnt=$(get_prop mountpoint $TESTPOOL/$TESTFS)
+
+# 1. Write some data and detatch the first drive so it has resilver work to do
+log_must file_write -b 524288 -c 1024 -o create -d 0 -f $mntpnt/biggerfile1
+log_must sync
+log_must zpool detach $TESTPOOL $DISK2
+
+# 2. Repeat the process with a second disk
+log_must file_write -b 524288 -c 1024 -o create -d 0 -f $mntpnt/biggerfile2
+log_must sync
+log_must zpool detach $TESTPOOL $DISK3
+
+# 3. Reattach the drives, causing the second drive's resilver to be deferred
+log_must set_tunable32 zfs_scan_suspend_progress 1
+
+log_must zpool attach $TESTPOOL $DISK1 $DISK2
+log_must is_pool_resilvering $TESTPOOL true
+
+log_must zpool attach $TESTPOOL $DISK1 $DISK3
+log_must is_pool_resilvering $TESTPOOL true
+
+# 4. Manually restart the resilver with all drives
+log_must zpool resilver $TESTPOOL
+log_must is_deferred_scan_started $TESTPOOL
+log_must set_tunable32 zfs_scan_suspend_progress 0
+log_must wait_for_resilver_end $TESTPOOL $MAXTIMEOUT
+log_must check_state $TESTPOOL "$DISK2" "online"
+log_must check_state $TESTPOOL "$DISK3" "online"
+
+log_pass "Verified 'zpool resilver' restarts in-progress resilvers"
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_scrub/cleanup.ksh	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_scrub/cleanup.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -30,5 +30,5 @@
 
 verify_runnable "global"
 
-log_must set_tunable64 zfs_scan_vdev_limit $ZFS_SCAN_VDEV_LIMIT_DEFAULT
+log_must set_tunable32 zfs_scan_suspend_progress 0
 destroy_mirrors
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_scrub/zpool_scrub_002_pos.ksh	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_scrub/zpool_scrub_002_pos.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -45,18 +45,12 @@
 #	5. Resume the paused scrub and verify scrub is again being performed.
 #	6. Verify zpool scrub -s succeed when the system is scrubbing.
 #
-# NOTES:
-#	Artificially limit the scrub speed by setting the zfs_scan_vdev_limit
-#	low and adding a 50ms zio delay in order to ensure that the scrub does
-#	not complete early.
-#
 
 verify_runnable "global"
 
 function cleanup
 {
-	log_must zinject -c all
-	log_must set_tunable64 zfs_scan_vdev_limit $ZFS_SCAN_VDEV_LIMIT_DEFAULT
+	log_must set_tunable32 zfs_scan_suspend_progress 0
 	log_must rm -f $mntpnt/biggerfile
 }
 
@@ -69,8 +63,7 @@
 log_must file_write -b 1048576 -c 1024 -o create -d 0 -f $mntpnt/biggerfile
 log_must sync
 
-log_must zinject -d $DISK1 -D50:1 $TESTPOOL
-log_must set_tunable64 zfs_scan_vdev_limit $ZFS_SCAN_VDEV_LIMIT_SLOW
+log_must set_tunable32 zfs_scan_suspend_progress 1
 log_must zpool scrub $TESTPOOL
 log_must is_pool_scrubbing $TESTPOOL true
 log_must zpool scrub -p $TESTPOOL
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_scrub/zpool_scrub_003_pos.ksh	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_scrub/zpool_scrub_003_pos.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -42,23 +42,19 @@
 #	2. Kick off a scrub
 #	2. Kick off a second scrub and verify it fails
 #
-# NOTES:
-#	Artificially limit the scrub speed by setting the zfs_scan_vdev_limit
-#	low in order to ensure that the scrub does not complete early.
-#
 
 verify_runnable "global"
 
 function cleanup
 {
-	log_must set_tunable64 zfs_scan_vdev_limit $ZFS_SCAN_VDEV_LIMIT_DEFAULT
+	log_must set_tunable32 zfs_scan_suspend_progress 0
 }
 
 log_onexit cleanup
 
 log_assert "Scrub command fails when there is already a scrub in progress"
 
-log_must set_tunable64 zfs_scan_vdev_limit $ZFS_SCAN_VDEV_LIMIT_SLOW
+log_must set_tunable32 zfs_scan_suspend_progress 1
 log_must zpool scrub $TESTPOOL
 log_must is_pool_scrubbing $TESTPOOL true
 log_mustnot zpool scrub $TESTPOOL
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_scrub/zpool_scrub_004_pos.ksh	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_scrub/zpool_scrub_004_pos.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -39,24 +39,40 @@
 # STRATEGY:
 #	1. Setup a mirror pool and filled with data.
 #	2. Detach one of devices
-#	3. Verify scrub failed until the resilver completed
+#	3. Create a file for the resilver to work on so it takes some time
+#	4. Export/import the pool to ensure the cache is dropped
+#	5. Verify scrub failed until the resilver completed
 #
 
 function cleanup
 {
-	log_must set_tunable64 zfs_scan_vdev_limit $ZFS_SCAN_VDEV_LIMIT_DEFAULT
+	log_must set_tunable32 zfs_scan_suspend_progress 0
+	rm -f $mntpnt/extra
 }
 
 verify_runnable "global"
 
+log_onexit cleanup
+
 log_assert "Resilver prevent scrub from starting until the resilver completes"
 
-log_must set_tunable64 zfs_scan_vdev_limit $ZFS_SCAN_VDEV_LIMIT_SLOW
-log_must zpool detach $TESTPOOL $DISK2
-log_must zpool attach $TESTPOOL $DISK1 $DISK2
+mntpnt=$(get_prop mountpoint $TESTPOOL/$TESTFS)
+
+# Temporarily prevent scan progress so our test doesn't race
+log_must set_tunable32 zfs_scan_suspend_progress 1
+
+while ! is_pool_resilvering $TESTPOOL; do
+	log_must zpool detach $TESTPOOL $DISK2
+	log_must file_write -b 1048576 -c 128 -o create -d 0 -f $mntpnt/extra
+	log_must zpool export $TESTPOOL
+	log_must zpool import $TESTPOOL
+	log_must zpool attach $TESTPOOL $DISK1 $DISK2
+done
+
 log_must is_pool_resilvering $TESTPOOL
 log_mustnot zpool scrub $TESTPOOL
 
+log_must set_tunable32 zfs_scan_suspend_progress 0
 while ! is_pool_resilvered $TESTPOOL; do
 	sleep 1
 done
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_scrub/zpool_scrub_offline_device.ksh	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zpool_scrub/zpool_scrub_offline_device.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -22,6 +22,7 @@
 
 #
 # Copyright 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
+# Copyright 2019 Joyent, Inc.
 #
 
 . $STF_SUITE/include/libtest.shlib
@@ -125,7 +126,8 @@
 zpool_scrub_sync $TESTPOOL2
 
 # 7. Verify data integrity
-cksum=$(zpool status $TESTPOOL2 | awk 'L{print $NF;L=0} /CKSUM$/{L=1}')
+cksum=$(zpool status $TESTPOOL2 | awk '{if ($NF == "CKSUM") {fnd=1; next} \
+    if (fnd && NF < 1) {fnd=0; next} if (fnd) csum += $NF} END {print csum}')
 if [[ $cksum != 0 ]]; then
 	log_fail "Unexpected CKSUM errors found on $TESTPOOL2 ($cksum)"
 fi
--- a/usr/src/test/zfs-tests/tests/functional/mmp/mmp_on_zdb.ksh	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/mmp/mmp_on_zdb.ksh	Mon Jun 03 18:18:53 2019 +0200
@@ -14,6 +14,7 @@
 #
 # Copyright (c) 2018 Lawrence Livermore National Security, LLC.
 # Copyright (c) 2018 by Nutanix. All rights reserved.
+# Copyright 2019 Joyent, Inc.
 #
 
 . $STF_SUITE/include/libtest.shlib
@@ -38,9 +39,7 @@
 function cleanup
 {
 	datasetexists $TESTPOOL && destroy_pool $TESTPOOL
-	for DISK in $DISKS; do
-		zpool labelclear -f $DEV_RDSKDIR/$DISK
-	done
+	cleanup_devices $DISKS
 	log_must mmp_clear_hostid
 }
 
--- a/usr/src/test/zfs-tests/tests/functional/removal/removal.kshlib	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/test/zfs-tests/tests/functional/removal/removal.kshlib	Mon Jun 03 18:18:53 2019 +0200
@@ -62,7 +62,7 @@
 	typeset callback=$3
 
 	shift 3
-	mdb_ctf_set_int zfs_remove_max_bytes_pause 0t0
+	mdb_ctf_set_int zfs_removal_suspend_progress 0t1
 
 	log_must zpool remove $pool $disk
 
@@ -81,7 +81,7 @@
 	#
 	log_must is_pool_removing $pool
 
-	mdb_ctf_set_int zfs_remove_max_bytes_pause -0t1
+	mdb_ctf_set_int zfs_removal_suspend_progress 0t0
 
 	log_must wait_for_removal $pool
 	log_mustnot vdevs_in_pool $pool $disk
--- a/usr/src/tools/quick/make-idmap	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/tools/quick/make-idmap	Mon Jun 03 18:18:53 2019 +0200
@@ -11,7 +11,7 @@
 #
 
 #
-# Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
+# Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
 #
 
 # Use distributed make (dmake) by default.
@@ -186,6 +186,8 @@
 do_tar() {
 	git_rev=`git rev-parse --short=8 HEAD`
 	files="
+kernel/misc/idmap
+kernel/misc/amd64/idmap
 lib/svc/manifest/system/idmap.xml
 usr/lib/idmapd
 usr/lib/libads.so.1
--- a/usr/src/uts/common/fs/smbsrv/smb_common_open.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_open.c	Mon Jun 03 18:18:53 2019 +0200
@@ -38,6 +38,8 @@
 #include <smbsrv/smb_fsops.h>
 #include <smbsrv/smbinfo.h>
 
+int smb_session_ofile_max = 32768;
+
 static volatile uint32_t smb_fids = 0;
 #define	SMB_UNIQ_FID()	atomic_inc_32_nv(&smb_fids)
 
@@ -339,7 +341,7 @@
 	}
 	op->desired_access = smb_access_generic_to_file(op->desired_access);
 
-	if (sr->session->s_file_cnt >= SMB_SESSION_OFILE_MAX) {
+	if (sr->session->s_file_cnt >= smb_session_ofile_max) {
 		ASSERT(sr->uid_user);
 		cmn_err(CE_NOTE, "smbsrv[%s\\%s]: TOO_MANY_OPENED_FILES",
 		    sr->uid_user->u_domain, sr->uid_user->u_name);
@@ -527,6 +529,11 @@
 					smb_node_release(dnode);
 					return (NT_STATUS_ACCESS_DENIED);
 				}
+				if (op->create_options & FILE_DELETE_ON_CLOSE) {
+					smb_node_release(node);
+					smb_node_release(dnode);
+					return (NT_STATUS_CANNOT_DELETE);
+				}
 			}
 		}
 
@@ -695,6 +702,14 @@
 		}
 
 		/*
+		 * Don't create in directories marked "Delete on close".
+		 */
+		if (dnode->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
+			smb_node_release(dnode);
+			return (NT_STATUS_DELETE_PENDING);
+		}
+
+		/*
 		 * lock the parent dir node in case another create
 		 * request to the same parent directory comes in.
 		 */
--- a/usr/src/uts/common/fs/smbsrv/smb_idmap.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/smbsrv/smb_idmap.c	Mon Jun 03 18:18:53 2019 +0200
@@ -20,24 +20,24 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
  * SMB server interface to idmap
  * (smb_idmap_get..., smb_idmap_batch_...)
  *
- * There are three implementations of this interface:
- *	uts/common/fs/smbsrv/smb_idmap.c (smbsrv kmod)
- *	lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c (libfksmbsrv)
- *	lib/smbsrv/libsmb/common/smb_idmap.c (libsmb)
+ * There are three implementations of this interface.
+ * This is the kernel version of these routines.  See also:
+ * $SRC/lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c
+ * $SRC/lib/smbsrv/libsmb/common/smb_idmap.c
  *
  * There are enough differences (relative to the code size)
  * that it's more trouble than it's worth to merge them.
  *
  * This one differs from the others in that it:
  *	calls kernel (kidmap_...) interfaces
- *	domain SIDs are shared, not strdup'ed
+ *	returned domain SIDs are shared, not strdup'ed
  */
 
 /*
@@ -104,6 +104,14 @@
 		return (IDMAP_ERR_ARG);
 	}
 
+	/*
+	 * IDMAP_ERR_NOTFOUND is an advisory error
+	 * and idmap will generate a local sid.
+	 */
+	if (sim.sim_stat == IDMAP_ERR_NOTFOUND &&
+	    sim.sim_domsid != NULL)
+		sim.sim_stat = IDMAP_SUCCESS;
+
 	if (sim.sim_stat != IDMAP_SUCCESS)
 		return (sim.sim_stat);
 
@@ -174,7 +182,7 @@
 idmap_stat
 smb_idmap_batch_create(smb_idmap_batch_t *sib, uint16_t nmap, int flags)
 {
-	ASSERT(sib);
+	ASSERT(sib != NULL);
 
 	bzero(sib, sizeof (smb_idmap_batch_t));
 
@@ -201,11 +209,13 @@
 	char *domsid;
 	int i;
 
-	ASSERT(sib);
-	ASSERT(sib->sib_maps);
+	ASSERT(sib != NULL);
+	ASSERT(sib->sib_maps != NULL);
 
-	if (sib->sib_idmaph)
+	if (sib->sib_idmaph) {
 		kidmap_get_destroy(sib->sib_idmaph);
+		sib->sib_idmaph = NULL;
+	}
 
 	if (sib->sib_flags & SMB_IDMAP_ID2SID) {
 		/*
@@ -226,8 +236,10 @@
 		}
 	}
 
-	if (sib->sib_size && sib->sib_maps)
+	if (sib->sib_size && sib->sib_maps) {
 		kmem_free(sib->sib_maps, sib->sib_size);
+		sib->sib_maps = NULL;
+	}
 }
 
 /*
@@ -249,14 +261,16 @@
 	char strsid[SMB_SID_STRSZ];
 	idmap_stat idm_stat;
 
-	ASSERT(idmaph);
-	ASSERT(sim);
-	ASSERT(sid);
+	ASSERT(idmaph != NULL);
+	ASSERT(sim != NULL);
+	ASSERT(sid != NULL);
 
 	smb_sid_tostr(sid, strsid);
 	if (smb_sid_splitstr(strsid, &sim->sim_rid) != 0)
 		return (IDMAP_ERR_SID);
+	/* Note: Free sim_domsid in smb_idmap_batch_destroy */
 	sim->sim_domsid = smb_mem_strdup(strsid);
+	sim->sim_idtype = idtype;
 
 	switch (idtype) {
 	case SMB_IDMAP_USER:
@@ -290,6 +304,7 @@
  *
  * sim->sim_domsid and sim->sim_rid will contain the mapping
  * result upon successful process of the batched request.
+ * Stash the type for error reporting (caller saves the ID).
  */
 idmap_stat
 smb_idmap_batch_getsid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
@@ -297,6 +312,7 @@
 {
 	idmap_stat idm_stat;
 
+	sim->sim_idtype = idtype;
 	switch (idtype) {
 	case SMB_IDMAP_USER:
 		idm_stat = kidmap_batch_getsidbyuid(idmaph, id,
@@ -342,6 +358,28 @@
 	return (idm_stat);
 }
 
+static void
+smb_idmap_bgm_report(smb_idmap_batch_t *sib, smb_idmap_t *sim)
+{
+
+	if ((sib->sib_flags & SMB_IDMAP_ID2SID) != 0) {
+		/*
+		 * Note: The ID and type we asked idmap to map
+		 * were saved in *sim_id and sim_idtype.
+		 */
+		uint_t id = (sim->sim_id == NULL) ?
+		    0 : (uint_t)*sim->sim_id;
+		cmn_err(CE_WARN, "Can't get SID for "
+		    "ID=%u type=%d, status=%d",
+		    id, sim->sim_idtype, sim->sim_stat);
+	}
+
+	if ((sib->sib_flags & SMB_IDMAP_SID2ID) != 0) {
+		cmn_err(CE_WARN, "Can't get ID for SID %s-%u, status=%d",
+		    sim->sim_domsid, sim->sim_rid, sim->sim_stat);
+	}
+}
+
 /*
  * smb_idmap_batch_getmappings
  *
@@ -356,6 +394,7 @@
 smb_idmap_batch_getmappings(smb_idmap_batch_t *sib)
 {
 	idmap_stat idm_stat = IDMAP_SUCCESS;
+	smb_idmap_t *sim;
 	int i;
 
 	idm_stat = kidmap_get_mappings(sib->sib_idmaph);
@@ -365,9 +404,13 @@
 	/*
 	 * Check the status for all the queued requests
 	 */
-	for (i = 0; i < sib->sib_nmap; i++) {
-		if (sib->sib_maps[i].sim_stat != IDMAP_SUCCESS)
-			return (sib->sib_maps[i].sim_stat);
+	for (i = 0, sim = sib->sib_maps; i < sib->sib_nmap; i++, sim++) {
+		if (sim->sim_stat != IDMAP_SUCCESS) {
+			smb_idmap_bgm_report(sib, sim);
+			if ((sib->sib_flags & SMB_IDMAP_SKIP_ERRS) == 0) {
+				return (sim->sim_stat);
+			}
+		}
 	}
 
 	if (smb_idmap_batch_binsid(sib) != 0)
@@ -396,7 +439,7 @@
 
 	sim = sib->sib_maps;
 	for (i = 0; i < sib->sib_nmap; sim++, i++) {
-		ASSERT(sim->sim_domsid);
+		ASSERT(sim->sim_domsid != NULL);
 		if (sim->sim_domsid == NULL)
 			return (1);
 
--- a/usr/src/uts/common/fs/smbsrv/smb_node.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/smbsrv/smb_node.c	Mon Jun 03 18:18:53 2019 +0200
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  */
 /*
  * SMB Node State Machine
@@ -596,8 +596,8 @@
 /*
  * Helper function for smb_node_set_delete_on_close(). Assumes node is a dir.
  * Return 0 if this is an empty dir. Otherwise return a NT_STATUS code.
- * We distinguish between readdir failure and non-empty dir by returning
- * different values.
+ * Unfortunately, to find out if a directory is empty, we have to read it
+ * and check for anything other than "." or ".." in the readdir buf.
  */
 static uint32_t
 smb_rmdir_possible(smb_node_t *n, uint32_t flags)
@@ -618,9 +618,9 @@
 #define	dp	u.u_dp
 
 	if (smb_vop_readdir(n->vp, 0, buf, &bsize, &eof, flags, zone_kcred()))
-		return (NT_STATUS_CANNOT_DELETE);
+		return (NT_STATUS_INTERNAL_ERROR);
 	if (bsize == 0)
-		return (NT_STATUS_CANNOT_DELETE);
+		return (0); /* empty dir */
 	bufptr = buf;
 	while ((bufptr += reclen) < buf + bsize) {
 		if (edp) {
@@ -647,23 +647,13 @@
  * whichever the first file handle is closed will trigger the node to be
  * marked as delete-on-close. The credentials of that ofile will be used
  * as the delete-on-close credentials of the node.
+ *
+ * Note that "read-only" tests have already happened before this call.
  */
 uint32_t
 smb_node_set_delete_on_close(smb_node_t *node, cred_t *cr, uint32_t flags)
 {
-	int rc = 0;
 	uint32_t status;
-	smb_attr_t attr;
-
-	if (node->n_pending_dosattr & FILE_ATTRIBUTE_READONLY)
-		return (NT_STATUS_CANNOT_DELETE);
-
-	bzero(&attr, sizeof (smb_attr_t));
-	attr.sa_mask = SMB_AT_DOSATTR;
-	rc = smb_fsop_getattr(NULL, zone_kcred(), node, &attr);
-	if ((rc != 0) || (attr.sa_dosattr & FILE_ATTRIBUTE_READONLY)) {
-		return (NT_STATUS_CANNOT_DELETE);
-	}
 
 	/*
 	 * If the directory is not empty we should fail setting del-on-close
@@ -679,8 +669,9 @@
 
 	mutex_enter(&node->n_mutex);
 	if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
+		/* It was already marked.  We're done. */
 		mutex_exit(&node->n_mutex);
-		return (NT_STATUS_CANNOT_DELETE);
+		return (NT_STATUS_SUCCESS);
 	}
 
 	crhold(cr);
--- a/usr/src/uts/common/fs/smbsrv/smb_ofile.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/smbsrv/smb_ofile.c	Mon Jun 03 18:18:53 2019 +0200
@@ -1143,13 +1143,10 @@
 /*
  * smb_ofile_rename_check
  *
- * An open file can be renamed if
- *
- *  1. isn't opened for data writing or deleting
- *
- *  2. Opened with "Deny Delete" share mode
- *         But not opened for data reading or executing
- *         (opened for accessing meta data)
+ * This does the work described in MS-FSA 2.1.5.1.2.2 (Algorithm
+ * to Check Sharing Access to an Existing Stream or Directory),
+ * where the "open in-progress" has DesiredAccess = DELETE and
+ * SharingMode = SHARE_READ | SHARE_WRITE | SHARE_DELETE.
  */
 
 uint32_t
@@ -1164,18 +1161,14 @@
 		return (NT_STATUS_INVALID_HANDLE);
 	}
 
-	if (of->f_granted_access &
-	    (FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE)) {
+	if ((of->f_granted_access & FILE_DATA_ALL) == 0) {
 		mutex_exit(&of->f_mutex);
-		return (NT_STATUS_SHARING_VIOLATION);
+		return (NT_STATUS_SUCCESS);
 	}
 
 	if ((of->f_share_access & FILE_SHARE_DELETE) == 0) {
-		if (of->f_granted_access &
-		    (FILE_READ_DATA | FILE_EXECUTE)) {
-			mutex_exit(&of->f_mutex);
-			return (NT_STATUS_SHARING_VIOLATION);
-		}
+		mutex_exit(&of->f_mutex);
+		return (NT_STATUS_SHARING_VIOLATION);
 	}
 
 	mutex_exit(&of->f_mutex);
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_dfs.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_dfs.c	Mon Jun 03 18:18:53 2019 +0200
@@ -72,16 +72,16 @@
 
 	status = smb_dfs_get_referrals(sr, &fsctl);
 
-	/* Out param is the API-level return code. */
+	/*
+	 * Out param is the API-level return code.
+	 * Out data (rep_data_mb) is the referral.
+	 */
 	doserr = smb_status2doserr(status);
 	(void) smb_mbc_encodef(&xa->rep_param_mb, "w", doserr);
-
-#if 0	/* XXX - Is API-level return code enough? */
-	if (status) {
-		smbsr_error(sr, NT_STATUS_NO_SUCH_DEVICE, 0, 0);
+	if (status != 0) {
+		smbsr_error(sr, status, ERRDOS, doserr);
 		return (SDRC_ERROR);
 	}
-#endif
 
 	return (SDRC_SUCCESS);
 }
--- a/usr/src/uts/common/fs/smbsrv/smb_vops.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/smbsrv/smb_vops.c	Mon Jun 03 18:18:53 2019 +0200
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include <sys/types.h>
@@ -501,7 +501,7 @@
 
 int
 smb_vop_space(vnode_t *vp, int cmd, flock64_t *bfp, int flags,
-	offset_t offset, cred_t *cr)
+    offset_t offset, cred_t *cr)
 {
 	int error;
 
@@ -529,19 +529,32 @@
 	if (mode == 0)
 		return (0);
 
-	if ((flags == V_ACE_MASK) && (mode & ACE_DELETE)) {
-		if (dir_vp) {
-			error = VOP_ACCESS(dir_vp, ACE_DELETE_CHILD, flags,
-			    cr, NULL);
+	error = VOP_ACCESS(vp, mode, flags, cr, NULL);
+
+	if (error == 0)
+		return (0);
+
+	if ((mode & (ACE_DELETE|ACE_READ_ATTRIBUTES)) == 0 ||
+	    flags != V_ACE_MASK || dir_vp == NULL)
+		return (error);
 
-			if (error == 0)
-				mode &= ~ACE_DELETE;
-		}
+	if ((mode & ACE_DELETE) != 0) {
+		error = VOP_ACCESS(dir_vp, ACE_DELETE_CHILD, flags,
+		    cr, NULL);
+
+		if (error == 0)
+			mode &= ~ACE_DELETE;
+	}
+	if ((mode & ACE_READ_ATTRIBUTES) != 0) {
+		error = VOP_ACCESS(dir_vp, ACE_LIST_DIRECTORY, flags,
+		    cr, NULL);
+
+		if (error == 0)
+			mode &= ~ACE_READ_ATTRIBUTES;
 	}
 
-	if (mode) {
+	if (mode != 0)
 		error = VOP_ACCESS(vp, mode, flags, cr, NULL);
-	}
 
 	return (error);
 }
@@ -554,7 +567,7 @@
  * vpp:		looked-up vnode (out)
  * od_name:	on-disk name of file (out).
  *		This parameter is optional.  If a pointer is passed in, it
- * 		must be allocated with MAXNAMELEN bytes
+ *		must be allocated with MAXNAMELEN bytes
  * rootvp:	vnode of the tree root (in)
  *		This parameter is always passed in non-NULL except at the time
  *		of share set up.
--- a/usr/src/uts/common/fs/zfs/dsl_scan.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/zfs/dsl_scan.c	Mon Jun 03 18:18:53 2019 +0200
@@ -183,12 +183,15 @@
 unsigned int zfs_obsolete_min_time_ms = 500;
 /* min millisecs to resilver per txg */
 unsigned int zfs_resilver_min_time_ms = 3000;
+int zfs_scan_suspend_progress = 0; /* set to prevent scans from progressing */
 boolean_t zfs_no_scrub_io = B_FALSE; /* set to disable scrub i/o */
 boolean_t zfs_no_scrub_prefetch = B_FALSE; /* set to disable scrub prefetch */
 enum ddt_class zfs_scrub_ddt_class_max = DDT_CLASS_DUPLICATE;
 /* max number of blocks to free in a single TXG */
 uint64_t zfs_async_block_max_blocks = UINT64_MAX;
 
+int zfs_resilver_disable_defer = 0; /* set to disable resilver deferring */
+
 /*
  * We wait a few txgs after importing a pool to begin scanning so that
  * the import / mounting code isn't held up by scrub / resilver IO.
@@ -455,7 +458,6 @@
 	scn->scn_async_destroying = spa_feature_is_active(dp->dp_spa,
 	    SPA_FEATURE_ASYNC_DESTROY);
 
-	bcopy(&scn->scn_phys, &scn->scn_phys_cached, sizeof (scn->scn_phys));
 	avl_create(&scn->scn_queue, scan_ds_queue_compare, sizeof (scan_ds_t),
 	    offsetof(scan_ds_t, sds_node));
 	avl_create(&scn->scn_prefetch_queue, scan_prefetch_queue_compare,
@@ -513,6 +515,8 @@
 		}
 	}
 
+	bcopy(&scn->scn_phys, &scn->scn_phys_cached, sizeof (scn->scn_phys));
+
 	/* reload the queue into the in-core state */
 	if (scn->scn_phys.scn_queue_obj != 0) {
 		zap_cursor_t zc;
@@ -751,6 +755,11 @@
 	spa->spa_scrub_reopen = B_FALSE;
 	(void) spa_vdev_state_exit(spa, NULL, 0);
 
+	if (func == POOL_SCAN_RESILVER) {
+		dsl_resilver_restart(spa->spa_dsl_pool, 0);
+		return (0);
+	}
+
 	if (func == POOL_SCAN_SCRUB && dsl_scan_is_paused_scrub(scn)) {
 		/* got scrub start cmd, resume paused scrub */
 		int err = dsl_scrub_set_pause_resume(scn->scn_dp,
@@ -766,6 +775,41 @@
 	    dsl_scan_setup_sync, &func, 0, ZFS_SPACE_CHECK_EXTRA_RESERVED));
 }
 
+/*
+ * Sets the resilver defer flag to B_FALSE on all leaf devs under vd. Returns
+ * B_TRUE if we have devices that need to be resilvered and are available to
+ * accept resilver I/Os.
+ */
+static boolean_t
+dsl_scan_clear_deferred(vdev_t *vd, dmu_tx_t *tx)
+{
+	boolean_t resilver_needed = B_FALSE;
+	spa_t *spa = vd->vdev_spa;
+
+	for (int c = 0; c < vd->vdev_children; c++) {
+		resilver_needed |=
+		    dsl_scan_clear_deferred(vd->vdev_child[c], tx);
+	}
+
+	if (vd == spa->spa_root_vdev &&
+	    spa_feature_is_active(spa, SPA_FEATURE_RESILVER_DEFER)) {
+		spa_feature_decr(spa, SPA_FEATURE_RESILVER_DEFER, tx);
+		vdev_config_dirty(vd);
+		spa->spa_resilver_deferred = B_FALSE;
+		return (resilver_needed);
+	}
+
+	if (!vdev_is_concrete(vd) || vd->vdev_aux ||
+	    !vd->vdev_ops->vdev_op_leaf)
+		return (resilver_needed);
+
+	if (vd->vdev_resilver_deferred)
+		vd->vdev_resilver_deferred = B_FALSE;
+
+	return (!vdev_is_dead(vd) && !vd->vdev_offline &&
+	    vdev_resilver_needed(vd, NULL, NULL));
+}
+
 /* ARGSUSED */
 static void
 dsl_scan_done(dsl_scan_t *scn, boolean_t complete, dmu_tx_t *tx)
@@ -865,6 +909,25 @@
 		 * Let the async thread assess this and handle the detach.
 		 */
 		spa_async_request(spa, SPA_ASYNC_RESILVER_DONE);
+
+		/*
+		 * Clear any deferred_resilver flags in the config.
+		 * If there are drives that need resilvering, kick
+		 * off an asynchronous request to start resilver.
+		 * dsl_scan_clear_deferred() may update the config
+		 * before the resilver can restart. In the event of
+		 * a crash during this period, the spa loading code
+		 * will find the drives that need to be resilvered
+		 * when the machine reboots and start the resilver then.
+		 */
+		boolean_t resilver_needed =
+		    dsl_scan_clear_deferred(spa->spa_root_vdev, tx);
+		if (resilver_needed) {
+			spa_history_log_internal(spa,
+			    "starting deferred resilver", tx,
+			    "errors=%llu", spa_get_errlog_size(spa));
+			spa_async_request(spa, SPA_ASYNC_RESILVER);
+		}
 	}
 
 	scn->scn_phys.scn_end_time = gethrestime_sec();
@@ -935,6 +998,7 @@
 		/* can't pause a scrub when there is no in-progress scrub */
 		spa->spa_scan_pass_scrub_pause = gethrestime_sec();
 		scn->scn_phys.scn_flags |= DSF_SCRUB_PAUSED;
+		scn->scn_phys_cached.scn_flags |= DSF_SCRUB_PAUSED;
 		dsl_scan_sync_state(scn, tx, SYNC_CACHED);
 		spa_event_notify(spa, NULL, NULL, ESC_ZFS_SCRUB_PAUSED);
 	} else {
@@ -949,6 +1013,7 @@
 			    gethrestime_sec() - spa->spa_scan_pass_scrub_pause;
 			spa->spa_scan_pass_scrub_pause = 0;
 			scn->scn_phys.scn_flags &= ~DSF_SCRUB_PAUSED;
+			scn->scn_phys_cached.scn_flags &= ~DSF_SCRUB_PAUSED;
 			dsl_scan_sync_state(scn, tx, SYNC_CACHED);
 		}
 	}
@@ -2335,6 +2400,20 @@
 	if (scn->scn_phys.scn_state != DSS_SCANNING)
 		return;
 
+	/*
+	 * This function is special because it is the only thing
+	 * that can add scan_io_t's to the vdev scan queues from
+	 * outside dsl_scan_sync(). For the most part this is ok
+	 * as long as it is called from within syncing context.
+	 * However, dsl_scan_sync() expects that no new sio's will
+	 * be added between when all the work for a scan is done
+	 * and the next txg when the scan is actually marked as
+	 * completed. This check ensures we do not issue new sio's
+	 * during this period.
+	 */
+	if (scn->scn_done_txg != 0)
+		return;
+
 	for (p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
 		if (ddp->ddp_phys_birth == 0 ||
 		    ddp->ddp_phys_birth > scn->scn_phys.scn_max_txg)
@@ -2986,6 +3065,26 @@
 }
 
 static boolean_t
+dsl_scan_check_deferred(vdev_t *vd)
+{
+	boolean_t need_resilver = B_FALSE;
+
+	for (int c = 0; c < vd->vdev_children; c++) {
+		need_resilver |=
+		    dsl_scan_check_deferred(vd->vdev_child[c]);
+	}
+
+	if (!vdev_is_concrete(vd) || vd->vdev_aux ||
+	    !vd->vdev_ops->vdev_op_leaf)
+		return (need_resilver);
+
+	if (!vd->vdev_resilver_deferred)
+		need_resilver = B_TRUE;
+
+	return (need_resilver);
+}
+
+static boolean_t
 dsl_scan_need_resilver(spa_t *spa, const dva_t *dva, size_t psize,
     uint64_t phys_birth)
 {
@@ -3032,6 +3131,13 @@
 	if (!vdev_dtl_need_resilver(vd, DVA_GET_OFFSET(dva), psize))
 		return (B_FALSE);
 
+	/*
+	 * Check that this top-level vdev has a device under it which
+	 * is resilvering and is not deferred.
+	 */
+	if (!dsl_scan_check_deferred(vd))
+		return (B_FALSE);
+
 	return (B_TRUE);
 }
 
@@ -3193,12 +3299,19 @@
 	int err = 0;
 	state_sync_type_t sync_type = SYNC_OPTIONAL;
 
+	if (spa->spa_resilver_deferred &&
+	    !spa_feature_is_active(dp->dp_spa, SPA_FEATURE_RESILVER_DEFER))
+		spa_feature_incr(spa, SPA_FEATURE_RESILVER_DEFER, tx);
+
 	/*
 	 * Check for scn_restart_txg before checking spa_load_state, so
 	 * that we can restart an old-style scan while the pool is being
-	 * imported (see dsl_scan_init).
+	 * imported (see dsl_scan_init). We also restart scans if there
+	 * is a deferred resilver and the user has manually disabled
+	 * deferred resilvers via the tunable.
 	 */
-	if (dsl_scan_restarting(scn, tx)) {
+	if (dsl_scan_restarting(scn, tx) ||
+	    (spa->spa_resilver_deferred && zfs_resilver_disable_defer)) {
 		pool_scan_func_t func = POOL_SCAN_SCRUB;
 		dsl_scan_done(scn, B_FALSE, tx);
 		if (vdev_resilver_needed(spa->spa_root_vdev, NULL, NULL))
@@ -3265,6 +3378,27 @@
 		return;
 
 	/*
+	 * zfs_scan_suspend_progress can be set to disable scan progress.
+	 * We don't want to spin the txg_sync thread, so we add a delay
+	 * here to simulate the time spent doing a scan. This is mostly
+	 * useful for testing and debugging.
+	 */
+	if (zfs_scan_suspend_progress) {
+		uint64_t scan_time_ns = gethrtime() - scn->scn_sync_start_time;
+		int mintime = (scn->scn_phys.scn_func == POOL_SCAN_RESILVER) ?
+		    zfs_resilver_min_time_ms : zfs_scrub_min_time_ms;
+
+		while (zfs_scan_suspend_progress &&
+		    !txg_sync_waiting(scn->scn_dp) &&
+		    !spa_shutting_down(scn->scn_dp->dp_spa) &&
+		    NSEC2MSEC(scan_time_ns) < mintime) {
+			delay(hz);
+			scan_time_ns = gethrtime() - scn->scn_sync_start_time;
+		}
+		return;
+	}
+
+	/*
 	 * It is possible to switch from unsorted to sorted at any time,
 	 * but afterwards the scan will remain sorted unless reloaded from
 	 * a checkpoint after a reboot.
@@ -3393,6 +3527,8 @@
 			    (longlong_t)tx->tx_txg);
 		}
 	} else if (scn->scn_is_sorted && scn->scn_bytes_pending != 0) {
+		ASSERT(scn->scn_clearing);
+
 		/* need to issue scrubbing IOs from per-vdev queues */
 		scn->scn_zio_root = zio_root(dp->dp_spa, NULL,
 		    NULL, ZIO_FLAG_CANFAIL);
--- a/usr/src/uts/common/fs/zfs/metaslab.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/zfs/metaslab.c	Mon Jun 03 18:18:53 2019 +0200
@@ -1024,7 +1024,7 @@
  */
 static boolean_t
 metaslab_group_allocatable(metaslab_group_t *mg, metaslab_group_t *rotor,
-    uint64_t psize, int allocator)
+    uint64_t psize, int allocator, int d)
 {
 	spa_t *spa = mg->mg_vd->vdev_spa;
 	metaslab_class_t *mc = mg->mg_class;
@@ -1068,6 +1068,13 @@
 		if (mg->mg_no_free_space)
 			return (B_FALSE);
 
+		/*
+		 * Relax allocation throttling for ditto blocks.  Due to
+		 * random imbalances in allocation it tends to push copies
+		 * to one vdev, that looks a bit better at the moment.
+		 */
+		qmax = qmax * (4 + d) / 4;
+
 		qdepth = zfs_refcount_count(
 		    &mg->mg_alloc_queue_depth[allocator]);
 
@@ -1089,7 +1096,7 @@
 		 */
 		for (mgp = mg->mg_next; mgp != rotor; mgp = mgp->mg_next) {
 			qmax = mgp->mg_cur_max_alloc_queue_depth[allocator];
-
+			qmax = qmax * (4 + d) / 4;
 			qdepth = zfs_refcount_count(
 			    &mgp->mg_alloc_queue_depth[allocator]);
 
@@ -3737,7 +3744,7 @@
 		 */
 		if (allocatable && !GANG_ALLOCATION(flags) && !try_hard) {
 			allocatable = metaslab_group_allocatable(mg, rotor,
-			    psize, allocator);
+			    psize, allocator, d);
 		}
 
 		if (!allocatable) {
--- a/usr/src/uts/common/fs/zfs/spa.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/zfs/spa.c	Mon Jun 03 18:18:53 2019 +0200
@@ -6103,9 +6103,14 @@
 	/*
 	 * Schedule the resilver to restart in the future. We do this to
 	 * ensure that dmu_sync-ed blocks have been stitched into the
-	 * respective datasets.
-	 */
-	dsl_resilver_restart(spa->spa_dsl_pool, dtl_max_txg);
+	 * respective datasets. We do not do this if resilvers have been
+	 * deferred.
+	 */
+	if (dsl_scan_resilvering(spa_get_dsl(spa)) &&
+	    spa_feature_is_enabled(spa, SPA_FEATURE_RESILVER_DEFER))
+		vdev_set_deferred_resilver(spa, newvd);
+	else
+		dsl_resilver_restart(spa->spa_dsl_pool, dtl_max_txg);
 
 	if (spa->spa_bootfs)
 		spa_event_notify(spa, newvd, NULL, ESC_ZFS_BOOTFS_VDEV_ATTACH);
@@ -6996,6 +7001,10 @@
 	if (func >= POOL_SCAN_FUNCS || func == POOL_SCAN_NONE)
 		return (SET_ERROR(ENOTSUP));
 
+	if (func == POOL_SCAN_RESILVER &&
+	    !spa_feature_is_enabled(spa, SPA_FEATURE_RESILVER_DEFER))
+		return (SET_ERROR(ENOTSUP));
+
 	/*
 	 * If a resilver was requested, but there is no DTL on a
 	 * writeable leaf device, we have nothing to do.
@@ -7087,6 +7096,7 @@
 spa_async_thread(void *arg)
 {
 	spa_t *spa = (spa_t *)arg;
+	dsl_pool_t *dp = spa->spa_dsl_pool;
 	int tasks;
 
 	ASSERT(spa->spa_sync_on);
@@ -7162,8 +7172,10 @@
 	/*
 	 * Kick off a resilver.
 	 */
-	if (tasks & SPA_ASYNC_RESILVER)
-		dsl_resilver_restart(spa->spa_dsl_pool, 0);
+	if (tasks & SPA_ASYNC_RESILVER &&
+	    (!dsl_scan_resilvering(dp) ||
+	    !spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_RESILVER_DEFER)))
+		dsl_resilver_restart(dp, 0);
 
 	if (tasks & SPA_ASYNC_INITIALIZE_RESTART) {
 		mutex_enter(&spa_namespace_lock);
--- a/usr/src/uts/common/fs/zfs/sys/spa_impl.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/zfs/sys/spa_impl.h	Mon Jun 03 18:18:53 2019 +0200
@@ -279,6 +279,13 @@
 	uint64_t	spa_scan_pass_scrub_spent_paused; /* total paused */
 	uint64_t	spa_scan_pass_exam;	/* examined bytes per pass */
 	uint64_t	spa_scan_pass_issued;	/* issued bytes per pass */
+
+	/*
+	 * We are in the middle of a resilver, and another resilver
+	 * is needed once this one completes. This is set iff any
+	 * vdev_resilver_deferred is set.
+	 */
+	boolean_t	spa_resilver_deferred;
 	kmutex_t	spa_async_lock;		/* protect async state */
 	kthread_t	*spa_async_thread;	/* thread doing async task */
 	int		spa_async_suspended;	/* async tasks suspended */
--- a/usr/src/uts/common/fs/zfs/sys/vdev.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/zfs/sys/vdev.h	Mon Jun 03 18:18:53 2019 +0200
@@ -149,6 +149,8 @@
 extern void vdev_state_dirty(vdev_t *vd);
 extern void vdev_state_clean(vdev_t *vd);
 
+extern void vdev_set_deferred_resilver(spa_t *spa, vdev_t *vd);
+
 typedef enum vdev_config_flag {
 	VDEV_CONFIG_SPARE = 1 << 0,
 	VDEV_CONFIG_L2CACHE = 1 << 1,
--- a/usr/src/uts/common/fs/zfs/sys/vdev_impl.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/zfs/sys/vdev_impl.h	Mon Jun 03 18:18:53 2019 +0200
@@ -348,6 +348,7 @@
 	boolean_t	vdev_cant_write; /* vdev is failing all writes	*/
 	boolean_t	vdev_isspare;	/* was a hot spare		*/
 	boolean_t	vdev_isl2cache;	/* was a l2cache device		*/
+	boolean_t	vdev_resilver_deferred;  /* resilver deferred */
 	vdev_queue_t	vdev_queue;	/* I/O deadline schedule queue	*/
 	vdev_cache_t	vdev_cache;	/* physical block cache		*/
 	spa_aux_vdev_t	*vdev_aux;	/* for l2cache and spares vdevs	*/
--- a/usr/src/uts/common/fs/zfs/sys/zfs_fuid.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/zfs/sys/zfs_fuid.h	Mon Jun 03 18:18:53 2019 +0200
@@ -21,6 +21,8 @@
 /*
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #ifndef	_SYS_FS_ZFS_FUID_H
@@ -70,8 +72,8 @@
  * Used for mapping ephemeral uid/gid during ACL setting to FUIDs
  */
 typedef struct zfs_fuid {
-	list_node_t 	z_next;
-	uint64_t 	z_id;		/* uid/gid being converted to fuid */
+	list_node_t	z_next;
+	uint64_t	z_id;		/* uid/gid being converted to fuid */
 	uint64_t	z_domidx;	/* index in AVL domain table */
 	uint64_t	z_logfuid;	/* index for domain in log */
 } zfs_fuid_t;
@@ -111,6 +113,7 @@
     uid_t *uid, uid_t *gid);
 extern zfs_fuid_info_t *zfs_fuid_info_alloc(void);
 extern void zfs_fuid_info_free(zfs_fuid_info_t *);
+extern boolean_t zfs_user_in_cred(zfsvfs_t *, uint64_t, cred_t *);
 extern boolean_t zfs_groupmember(zfsvfs_t *, uint64_t, cred_t *);
 void zfs_fuid_sync(zfsvfs_t *, dmu_tx_t *);
 extern int zfs_fuid_find_by_domain(zfsvfs_t *, const char *domain,
--- a/usr/src/uts/common/fs/zfs/vdev.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/zfs/vdev.c	Mon Jun 03 18:18:53 2019 +0200
@@ -759,6 +759,9 @@
 		(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_RESILVER_TXG,
 		    &vd->vdev_resilver_txg);
 
+		if (nvlist_exists(nv, ZPOOL_CONFIG_RESILVER_DEFER))
+			vdev_set_deferred_resilver(spa, vd);
+
 		/*
 		 * When importing a pool, we want to ignore the persistent fault
 		 * state, as the diagnosis made on another system may not be
@@ -1732,8 +1735,13 @@
 	 * since this would just restart the scrub we are already doing.
 	 */
 	if (vd->vdev_ops->vdev_op_leaf && !spa->spa_scrub_reopen &&
-	    vdev_resilver_needed(vd, NULL, NULL))
-		spa_async_request(spa, SPA_ASYNC_RESILVER);
+	    vdev_resilver_needed(vd, NULL, NULL)) {
+		if (dsl_scan_resilvering(spa->spa_dsl_pool) &&
+		    spa_feature_is_enabled(spa, SPA_FEATURE_RESILVER_DEFER))
+			vdev_set_deferred_resilver(spa, vd);
+		else
+			spa_async_request(spa, SPA_ASYNC_RESILVER);
+	}
 
 	return (0);
 }
@@ -2440,6 +2448,9 @@
 	if (vd->vdev_state < VDEV_STATE_DEGRADED)
 		return (B_FALSE);
 
+	if (vd->vdev_resilver_deferred)
+		return (B_FALSE);
+
 	if (vd->vdev_resilver_txg == 0 ||
 	    range_tree_is_empty(vd->vdev_dtl[DTL_MISSING]))
 		return (B_TRUE);
@@ -3473,8 +3484,14 @@
 		if (vd != rvd && vdev_writeable(vd->vdev_top))
 			vdev_state_dirty(vd->vdev_top);
 
-		if (vd->vdev_aux == NULL && !vdev_is_dead(vd))
-			spa_async_request(spa, SPA_ASYNC_RESILVER);
+		if (vd->vdev_aux == NULL && !vdev_is_dead(vd)) {
+			if (dsl_scan_resilvering(spa->spa_dsl_pool) &&
+			    spa_feature_is_enabled(spa,
+			    SPA_FEATURE_RESILVER_DEFER))
+				vdev_set_deferred_resilver(spa, vd);
+			else
+				spa_async_request(spa, SPA_ASYNC_RESILVER);
+		}
 
 		spa_event_notify(spa, vd, NULL, ESC_ZFS_VDEV_CLEAR);
 	}
@@ -3617,6 +3634,8 @@
 		vs->vs_fragmentation = (vd->vdev_mg != NULL) ?
 		    vd->vdev_mg->mg_fragmentation : 0;
 	}
+	if (vd->vdev_ops->vdev_op_leaf)
+		vs->vs_resilver_deferred = vd->vdev_resilver_deferred;
 
 	/*
 	 * If we're getting stats on the root vdev, aggregate the I/O counts
@@ -4330,3 +4349,18 @@
 		mutex_exit(&vq->vq_lock);
 	}
 }
+
+void
+vdev_set_deferred_resilver(spa_t *spa, vdev_t *vd)
+{
+	for (uint64_t i = 0; i < vd->vdev_children; i++)
+		vdev_set_deferred_resilver(spa, vd->vdev_child[i]);
+
+	if (!vd->vdev_ops->vdev_op_leaf || !vdev_writeable(vd) ||
+	    range_tree_is_empty(vd->vdev_dtl[DTL_MISSING])) {
+		return;
+	}
+
+	vd->vdev_resilver_deferred = B_TRUE;
+	spa->spa_resilver_deferred = B_TRUE;
+}
--- a/usr/src/uts/common/fs/zfs/vdev_indirect.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/zfs/vdev_indirect.c	Mon Jun 03 18:18:53 2019 +0200
@@ -1239,6 +1239,8 @@
 {
 	indirect_vsd_t *iv = zio->io_vsd;
 
+	ASSERT3U(zio->io_type, ==, ZIO_TYPE_READ);
+
 	for (indirect_split_t *is = list_head(&iv->iv_splits);
 	    is != NULL; is = list_next(&iv->iv_splits, is)) {
 		for (int i = 0; i < is->is_children; i++) {
@@ -1321,7 +1323,8 @@
 		    vdev_indirect_child_io_done, zio));
 	} else {
 		iv->iv_split_block = B_TRUE;
-		if (zio->io_flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)) {
+		if (zio->io_type == ZIO_TYPE_READ &&
+		    zio->io_flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)) {
 			/*
 			 * Read all copies.  Note that for simplicity,
 			 * we don't bother consulting the DTL in the
@@ -1330,13 +1333,17 @@
 			vdev_indirect_read_all(zio);
 		} else {
 			/*
-			 * Read one copy of each split segment, from the
-			 * top-level vdev.  Since we don't know the
-			 * checksum of each split individually, the child
-			 * zio can't ensure that we get the right data.
-			 * E.g. if it's a mirror, it will just read from a
-			 * random (healthy) leaf vdev.  We have to verify
-			 * the checksum in vdev_indirect_io_done().
+			 * If this is a read zio, we read one copy of each
+			 * split segment, from the top-level vdev.  Since
+			 * we don't know the checksum of each split
+			 * individually, the child zio can't ensure that
+			 * we get the right data. E.g. if it's a mirror,
+			 * it will just read from a random (healthy) leaf
+			 * vdev. We have to verify the checksum in
+			 * vdev_indirect_io_done().
+			 *
+			 * For write zios, the vdev code will ensure we write
+			 * to all children.
 			 */
 			for (indirect_split_t *is = list_head(&iv->iv_splits);
 			    is != NULL; is = list_next(&iv->iv_splits, is)) {
--- a/usr/src/uts/common/fs/zfs/vdev_label.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/zfs/vdev_label.c	Mon Jun 03 18:18:53 2019 +0200
@@ -377,6 +377,12 @@
 			fnvlist_add_uint64(nv, ZPOOL_CONFIG_VDEV_TOP_ZAP,
 			    vd->vdev_top_zap);
 		}
+
+		if (vd->vdev_resilver_deferred) {
+			ASSERT(vd->vdev_ops->vdev_op_leaf);
+			ASSERT(spa->spa_resilver_deferred);
+			fnvlist_add_boolean(nv, ZPOOL_CONFIG_RESILVER_DEFER);
+		}
 	}
 
 	if (getstats) {
--- a/usr/src/uts/common/fs/zfs/vdev_removal.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/zfs/vdev_removal.c	Mon Jun 03 18:18:53 2019 +0200
@@ -127,7 +127,7 @@
  * This is used by the test suite so that it can ensure that certain
  * actions happen while in the middle of a removal.
  */
-uint64_t zfs_remove_max_bytes_pause = UINT64_MAX;
+int zfs_removal_suspend_progress = 0;
 
 #define	VDEV_REMOVAL_ZAP_OBJS	"lzap"
 
@@ -1433,14 +1433,14 @@
 
 			/*
 			 * This delay will pause the removal around the point
-			 * specified by zfs_remove_max_bytes_pause. We do this
+			 * specified by zfs_removal_suspend_progress. We do this
 			 * solely from the test suite or during debugging.
 			 */
 			uint64_t bytes_copied =
 			    spa->spa_removing_phys.sr_copied;
 			for (int i = 0; i < TXG_SIZE; i++)
 				bytes_copied += svr->svr_bytes_done[i];
-			while (zfs_remove_max_bytes_pause <= bytes_copied &&
+			while (zfs_removal_suspend_progress &&
 			    !svr->svr_thread_exit)
 				delay(hz);
 
--- a/usr/src/uts/common/fs/zfs/zfs_acl.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/zfs/zfs_acl.c	Mon Jun 03 18:18:53 2019 +0200
@@ -2106,18 +2106,13 @@
 	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
 	zfs_acl_t	*aclp;
 	int		error;
-	uid_t		uid = crgetuid(cr);
-	uint64_t	who;
+	uint64_t	who;		/* FUID from the ACE */
 	uint16_t	type, iflags;
 	uint16_t	entry_type;
 	uint32_t	access_mask;
 	uint32_t	deny_mask = 0;
 	zfs_ace_hdr_t	*acep = NULL;
-	boolean_t	checkit;
-	uid_t		gowner;
-	uid_t		fowner;
-
-	zfs_fuid_map_ids(zp, cr, &fowner, &gowner);
+	boolean_t	checkit;	/* ACE ID matches */
 
 	mutex_enter(&zp->z_acl_lock);
 
@@ -2150,11 +2145,13 @@
 
 		switch (entry_type) {
 		case ACE_OWNER:
-			if (uid == fowner)
-				checkit = B_TRUE;
+			who = zp->z_uid;
+			/*FALLTHROUGH*/
+		case 0:	/* USER Entry */
+			checkit = zfs_user_in_cred(zfsvfs, who, cr);
 			break;
 		case OWNING_GROUP:
-			who = gowner;
+			who = zp->z_gid;
 			/*FALLTHROUGH*/
 		case ACE_IDENTIFIER_GROUP:
 			checkit = zfs_groupmember(zfsvfs, who, cr);
@@ -2163,21 +2160,13 @@
 			checkit = B_TRUE;
 			break;
 
-		/* USER Entry */
 		default:
-			if (entry_type == 0) {
-				uid_t newid;
-
-				newid = zfs_fuid_map_id(zfsvfs, who, cr,
-				    ZFS_ACE_USER);
-				if (newid != IDMAP_WK_CREATOR_OWNER_UID &&
-				    uid == newid)
-					checkit = B_TRUE;
-				break;
-			} else {
-				mutex_exit(&zp->z_acl_lock);
-				return (SET_ERROR(EIO));
-			}
+			/*
+			 * The zfs_acl_valid_ace_type check above
+			 * should make this case impossible.
+			 */
+			mutex_exit(&zp->z_acl_lock);
+			return (SET_ERROR(EIO));
 		}
 
 		if (checkit) {
--- a/usr/src/uts/common/fs/zfs/zfs_fuid.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/zfs/zfs_fuid.c	Mon Jun 03 18:18:53 2019 +0200
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include <sys/zfs_context.h>
@@ -492,7 +493,7 @@
 	uint64_t	idx;
 	ksid_t		*ksid;
 	uint32_t	rid;
-	char 		*kdomain;
+	char		*kdomain;
 	const char	*domain;
 	uid_t		id;
 
@@ -685,6 +686,57 @@
 }
 
 /*
+ * Check to see if user ID is in the list of SIDs in CR.
+ */
+boolean_t
+zfs_user_in_cred(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
+{
+	ksid_t		*ksid = crgetsid(cr, KSID_USER);
+	ksidlist_t	*ksidlist = crgetsidlist(cr);
+	uid_t		uid;
+
+	/* Check for match with cred->cr_uid */
+	uid = zfs_fuid_map_id(zfsvfs, id, cr, ZFS_ACE_USER);
+	if (uid != IDMAP_WK_CREATOR_OWNER_UID &&
+	    uid == crgetuid(cr))
+		return (B_TRUE);
+
+	/* Check for any match in the ksidlist */
+	if (ksid && ksidlist) {
+		int		i;
+		ksid_t		*ksid_vec;
+		uint32_t	idx = FUID_INDEX(id);
+		uint32_t	rid = FUID_RID(id);
+		const char	*domain;
+
+		if (idx == 0) {
+			/*
+			 * The ID passed in has idx zero, which means
+			 * it's just a Unix UID.  That can never match
+			 * anything in ksid_vec[] because those all
+			 * have ksid->ks_id set to a Group ID.
+			 */
+			return (B_FALSE);
+		}
+
+		domain = zfs_fuid_find_by_idx(zfsvfs, idx);
+		ASSERT(domain != NULL);
+
+		if (strcmp(domain, IDMAP_WK_CREATOR_SID_AUTHORITY) == 0)
+			return (B_FALSE);
+
+		ksid_vec = ksidlist->ksl_sids;
+		for (i = 0; i != ksidlist->ksl_nsid; i++) {
+			if ((strcmp(domain,
+			    ksid_vec[i].ks_domain->kd_name) == 0) &&
+			    rid == ksid_vec[i].ks_rid)
+				return (B_TRUE);
+		}
+	}
+	return (B_FALSE);
+}
+
+/*
  * Check to see if id is a groupmember.  If cred
  * has ksid info then sidlist is checked first
  * and if still not found then POSIX groups are checked
@@ -699,7 +751,7 @@
 	uid_t		gid;
 
 	if (ksid && ksidlist) {
-		int 		i;
+		int		i;
 		ksid_t		*ksid_groups;
 		uint32_t	idx = FUID_INDEX(id);
 		uint32_t	rid = FUID_RID(id);
--- a/usr/src/uts/common/fs/zfs/zil.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/fs/zfs/zil.c	Mon Jun 03 18:18:53 2019 +0200
@@ -1252,7 +1252,7 @@
 		 * root zios). This is required because of how we can
 		 * defer the DKIOCFLUSHWRITECACHE commands for each lwb.
 		 *
-		 * When the DKIOCFLUSHWRITECACHE commands are defered,
+		 * When the DKIOCFLUSHWRITECACHE commands are deferred,
 		 * the previous lwb will rely on this lwb to flush the
 		 * vdevs written to by that previous lwb. Thus, we need
 		 * to ensure this lwb doesn't issue the flush until
--- a/usr/src/uts/common/idmap/idmap_kapi.c	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/idmap/idmap_kapi.c	Mon Jun 03 18:18:53 2019 +0200
@@ -22,6 +22,8 @@
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright 2018 Nexenta Systems, Inc.
  */
 
 /*
@@ -76,8 +78,8 @@
 /* Batch mapping handle structure */
 struct idmap_get_handle {
 	struct idmap_zone_specific *zs;
-	int 		mapping_num;
-	int 		mapping_size;
+	int		mapping_num;
+	int		mapping_size;
 	idmap_mapping	*mapping;
 	idmap_get_res	*result;
 };
@@ -88,7 +90,7 @@
 	zoneid_t	zone_id;
 	kmutex_t	zone_mutex;
 	idmap_cache_t	cache;
-	door_handle_t 	door_handle;
+	door_handle_t	door_handle;
 	int		door_valid;
 	int		door_retried;
 	uint32_t	message_id;
@@ -195,7 +197,7 @@
 static int
 kidmap_call_door(idmap_zone_specific_t *zs, door_arg_t *arg)
 {
-	door_handle_t 	dh;
+	door_handle_t	dh;
 	door_info_t	di;
 	int		status = 0;
 	int		num_retries = 5;
@@ -819,7 +821,7 @@
  * Create handle to get SID to UID/GID mapping entries
  *
  * Input:
- * 	none
+ *	none
  * Return:
  *	get_handle
  *
@@ -898,7 +900,7 @@
     uint32_t rid, uid_t *uid, idmap_stat *stat)
 {
 	idmap_mapping	*mapping;
-	idmap_get_res 	*result;
+	idmap_get_res	*result;
 
 	if (get_handle == NULL || sid_prefix == NULL ||
 	    uid == NULL || stat == NULL)
@@ -959,7 +961,7 @@
     uint32_t rid, uid_t *gid, idmap_stat *stat)
 {
 	idmap_mapping	*mapping;
-	idmap_get_res 	*result;
+	idmap_get_res	*result;
 
 	if (get_handle == NULL || sid_prefix == NULL ||
 	    gid == NULL || stat == NULL)
@@ -1022,7 +1024,7 @@
     uint32_t rid, uid_t *pid, int *is_user, idmap_stat *stat)
 {
 	idmap_mapping	*mapping;
-	idmap_get_res 	*result;
+	idmap_get_res	*result;
 
 	if (get_handle == NULL || sid_prefix == NULL || pid == NULL ||
 	    is_user == NULL || stat == NULL)
@@ -1081,7 +1083,7 @@
     const char **sid_prefix, uint32_t *rid, idmap_stat *stat)
 {
 	idmap_mapping	*mapping;
-	idmap_get_res 	*result;
+	idmap_get_res	*result;
 
 	if (get_handle == NULL || sid_prefix == NULL ||
 	    rid == NULL || stat == NULL)
@@ -1136,7 +1138,7 @@
     const char **sid_prefix, uint32_t *rid, idmap_stat *stat)
 {
 	idmap_mapping	*mapping;
-	idmap_get_res 	*result;
+	idmap_get_res	*result;
 
 	if (get_handle == NULL || sid_prefix == NULL ||
 	    rid == NULL || stat == NULL)
@@ -1307,6 +1309,12 @@
 				*result->sid_prefix = sid_prefix;
 				*result->rid = id->idmap_id_u.sid.rid;
 			}
+			if (*result->stat == IDMAP_ERR_NOTFOUND &&
+			    sid_prefix != NULL) {
+				/* IDMAP generated a local SID. Use it. */
+				*result->stat = IDMAP_SUCCESS;
+			}
+
 			if (*result->stat == IDMAP_SUCCESS &&
 			    request->id1.idtype == IDMAP_UID)
 				kidmap_cache_add_sid2uid(
@@ -1401,11 +1409,11 @@
 	char		*inbuf_ptr = NULL;
 	size_t		inbuf_size = 4096;
 	char		*outbuf_ptr = NULL;
-	size_t 		outbuf_size = 4096;
+	size_t		outbuf_size = 4096;
 	size_t		size;
 	int		status = 0;
 	door_arg_t	params;
-	int 		retry = 0;
+	int		retry = 0;
 	struct rpc_msg	call_msg;
 
 	params.rbuf = NULL;
--- a/usr/src/uts/common/smbsrv/smb_idmap.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/smbsrv/smb_idmap.h	Mon Jun 03 18:18:53 2019 +0200
@@ -22,7 +22,7 @@
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #ifndef _SMB_IDMAP_H
@@ -59,6 +59,7 @@
 
 #define	SMB_IDMAP_SID2ID	0x0001
 #define	SMB_IDMAP_ID2SID	0x0002
+#define	SMB_IDMAP_SKIP_ERRS	0x0004
 
 /*
  * smb_idmap_t
@@ -79,8 +80,8 @@
 	uint16_t		sib_nmap;
 	uint32_t		sib_flags;
 	uint32_t		sib_size;
-	smb_idmap_t 		*sib_maps;
-	idmap_get_handle_t 	*sib_idmaph;
+	smb_idmap_t		*sib_maps;
+	idmap_get_handle_t	*sib_idmaph;
 } smb_idmap_batch_t;
 
 idmap_stat smb_idmap_getsid(uid_t, int, smb_sid_t **);
--- a/usr/src/uts/common/smbsrv/smb_ktypes.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/smbsrv/smb_ktypes.h	Mon Jun 03 18:18:53 2019 +0200
@@ -792,8 +792,6 @@
  */
 #define	SMB_SESSION_INACTIVITY_TIMEOUT		(15 * 60)
 
-#define	SMB_SESSION_OFILE_MAX			(16 * 1024)
-
 /* SMB1 signing */
 struct smb_sign {
 	unsigned int flags;
--- a/usr/src/uts/common/sys/fs/zfs.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/sys/fs/zfs.h	Mon Jun 03 18:18:53 2019 +0200
@@ -597,6 +597,7 @@
 #define	ZPOOL_CONFIG_VDEV_TOP_ZAP	"com.delphix:vdev_zap_top"
 #define	ZPOOL_CONFIG_VDEV_LEAF_ZAP	"com.delphix:vdev_zap_leaf"
 #define	ZPOOL_CONFIG_HAS_PER_VDEV_ZAPS	"com.delphix:has_per_vdev_zaps"
+#define	ZPOOL_CONFIG_RESILVER_DEFER	"com.datto:resilver_defer"
 #define	ZPOOL_CONFIG_CACHEFILE		"cachefile"	/* not stored on disk */
 #define	ZPOOL_CONFIG_MMP_STATE		"mmp_state"	/* not stored on disk */
 #define	ZPOOL_CONFIG_MMP_TXG		"mmp_txg"	/* not stored on disk */
@@ -895,6 +896,7 @@
 	uint64_t	vs_initialize_state;	/* vdev_initialzing_state_t */
 	uint64_t	vs_initialize_action_time; /* time_t */
 	uint64_t	vs_checkpoint_space;    /* checkpoint-consumed space */
+	uint64_t	vs_resilver_deferred;	/* resilver deferred	*/
 } vdev_stat_t;
 
 /*
--- a/usr/src/uts/common/sys/tsol/tndb.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/sys/tsol/tndb.h	Mon Jun 03 18:18:53 2019 +0200
@@ -248,6 +248,7 @@
 } tsol_zcent_t;
 #define	TSOL_MLP_END(mlp)	((mlp)->mlp_ipp == 0 && (mlp)->mlp_port == 0)
 
+#if (defined(_KERNEL) || defined(_KMEMUSER))
 typedef struct tsol_tpc {
 	kmutex_t		tpc_lock;	/* lock for structure */
 	uint_t			tpc_refcnt;	/* reference count */
@@ -265,6 +266,7 @@
 	char			rhc_isbcast;	/* broadcast address */
 	char			rhc_local;	/* loopback or local interace */
 } tsol_tnrhc_t;
+#endif	/* _KERNEL || _KMEMUSER */
 
 /* Size of remote host hash tables in kernel */
 #define	TNRHC_SIZE 256
@@ -361,11 +363,13 @@
 	in_addr_t		ip_address;
 } tsol_address_t;
 
+#if (defined(_KERNEL) || defined(_KMEMUSER))
 /* This is shared between tcache and mdb */
 typedef struct tnrhc_hash_s {
 	tsol_tnrhc_t *tnrh_list;
 	kmutex_t tnrh_lock;
 } tnrhc_hash_t;
+#endif	/* _KERNEL || _KMEMUSER */
 
 #ifdef _KERNEL
 typedef enum {
--- a/usr/src/uts/common/sys/zone.h	Sun Jun 02 09:38:09 2019 +0000
+++ b/usr/src/uts/common/sys/zone.h	Mon Jun 03 18:18:53 2019 +0200
@@ -21,7 +21,7 @@
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2018 Joyent, Inc.
- * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2019 Nexenta Systems, Inc. All rights reserved.
  * Copyright 2014 Igor Kozhukhov <ikozhukhov@gmail.com>.
  * Copyright 2018, Joyent, Inc.
  */
@@ -30,20 +30,29 @@
 #define	_SYS_ZONE_H
 
 #include <sys/types.h>
+#include <sys/param.h>
+#include <sys/tsol/label.h>
+#include <sys/uadmin.h>
+#include <netinet/in.h>
+
+#ifdef _KERNEL
+/*
+ * Many includes are kernel-only to reduce namespace pollution of
+ * userland applications.
+ */
 #include <sys/mutex.h>
-#include <sys/param.h>
 #include <sys/rctl.h>
 #include <sys/ipc_rctl.h>
 #include <sys/pset.h>
-#include <sys/tsol/label.h>
 #include <sys/cred.h>
 #include <sys/netstack.h>
-#include <sys/uadmin.h>
 #include <sys/ksynch.h>
 #include <sys/socket_impl.h>
 #include <sys/secflags.h>
-#include <netinet/in.h>
 #include <sys/cpu_uarray.h>
+#include <sys/list.h>
+#include <sys/loadavg.h>
+#endif	/* _KERNEL */
 
 #ifdef	__cplusplus
 extern "C" {
@@ -342,13 +351,6 @@
 
 #ifdef _KERNEL
 
-/*
- * We need to protect the definition of 'list_t' from userland applications and
- * libraries which may be defining ther own versions.
- */
-#include <sys/list.h>
-#include <sys/loadavg.h>
-
 #define	GLOBAL_ZONEUNIQID	0	/* uniqid of the global zone */
 
 /*