changeset 9862:e8921084ee49

PSARC 2009/338 Introducing non-persistent property group config_ovr 6846870 Need to add non-persistent Fast Reboot disable support
author Sherry Moore <Sherry.Moore@Sun.COM>
date Fri, 12 Jun 2009 17:14:00 -0700
parents 7d024f07c388
children a7a0544360c9
files usr/src/cmd/fwflash/Makefile.com usr/src/cmd/fwflash/common/fwflash.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/sys/uadmin.h
diffstat 6 files changed, 184 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/fwflash/Makefile.com	Fri Jun 12 14:55:26 2009 -0700
+++ b/usr/src/cmd/fwflash/Makefile.com	Fri Jun 12 17:14:00 2009 -0700
@@ -18,7 +18,7 @@
 #
 # CDDL HEADER END
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # cmd/fwflash/Makefile.com
@@ -38,7 +38,7 @@
 ROOTUSRINCLUDEFWFLASH=  $(ROOTUSRINCLUDE)/fwflash
 ROOTUSRSBIN=		$(ROOT)/usr/sbin
 
-
+LDLIBS += -lscf
 
 $(ROOTLIB):
 	$(INS.dir)
--- a/usr/src/cmd/fwflash/common/fwflash.c	Fri Jun 12 14:55:26 2009 -0700
+++ b/usr/src/cmd/fwflash/common/fwflash.c	Fri Jun 12 17:14:00 2009 -0700
@@ -43,6 +43,7 @@
 #include <sys/varargs.h>
 #include <libintl.h> /* for gettext(3c) */
 #include <libdevinfo.h>
+#include <libscf_priv.h>
 #include <fwflash/fwflash.h>
 #include <sys/modctl.h> /* for MAXMODCONFNAME */
 
