changeset 10559:6030a9284200

6880616 Need to provide interfaces for FMA to disable fast reboot on terminal errors
author Sherry Moore <Sherry.Moore@Sun.COM>
date Wed, 16 Sep 2009 09:51:25 -0700
parents 39a5e9474d0b
children f96522350e81
files usr/src/cmd/uadmin/uadmin.c usr/src/lib/libscf/common/highlevel.c usr/src/lib/libscf/common/mapfile-vers usr/src/lib/libscf/inc/libscf_priv.h usr/src/uts/common/syscall/uadmin.c usr/src/uts/i86pc/os/fakebop.c usr/src/uts/i86pc/os/fastboot.c usr/src/uts/i86pc/sys/fastboot.h
diffstat 8 files changed, 90 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/uadmin/uadmin.c	Wed Sep 16 09:42:38 2009 -0700
+++ b/usr/src/cmd/uadmin/uadmin.c	Wed Sep 16 09:51:25 2009 -0700
@@ -67,10 +67,6 @@
 	adt_event_data_t *event = NULL; /* event to be generated */
 	au_event_t event_id;
 	enum adt_uadmin_fcn fcn_id;
-#ifdef	__i386
-	uint8_t boot_config = 0;
-#endif /* __i386 */
-
 
 	if (argc < 3 || argc > 4) {
 		(void) fprintf(stderr, Usage, argv[0]);
@@ -208,10 +204,16 @@
 		}
 #ifdef	__i386
 	} else if (cmd == A_CONFIG) {
+		uint8_t boot_config = 0;
+		uint8_t boot_config_ovr = 0;
+
 		switch (fcn) {
 		case AD_UPDATE_BOOT_CONFIG:
 			fcn_id = ADT_UADMIN_FCN_AD_UPDATE_BOOT_CONFIG;
 			scf_get_boot_config(&boot_config);
+			boot_config_ovr = boot_config;
+			scf_get_boot_config_ovr(&boot_config_ovr);
+			boot_config &= boot_config_ovr;
 			mdep = (uintptr_t)(&boot_config);
 			break;
 		}
--- a/usr/src/lib/libscf/common/highlevel.c	Wed Sep 16 09:42:38 2009 -0700
+++ b/usr/src/lib/libscf/common/highlevel.c	Wed Sep 16 09:51:25 2009 -0700
@@ -230,6 +230,8 @@
 		scf_propvec_t ua_boot_config_ovr[] = {
 			{ FASTREBOOT_DEFAULT, NULL, SCF_TYPE_BOOLEAN, NULL,
 			    UA_FASTREBOOT_DEFAULT },
+			{ FASTREBOOT_ONPANIC, NULL, SCF_TYPE_BOOLEAN, NULL,
+			    UA_FASTREBOOT_ONPANIC },
 			{ NULL }
 		};
 		scf_propvec_t	*prop;
@@ -274,6 +276,10 @@
 			}
 		}
 #endif	/* FASTREBOOT_DEBUG */
+
+		if (set)
+			(void) smf_refresh_instance(FMRI_BOOT_CONFIG);
+
 		return (rc);
 
 	}
@@ -283,7 +289,7 @@
 /*
  * Get values of properties in non-persistent "config_ovr" property group.
  */
-static void
+void
 scf_get_boot_config_ovr(uint8_t *boot_config_ovr)
 {
 	(void) scf_getset_boot_config_ovr(B_FALSE, boot_config_ovr);
@@ -295,7 +301,10 @@
 int
 scf_fastreboot_default_set_transient(boolean_t value)
 {
-	uint8_t	boot_config_ovr = (value & UA_FASTREBOOT_DEFAULT);
+	uint8_t	boot_config_ovr = 0;
+
+	if (value == B_TRUE)
+		boot_config_ovr = UA_FASTREBOOT_DEFAULT | UA_FASTREBOOT_ONPANIC;
 
 	return (scf_getset_boot_config_ovr(B_TRUE, &boot_config_ovr));
 }
--- a/usr/src/lib/libscf/common/mapfile-vers	Wed Sep 16 09:42:38 2009 -0700
+++ b/usr/src/lib/libscf/common/mapfile-vers	Wed Sep 16 09:51:25 2009 -0700
@@ -315,6 +315,7 @@
 	scf_clean_propvec;
 	scf_instance_delete_prop;
 	scf_get_boot_config;
+	scf_get_boot_config_ovr;
 	scf_is_fastboot_default;
 	scf_fastreboot_default_set_transient;
     local:
--- a/usr/src/lib/libscf/inc/libscf_priv.h	Wed Sep 16 09:42:38 2009 -0700
+++ b/usr/src/lib/libscf/inc/libscf_priv.h	Wed Sep 16 09:51:25 2009 -0700
@@ -530,6 +530,7 @@
  * Functions to extract boot config information from FMRI_BOOT_CONFIG
  */
 void scf_get_boot_config(uint8_t *);
+void scf_get_boot_config_ovr(uint8_t *);
 int scf_is_fastboot_default(void);
 
 /*
--- a/usr/src/uts/common/syscall/uadmin.c	Wed Sep 16 09:42:38 2009 -0700
+++ b/usr/src/uts/common/syscall/uadmin.c	Wed Sep 16 09:51:25 2009 -0700
@@ -307,11 +307,9 @@
 		case AD_UPDATE_BOOT_CONFIG:
 #ifndef	__sparc
 		{
-			extern int fastreboot_capable;
 			extern void fastboot_update_config(const char *);
 
-			if (fastreboot_capable)
-				fastboot_update_config(mdep);
+			fastboot_update_config(mdep);
 		}
 #endif
 
@@ -379,22 +377,9 @@
 			panic_bootstr = mdep;
 
 #ifndef	__sparc
-		extern int fastreboot_onpanic;
-		if (fcn != AD_FASTREBOOT) {
-			extern void fastboot_update_config(const char *);
-			/*
-			 * If user has explicitly requested reboot to prom,
-			 * or uadmin(1M) was invoked with other functions,
-			 * don't try to fast reboot after dumping.
-			 */
-			fastreboot_onpanic = 0;
-			fastboot_update_config((char *)&fastreboot_onpanic);
-		}
+		extern void fastboot_update_and_load(int, char *);
 
