diff options
| author | Sherry Moore <Sherry.Moore@Sun.COM> | 2009-06-12 17:14:00 -0700 |
|---|---|---|
| committer | Sherry Moore <Sherry.Moore@Sun.COM> | 2009-06-12 17:14:00 -0700 |
| commit | 4196e26398ab7019943a8f276006fa66937b4425 (patch) | |
| tree | 74790ea356e100701e125e1181b377b68ecb6f00 | |
| parent | c0fff658e7a381fc0f01e482f7bb09d12aee801a (diff) | |
| download | illumos-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.com | 4 | ||||
| -rw-r--r-- | usr/src/cmd/fwflash/common/fwflash.c | 10 | ||||
| -rw-r--r-- | usr/src/lib/libscf/common/highlevel.c | 164 | ||||
| -rw-r--r-- | usr/src/lib/libscf/common/mapfile-vers | 1 | ||||
| -rw-r--r-- | usr/src/lib/libscf/inc/libscf_priv.h | 5 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/uadmin.h | 7 |
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" |
