--- old/usr/src/uts/common/os/dumpsubr.c	Mon Aug  5 17:33:07 2019
+++ new/usr/src/uts/common/os/dumpsubr.c	Mon Aug  5 17:33:07 2019
@@ -22,6 +22,7 @@
 /*
  * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2016 Joyent, Inc.
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
  */
 
 #include <sys/types.h>
@@ -71,28 +72,15 @@
 #include <vm/seg_kmem.h>
 #include <sys/clock_impl.h>
 #include <sys/hold_page.h>
+#include <sys/cpu.h>
 
-#include <bzip2/bzlib.h>
+#include <sys/uuid.h>
 
 /*
- * Crash dump time is dominated by disk write time.  To reduce this,
- * the stronger compression method bzip2 is applied to reduce the dump
- * size and hence reduce I/O time.  However, bzip2 is much more
- * computationally expensive than the existing lzjb algorithm, so to
- * avoid increasing compression time, CPUs that are otherwise idle
- * during panic are employed to parallelize the compression task.
- * Many helper CPUs are needed to prevent bzip2 from being a
- * bottleneck, and on systems with too few CPUs, the lzjb algorithm is
- * parallelized instead. Lastly, I/O and compression are performed by
- * different CPUs, and are hence overlapped in time, unlike the older
- * serial code.
- *
- * Another important consideration is the speed of the dump
- * device. Faster disks need less CPUs in order to benefit from
- * parallel lzjb versus parallel bzip2. Therefore, the CPU count
- * threshold for switching from parallel lzjb to paralled bzip2 is
- * elevated for faster disks. The dump device speed is adduced from
- * the setting for dumpbuf.iosize, see dump_update_clevel.
+ * Parallel Dump:
+ * CPUs that are otherwise idle during panic are employed to parallelize
+ * the compression task. I/O and compression are performed by different
+ * CPUs, and are hence overlapped in time, unlike the older serial code.
  */
 
 /*
@@ -108,34 +96,22 @@
 int		dump_timeleft;		/* portion of dump_timeout remaining */
 int		dump_ioerr;		/* dump i/o error */
 int		dump_check_used;	/* enable check for used pages */
-char	    *dump_stack_scratch; /* scratch area for saving stack summary */
+char		*dump_stack_scratch; /* scratch area for saving stack summary */
 
 /*
- * Tunables for dump compression and parallelism. These can be set via
- * /etc/system.
+ * Tunables for dump compression and parallelism.
+ * These can be set via /etc/system.
  *
- * dump_ncpu_low	number of helpers for parallel lzjb
- *	This is also the minimum configuration.
+ * dump_ncpu_low:
+ * This is the minimum configuration for parallel lzjb.
+ * A special value of 0 means that parallel dump will not be used.
  *
- * dump_bzip2_level	bzip2 compression level: 1-9
- *	Higher numbers give greater compression, but take more memory
- *	and time. Memory used per helper is ~(dump_bzip2_level * 1MB).
- *
- * dump_plat_mincpu	the cross-over limit for using bzip2 (per platform):
- *	if dump_plat_mincpu == 0, then always do single threaded dump
- *	if ncpu >= dump_plat_mincpu then try to use bzip2
- *
- * dump_metrics_on	if set, metrics are collected in the kernel, passed
- *	to savecore via the dump file, and recorded by savecore in
- *	METRICS.txt.
+ * dump_metrics_on:
+ * If set, metrics are collected in the kernel, passed to savecore
+ * via the dump file, and recorded by savecore in METRICS.txt.
  */
 uint_t dump_ncpu_low = 4;	/* minimum config for parallel lzjb */
-uint_t dump_bzip2_level = 1;	/* bzip2 level (1-9) */
 
-/* Use dump_plat_mincpu_default unless this variable is set by /etc/system */
-#define	MINCPU_NOT_SET	((uint_t)-1)
-uint_t dump_plat_mincpu = MINCPU_NOT_SET;
-
 /* tunables for pre-reserved heap */
 uint_t dump_kmem_permap = 1024;
 uint_t dump_kmem_pages = 8;