-		if (fastreboot_onpanic) {
-			extern void fastboot_load_kernel(char *);
-			fastboot_load_kernel(mdep);
-		}
+		fastboot_update_and_load(fcn, mdep);
 #endif
 
 		panic("forced crash dump initiated at user request");
--- a/usr/src/uts/i86pc/os/fakebop.c	Wed Sep 16 09:42:38 2009 -0700
+++ b/usr/src/uts/i86pc/os/fakebop.c	Wed Sep 16 09:51:25 2009 -0700
@@ -124,7 +124,7 @@
 static int early_allocation = 1;
 
 int force_fastreboot = 0;
-int fastreboot_onpanic = 0;
+volatile int fastreboot_onpanic = 0;
 int post_fastreboot = 0;
 #ifdef	__xpv
 int fastreboot_capable = 0;
--- a/usr/src/uts/i86pc/os/fastboot.c	Wed Sep 16 09:42:38 2009 -0700
+++ b/usr/src/uts/i86pc/os/fastboot.c	Wed Sep 16 09:51:25 2009 -0700
@@ -136,6 +136,11 @@
 int reserve_mem_enabled = 1;
 
 /*
+ * Mutex to protect fastreboot_onpanic.
+ */
+kmutex_t fastreboot_config_mutex;
+
+/*
  * Amount of memory below PA 1G to reserve for constructing the multiboot
  * data structure and the page tables as we tend to run out of those
  * when more drivers are loaded.
@@ -868,7 +873,8 @@
 	int		is_retry = 0;
 	uint64_t	end_addr;
 
-	ASSERT(fastreboot_capable);
+	if (!fastreboot_capable)
+		return;
 
 	if (newkernel.fi_valid)
 		fastboot_free_newkernel(&newkernel);
@@ -1408,12 +1414,16 @@
 	if (!fastreboot_capable)
 		return;
 
+	mutex_enter(&fastreboot_config_mutex);
+
 	fastboot_get_bootprop();
 
 	if (fastreboot_onpanic)
 		fastboot_load_kernel(fastreboot_onpanic_cmdline);
 	else if (reserve_mem_enabled)
 		fastboot_reserve_mem(&newkernel);
+
+	mutex_exit(&fastreboot_config_mutex);
 }
 
 /*
@@ -1427,15 +1437,69 @@
 fastboot_update_config(const char *mdep)
 {
 	uint8_t boot_config = (uint8_t)*mdep;
-	int cur_fastreboot_onpanic = fastreboot_onpanic;
+	int cur_fastreboot_onpanic;
 
 	if (!fastreboot_capable)
 		return;
 
+	mutex_enter(&fastreboot_config_mutex);
+
+	cur_fastreboot_onpanic = fastreboot_onpanic;
 	fastreboot_onpanic = boot_config & UA_FASTREBOOT_ONPANIC;
+
 	if (fastreboot_onpanic && (!cur_fastreboot_onpanic ||
 	    !newkernel.fi_valid))
 		fastboot_load_kernel(fastreboot_onpanic_cmdline);
 	if (cur_fastreboot_onpanic && !fastreboot_onpanic)
 		fastboot_free_newkernel(&newkernel);
+
+	mutex_exit(&fastreboot_config_mutex);
 }
+
+/*
+ * This is the interface to be called by other kernel components to
+ * disable fastreboot_onpanic.
+ */
+void
+fastreboot_disable()
+{
+	uint8_t boot_config = (uint8_t)(~UA_FASTREBOOT_ONPANIC);
+	fastboot_update_config((const char *)&boot_config);
+}
+
+/*
+ * This is the interface to be called by fm_panic() in case FMA has diagnosed
+ * a terminal machine check exception.  It does not free up memory allocated
+ * for the backup kernel.  General disabling fastreboot_onpanic in a
+ * non-panicking situation must go through fastboot_update_config().
+ */
+void
+fastreboot_disable_highpil()
+{
+	fastreboot_onpanic = 0;
+}
+
+
+/*
+ * A simplified interface for uadmin to call to update the configuration
+ * setting and load a new kernel if necessary.
+ */
+void
+fastboot_update_and_load(int fcn, char *mdep)
+{
+	if (fcn != AD_FASTREBOOT) {
+		/*
+		 * If user has explicitly requested reboot to prom,
+		 * or uadmin(1M) was invoked with other functions,
+		 * don't try to fast reboot after dumping.
+		 */
+		fastreboot_disable();
+	}
+
+	mutex_enter(&fastreboot_config_mutex);
+
+	if (fastreboot_onpanic)
+		fastboot_load_kernel(mdep);
+
+	mutex_exit(&fastreboot_config_mutex);
+}
--- a/usr/src/uts/i86pc/sys/fastboot.h	Wed Sep 16 09:42:38 2009 -0700
+++ b/usr/src/uts/i86pc/sys/fastboot.h	Wed Sep 16 09:51:25 2009 -0700
@@ -173,7 +173,7 @@
 extern int force_fastreboot;
 
 /* If set, fast reboot after panic. */
-extern int fastreboot_onpanic;
+extern volatile int fastreboot_onpanic;
 extern char fastreboot_onpanic_cmdline[FASTBOOT_SAVED_CMDLINE_LEN];
 
 #endif	/* _ASM */