--- old/usr/src/uts/common/os/modsysfile.c	Mon Feb 11 08:17:18 2019
+++ new/usr/src/uts/common/os/modsysfile.c	Mon Feb 11 08:17:18 2019
@@ -22,7 +22,7 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
- * Copyright 2016 Nexenta Systems, Inc.
+ * Copyright 2017 Nexenta Systems, Inc.
  */
 
 #include <sys/types.h>
@@ -64,6 +64,7 @@
 static char dafile[] = DAFILE;
 static char dacffile[] = DACFFILE;
 
+char *self_assembly = "/etc/system.d/.self-assembly";
 char *systemfile = "/etc/system";	/* name of ascii system file */
 
 static struct sysparam *sysparam_hd;	/* head of parameters list */
@@ -751,8 +752,8 @@
 	return (NULL);
 }
 
-void
-mod_read_system_file(int ask)
+static void
+read_system_file(char *name)
 {
 	register struct sysparam *sp;
 	register struct _buf *file;
@@ -759,61 +760,74 @@
 	register token_t token, last_tok;
 	char tokval[MAXLINESIZE];
 
-	mod_sysfile_arena = vmem_create("mod_sysfile", NULL, 0, 8,
-	    segkmem_alloc, segkmem_free, heap_arena, 0, VM_SLEEP);
-
-	if (ask)
-		mod_askparams();
-
-	if (systemfile != NULL) {
-
-		if ((file = kobj_open_file(systemfile)) ==
-		    (struct _buf *)-1) {
+	if ((file = kobj_open_file(name)) ==
+	    (struct _buf *)-1) {
+		if (strcmp(name, systemfile) == 0)
 			cmn_err(CE_WARN, "cannot open system file: %s",
-			    systemfile);
-		} else {
+			    name);
+	} else {
+		if (sysparam_tl == NULL)
 			sysparam_tl = (struct sysparam *)&sysparam_hd;
 
-			last_tok = NEWLINE;
-			while ((token = kobj_lex(file, tokval,
-			    sizeof (tokval))) != EOF) {
-				switch (token) {
-				case STAR:
-				case POUND:
-					/*
-					 * Skip comments.
-					 */
+		last_tok = NEWLINE;
+		while ((token = kobj_lex(file, tokval,
+		    sizeof (tokval))) != EOF) {
+			switch (token) {
+			case STAR:
+			case POUND:
+				/*
+				 * Skip comments.
+				 */
+				kobj_find_eol(file);
+				break;
+			case NEWLINE:
+				kobj_newline(file);
+				last_tok = NEWLINE;
+				break;
+			case NAME:
+				if (last_tok != NEWLINE) {
+					kobj_file_err(CE_WARN, file,
+					    extra_err, tokval);
 					kobj_find_eol(file);
-					break;
-				case NEWLINE:
-					kobj_newline(file);
-					last_tok = NEWLINE;
-					break;
-				case NAME:
-					if (last_tok != NEWLINE) {
-						kobj_file_err(CE_WARN, file,
-						    extra_err, tokval);
-						kobj_find_eol(file);
-					} else if ((sp = do_sysfile_cmd(file,
-					    tokval)) != NULL) {
-						sp->sys_next = NULL;
-						sysparam_tl->sys_next = sp;
-						sysparam_tl = sp;
-					}
-					last_tok = NAME;
-					break;
-				default:
-					kobj_file_err(CE_WARN,
-					    file, tok_err, tokval);
-					kobj_find_eol(file);
-					break;
+				} else if ((sp = do_sysfile_cmd(file,
+				    tokval)) != NULL) {
+					sp->sys_next = NULL;
+					sysparam_tl->sys_next = sp;
+					sysparam_tl = sp;
 				}
+				last_tok = NAME;
+				break;
+			default:
+				kobj_file_err(CE_WARN,
+				    file, tok_err, tokval);
+				kobj_find_eol(file);
+				break;
 			}
-			kobj_close_file(file);
 		}
+		kobj_close_file(file);
 	}
+}
 
+void
+mod_read_system_file(int ask)
+{
+	mod_sysfile_arena = vmem_create("mod_sysfile", NULL, 0, 8,
+	    segkmem_alloc, segkmem_free, heap_arena, 0, VM_SLEEP);
+
+	if (ask)
+		mod_askparams();
+
 	/*
+	 * Read the user self-assembly file first
+	 * to preserve existing system settings.
+	 */
+	if (self_assembly != NULL)
+		read_system_file(self_assembly);
+
+	if (systemfile != NULL)
+		read_system_file(systemfile);
+
+	/*
 	 * Sanity check of /etc/system.
 	 */
 	check_system_file();
@@ -2384,16 +2398,16 @@
 
 /*
  * read_dacf_binding_file()
- * 	Read the /etc/dacf.conf file and build the dacf_rule_t database from it.
+ *	Read the /etc/dacf.conf file and build the dacf_rule_t database from it.
  *
  * The syntax of a line in the dacf.conf file is:
- *   dev-spec 	[module:]op-set	operation options 	[config-args];
+ *   dev-spec	[module:]op-set	operation options	[config-args];
  *
  * Where:
- *   	1. dev-spec is of the format: name="data"
- *   	2. operation is the operation that this rule matches. (i.e. pre-detach)
- *   	3. options is a comma delimited list of options (i.e. debug,foobar)
- *   	4. config-data is a whitespace delimited list of the format: name="data"
+ *	1. dev-spec is of the format: name="data"
+ *	2. operation is the operation that this rule matches. (i.e. pre-detach)
+ *	3. options is a comma delimited list of options (i.e. debug,foobar)
+ *	4. config-data is a whitespace delimited list of the format: name="data"
  */
 int
 read_dacf_binding_file(char *filename)
