17aec1d6eScindi /* 27aec1d6eScindi * CDDL HEADER START 37aec1d6eScindi * 47aec1d6eScindi * The contents of this file are subject to the terms of the 574a31ce6Stimh * Common Development and Distribution License (the "License"). 674a31ce6Stimh * You may not use this file except in compliance with the License. 77aec1d6eScindi * 87aec1d6eScindi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97aec1d6eScindi * or http://www.opensolaris.org/os/licensing. 107aec1d6eScindi * See the License for the specific language governing permissions 117aec1d6eScindi * and limitations under the License. 127aec1d6eScindi * 137aec1d6eScindi * When distributing Covered Code, include this CDDL HEADER in each 147aec1d6eScindi * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157aec1d6eScindi * If applicable, add the following below this CDDL HEADER, with the 167aec1d6eScindi * fields enclosed by brackets "[]" replaced with your own identifying 177aec1d6eScindi * information: Portions Copyright [yyyy] [name of copyright owner] 187aec1d6eScindi * 197aec1d6eScindi * CDDL HEADER END 207aec1d6eScindi */ 217aec1d6eScindi 227aec1d6eScindi /* 238393544eSHyon Kim * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 247aec1d6eScindi */ 258522c52aSRob Johnston /* 26*c5591576SRob Johnston * Copyright 2020 Joyent, Inc. 278522c52aSRob Johnston */ 287aec1d6eScindi 297aec1d6eScindi #include <alloca.h> 300eb822a1Scindi #include <ctype.h> 310eb822a1Scindi #include <limits.h> 327aec1d6eScindi #include <syslog.h> 337aec1d6eScindi #include <strings.h> 340eb822a1Scindi #include <unistd.h> 358522c52aSRob Johnston #include <sys/fm/protocol.h> 368522c52aSRob Johnston #include <sys/systeminfo.h> 378522c52aSRob Johnston #include <sys/utsname.h> 387aec1d6eScindi 397aec1d6eScindi #include <topo_error.h> 40*c5591576SRob Johnston #include <topo_digraph.h> 417aec1d6eScindi #include <topo_subr.h> 427aec1d6eScindi 437aec1d6eScindi void 447aec1d6eScindi topo_hdl_lock(topo_hdl_t *thp) 457aec1d6eScindi { 467aec1d6eScindi (void) pthread_mutex_lock(&thp->th_lock); 477aec1d6eScindi } 487aec1d6eScindi 497aec1d6eScindi void 507aec1d6eScindi topo_hdl_unlock(topo_hdl_t *thp) 517aec1d6eScindi { 527aec1d6eScindi (void) pthread_mutex_unlock(&thp->th_lock); 537aec1d6eScindi } 547aec1d6eScindi 557aec1d6eScindi const char * 560eb822a1Scindi topo_stability2name(topo_stability_t s) 577aec1d6eScindi { 587aec1d6eScindi switch (s) { 590eb822a1Scindi case TOPO_STABILITY_INTERNAL: return (TOPO_STABSTR_INTERNAL); 600eb822a1Scindi case TOPO_STABILITY_PRIVATE: return (TOPO_STABSTR_PRIVATE); 610eb822a1Scindi case TOPO_STABILITY_OBSOLETE: return (TOPO_STABSTR_OBSOLETE); 620eb822a1Scindi case TOPO_STABILITY_EXTERNAL: return (TOPO_STABSTR_EXTERNAL); 630eb822a1Scindi case TOPO_STABILITY_UNSTABLE: return (TOPO_STABSTR_UNSTABLE); 640eb822a1Scindi case TOPO_STABILITY_EVOLVING: return (TOPO_STABSTR_EVOLVING); 650eb822a1Scindi case TOPO_STABILITY_STABLE: return (TOPO_STABSTR_STABLE); 660eb822a1Scindi case TOPO_STABILITY_STANDARD: return (TOPO_STABSTR_STANDARD); 670eb822a1Scindi default: return (TOPO_STABSTR_UNKNOWN); 687aec1d6eScindi } 697aec1d6eScindi } 707aec1d6eScindi 710eb822a1Scindi topo_stability_t 720eb822a1Scindi topo_name2stability(const char *name) 730eb822a1Scindi { 740eb822a1Scindi if (strcmp(name, TOPO_STABSTR_INTERNAL) == 0) 750eb822a1Scindi return (TOPO_STABILITY_INTERNAL); 760eb822a1Scindi else if (strcmp(name, TOPO_STABSTR_PRIVATE) == 0) 770eb822a1Scindi return (TOPO_STABILITY_PRIVATE); 780eb822a1Scindi else if (strcmp(name, TOPO_STABSTR_OBSOLETE) == 0) 790eb822a1Scindi return (TOPO_STABILITY_OBSOLETE); 800eb822a1Scindi else if (strcmp(name, TOPO_STABSTR_EXTERNAL) == 0) 810eb822a1Scindi return (TOPO_STABILITY_EXTERNAL); 820eb822a1Scindi else if (strcmp(name, TOPO_STABSTR_UNSTABLE) == 0) 830eb822a1Scindi return (TOPO_STABILITY_UNSTABLE); 840eb822a1Scindi else if (strcmp(name, TOPO_STABSTR_EVOLVING) == 0) 850eb822a1Scindi return (TOPO_STABILITY_EVOLVING); 860eb822a1Scindi else if (strcmp(name, TOPO_STABSTR_STABLE) == 0) 870eb822a1Scindi return (TOPO_STABILITY_STABLE); 880eb822a1Scindi else if (strcmp(name, TOPO_STABSTR_STANDARD) == 0) 890eb822a1Scindi return (TOPO_STABILITY_STANDARD); 900eb822a1Scindi 910eb822a1Scindi return (TOPO_STABILITY_UNKNOWN); 920eb822a1Scindi } 930eb822a1Scindi 947aec1d6eScindi static const topo_debug_mode_t _topo_dbout_modes[] = { 957aec1d6eScindi { "stderr", "send debug messages to stderr", TOPO_DBOUT_STDERR }, 967aec1d6eScindi { "syslog", "send debug messages to syslog", TOPO_DBOUT_SYSLOG }, 977aec1d6eScindi { NULL, NULL, 0 } 987aec1d6eScindi }; 997aec1d6eScindi 1000eb822a1Scindi static const topo_debug_mode_t _topo_dbflag_modes[] = { 1010eb822a1Scindi { "error", "error handling debug messages enabled", TOPO_DBG_ERR }, 1020eb822a1Scindi { "module", "module debug messages enabled", TOPO_DBG_MOD }, 1030eb822a1Scindi { "modulesvc", "module services debug messages enabled", 1040eb822a1Scindi TOPO_DBG_MODSVC }, 1050eb822a1Scindi { "walk", "walker subsystem debug messages enabled", TOPO_DBG_WALK }, 1060eb822a1Scindi { "xml", "xml file parsing messages enabled", TOPO_DBG_XML }, 1078393544eSHyon Kim { "devinfoforce", "devinfo DINFOFORCE snapshot used", TOPO_DBG_FORCE }, 1080eb822a1Scindi { "all", "all debug modes enabled", TOPO_DBG_ALL}, 1090eb822a1Scindi { NULL, NULL, 0 } 1100eb822a1Scindi }; 1110eb822a1Scindi 1127aec1d6eScindi void 1130eb822a1Scindi env_process_value(topo_hdl_t *thp, const char *begin, const char *end) 1147aec1d6eScindi { 1150eb822a1Scindi char buf[MAXNAMELEN]; 1160eb822a1Scindi size_t count; 1170eb822a1Scindi topo_debug_mode_t *dbp; 1180eb822a1Scindi 1190eb822a1Scindi while (begin < end && isspace(*begin)) 1200eb822a1Scindi begin++; 1210eb822a1Scindi 1220eb822a1Scindi while (begin < end && isspace(*(end - 1))) 1230eb822a1Scindi end--; 1240eb822a1Scindi 1250eb822a1Scindi if (begin >= end) 1260eb822a1Scindi return; 1270eb822a1Scindi 1280eb822a1Scindi count = end - begin; 1290eb822a1Scindi count += 1; 1300eb822a1Scindi 1310eb822a1Scindi if (count > sizeof (buf)) 1320eb822a1Scindi return; 1330eb822a1Scindi 1340eb822a1Scindi (void) snprintf(buf, count, "%s", begin); 1350eb822a1Scindi 1360eb822a1Scindi for (dbp = (topo_debug_mode_t *)_topo_dbflag_modes; 1370eb822a1Scindi dbp->tdm_name != NULL; ++dbp) { 1380eb822a1Scindi if (strcmp(buf, dbp->tdm_name) == 0) 1390eb822a1Scindi thp->th_debug |= dbp->tdm_mode; 1400eb822a1Scindi } 1410eb822a1Scindi } 1420eb822a1Scindi 1430eb822a1Scindi void 1440eb822a1Scindi topo_debug_set(topo_hdl_t *thp, const char *dbmode, const char *dout) 1450eb822a1Scindi { 1460eb822a1Scindi char *end, *value, *next; 1470eb822a1Scindi topo_debug_mode_t *dbp; 1480eb822a1Scindi 1490eb822a1Scindi topo_hdl_lock(thp); 1500eb822a1Scindi value = (char *)dbmode; 1510eb822a1Scindi 1520eb822a1Scindi for (end = (char *)dbmode; *end != '\0'; value = next) { 1530eb822a1Scindi end = strchr(value, ','); 1540eb822a1Scindi if (end != NULL) 1550eb822a1Scindi next = end + 1; /* skip the comma */ 1560eb822a1Scindi else 1570eb822a1Scindi next = end = value + strlen(value); 1580eb822a1Scindi 1590eb822a1Scindi env_process_value(thp, value, end); 1600eb822a1Scindi } 1610eb822a1Scindi 1620eb822a1Scindi if (dout == NULL) { 1630eb822a1Scindi topo_hdl_unlock(thp); 1640eb822a1Scindi return; 1657aec1d6eScindi } 1660eb822a1Scindi 1670eb822a1Scindi for (dbp = (topo_debug_mode_t *)_topo_dbout_modes; 1680eb822a1Scindi dbp->tdm_name != NULL; ++dbp) { 1690eb822a1Scindi if (strcmp(dout, dbp->tdm_name) == 0) 1701e95bfe1SRob Johnston thp->th_dbout = dbp->tdm_mode; 1710eb822a1Scindi } 1720eb822a1Scindi topo_hdl_unlock(thp); 1737aec1d6eScindi } 1747aec1d6eScindi 1757aec1d6eScindi void 1761de1e652SRob Johnston topo_vdprintf(topo_hdl_t *thp, const char *mod, const char *format, va_list ap) 1777aec1d6eScindi { 1787aec1d6eScindi char *msg; 1797aec1d6eScindi size_t len; 1807aec1d6eScindi char c; 1817aec1d6eScindi 1827aec1d6eScindi len = vsnprintf(&c, 1, format, ap); 1837aec1d6eScindi msg = alloca(len + 2); 1847aec1d6eScindi (void) vsnprintf(msg, len + 1, format, ap); 1857aec1d6eScindi 1867aec1d6eScindi if (msg[len - 1] != '\n') 1877aec1d6eScindi (void) strcpy(&msg[len], "\n"); 1887aec1d6eScindi 1890eb822a1Scindi if (thp->th_dbout == TOPO_DBOUT_SYSLOG) { 1900eb822a1Scindi if (mod == NULL) { 1910eb822a1Scindi syslog(LOG_DEBUG | LOG_USER, "libtopo DEBUG: %s", msg); 1920eb822a1Scindi } else { 1930eb822a1Scindi syslog(LOG_DEBUG | LOG_USER, "libtopo DEBUG: %s: %s", 1940eb822a1Scindi mod, msg); 1950eb822a1Scindi } 1960eb822a1Scindi } else { 1970eb822a1Scindi if (mod == NULL) { 1980eb822a1Scindi (void) fprintf(stderr, "libtopo DEBUG: %s", msg); 1990eb822a1Scindi } else { 2000eb822a1Scindi (void) fprintf(stderr, "libtopo DEBUG: %s: %s", mod, 2010eb822a1Scindi msg); 2020eb822a1Scindi } 2030eb822a1Scindi } 2047aec1d6eScindi } 2057aec1d6eScindi 2060eb822a1Scindi /*PRINTFLIKE3*/ 2077aec1d6eScindi void 2080eb822a1Scindi topo_dprintf(topo_hdl_t *thp, int mask, const char *format, ...) 2097aec1d6eScindi { 2107aec1d6eScindi va_list ap; 2117aec1d6eScindi 2121de1e652SRob Johnston if (!(thp->th_debug & mask)) 2131de1e652SRob Johnston return; 2141de1e652SRob Johnston 2157aec1d6eScindi va_start(ap, format); 2161de1e652SRob Johnston topo_vdprintf(thp, NULL, format, ap); 2177aec1d6eScindi va_end(ap); 2187aec1d6eScindi } 2197aec1d6eScindi 2207aec1d6eScindi tnode_t * 2217aec1d6eScindi topo_hdl_root(topo_hdl_t *thp, const char *scheme) 2227aec1d6eScindi { 2237aec1d6eScindi ttree_t *tp; 224*c5591576SRob Johnston topo_digraph_t *tdg; 2257aec1d6eScindi 2267aec1d6eScindi for (tp = topo_list_next(&thp->th_trees); tp != NULL; 2277aec1d6eScindi tp = topo_list_next(tp)) { 2287aec1d6eScindi if (strcmp(scheme, tp->tt_scheme) == 0) 2297aec1d6eScindi return (tp->tt_root); 2307aec1d6eScindi } 231*c5591576SRob Johnston for (tdg = topo_list_next(&thp->th_digraphs); tdg != NULL; 232*c5591576SRob Johnston tdg = topo_list_next(tdg)) { 233*c5591576SRob Johnston if (strcmp(scheme, tdg->tdg_scheme) == 0) 234*c5591576SRob Johnston return (tdg->tdg_rootnode); 235*c5591576SRob Johnston } 2367aec1d6eScindi 2377aec1d6eScindi return (NULL); 2387aec1d6eScindi } 23974a31ce6Stimh 24074a31ce6Stimh /* 24174a31ce6Stimh * buf_append -- Append str to buf (if it's non-NULL). Place prepend 24274a31ce6Stimh * in buf in front of str and append behind it (if they're non-NULL). 24374a31ce6Stimh * Continue to update size even if we run out of space to actually 24474a31ce6Stimh * stuff characters in the buffer. 24574a31ce6Stimh */ 24674a31ce6Stimh void 24774a31ce6Stimh topo_fmristr_build(ssize_t *sz, char *buf, size_t buflen, char *str, 24874a31ce6Stimh char *prepend, char *append) 24974a31ce6Stimh { 25074a31ce6Stimh ssize_t left; 25174a31ce6Stimh 25274a31ce6Stimh if (str == NULL) 25374a31ce6Stimh return; 25474a31ce6Stimh 25574a31ce6Stimh if (buflen == 0 || (left = buflen - *sz) < 0) 25674a31ce6Stimh left = 0; 25774a31ce6Stimh 25874a31ce6Stimh if (buf != NULL && left != 0) 25974a31ce6Stimh buf += *sz; 26074a31ce6Stimh 26174a31ce6Stimh if (prepend == NULL && append == NULL) 26274a31ce6Stimh *sz += snprintf(buf, left, "%s", str); 26374a31ce6Stimh else if (append == NULL) 26474a31ce6Stimh *sz += snprintf(buf, left, "%s%s", prepend, str); 26574a31ce6Stimh else if (prepend == NULL) 26674a31ce6Stimh *sz += snprintf(buf, left, "%s%s", str, append); 26774a31ce6Stimh else 26874a31ce6Stimh *sz += snprintf(buf, left, "%s%s%s", prepend, str, append); 26974a31ce6Stimh } 2700eb822a1Scindi 2710eb822a1Scindi #define TOPO_PLATFORM_PATH "%s/usr/platform/%s/lib/fm/topo/%s" 2720eb822a1Scindi #define TOPO_COMMON_PATH "%s/usr/lib/fm/topo/%s" 2730eb822a1Scindi 2740eb822a1Scindi char * 2750eb822a1Scindi topo_search_path(topo_mod_t *mod, const char *rootdir, const char *file) 2760eb822a1Scindi { 2770eb822a1Scindi char *pp, sp[PATH_MAX]; 2780eb822a1Scindi topo_hdl_t *thp = mod->tm_hdl; 2790eb822a1Scindi 2800eb822a1Scindi /* 2810eb822a1Scindi * Search for file name in order of platform, machine and common 2820eb822a1Scindi * topo directories 2830eb822a1Scindi */ 2840eb822a1Scindi (void) snprintf(sp, PATH_MAX, TOPO_PLATFORM_PATH, rootdir, 2850eb822a1Scindi thp->th_platform, file); 2860eb822a1Scindi if (access(sp, F_OK) != 0) { 2870eb822a1Scindi (void) snprintf(sp, PATH_MAX, TOPO_PLATFORM_PATH, 2880eb822a1Scindi thp->th_rootdir, thp->th_machine, file); 2890eb822a1Scindi if (access(sp, F_OK) != 0) { 2900eb822a1Scindi (void) snprintf(sp, PATH_MAX, TOPO_COMMON_PATH, 2910eb822a1Scindi thp->th_rootdir, file); 2920eb822a1Scindi if (access(sp, F_OK) != 0) { 2930eb822a1Scindi return (NULL); 2940eb822a1Scindi } 2950eb822a1Scindi } 2960eb822a1Scindi } 2970eb822a1Scindi 2980eb822a1Scindi pp = topo_mod_strdup(mod, sp); 2990eb822a1Scindi 3000eb822a1Scindi return (pp); 3010eb822a1Scindi } 30224db4641Seschrock 30324db4641Seschrock /* 30424db4641Seschrock * SMBIOS serial numbers can contain characters (particularly ':' and ' ') 30524db4641Seschrock * that are invalid for the authority and can break FMRI parsing. We translate 30624db4641Seschrock * any invalid characters to a safe '-', as well as trimming any leading or 30720c794b3Sgavinm * trailing whitespace. Similarly, '/' can be found in some product names 30820c794b3Sgavinm * so we translate that to '-'. 30924db4641Seschrock */ 31024db4641Seschrock char * 311e3d60c9bSAdrian Frost topo_cleanup_auth_str(topo_hdl_t *thp, const char *begin) 31224db4641Seschrock { 31324db4641Seschrock char buf[MAXNAMELEN]; 314e3d60c9bSAdrian Frost const char *end, *cp; 315e3d60c9bSAdrian Frost char *pp; 316e3d60c9bSAdrian Frost char c; 317e3d60c9bSAdrian Frost int i; 31824db4641Seschrock 31924db4641Seschrock end = begin + strlen(begin); 32024db4641Seschrock 32124db4641Seschrock while (begin < end && isspace(*begin)) 32224db4641Seschrock begin++; 32324db4641Seschrock while (begin < end && isspace(*(end - 1))) 32424db4641Seschrock end--; 32524db4641Seschrock 32624db4641Seschrock if (begin >= end) 32724db4641Seschrock return (NULL); 32824db4641Seschrock 329e3d60c9bSAdrian Frost cp = begin; 330e3d60c9bSAdrian Frost for (i = 0; i < MAXNAMELEN - 1; i++) { 331e3d60c9bSAdrian Frost if (cp >= end) 332e3d60c9bSAdrian Frost break; 333e3d60c9bSAdrian Frost c = *cp; 334e3d60c9bSAdrian Frost if (c == ':' || c == '=' || c == '/' || isspace(c) || 335e3d60c9bSAdrian Frost !isprint(c)) 336e3d60c9bSAdrian Frost buf[i] = '-'; 337e3d60c9bSAdrian Frost else 338e3d60c9bSAdrian Frost buf[i] = c; 339e3d60c9bSAdrian Frost cp++; 340e3d60c9bSAdrian Frost } 341e3d60c9bSAdrian Frost buf[i] = 0; 34224db4641Seschrock 34324db4641Seschrock pp = topo_hdl_strdup(thp, buf); 34424db4641Seschrock return (pp); 34524db4641Seschrock } 346825ba0f2Srobj 347825ba0f2Srobj void 348825ba0f2Srobj topo_sensor_type_name(uint32_t type, char *buf, size_t len) 349825ba0f2Srobj { 350825ba0f2Srobj topo_name_trans_t *ntp; 351825ba0f2Srobj 352825ba0f2Srobj for (ntp = &topo_sensor_type_table[0]; ntp->int_name != NULL; ntp++) { 353825ba0f2Srobj if (ntp->int_value == type) { 354825ba0f2Srobj (void) strlcpy(buf, ntp->int_name, len); 355825ba0f2Srobj return; 356825ba0f2Srobj } 357825ba0f2Srobj } 358825ba0f2Srobj 359825ba0f2Srobj (void) snprintf(buf, len, "0x%02x", type); 360825ba0f2Srobj } 361825ba0f2Srobj 362825ba0f2Srobj void 363825ba0f2Srobj topo_sensor_units_name(uint8_t type, char *buf, size_t len) 364825ba0f2Srobj { 365825ba0f2Srobj topo_name_trans_t *ntp; 366825ba0f2Srobj 367825ba0f2Srobj for (ntp = &topo_units_type_table[0]; ntp->int_name != NULL; ntp++) { 368825ba0f2Srobj if (ntp->int_value == type) { 369825ba0f2Srobj (void) strlcpy(buf, ntp->int_name, len); 370825ba0f2Srobj return; 371825ba0f2Srobj } 372825ba0f2Srobj } 373825ba0f2Srobj 374825ba0f2Srobj (void) snprintf(buf, len, "0x%02x", type); 375825ba0f2Srobj } 376825ba0f2Srobj 377825ba0f2Srobj void 378825ba0f2Srobj topo_led_type_name(uint8_t type, char *buf, size_t len) 379825ba0f2Srobj { 380825ba0f2Srobj topo_name_trans_t *ntp; 381825ba0f2Srobj 382825ba0f2Srobj for (ntp = &topo_led_type_table[0]; ntp->int_name != NULL; ntp++) { 383825ba0f2Srobj if (ntp->int_value == type) { 384825ba0f2Srobj (void) strlcpy(buf, ntp->int_name, len); 385825ba0f2Srobj return; 386825ba0f2Srobj } 387825ba0f2Srobj } 388825ba0f2Srobj 389825ba0f2Srobj (void) snprintf(buf, len, "0x%02x", type); 390825ba0f2Srobj } 391825ba0f2Srobj 392825ba0f2Srobj void 393825ba0f2Srobj topo_led_state_name(uint8_t type, char *buf, size_t len) 394825ba0f2Srobj { 395825ba0f2Srobj topo_name_trans_t *ntp; 396825ba0f2Srobj 397825ba0f2Srobj for (ntp = &topo_led_states_table[0]; ntp->int_name != NULL; ntp++) { 398825ba0f2Srobj if (ntp->int_value == type) { 399825ba0f2Srobj (void) strlcpy(buf, ntp->int_name, len); 400825ba0f2Srobj return; 401825ba0f2Srobj } 402825ba0f2Srobj } 403825ba0f2Srobj 404825ba0f2Srobj (void) snprintf(buf, len, "0x%02x", type); 405825ba0f2Srobj } 406825ba0f2Srobj 407825ba0f2Srobj void 408825ba0f2Srobj topo_sensor_state_name(uint32_t sensor_type, uint8_t state, char *buf, 4098522c52aSRob Johnston size_t len) 410825ba0f2Srobj { 411825ba0f2Srobj topo_name_trans_t *ntp; 412825ba0f2Srobj 413825ba0f2Srobj switch (sensor_type) { 414825ba0f2Srobj case TOPO_SENSOR_TYPE_PHYSICAL: 415825ba0f2Srobj ntp = &topo_sensor_states_physical_table[0]; 416825ba0f2Srobj break; 417825ba0f2Srobj case TOPO_SENSOR_TYPE_PLATFORM: 418825ba0f2Srobj ntp = &topo_sensor_states_platform_table[0]; 419825ba0f2Srobj break; 420825ba0f2Srobj case TOPO_SENSOR_TYPE_PROCESSOR: 421825ba0f2Srobj ntp = &topo_sensor_states_processor_table[0]; 422825ba0f2Srobj break; 423825ba0f2Srobj case TOPO_SENSOR_TYPE_POWER_SUPPLY: 424825ba0f2Srobj ntp = &topo_sensor_states_power_supply_table[0]; 425825ba0f2Srobj break; 426825ba0f2Srobj case TOPO_SENSOR_TYPE_POWER_UNIT: 427825ba0f2Srobj ntp = &topo_sensor_states_power_unit_table[0]; 428825ba0f2Srobj break; 429825ba0f2Srobj case TOPO_SENSOR_TYPE_MEMORY: 430825ba0f2Srobj ntp = &topo_sensor_states_memory_table[0]; 431825ba0f2Srobj break; 432825ba0f2Srobj case TOPO_SENSOR_TYPE_BAY: 433825ba0f2Srobj ntp = &topo_sensor_states_bay_table[0]; 434825ba0f2Srobj break; 435825ba0f2Srobj case TOPO_SENSOR_TYPE_FIRMWARE: 436825ba0f2Srobj ntp = &topo_sensor_states_firmware_table[0]; 437825ba0f2Srobj break; 438825ba0f2Srobj case TOPO_SENSOR_TYPE_EVENT_LOG: 439825ba0f2Srobj ntp = &topo_sensor_states_event_log_table[0]; 440825ba0f2Srobj break; 441825ba0f2Srobj case TOPO_SENSOR_TYPE_WATCHDOG1: 442825ba0f2Srobj ntp = &topo_sensor_states_watchdog1_table[0]; 443825ba0f2Srobj break; 444825ba0f2Srobj case TOPO_SENSOR_TYPE_SYSTEM: 445825ba0f2Srobj ntp = &topo_sensor_states_system_table[0]; 446825ba0f2Srobj break; 447825ba0f2Srobj case TOPO_SENSOR_TYPE_CRITICAL: 448825ba0f2Srobj ntp = &topo_sensor_states_critical_table[0]; 449825ba0f2Srobj break; 450825ba0f2Srobj case TOPO_SENSOR_TYPE_BUTTON: 451825ba0f2Srobj ntp = &topo_sensor_states_button_table[0]; 452825ba0f2Srobj break; 453825ba0f2Srobj case TOPO_SENSOR_TYPE_CABLE: 454825ba0f2Srobj ntp = &topo_sensor_states_cable_table[0]; 455825ba0f2Srobj break; 456825ba0f2Srobj case TOPO_SENSOR_TYPE_BOOT_STATE: 457825ba0f2Srobj ntp = &topo_sensor_states_boot_state_table[0]; 458825ba0f2Srobj break; 459825ba0f2Srobj case TOPO_SENSOR_TYPE_BOOT_ERROR: 460825ba0f2Srobj ntp = &topo_sensor_states_boot_error_table[0]; 461825ba0f2Srobj break; 462825ba0f2Srobj case TOPO_SENSOR_TYPE_BOOT_OS: 463825ba0f2Srobj ntp = &topo_sensor_states_boot_os_table[0]; 464825ba0f2Srobj break; 465825ba0f2Srobj case TOPO_SENSOR_TYPE_OS_SHUTDOWN: 466825ba0f2Srobj ntp = &topo_sensor_states_os_table[0]; 467825ba0f2Srobj break; 468825ba0f2Srobj case TOPO_SENSOR_TYPE_SLOT: 469825ba0f2Srobj ntp = &topo_sensor_states_slot_table[0]; 470825ba0f2Srobj break; 471825ba0f2Srobj case TOPO_SENSOR_TYPE_ACPI: 472825ba0f2Srobj ntp = &topo_sensor_states_acpi_table[0]; 473825ba0f2Srobj break; 474825ba0f2Srobj case TOPO_SENSOR_TYPE_WATCHDOG2: 475825ba0f2Srobj ntp = &topo_sensor_states_watchdog2_table[0]; 476825ba0f2Srobj break; 477825ba0f2Srobj case TOPO_SENSOR_TYPE_ALERT: 478825ba0f2Srobj ntp = &topo_sensor_states_alert_table[0]; 479825ba0f2Srobj break; 480825ba0f2Srobj case TOPO_SENSOR_TYPE_PRESENCE: 481825ba0f2Srobj ntp = &topo_sensor_states_presence_table[0]; 482825ba0f2Srobj break; 483825ba0f2Srobj case TOPO_SENSOR_TYPE_LAN: 484825ba0f2Srobj ntp = &topo_sensor_states_lan_table[0]; 485825ba0f2Srobj break; 486825ba0f2Srobj case TOPO_SENSOR_TYPE_HEALTH: 487825ba0f2Srobj ntp = &topo_sensor_states_health_table[0]; 488825ba0f2Srobj break; 489825ba0f2Srobj case TOPO_SENSOR_TYPE_BATTERY: 490825ba0f2Srobj ntp = &topo_sensor_states_battery_table[0]; 491825ba0f2Srobj break; 492825ba0f2Srobj case TOPO_SENSOR_TYPE_AUDIT: 493825ba0f2Srobj ntp = &topo_sensor_states_audit_table[0]; 494825ba0f2Srobj break; 495825ba0f2Srobj case TOPO_SENSOR_TYPE_VERSION: 496825ba0f2Srobj ntp = &topo_sensor_states_version_table[0]; 497825ba0f2Srobj break; 498825ba0f2Srobj case TOPO_SENSOR_TYPE_FRU_STATE: 499825ba0f2Srobj ntp = &topo_sensor_states_fru_state_table[0]; 500825ba0f2Srobj break; 501825ba0f2Srobj case TOPO_SENSOR_TYPE_THRESHOLD_STATE: 502825ba0f2Srobj ntp = &topo_sensor_states_thresh_table[0]; 503825ba0f2Srobj break; 504825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_USAGE: 505825ba0f2Srobj ntp = &topo_sensor_states_generic_usage_table[0]; 506825ba0f2Srobj break; 507825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_STATE: 508825ba0f2Srobj ntp = &topo_sensor_states_generic_state_table[0]; 509825ba0f2Srobj break; 510825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_PREDFAIL: 511825ba0f2Srobj ntp = &topo_sensor_states_generic_predfail_table[0]; 512825ba0f2Srobj break; 513825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_LIMIT: 514825ba0f2Srobj ntp = &topo_sensor_states_generic_limit_table[0]; 515825ba0f2Srobj break; 516825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_PERFORMANCE: 517825ba0f2Srobj ntp = &topo_sensor_states_generic_perf_table[0]; 518825ba0f2Srobj break; 519825ba0f2Srobj case TOPO_SENSOR_TYPE_SEVERITY: 520825ba0f2Srobj ntp = &topo_sensor_states_severity_table[0]; 521825ba0f2Srobj break; 522825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_PRESENCE: 523825ba0f2Srobj ntp = &topo_sensor_states_generic_presence_table[0]; 524825ba0f2Srobj break; 525825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_AVAILABILITY: 526825ba0f2Srobj ntp = &topo_sensor_states_generic_avail_table[0]; 527825ba0f2Srobj break; 528825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_STATUS: 529825ba0f2Srobj ntp = &topo_sensor_states_generic_status_table[0]; 530825ba0f2Srobj break; 531825ba0f2Srobj case TOPO_SENSOR_TYPE_GENERIC_ACPI: 532825ba0f2Srobj ntp = &topo_sensor_states_generic_acpi_pwr_table[0]; 533825ba0f2Srobj break; 534e5dcf7beSRobert Johnston case TOPO_SENSOR_TYPE_GENERIC_FAILURE: 535e5dcf7beSRobert Johnston ntp = &topo_sensor_states_generic_failure_table[0]; 536e5dcf7beSRobert Johnston break; 537e5dcf7beSRobert Johnston case TOPO_SENSOR_TYPE_GENERIC_OK: 538e5dcf7beSRobert Johnston ntp = &topo_sensor_states_generic_ok_table[0]; 539e5dcf7beSRobert Johnston break; 540825ba0f2Srobj default: 541825ba0f2Srobj (void) snprintf(buf, len, "0x%02x", state); 542825ba0f2Srobj return; 543825ba0f2Srobj } 544881aaecdSRob Johnston if (state == 0) { 545881aaecdSRob Johnston (void) snprintf(buf, len, "NO_STATES_ASSERTED"); 546881aaecdSRob Johnston return; 547881aaecdSRob Johnston } 548881aaecdSRob Johnston buf[0] = '\0'; 549825ba0f2Srobj for (; ntp->int_name != NULL; ntp++) { 550881aaecdSRob Johnston if (state & ntp->int_value) { 551881aaecdSRob Johnston if (buf[0] != '\0') 552881aaecdSRob Johnston (void) strlcat(buf, "|", len); 553881aaecdSRob Johnston (void) strlcat(buf, ntp->int_name, len); 554825ba0f2Srobj } 555825ba0f2Srobj } 556825ba0f2Srobj 557881aaecdSRob Johnston if (buf[0] == '\0') 558881aaecdSRob Johnston (void) snprintf(buf, len, "0x%02x", state); 559825ba0f2Srobj } 5608522c52aSRob Johnston 5618522c52aSRob Johnston static const topo_pgroup_info_t sys_pgroup = { 5628522c52aSRob Johnston TOPO_PGROUP_SYSTEM, 5638522c52aSRob Johnston TOPO_STABILITY_PRIVATE, 5648522c52aSRob Johnston TOPO_STABILITY_PRIVATE, 5658522c52aSRob Johnston 1 5668522c52aSRob Johnston }; 5678522c52aSRob Johnston static const topo_pgroup_info_t auth_pgroup = { 5688522c52aSRob Johnston FM_FMRI_AUTHORITY, 5698522c52aSRob Johnston TOPO_STABILITY_PRIVATE, 5708522c52aSRob Johnston TOPO_STABILITY_PRIVATE, 5718522c52aSRob Johnston 1 5728522c52aSRob Johnston }; 5738522c52aSRob Johnston 5748522c52aSRob Johnston void 5758522c52aSRob Johnston topo_pgroup_hcset(tnode_t *node, nvlist_t *auth) 5768522c52aSRob Johnston { 5778522c52aSRob Johnston int err; 5788522c52aSRob Johnston char isa[MAXNAMELEN]; 5798522c52aSRob Johnston struct utsname uts; 5808522c52aSRob Johnston char *prod, *psn, *csn, *server; 5818522c52aSRob Johnston 5828522c52aSRob Johnston if (auth == NULL) 5838522c52aSRob Johnston return; 5848522c52aSRob Johnston 5858522c52aSRob Johnston if (topo_pgroup_create(node, &auth_pgroup, &err) != 0) { 5868522c52aSRob Johnston if (err != ETOPO_PROP_DEFD) 5878522c52aSRob Johnston return; 5888522c52aSRob Johnston } 5898522c52aSRob Johnston 5908522c52aSRob Johnston /* 5918522c52aSRob Johnston * Inherit if we can, it saves memory 5928522c52aSRob Johnston */ 5938522c52aSRob Johnston if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT, 5948522c52aSRob Johnston &err) != 0) && (err != ETOPO_PROP_DEFD)) { 5958522c52aSRob Johnston if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT, &prod) == 5968522c52aSRob Johnston 0) 5978522c52aSRob Johnston (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY, 5988522c52aSRob Johnston FM_FMRI_AUTH_PRODUCT, TOPO_PROP_IMMUTABLE, prod, 5998522c52aSRob Johnston &err); 6008522c52aSRob Johnston } 6018522c52aSRob Johnston if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT_SN, 6028522c52aSRob Johnston &err) != 0) && (err != ETOPO_PROP_DEFD)) { 6038522c52aSRob Johnston if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN, &psn) == 6048522c52aSRob Johnston 0) 6058522c52aSRob Johnston (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY, 6068522c52aSRob Johnston FM_FMRI_AUTH_PRODUCT_SN, TOPO_PROP_IMMUTABLE, psn, 6078522c52aSRob Johnston &err); 6088522c52aSRob Johnston } 6098522c52aSRob Johnston if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS, 6108522c52aSRob Johnston &err) != 0) && (err != ETOPO_PROP_DEFD)) { 6118522c52aSRob Johnston if (nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS, &csn) == 0) 6128522c52aSRob Johnston (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY, 6138522c52aSRob Johnston FM_FMRI_AUTH_CHASSIS, TOPO_PROP_IMMUTABLE, csn, 6148522c52aSRob Johnston &err); 6158522c52aSRob Johnston } 6168522c52aSRob Johnston if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_SERVER, 6178522c52aSRob Johnston &err) != 0) && (err != ETOPO_PROP_DEFD)) { 6188522c52aSRob Johnston if (nvlist_lookup_string(auth, FM_FMRI_AUTH_SERVER, &server) == 6198522c52aSRob Johnston 0) 6208522c52aSRob Johnston (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY, 6218522c52aSRob Johnston FM_FMRI_AUTH_SERVER, TOPO_PROP_IMMUTABLE, server, 6228522c52aSRob Johnston &err); 6238522c52aSRob Johnston } 6248522c52aSRob Johnston 6258522c52aSRob Johnston if (topo_pgroup_create(node, &sys_pgroup, &err) != 0) 6268522c52aSRob Johnston return; 6278522c52aSRob Johnston 6288522c52aSRob Johnston if (sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)) != -1) 6298522c52aSRob Johnston (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM, 6308522c52aSRob Johnston TOPO_PROP_ISA, TOPO_PROP_IMMUTABLE, isa, &err); 6318522c52aSRob Johnston 6328522c52aSRob Johnston if (uname(&uts) != -1) 6338522c52aSRob Johnston (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM, 6348522c52aSRob Johnston TOPO_PROP_MACHINE, TOPO_PROP_IMMUTABLE, uts.machine, &err); 6358522c52aSRob Johnston } 636