--- old/usr/src/cmd/boot/filelist/i386/filelist.ramdisk	Wed Sep  4 04:06:03 2019
+++ new/usr/src/cmd/boot/filelist/i386/filelist.ramdisk	Wed Sep  4 04:06:03 2019
@@ -18,6 +18,7 @@
 etc/system
 etc/system.d
 etc/hostid
+etc/versions
 kernel
 platform/i86hvm/kernel
 platform/i86pc/kernel
--- old/usr/src/cmd/mdb/common/kmdb/kmdb_kvm.c	Wed Sep  4 04:06:03 2019
+++ new/usr/src/cmd/mdb/common/kmdb/kmdb_kvm.c	Wed Sep  4 04:06:03 2019
@@ -22,7 +22,7 @@
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2013 by Delphix. All rights reserved.
  *
- * Copyright 2018 Joyent, Inc.
+ * Copyright 2019 Joyent, Inc.
  */
 
 #include <kmdb/kmdb_kvm.h>
@@ -49,6 +49,7 @@
 #include <sys/kobj.h>
 #include <sys/kobj_impl.h>
 #include <sys/bitmap.h>
+#include <sys/uuid.h>
 #include <vm/as.h>
 
 static const char KMT_RTLD_NAME[] = "krtld";
@@ -552,7 +553,7 @@
 kmt_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 {
 	struct utsname uts;
-	char uuid[37];
+	char uuid[UUID_PRINTABLE_STRING_LENGTH];
 	kreg_t tt;
 
 	if (mdb_tgt_readsym(mdb.m_target, MDB_TGT_AS_VIRT, &uts, sizeof (uts),
@@ -568,16 +569,14 @@
 	mdb_printf("operating system: %s %s (%s)\n",
 	    uts.release, uts.version, uts.machine);
 
-	if (mdb_tgt_readsym(mdb.m_target, MDB_TGT_AS_VIRT, uuid, sizeof (uuid),
-	    "genunix", "dump_osimage_uuid") != sizeof (uuid)) {
-		warn("failed to read 'dump_osimage_uuid' string from kernel\n");
-		(void) strcpy(uuid, "(error)");
-	} else if (*uuid == '\0') {
-		(void) strcpy(uuid, "(not set)");
-	} else if (uuid[36] != '\0') {
-		(void) strcpy(uuid, "(invalid)");
+	mdb_print_buildversion();
+
+	if (mdb_readsym(uuid, sizeof (uuid),
+	    "dump_osimage_uuid") == sizeof (uuid) &&
+	    uuid[sizeof (uuid) - 1] == '\0') {
+		mdb_printf("image uuid: %s\n", uuid[0] != '\0' ?
+		    uuid : "(not set)");
 	}
-	mdb_printf("image uuid: %s\n", uuid);
 
 	mdb_printf("DTrace state: %s\n", (kmdb_kdi_dtrace_get_state() ==
 	    KDI_DTSTATE_DTRACE_ACTIVE ? "active (debugger breakpoints cannot "
--- old/usr/src/cmd/mdb/common/mdb/mdb_ks.h	Wed Sep  4 04:06:04 2019
+++ new/usr/src/cmd/mdb/common/mdb/mdb_ks.h	Wed Sep  4 04:06:04 2019
@@ -23,6 +23,10 @@
  * Use is subject to license terms.
  */
 
+/*
+ * Copyright 2019 Joyent, Inc.
+ */
+
 #ifndef	_MDB_KS_H
 #define	_MDB_KS_H
 
@@ -140,6 +144,8 @@
 /* Generic function for working with MAC (network layer 2) addresses. */
 extern void mdb_mac_addr(const uint8_t *, size_t, char *, size_t);
 
+extern void mdb_print_buildversion(void);
+
 /*
  * Target-specific interfaces
  *
--- old/usr/src/cmd/mdb/common/mdb/mdb_kvm.c	Wed Sep  4 04:06:04 2019
+++ new/usr/src/cmd/mdb/common/mdb/mdb_kvm.c	Wed Sep  4 04:06:04 2019
@@ -23,7 +23,7 @@
  */
 
 /*
- * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
+ * Copyright 2019 Joyent, Inc.
  */
 
 /*
@@ -51,6 +51,7 @@
 #include <sys/panic.h>
 #include <sys/dumphdr.h>
 #include <sys/dumpadm.h>
+#include <sys/uuid.h>
 
 #include <dlfcn.h>
 #include <libctf.h>
@@ -68,6 +69,7 @@
 #include <mdb/mdb_kvm.h>
 #include <mdb/mdb_module.h>
 #include <mdb/mdb_kb.h>
+#include <mdb/mdb_ks.h>
 #include <mdb/mdb.h>
 
 #define	KT_RELOC_BUF(buf, obase, nbase) \
@@ -94,6 +96,8 @@
 static const char KT_MODULE[] = "mdb_ks";
 static const char KT_CTFPARENT[] = "genunix";
 
+static void (*print_buildversion)(void);
+
 static void
 kt_load_module(kt_data_t *kt, mdb_tgt_t *t, kt_module_t *km)
 {
@@ -485,6 +489,9 @@
 	mdb_printf("operating system: %s %s (%s)\n",
 	    uts.release, uts.version, uts.machine);
 
+	if (print_buildversion != NULL)
+		print_buildversion();
+
 	if (kt->k_dumphdr) {
 		dumphdr_t *dh = kt->k_dumphdr;
 
@@ -494,11 +501,13 @@
 
 		kt->k_dump_print_content(dh, kt->k_dumpcontent);
 	} else {
-		char uuid[37];
+		char uuid[UUID_PRINTABLE_STRING_LENGTH];
 
-		if (mdb_readsym(uuid, 37, "dump_osimage_uuid") == 37 &&
-		    uuid[36] == '\0') {
-			mdb_printf("image uuid: %s\n", uuid);
+		if (mdb_readsym(uuid, sizeof (uuid),
+		    "dump_osimage_uuid") == sizeof (uuid) &&
+		    uuid[sizeof (uuid) - 1] == '\0') {
+			mdb_printf("image uuid: %s\n", uuid[0] != '\0' ?
+			    uuid : "(not set)");
 		}
 	}
 
@@ -582,6 +591,9 @@
 			    "some modules may not load\n");
 		}
 
+		print_buildversion = (void (*)(void))dlsym(RTLD_NEXT,
+		    "mdb_print_buildversion");
+
 		if (mdb_prop_postmortem && kt->k_dumphdr != NULL) {
 			sym = dlsym(RTLD_NEXT, "mdb_dump_print_content");
 			if (sym != NULL)
--- old/usr/src/cmd/mdb/common/modules/mdb_ks/mdb_ks.c	Wed Sep  4 04:06:04 2019
+++ new/usr/src/cmd/mdb/common/modules/mdb_ks/mdb_ks.c	Wed Sep  4 04:06:05 2019
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2017 Joyent, Inc.
+ * Copyright 2019 Joyent, Inc.
  */
 
 /*
@@ -1012,9 +1012,9 @@
 int
 mdb_name_to_major(const char *name, major_t *major)
 {
-	uintptr_t	mbind;
-	uintptr_t	mb_hashtab[MOD_BIND_HASHSIZE];
-	struct bind	mbind_local;
+	uintptr_t mbind;
+	uintptr_t mb_hashtab[MOD_BIND_HASHSIZE];
+	struct bind mbind_local;
 
 
 	if (mdb_readsym(mb_hashtab, sizeof (mb_hashtab), "mb_hashtab") == -1) {
@@ -1809,4 +1809,20 @@
 	}
 
 	return ((ts/nsec) - lbi.lbi_debug_time);
+}
+
+void
+mdb_print_buildversion(void)
+{
+	GElf_Sym sym;
+
+	if (mdb_lookup_by_name("buildversion", &sym) != 0)
+		return;
+
+	char *str = mdb_zalloc(4096, UM_SLEEP | UM_GC);
+
+	if (mdb_readstr(str, 4096, sym.st_value) < 1)
+		return;
+
+	mdb_printf("build version: %s\n", str);
 }
--- old/usr/src/cmd/nsadmin/Makefile	Wed Sep  4 04:06:05 2019
+++ new/usr/src/cmd/nsadmin/Makefile	Wed Sep  4 04:06:05 2019
@@ -22,6 +22,8 @@
 # Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
+# Copyright 2019 Joyent, Inc.
+#
 
 PROG= profile .login ksh.kshrc system
 PROGSKEL= .profile .kshrc
@@ -32,6 +34,8 @@
 ROOTROOT= $(ROOT)/root
 ROOTETCSKEL= $(ROOTETC)/skel
 ROOTETCSKELPROG= $(PROGSKEL:%=$(ROOTETCSKEL)/%)
+ROOTETCVERSIONS= $(ROOTETC)/versions
+ROOTETCVERSIONSPROG= $(ROOTETCVERSIONS)/build
 ROOTROOTPROG= $(PROGROOT:%=$(ROOTROOT)/%)
 FILEMODE= 0644
 
@@ -66,14 +70,23 @@
 	$(INS.file)
 
 $(ROOTROOT) \
+$(ROOTETCVERSIONS) \
 $(ROOTETCSKEL):
 	$(INS.dir)
 
-install: all $(ROOTETCSKEL) $(ROOTETCPROG) $(ROOTETCSKELPROG) $(ROOTROOTPROG)
+$(ROOTETCVERSIONSPROG): $(ROOTETCVERSIONS) FRC
+	if [[ -n "$$BUILDVERSION_EXEC" ]]; then \
+		$$BUILDVERSION_EXEC >$(ROOTETCVERSIONSPROG) ; \
+	else \
+		touch $(ROOTETCVERSIONSPROG) ; \
+	fi
 
+install: all $(ROOTETCSKEL) $(ROOTETCPROG) \
+    $(ROOTETCSKELPROG) $(ROOTROOTPROG) $(ROOTETCVERSIONSPROG)
+
 clean:
 
 clobber:
 	$(RM) $(CLOBBERFILES)
 
-lint:
+FRC:
--- old/usr/src/pkg/manifests/SUNWcs.mf	Wed Sep  4 04:06:05 2019
+++ new/usr/src/pkg/manifests/SUNWcs.mf	Wed Sep  4 04:06:05 2019
@@ -26,6 +26,7 @@
 # Copyright 2017 Nexenta Systems, Inc.
 # Copyright 2017 Toomas Soome <tsoome@me.com>
 # Copyright 2019 Peter Tribble.
+# Copyright 2019 Joyent, Inc.
 # Copyright (c) 2011, 2015 by Delphix. All rights reserved.
 #
 
@@ -94,6 +95,7 @@
 dir path=etc/system.d group=sys
 dir path=etc/tm group=sys
 dir path=etc/user_attr.d group=sys
+dir path=etc/versions group=sys
 dir path=export group=sys
 dir path=home group=root mode=0555
 dir path=lib
@@ -463,6 +465,7 @@
 file path=etc/ttysrch group=sys preserve=true
 file path=etc/user_attr group=sys preserve=true timestamp=19700101T000000Z
 file path=etc/user_attr.d/SUNWcs group=sys
+file path=etc/versions/build group=sys
 file path=etc/vfstab group=sys preserve=true
 file path=lib/inet/in.mpathd mode=0555
 file path=lib/inet/ipmgmtd mode=0555
--- old/usr/src/tools/env/illumos.sh	Wed Sep  4 04:06:06 2019
+++ new/usr/src/tools/env/illumos.sh	Wed Sep  4 04:06:06 2019
@@ -135,6 +135,9 @@
 # nightly(1) for interactions between environment variables and this command.
 #POST_NIGHTLY=
 
+# Populates /etc/versions/build on each nightly run
+export BUILDVERSION_EXEC="git describe --all --long --dirty"
+
 # -----------------------------------------------------------------------------
 # You are less likely to need to modify parameters below.
 # -----------------------------------------------------------------------------
--- old/usr/src/uts/common/os/modsysfile.c	Wed Sep  4 04:06:06 2019
+++ new/usr/src/uts/common/os/modsysfile.c	Wed Sep  4 04:06:06 2019
@@ -23,6 +23,7 @@
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  * Copyright 2017 Nexenta Systems, Inc.
+ * Copyright 2019 Joyent, Inc.
  */
 
 #include <sys/types.h>
@@ -67,6 +68,11 @@
 char *self_assembly = "/etc/system.d/.self-assembly";
 char *systemfile = "/etc/system";	/* name of ascii system file */
 
+#define	BUILDVERSION_LEN (4096)
+
+char *versionfile = "/etc/versions/build";
+char buildversion[BUILDVERSION_LEN];
+
 static struct sysparam *sysparam_hd;	/* head of parameters list */
 static struct sysparam *sysparam_tl;	/* tail of parameters list */
 static vmem_t *mod_sysfile_arena;	/* parser memory */
@@ -811,6 +817,8 @@
 void
 mod_read_system_file(int ask)
 {
+	struct _buf *file;
+
 	mod_sysfile_arena = vmem_create("mod_sysfile", NULL, 0, 8,
 	    segkmem_alloc, segkmem_free, heap_arena, 0, VM_SLEEP);
 
@@ -838,6 +846,18 @@
 
 	if (ask == 0)
 		setparams();
+
+	/*
+	 * A convenient place to read in our build version string.
+	 */
+
+	if ((file = kobj_open_file(versionfile)) != (struct _buf *)-1) {
+		if (kobj_read_file(file, buildversion,
+		    sizeof (buildversion) - 1, 0) == -1) {
+			cmn_err(CE_WARN, "failed to read %s\n", versionfile);
+		}
+		kobj_close_file(file);
+	}
 }
 
 /*