@@ -145,7 +121,7 @@
 #define	NCMAP_PER_HELPER	4
 
 /* minimum number of helpers configured */
-#define	MINHELPERS	(dump_ncpu_low)
+#define	MINHELPERS	(MAX(dump_ncpu_low, 1))
 #define	MINCBUFS	(MINHELPERS * NCBUF_PER_HELPER)
 
 /*
@@ -260,7 +236,7 @@
 	int off;			/* byte offset to first pfn */
 };
 
-static char dump_osimage_uuid[36 + 1];
+static char dump_osimage_uuid[UUID_PRINTABLE_STRING_LENGTH];
 
 #define	isdigit(ch)	((ch) >= '0' && (ch) <= '9')
 #define	isxdigit(ch)	(isdigit(ch) || ((ch) >= 'a' && (ch) <= 'f') || \
@@ -380,7 +356,6 @@
 	size_t used;			/* counts input consumed */
 	char *page;			/* buffer for page copy */
 	char *lzbuf;			/* lzjb output */
-	bz_stream bzstream;		/* bzip2 state */
 } helper_t;
 
 #define	MAINHELPER	(-1)		/* helper is also the main task */
@@ -391,7 +366,6 @@
  * configuration vars for dumpsys
  */
 typedef struct dumpcfg {
-	int	threshold;	/* ncpu threshold for bzip2 */
 	int	nhelper;	/* number of helpers */
 	int	nhelper_used;	/* actual number of helpers used */
 	int	ncmap;		/* number VA pages for compression */
@@ -438,6 +412,14 @@
 dumpbuf_t dumpbuf;		/* I/O buffer */
 
 /*
+ * DUMP_HELPER_MAX_WAIT
+ * For parallel dump, defines maximum time main task thread will wait
+ * for at least one helper to register in dumpcfg.helpermap, before
+ * assuming there are no helpers and falling back to serial mode.
+ */
+#define	DUMP_HELPER_MAX_WAIT	1000	/* millisec */
+
+/*
  * The dump I/O buffer must be at least one page, at most xfer_size
  * bytes, and should scale with physmem in between.  The transfer size
  * passed in will either represent a global default (maxphys) or the
@@ -489,8 +471,11 @@
 
 /*
  * dump_update_clevel is called when dumpadm configures the dump device.
- * 	Calculate number of helpers and buffers.
- * 	Allocate the minimum configuration for now.
+ *	Determine the compression level / type
+ *	- DUMP_CLEVEL_SERIAL is single threaded lzjb
+ *	- DUMP_CLEVEL_LZJB   is parallel lzjb
+ *	Calculate number of helpers and buffers.
+ *	Allocate the minimum configuration for now.
  *
  * When the dump file is configured we reserve a minimum amount of
  * memory for use at crash time. But we reserve VA for all the memory
@@ -501,33 +486,6 @@
  *
  * Live dump (savecore -L) always uses the minimum config.
  *
- * clevel 0 is single threaded lzjb
- * clevel 1 is parallel lzjb
- * clevel 2 is parallel bzip2
- *
- * The ncpu threshold is selected with dump_plat_mincpu.
- * On OPL, set_platform_defaults() overrides the sun4u setting.
- * The actual values are defined via DUMP_PLAT_*_MINCPU macros.
- *
- * Architecture		Threshold	Algorithm
- * sun4u       		<  51		parallel lzjb
- * sun4u       		>= 51		parallel bzip2(*)
- * sun4u OPL   		<  8		parallel lzjb
- * sun4u OPL   		>= 8		parallel bzip2(*)
- * sun4v       		<  128		parallel lzjb
- * sun4v       		>= 128		parallel bzip2(*)
- * x86			< 11		parallel lzjb
- * x86			>= 11		parallel bzip2(*)
- * 32-bit      		N/A		single-threaded lzjb
- *
- * (*) bzip2 is only chosen if there is sufficient available
- * memory for buffers at dump time. See dumpsys_get_maxmem().
- *
- * Faster dump devices have larger I/O buffers. The threshold value is
- * increased according to the size of the dump I/O buffer, because
- * parallel lzjb performs better with faster disks. For buffers >= 1MB
- * the threshold is 3X; for buffers >= 256K threshold is 2X.
- *
  * For parallel dumps, the number of helpers is ncpu-1. The CPU
  * running panic runs the main task. For single-threaded dumps, the
  * panic CPU does lzjb compression (it is tagged as MAINHELPER.)
@@ -543,7 +501,6 @@
 dump_update_clevel()
 {
 	int tag;
-	size_t bz2size;
 	helper_t *hp, *hpend;
 	cbuf_t *cp, *cpend;
 	dumpcfg_t *old = &dumpcfg;
@@ -596,31 +553,14 @@
 	if (new->nhelper > DUMP_MAX_NHELPER)
 		new->nhelper = DUMP_MAX_NHELPER;
 
-	/* use platform default, unless /etc/system overrides */
-	if (dump_plat_mincpu == MINCPU_NOT_SET)
-		dump_plat_mincpu = dump_plat_mincpu_default;
-
-	/* increase threshold for faster disks */
-	new->threshold = dump_plat_mincpu;
-	if (dumpbuf.iosize >= DUMP_1MB)
-		new->threshold *= 3;
-	else if (dumpbuf.iosize >= (256 * DUMP_1KB))
-		new->threshold *= 2;
-
-	/* figure compression level based upon the computed threshold. */
-	if (dump_plat_mincpu == 0 || new->nhelper < 2) {
-		new->clevel = 0;
+	/* If dump_ncpu_low is 0 or greater than ncpus, do serial dump */
+	if (dump_ncpu_low == 0 || dump_ncpu_low > ncpus || new->nhelper < 2) {
+		new->clevel = DUMP_CLEVEL_SERIAL;
 		new->nhelper = 1;
-	} else if ((new->nhelper + 1) >= new->threshold) {
-		new->clevel = DUMP_CLEVEL_BZIP2;
-	} else {
-		new->clevel = DUMP_CLEVEL_LZJB;
-	}
-
-	if (new->clevel == 0) {
 		new->ncbuf = 1;
 		new->ncmap = 1;
 	} else {
+		new->clevel = DUMP_CLEVEL_LZJB;
 		new->ncbuf = NCBUF_PER_HELPER * new->nhelper;
 		new->ncmap = NCMAP_PER_HELPER * new->nhelper;
 	}
@@ -629,7 +569,6 @@
 	 * Allocate new data structures and buffers for MINHELPERS,
 	 * and also figure the max desired size.
 	 */
-	bz2size = BZ2_bzCompressInitSize(dump_bzip2_level);
 	new->maxsize = 0;
 	new->maxvmsize = 0;
 	new->maxvm = NULL;
@@ -641,13 +580,9 @@
 		if (hp < &new->helper[MINHELPERS]) {
 			hp->lzbuf = kmem_alloc(PAGESIZE, KM_SLEEP);
 			hp->page = kmem_alloc(PAGESIZE, KM_SLEEP);
-		} else if (new->clevel < DUMP_CLEVEL_BZIP2) {
+		} else  {
 			new->maxsize += 2 * PAGESIZE;
-		} else {
-			new->maxsize += PAGESIZE;
 		}
-		if (new->clevel >= DUMP_CLEVEL_BZIP2)
-			new->maxsize += bz2size;
 	}
 
 	new->cbuf = kmem_zalloc(new->ncbuf * sizeof (cbuf_t), KM_SLEEP);
@@ -800,31 +735,6 @@
 }
 
 /*
- * dumpbzalloc and dumpbzfree are callbacks from the bzip2 library.
- * dumpsys_get_maxmem() uses them for BZ2_bzCompressInit().
- */
-static void *
-dumpbzalloc(void *opaque, int items, int size)
-{
-	size_t *sz;
-	char *ret;
-
-	ASSERT(opaque != NULL);
-	sz = opaque;
-	ret = dumpcfg.maxvm + *sz;
-	*sz += items * size;
-	*sz = P2ROUNDUP(*sz, BZ2_BZALLOC_ALIGN);
-	ASSERT(*sz <= dumpcfg.maxvmsize);
-	return (ret);
-}
-
-/*ARGSUSED*/
-static void
-dumpbzfree(void *opaque, void *addr)
-{
-}
-
-/*
  * Perform additional checks on the page to see if we can really use
  * it. The kernel (kas) pages are always set in the bitmap. However,
  * boot memory pages (prom_ppages or P_BOOTPAGES) are not in the
@@ -863,9 +773,7 @@
 
 /*
  * dumpsys_get_maxmem() is called during panic. Find unused ranges
- * and use them for buffers. If we find enough memory switch to
- * parallel bzip2, otherwise use parallel lzjb.
- *
+ * and use them for buffers.
  * It searches the dump bitmap in 2 passes. The first time it looks
  * for CBUF_MAPSIZE ranges. On the second pass it uses small pages.
  */