@@ -219,12 +220,21 @@
 	if ((fwflash_arg_list == (FWFLASH_FW_FLAG | FWFLASH_DEVICE_FLAG)) ||
 	    (fwflash_arg_list == (FWFLASH_FW_FLAG | FWFLASH_DEVICE_FLAG |
 	    FWFLASH_YES_FLAG))) {
+		int fastreboot_disabled = 0;
 		/* the update function handles the real arg parsing */
 		i = 0;
 		while (filelist[i] != NULL) {
 			if ((rv = fwflash_update(devpath, filelist[i],
 			    fwflash_arg_list)) == FWFLASH_SUCCESS) {
 				/* failed ops have already been noted */
+				if (!fastreboot_disabled &&
+				    scf_fastreboot_default_set_transient(
+				    B_FALSE) != SCF_SUCCESS)
+					logmsg(MSG_ERROR, gettext(
+					    "Failed to disable fast "
+					    "reboot.\n"));
+				else
+					fastreboot_disabled = 1;
 				logmsg(MSG_ERROR,
 				    gettext("New firmware will be activated "
 				    "after you reboot\n\n"));
--- a/usr/src/lib/libscf/common/highlevel.c	Fri Jun 12 14:55:26 2009 -0700
+++ b/usr/src/lib/libscf/common/highlevel.c	Fri Jun 12 17:14:00 2009 -0700
@@ -104,6 +104,54 @@
 
 	return (blacklisted);
 }
+
+/*
+ * Add or get a property group given an FMRI.
+ * Return SCF_SUCCESS on success, SCF_FAILED on failure.
+ */
+static int
+scf_fmri_pg_get_or_add(const char *fmri, const char *pgname,
+    const char *pgtype, uint32_t pgflags, int add)
+{
+	scf_handle_t	*handle = NULL;
+	scf_instance_t	*inst = NULL;
+	int		rc = SCF_FAILED;
+	int		error = SCF_ERROR_NONE;
+
+	if ((handle = scf_handle_create(SCF_VERSION)) == NULL ||
+	    scf_handle_bind(handle) != 0 ||
+	    (inst = scf_instance_create(handle)) == NULL ||
+	    scf_handle_decode_fmri(handle, fmri, NULL, NULL,
+	    inst, NULL, NULL, SCF_DECODE_FMRI_EXACT) != SCF_SUCCESS)
+		goto scferror;
+
+	if (add) {
+		rc = scf_instance_add_pg(inst, pgname, pgtype, pgflags, NULL);
+		/*
+		 * If the property group already exists, return SCF_SUCCESS.
+		 */
+		if (rc != SCF_SUCCESS && scf_error() == SCF_ERROR_EXISTS) {
+			(void) scf_set_error(SCF_ERROR_NONE);
+			rc = SCF_SUCCESS;
+		}
+	} else {
+		rc = scf_instance_get_pg(inst, pgname, NULL);
+	}
+
+scferror:
+	error = scf_error();
+
+	scf_instance_destroy(inst);
+	if (handle)
+		(void) scf_handle_unbind(handle);
+	scf_handle_destroy(handle);
+
+	if (error != SCF_ERROR_NONE) {
+		(void) scf_set_error(error);
+		rc = SCF_FAILED;
+	}
+	return (rc);
+}
 #endif	/* __x86 */
 
 /*
@@ -124,7 +172,7 @@
 		 * Property vector for BOOT_CONFIG_PG_PARAMS property group.
 		 */
 		scf_propvec_t ua_boot_config[] = {
-			{ "fastreboot_default", NULL, SCF_TYPE_BOOLEAN, NULL,
+			{ FASTREBOOT_DEFAULT, NULL, SCF_TYPE_BOOLEAN, NULL,
 			    UA_FASTREBOOT_DEFAULT },
 			{ FASTREBOOT_ONPANIC, NULL, SCF_TYPE_BOOLEAN, NULL,
 			    UA_FASTREBOOT_ONPANIC },
@@ -162,23 +210,119 @@
 }
 
 /*
+ * Get or set properties in non-persistent "config_ovr" property group
+ * in svc:/system/boot-config:default.
+ * It prints errors with uu_warn().
+ */
+/*ARGSUSED*/
+static int
+scf_getset_boot_config_ovr(int set, uint8_t *boot_config_ovr)
+{
+	int rc = SCF_SUCCESS;
+
+	assert(boot_config_ovr);
+
+#ifndef	__x86
+	return (rc);
+#else
+	{
+		/*
+		 * Property vector for BOOT_CONFIG_PG_OVR property group.
+		 */
+		scf_propvec_t ua_boot_config_ovr[] = {
+			{ FASTREBOOT_DEFAULT, NULL, SCF_TYPE_BOOLEAN, NULL,
+			    UA_FASTREBOOT_DEFAULT },
+			{ NULL }
+		};
+		scf_propvec_t	*prop;
+
+		rc = scf_fmri_pg_get_or_add(FMRI_BOOT_CONFIG,
+		    BOOT_CONFIG_PG_OVR, SCF_GROUP_APPLICATION,
+		    SCF_PG_FLAG_NONPERSISTENT, set);
+
+		if (rc != SCF_SUCCESS) {
+#if defined(FASTREBOOT_DEBUG)
+			if (set)
+				(void) uu_warn("Unable to add service %s "
+				    "property group '%s'\n",
+				    FMRI_BOOT_CONFIG, BOOT_CONFIG_PG_OVR);
+#endif	/* FASTREBOOT_DEBUG */
+			return (rc);
+		}
+
+		for (prop = ua_boot_config_ovr; prop->pv_prop != NULL; prop++)
+			prop->pv_ptr = boot_config_ovr;
+		prop = NULL;
+
+		if (set)
+			rc = scf_write_propvec(FMRI_BOOT_CONFIG,
+			    BOOT_CONFIG_PG_OVR, ua_boot_config_ovr, &prop);
+		else
+			rc = scf_read_propvec(FMRI_BOOT_CONFIG,
+			    BOOT_CONFIG_PG_OVR, B_FALSE, ua_boot_config_ovr,
+			    &prop);
+
+#if defined(FASTREBOOT_DEBUG)
+		if (rc != SCF_SUCCESS) {
+			if (prop != NULL) {
+				(void) uu_warn("Service %s property '%s/%s' "
+				    "not found.\n", FMRI_BOOT_CONFIG,
+				    BOOT_CONFIG_PG_OVR, prop->pv_prop);
+			} else {
+				(void) uu_warn("Unable to %s service %s "
+				    "property '%s': %s\n", set ? "set" : "get",
+				    FMRI_BOOT_CONFIG, BOOT_CONFIG_PG_OVR,
+				    scf_strerror(scf_error()));
+			}
+		}
+#endif	/* FASTREBOOT_DEBUG */
+		return (rc);
+
+	}
+#endif	/* __x86 */
+}
+
+/*
+ * Get values of properties in non-persistent "config_ovr" property group.
+ */
+static void
+scf_get_boot_config_ovr(uint8_t *boot_config_ovr)
+{
+	(void) scf_getset_boot_config_ovr(B_FALSE, boot_config_ovr);
+}
+
+/*
+ * Set value of "config_ovr/fastreboot_default".
+ */
+int
+scf_fastreboot_default_set_transient(boolean_t value)
+{
+	uint8_t	boot_config_ovr = (value & UA_FASTREBOOT_DEFAULT);
+
+	return (scf_getset_boot_config_ovr(B_TRUE, &boot_config_ovr));
+}
+
+/*
  * Check whether Fast Reboot is the default operating mode.
  * Return 0 if
  *   1. the platform is xVM
  * or
  *   2. svc:/system/boot-config:default service doesn't exist,
  * or
- *   3. property "fastreboot_default" doesn't exist,
+ *   3. property "config/fastreboot_default" doesn't exist,
  * or
- *   4. value of property "fastreboot_default" is set to 0.
+ *   4. value of property "config/fastreboot_default" is set to "false"
+ *      and "config_ovr/fastreboot_default" is not set to "true",
  * or
  *   5. the platform has been blacklisted.
+ * or
+ *   6. value of property "config_ovr/fastreboot_default" is set to "false".
  * Return non-zero otherwise.
  */
 int
 scf_is_fastboot_default(void)
 {
-	uint8_t	boot_config = 0;
+	uint8_t	boot_config = 0, boot_config_ovr;
 	char procbuf[SYS_NMLN];
 
 	/*
@@ -188,6 +332,16 @@
 	    strcmp(procbuf, "i86xpv") == 0)
 		return (0);
 
+	/*
+	 * Get property values from "config" property group
+	 */
 	scf_get_boot_config(&boot_config);
-	return (boot_config & UA_FASTREBOOT_DEFAULT);
+
+	/*
+	 * Get property values from non-persistent "config_ovr" property group
+	 */
+	boot_config_ovr = boot_config;
+	scf_get_boot_config_ovr(&boot_config_ovr);
+
+	return (boot_config & boot_config_ovr & UA_FASTREBOOT_DEFAULT);
 }
--- a/usr/src/lib/libscf/common/mapfile-vers	Fri Jun 12 14:55:26 2009 -0700
+++ b/usr/src/lib/libscf/common/mapfile-vers	Fri Jun 12 17:14:00 2009 -0700
@@ -316,6 +316,7 @@
 	scf_instance_delete_prop;
 	scf_get_boot_config;
 	scf_is_fastboot_default;
+	scf_fastreboot_default_set_transient;
     local:
 	*;
 };
--- a/usr/src/lib/libscf/inc/libscf_priv.h	Fri Jun 12 14:55:26 2009 -0700
+++ b/usr/src/lib/libscf/inc/libscf_priv.h	Fri Jun 12 17:14:00 2009 -0700
@@ -533,6 +533,11 @@
 int scf_is_fastboot_default(void);
 
 /*
+ * Set value of "config_ovr/fastreboot_default".
+ */
+int scf_fastreboot_default_set_transient(boolean_t);
+
+/*
  * scf_is_compatible_type()
  * Return true if the second type is the same type, or a subtype of the
  * first.
--- a/usr/src/uts/common/sys/uadmin.h	Fri Jun 12 14:55:26 2009 -0700
+++ b/usr/src/uts/common/sys/uadmin.h	Fri Jun 12 17:14:00 2009 -0700
@@ -122,6 +122,12 @@
  */
 #define	BOOT_CONFIG_PG_FBBLACKLIST	"fastreboot_blacklist"
 
+/*
+ * Non-persistent property group which contains all the properties that
+ * will override settings in the BOOT_CONFIG_PG_PARAMS property group.
+ */
+#define	BOOT_CONFIG_PG_OVR		"config_ovr"
+
 #endif	/* _KERNEL */
 
 /*
@@ -130,6 +136,7 @@
 #define	UA_FASTREBOOT_DEFAULT	0x01
 #define	UA_FASTREBOOT_ONPANIC	0x02
 
+#define	FASTREBOOT_DEFAULT		"fastreboot_default"
 #define	FASTREBOOT_ONPANIC		"fastreboot_onpanic"
 #define	FASTREBOOT_ONPANIC_CMDLINE	"fastreboot_onpanic_cmdline"