summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSherry Moore <Sherry.Moore@Sun.COM>2009-06-12 17:14:00 -0700
committerSherry Moore <Sherry.Moore@Sun.COM>2009-06-12 17:14:00 -0700
commit4196e26398ab7019943a8f276006fa66937b4425 (patch)
tree74790ea356e100701e125e1181b377b68ecb6f00
parentc0fff658e7a381fc0f01e482f7bb09d12aee801a (diff)
downloadillumos-joyent-4196e26398ab7019943a8f276006fa66937b4425.tar.gz
PSARC 2009/338 Introducing non-persistent property group config_ovr
6846870 Need to add non-persistent Fast Reboot disable support
-rw-r--r--usr/src/cmd/fwflash/Makefile.com4
-rw-r--r--usr/src/cmd/fwflash/common/fwflash.c10
-rw-r--r--usr/src/lib/libscf/common/highlevel.c164
-rw-r--r--usr/src/lib/libscf/common/mapfile-vers1
-rw-r--r--usr/src/lib/libscf/inc/libscf_priv.h5
-rw-r--r--usr/src/uts/common/sys/uadmin.h7
6 files changed, 184 insertions, 7 deletions
diff --git a/usr/src/cmd/fwflash/Makefile.com b/usr/src/cmd/fwflash/Makefile.com
index e0f1c58ec2..a3988a6e76 100644
--- a/usr/src/cmd/fwflash/Makefile.com
+++ b/usr/src/cmd/fwflash/Makefile.com
@@ -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 @@ ROOTUSRINCLUDE= $(ROOTUSR)/include
ROOTUSRINCLUDEFWFLASH= $(ROOTUSRINCLUDE)/fwflash
ROOTUSRSBIN= $(ROOT)/usr/sbin
-
+LDLIBS += -lscf
$(ROOTLIB):
$(INS.dir)
diff --git a/usr/src/cmd/fwflash/common/fwflash.c b/usr/src/cmd/fwflash/common/fwflash.c
index ead9c4f2ce..12a7a93665 100644
--- a/usr/src/cmd/fwflash/common/fwflash.c
+++ b/usr/src/cmd/fwflash/common/fwflash.c
@@ -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 @@ main(int argc, char **argv)
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"));
diff --git a/usr/src/lib/libscf/common/highlevel.c b/usr/src/lib/libscf/common/highlevel.c
index 6444d260c2..339c9d8ff4 100644
--- a/usr/src/lib/libscf/common/highlevel.c
+++ b/usr/src/lib/libscf/common/highlevel.c
@@ -104,6 +104,54 @@ fb_out:
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 @@ scf_get_boot_config(uint8_t *boot_config)
* 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 @@ scf_get_boot_config(uint8_t *boot_config)
}
/*
+ * 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 @@ scf_is_fastboot_default(void)
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);
}
diff --git a/usr/src/lib/libscf/common/mapfile-vers b/usr/src/lib/libscf/common/mapfile-vers
index d142b96372..0022b7cef5 100644
--- a/usr/src/lib/libscf/common/mapfile-vers
+++ b/usr/src/lib/libscf/common/mapfile-vers
@@ -316,6 +316,7 @@ SUNWprivate_1.1 {
scf_instance_delete_prop;
scf_get_boot_config;
scf_is_fastboot_default;
+ scf_fastreboot_default_set_transient;
local:
*;
};
diff --git a/usr/src/lib/libscf/inc/libscf_priv.h b/usr/src/lib/libscf/inc/libscf_priv.h
index f9b6c3b5b9..c34d905e0c 100644
--- a/usr/src/lib/libscf/inc/libscf_priv.h
+++ b/usr/src/lib/libscf/inc/libscf_priv.h
@@ -533,6 +533,11 @@ void scf_get_boot_config(uint8_t *);
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.
diff --git a/usr/src/uts/common/sys/uadmin.h b/usr/src/uts/common/sys/uadmin.h
index 8fad240cf3..c35d0a5cfb 100644
--- a/usr/src/uts/common/sys/uadmin.h
+++ b/usr/src/uts/common/sys/uadmin.h
@@ -122,6 +122,12 @@ extern "C" {
*/
#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 @@ extern "C" {
#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"