@@ -876,19 +784,18 @@
 	cbuf_t *endcp = &cfg->cbuf[cfg->ncbuf];
 	helper_t *endhp = &cfg->helper[cfg->nhelper];
 	pgcnt_t bitnum, end;
-	size_t sz, endsz, bz2size;
+	size_t sz, endsz;
 	pfn_t pfn, off;
 	cbuf_t *cp;
-	helper_t *hp, *ohp;
+	helper_t *hp;
 	dumpmlw_t mlw;
 	int k;
 
 	/*
-	 * Setting dump_plat_mincpu to 0 at any time forces a serial
-	 * dump.
+	 * Setting dump_ncpu_low to 0 forces a single threaded dump.
 	 */
-	if (dump_plat_mincpu == 0) {
-		cfg->clevel = 0;
+	if (dump_ncpu_low == 0) {
+		cfg->clevel = DUMP_CLEVEL_SERIAL;
 		return;
 	}
 
@@ -897,10 +804,8 @@
 	 * dumping all memory, then none is spare. If doing a serial
 	 * dump, then already have buffers.
 	 */
-	if (cfg->maxsize == 0 || cfg->clevel < DUMP_CLEVEL_LZJB ||
+	if (cfg->maxsize == 0 || cfg->clevel == DUMP_CLEVEL_SERIAL ||
 	    (dump_conflags & DUMP_ALL) != 0) {
-		if (cfg->clevel > DUMP_CLEVEL_LZJB)
-			cfg->clevel = DUMP_CLEVEL_LZJB;
 		return;
 	}
 
@@ -984,12 +889,6 @@
 		}
 	}
 
-	/* Fall back to lzjb if we did not get enough memory for bzip2. */
-	endsz = (cfg->maxsize * cfg->threshold) / cfg->nhelper;
-	if (sz < endsz) {
-		cfg->clevel = DUMP_CLEVEL_LZJB;
-	}
-
 	/* Allocate memory for as many helpers as we can. */
 foundmax:
 
@@ -997,42 +896,21 @@
 	endsz = sz;
 	sz = 0;
 
-	/* Set the size for bzip2 state. Only bzip2 needs it. */
-	bz2size = BZ2_bzCompressInitSize(dump_bzip2_level);
-
 	/* Skip the preallocate output buffers. */
 	cp = &cfg->cbuf[MINCBUFS];
 
-	/* Use this to move memory up from the preallocated helpers. */
-	ohp = cfg->helper;
-
 	/* Loop over all helpers and allocate memory. */
 	for (hp = cfg->helper; hp < endhp; hp++) {
 
 		/* Skip preallocated helpers by checking hp->page. */
 		if (hp->page == NULL) {
-			if (cfg->clevel <= DUMP_CLEVEL_LZJB) {
-				/* lzjb needs 2 1-page buffers */
-				if ((sz + (2 * PAGESIZE)) > endsz)
-					break;
-				hp->page = cfg->maxvm + sz;
-				sz += PAGESIZE;
-				hp->lzbuf = cfg->maxvm + sz;
-				sz += PAGESIZE;
-
-			} else if (ohp->lzbuf != NULL) {
-				/* re-use the preallocted lzjb page for bzip2 */
-				hp->page = ohp->lzbuf;
-				ohp->lzbuf = NULL;
-				++ohp;
-
-			} else {
-				/* bzip2 needs a 1-page buffer */
-				if ((sz + PAGESIZE) > endsz)
-					break;
-				hp->page = cfg->maxvm + sz;
-				sz += PAGESIZE;
-			}
+			/* lzjb needs 2 1-page buffers */
+			if ((sz + (2 * PAGESIZE)) > endsz)
+				break;
+			hp->page = cfg->maxvm + sz;
+			sz += PAGESIZE;
+			hp->lzbuf = cfg->maxvm + sz;
+			sz += PAGESIZE;
 		}
 
 		/*
@@ -1048,25 +926,6 @@
 			sz += CBUF_SIZE;
 			++cp;
 		}
-
-		/*
-		 * bzip2 needs compression state. Use the dumpbzalloc
-		 * and dumpbzfree callbacks to allocate the memory.
-		 * bzip2 does allocation only at init time.
-		 */
-		if (cfg->clevel >= DUMP_CLEVEL_BZIP2) {
-			if ((sz + bz2size) > endsz) {
-				hp->page = NULL;
-				break;
-			} else {
-				hp->bzstream.opaque = &sz;
-				hp->bzstream.bzalloc = dumpbzalloc;
-				hp->bzstream.bzfree = dumpbzfree;
-				(void) BZ2_bzCompressInit(&hp->bzstream,
-				    dump_bzip2_level, 0, 0);
-				hp->bzstream.opaque = NULL;
-			}
-		}
 	}
 
 	/* Finish allocating output buffers */
@@ -1910,8 +1769,7 @@
 			 * return the buffer to the main task.
 			 */
 			if (panicstr && hp->helper != MAINHELPER)
-				hat_flush_range(kas.a_hat,
-				    hp->cpin->buf, hp->cpin->size);
+				hat_flush();
 			dumpsys_errmsg(hp, NULL);
 			CQ_PUT(mainq, hp->cpin, CBUF_USEDMAP);
 			hp->cpin = NULL;
@@ -1922,136 +1780,6 @@
 }
 
 /*
- * Compress size bytes starting at buf with bzip2
- * mode:
- *	BZ_RUN		add one more compressed page
- *	BZ_FINISH	no more input, flush the state
- */
-static void
-dumpsys_bzrun(helper_t *hp, void *buf, size_t size, int mode)
-{
-	dumpsync_t *ds = hp->ds;
-	const int CSIZE = sizeof (dumpcsize_t);
-	bz_stream *ps = &hp->bzstream;
-	int rc = 0;
-	uint32_t csize;
-	dumpcsize_t cs;
-
-	/* Set input pointers to new input page */
-	if (size > 0) {
-		ps->avail_in = size;
-		ps->next_in = buf;
-	}
-
-	/* CONSTCOND */
-	while (1) {
-
-		/* Quit when all input has been consumed */
-		if (ps->avail_in == 0 && mode == BZ_RUN)
-			break;
-
-		/* Get a new output buffer */
-		if (hp->cpout == NULL) {
-			HRSTART(hp->perpage, outwait);
-			hp->cpout = CQ_GET(freebufq);
-			HRSTOP(hp->perpage, outwait);
-			ps->avail_out = hp->cpout->size - CSIZE;
-			ps->next_out = hp->cpout->buf + CSIZE;
-		}
-
-		/* Compress input, or finalize */
-		HRSTART(hp->perpage, compress);
-		rc = BZ2_bzCompress(ps, mode);
-		HRSTOP(hp->perpage, compress);
-
-		/* Check for error */
-		if (mode == BZ_RUN && rc != BZ_RUN_OK) {
-			dumpsys_errmsg(hp, "%d: BZ_RUN error %s at page %lx\n",
-			    hp->helper, BZ2_bzErrorString(rc),
-			    hp->cpin->pagenum);
-			break;
-		}
-
-		/* Write the buffer if it is full, or we are flushing */
-		if (ps->avail_out == 0 || mode == BZ_FINISH) {
-			csize = hp->cpout->size - CSIZE - ps->avail_out;
-			cs = DUMP_SET_TAG(csize, hp->tag);
-			if (csize > 0) {
-				(void) memcpy(hp->cpout->buf, &cs, CSIZE);
-				dumpsys_swrite(hp, hp->cpout, csize + CSIZE);
-				hp->cpout = NULL;
-			}
-		}
-
-		/* Check for final complete */
-		if (mode == BZ_FINISH) {
-			if (rc == BZ_STREAM_END)
-				break;
-			if (rc != BZ_FINISH_OK) {
-				dumpsys_errmsg(hp, "%d: BZ_FINISH error %s\n",
-				    hp->helper, BZ2_bzErrorString(rc));
-				break;
-			}
-		}
-	}
-
-	/* Cleanup state and buffers */
-	if (mode == BZ_FINISH) {
-
-		/* Reset state so that it is re-usable. */
-		(void) BZ2_bzCompressReset(&hp->bzstream);
-
-		/* Give any unused outout buffer to the main task */
-		if (hp->cpout != NULL) {
-			hp->cpout->used = 0;
-			CQ_PUT(mainq, hp->cpout, CBUF_ERRMSG);
-			hp->cpout = NULL;
-		}
-	}
-}
-
-static void
-dumpsys_bz2compress(helper_t *hp)
-{
-	dumpsync_t *ds = hp->ds;
-	dumpstreamhdr_t sh;
-
-	(void) strcpy(sh.stream_magic, DUMP_STREAM_MAGIC);
-	sh.stream_pagenum = (pgcnt_t)-1;
-	sh.stream_npages = 0;
-	hp->cpin = NULL;
-	hp->cpout = NULL;
-	hp->cperr = NULL;
-	hp->in = 0;
-	hp->out = 0;
-	hp->bzstream.avail_in = 0;
-
-	/* Bump reference to mainq while we are running */
-	CQ_OPEN(mainq);
-
-	/* Get one page at a time */
-	while (dumpsys_sread(hp)) {
-		if (sh.stream_pagenum != hp->cpin->pagenum) {
-			sh.stream_pagenum = hp->cpin->pagenum;
-			sh.stream_npages = btop(hp->cpin->used);
-			dumpsys_bzrun(hp, &sh, sizeof (sh), BZ_RUN);
-		}
-		dumpsys_bzrun(hp, hp->page, PAGESIZE, 0);
-	}
-
-	/* Done with input, flush any partial buffer */
-	if (sh.stream_pagenum != (pgcnt_t)-1) {
-		dumpsys_bzrun(hp, NULL, 0, BZ_FINISH);
-		dumpsys_errmsg(hp, NULL);
-	}
-
-	ASSERT(hp->cpin == NULL && hp->cpout == NULL && hp->cperr == NULL);
-
-	/* Decrement main queue count, we are done */
-	CQ_CLOSE(mainq);
-}
-
-/*
  * Compress with lzjb
  * write stream block if full or size==0
  * if csize==0 write stream header, else write <csize, data>
@@ -2193,14 +1921,8 @@
 			if (hp->helper == FREEHELPER) {
 				hp->helper = CPU->cpu_id;
 				BT_SET(dumpcfg.helpermap, CPU->cpu_seqid);
-
 				dumpsys_spinunlock(&dumpcfg.helper_lock);
-
-				if (dumpcfg.clevel < DUMP_CLEVEL_BZIP2)
-					dumpsys_lzjbcompress(hp);
-				else
-					dumpsys_bz2compress(hp);
-
+				dumpsys_lzjbcompress(hp);
 				hp->helper = DONEHELPER;
 				return;
 			}
@@ -2237,10 +1959,7 @@
 	helper_t *hp = arg;
 
 	BT_ATOMIC_SET(dumpcfg.helpermap, CPU->cpu_seqid);
-	if (dumpcfg.clevel < DUMP_CLEVEL_BZIP2)
-		dumpsys_lzjbcompress(hp);
-	else
-		dumpsys_bz2compress(hp);
+	dumpsys_lzjbcompress(hp);
 }
 
 /*
@@ -2287,28 +2006,44 @@
 	cbuf_t *cp;
 	pgcnt_t baseoff, pfnoff;
 	pfn_t base, pfn;
-	int i, dumpserial;
+	int i;
 
 	/*
 	 * Fall back to serial mode if there are no helpers.
-	 * dump_plat_mincpu can be set to 0 at any time.
+	 * dump_ncpu_low can be set to 0 at any time.
 	 * dumpcfg.helpermap must contain at least one member.
+	 *
+	 * It is possible that the helpers haven't registered
+	 * in helpermap yet; wait up to DUMP_HELPER_MAX_WAIT.
 	 */
-	dumpserial = 1;
+	if (dump_ncpu_low != 0 && dumpcfg.clevel != DUMP_CLEVEL_SERIAL) {
+		boolean_t dumpserial = B_TRUE;
+		hrtime_t hrtmax = MSEC2NSEC(DUMP_HELPER_MAX_WAIT);
+		hrtime_t hrtstart = gethrtime();
 
-	if (dump_plat_mincpu != 0 && dumpcfg.clevel != 0) {
-		for (i = 0; i < BT_BITOUL(NCPU); ++i) {
-			if (dumpcfg.helpermap[i] != 0) {
-				dumpserial = 0;
+		for (;;) {
+			for (i = 0; i < BT_BITOUL(NCPU); ++i) {
+				if (dumpcfg.helpermap[i] != 0) {
+					dumpserial = B_FALSE;
+					break;
+				}
+			}
+
+			if ((!dumpserial) ||
+			    ((gethrtime() - hrtstart) >= hrtmax)) {
 				break;
 			}
+
+			ht_pause();
 		}
-	}
 
-	if (dumpserial) {
-		dumpcfg.clevel = 0;
-		if (dumpcfg.helper[0].lzbuf == NULL)
-			dumpcfg.helper[0].lzbuf = dumpcfg.helper[1].page;
+		if (dumpserial) {
+			dumpcfg.clevel = DUMP_CLEVEL_SERIAL;
+			if (dumpcfg.helper[0].lzbuf == NULL) {
+				dumpcfg.helper[0].lzbuf =
+				    dumpcfg.helper[1].page;
+			}
+		}
 	}
 
 	dump_init_memlist_walker(&mlw);
@@ -2451,14 +2186,13 @@
 			 * If there are no helpers the main task does
 			 * non-streams lzjb compress.
 			 */
-			if (dumpserial) {
+			if (dumpcfg.clevel == DUMP_CLEVEL_SERIAL) {
 				dumpsys_lzjb_page(dumpcfg.helper, cp);
-				break;
+			} else {
+				/* pass mapped pages to a helper */
+				CQ_PUT(helperq, cp, CBUF_INREADY);
 			}
 
-			/* pass mapped pages to a helper */
-			CQ_PUT(helperq, cp, CBUF_INREADY);
-
 			/* the last page was done */
 			if (bitnum >= dumpcfg.bitmapsize)
 				CQ_CLOSE(helperq);
@@ -2563,8 +2297,8 @@
 	P("Found small pages,%ld\n", cfg->foundsm);
 
 	P("Compression level,%d\n", cfg->clevel);
-	P("Compression type,%s %s\n", cfg->clevel == 0 ? "serial" : "parallel",
-	    cfg->clevel >= DUMP_CLEVEL_BZIP2 ? "bzip2" : "lzjb");
+	P("Compression type,%s lzjb\n",
+	    cfg->clevel == DUMP_CLEVEL_SERIAL ? "serial" : "parallel");
 	P("Compression ratio,%d.%02d\n", compress_ratio / 100, compress_ratio %
 	    100);
 	P("nhelper_used,%d\n", cfg->nhelper_used);
@@ -2672,7 +2406,8 @@
 		(void) VOP_DUMPCTL(dumpvp, DUMP_ALLOC, NULL, NULL);
 		(void) vsnprintf(dumphdr->dump_panicstring, DUMP_PANICSIZE,
 		    panicstr, panicargs);
-
+		(void) strncpy(dumphdr->dump_uuid, dump_get_uuid(),
+		    sizeof (dumphdr->dump_uuid));
 	}
 
 	if (dump_conflags & DUMP_ALL)
@@ -2717,11 +2452,11 @@
 	lbolt_debug_entry();
 
 	/*
-	 * Leave room for the message and ereport save areas and terminal dump
-	 * header.
+	 * Leave room for the summary, message and ereport save areas
+	 * and terminal dump header.
 	 */
 	dumpbuf.vp_limit = dumpvp_size - DUMP_LOGSIZE - DUMP_OFFSET -
-	    DUMP_ERPTSIZE;
+	    DUMP_ERPTSIZE - DUMP_SUMMARYSIZE;
 
 	/*
 	 * Write out the symbol table.  It's no longer compressed,
@@ -2825,14 +2560,12 @@
 	dumphdr->dump_data = dumpvp_flush();
 
 	bzero(dumpcfg.helpermap, BT_SIZEOFMAP(NCPU));
-	ds->live = dumpcfg.clevel > 0 &&
+	ds->live = dumpcfg.clevel > DUMP_CLEVEL_SERIAL &&
 	    (dumphdr->dump_flags & DF_LIVE) != 0;
 
 	save_dump_clevel = dumpcfg.clevel;
 	if (panicstr)
 		dumpsys_get_maxmem();
-	else if (dumpcfg.clevel >= DUMP_CLEVEL_BZIP2)
-		dumpcfg.clevel = DUMP_CLEVEL_LZJB;
 
 	dumpcfg.nhelper_used = 0;
 	for (hp = dumpcfg.helper; hp != hpend; hp++) {
@@ -2845,8 +2578,6 @@
 		hp->taskqid = NULL;
 		hp->ds = ds;
 		bzero(&hp->perpage, sizeof (hp->perpage));
-		if (dumpcfg.clevel >= DUMP_CLEVEL_BZIP2)
-			(void) BZ2_bzCompressReset(&hp->bzstream);
 	}
 
 	CQ_OPEN(freebufq);
@@ -2884,7 +2615,7 @@
 	} else {
 		if (panicstr)
 			kmem_dump_begin();
-		dumpcfg.helpers_wanted = dumpcfg.clevel > 0;
+		dumpcfg.helpers_wanted = dumpcfg.clevel > DUMP_CLEVEL_SERIAL;
 		dumpsys_spinunlock(&dumpcfg.helper_lock);
 	}
 
@@ -3045,17 +2776,19 @@
 	return (0);
 }
 
-int
-dump_set_uuid(const char *uuidstr)
+static int
+dump_validate_uuid(const char *uuidstr)
 {
 	const char *ptr;
 	int i;
 
-	if (uuidstr == NULL || strnlen(uuidstr, 36 + 1) != 36)
+	if (uuidstr == NULL || strlen(uuidstr) !=
+	    UUID_PRINTABLE_STRING_LENGTH - 1)
 		return (EINVAL);
 
 	/* uuid_parse is not common code so check manually */
-	for (i = 0, ptr = uuidstr; i < 36; i++, ptr++) {
+	for (i = 0, ptr = uuidstr; i < UUID_PRINTABLE_STRING_LENGTH - 1;
+	    i++, ptr++) {
 		switch (i) {
 		case 8:
 		case 13:
@@ -3072,10 +2805,34 @@
 		}
 	}
 
+	return (0);
+}
+
+int
+dump_update_uuid(const char *uuidstr)
+{
+
+	if (dump_validate_uuid(uuidstr) != 0 || dumphdr == NULL)
+		return (EINVAL);
+
+	bzero(dumphdr->dump_uuid, sizeof (dumphdr->dump_uuid));
+	(void) strncpy(dumphdr->dump_uuid, uuidstr,
+	    sizeof (dumphdr->dump_uuid));
+
+	return (0);
+}
+
+int
+dump_set_uuid(const char *uuidstr)
+{
+	if (dump_validate_uuid(uuidstr) != 0)
+		return (EINVAL);
+
 	if (dump_osimage_uuid[0] != '\0')
 		return (EALREADY);
 
-	(void) strncpy(dump_osimage_uuid, uuidstr, 36 + 1);
+	(void) strncpy(dump_osimage_uuid, uuidstr,
+	    UUID_PRINTABLE_STRING_LENGTH);
 
 	cmn_err(CE_CONT, "?This Solaris instance has UUID %s\n",
 	    dump_osimage_uuid);
