void fmd_create(fmd_t *dp, const char *arg0, const char *root, const char *conf) { fmd_conf_path_t *pap; char file[PATH_MAX]; const char *name; fmd_stat_t *sp; int i; smbios_hdl_t *shp; smbios_system_t s1; smbios_info_t s2; id_t id; di_prom_handle_t promh = DI_PROM_HANDLE_NIL; di_node_t rooth = DI_NODE_NIL; char *bufp; (void) sysinfo(SI_PLATFORM, _fmd_plat, sizeof (_fmd_plat)); (void) sysinfo(SI_ARCHITECTURE, _fmd_isa, sizeof (_fmd_isa)); (void) uname(&_fmd_uts); if ((shp = smbios_open(NULL, SMB_VERSION, 0, NULL)) != NULL) { if ((id = smbios_info_system(shp, &s1)) != SMB_ERR && smbios_info_common(shp, id, &s2) != SMB_ERR) { (void) strlcpy(_fmd_prod, s2.smbi_product, MAXNAMELEN); (void) strlcpy(_fmd_csn, s2.smbi_serial, MAXNAMELEN); } smbios_close(shp); } else if ((rooth = di_init("/", DINFOPROP)) != DI_NODE_NIL && (promh = di_prom_init()) != DI_PROM_HANDLE_NIL) { if (di_prom_prop_lookup_bytes(promh, rooth, "chassis-sn", (unsigned char **)&bufp) != -1) { (void) strlcpy(_fmd_csn, bufp, MAXNAMELEN); } } if (promh != DI_PROM_HANDLE_NIL) di_prom_fini(promh); if (rooth != DI_NODE_NIL) di_fini(rooth); bzero(dp, sizeof (fmd_t)); dp->d_version = _fmd_version; dp->d_pname = fmd_strbasename(arg0); dp->d_pid = getpid(); if (pthread_key_create(&dp->d_key, NULL) != 0) fmd_error(EFMD_EXIT, "failed to create pthread key"); (void) pthread_mutex_init(&dp->d_xprt_lock, NULL); (void) pthread_mutex_init(&dp->d_err_lock, NULL); (void) pthread_mutex_init(&dp->d_thr_lock, NULL); (void) pthread_mutex_init(&dp->d_mod_lock, NULL); (void) pthread_mutex_init(&dp->d_stats_lock, NULL); (void) pthread_rwlock_init(&dp->d_log_lock, NULL); /* * A small number of properties must be set manually before we open * the root configuration file. These include any settings for our * memory allocator and path expansion token values, because these * values are needed by the routines in fmd_conf.c itself. After * the root configuration file is processed, we reset these properties * based upon the latest values from the configuration file. */ dp->d_alloc_msecs = 10; dp->d_alloc_tries = 3; dp->d_str_buckets = 211; dp->d_rootdir = root ? root : ""; dp->d_platform = _fmd_plat; dp->d_machine = _fmd_uts.machine; dp->d_isaname = _fmd_isa; dp->d_conf = fmd_conf_open(conf, sizeof (_fmd_conf) / sizeof (_fmd_conf[0]), _fmd_conf, FMD_CONF_DEFER); if (dp->d_conf == NULL) { fmd_error(EFMD_EXIT, "failed to load required configuration properties\n"); } (void) fmd_conf_getprop(dp->d_conf, "alloc.msecs", &dp->d_alloc_msecs); (void) fmd_conf_getprop(dp->d_conf, "alloc.tries", &dp->d_alloc_tries); (void) fmd_conf_getprop(dp->d_conf, "strbuckets", &dp->d_str_buckets); (void) fmd_conf_getprop(dp->d_conf, "platform", &dp->d_platform); (void) fmd_conf_getprop(dp->d_conf, "machine", &dp->d_machine); (void) fmd_conf_getprop(dp->d_conf, "isaname", &dp->d_isaname); /* * Manually specified rootdirs override config files, so only update * d_rootdir based on the config files we parsed if no 'root' was set. */ if (root == NULL) (void) fmd_conf_getprop(dp->d_conf, "rootdir", &dp->d_rootdir); else (void) fmd_conf_setprop(dp->d_conf, "rootdir", dp->d_rootdir); /* * Once the base conf file properties are loaded, lookup the values * of $conf_path and $conf_file and merge in any other conf files. */ (void) fmd_conf_getprop(dp->d_conf, "conf_path", &pap); (void) fmd_conf_getprop(dp->d_conf, "conf_file", &name); for (i = 0; i < pap->cpa_argc; i++) { (void) snprintf(file, sizeof (file), "%s/%s", pap->cpa_argv[i], name); if (access(file, F_OK) == 0) fmd_conf_merge(dp->d_conf, file); } /* * Update the value of fmd.d_fg based on "fg". We cache this property * because it must be accessed deep within fmd at fmd_verror() time. * Update any other properties that must be cached for performance. */ (void) fmd_conf_getprop(fmd.d_conf, "fg", &fmd.d_fg); (void) fmd_conf_getprop(fmd.d_conf, "xprt.ttl", &fmd.d_xprt_ttl); /* * Initialize our custom libnvpair allocator and create an nvlist for * authority elements corresponding to this instance of the daemon. */ (void) nv_alloc_init(&dp->d_nva, &fmd_nv_alloc_ops); dp->d_auth = fmd_protocol_authority(); /* * The fmd_module_t for the root module must be created manually. Most * of it remains unused and zero, except for the few things we fill in. */ dp->d_rmod = fmd_zalloc(sizeof (fmd_module_t), FMD_SLEEP); dp->d_rmod->mod_name = fmd_strdup(dp->d_pname, FMD_SLEEP); dp->d_rmod->mod_fmri = fmd_protocol_fmri_module(dp->d_rmod); fmd_list_append(&dp->d_mod_list, dp->d_rmod); fmd_module_hold(dp->d_rmod); (void) pthread_mutex_init(&dp->d_rmod->mod_lock, NULL); (void) pthread_cond_init(&dp->d_rmod->mod_cv, NULL); (void) pthread_mutex_init(&dp->d_rmod->mod_stats_lock, NULL); dp->d_rmod->mod_thread = fmd_thread_xcreate(dp->d_rmod, pthread_self()); dp->d_rmod->mod_stats = fmd_zalloc(sizeof (fmd_modstat_t), FMD_SLEEP); dp->d_rmod->mod_ustat = fmd_ustat_create(); if (pthread_setspecific(dp->d_key, dp->d_rmod->mod_thread) != 0) fmd_error(EFMD_EXIT, "failed to attach main thread key"); if ((dp->d_stats = (fmd_statistics_t *)fmd_ustat_insert( dp->d_rmod->mod_ustat, FMD_USTAT_NOALLOC, sizeof (_fmd_stats) / sizeof (fmd_stat_t), (fmd_stat_t *)&_fmd_stats, NULL)) == NULL) fmd_error(EFMD_EXIT, "failed to initialize statistics"); (void) pthread_mutex_lock(&dp->d_rmod->mod_lock); dp->d_rmod->mod_flags |= FMD_MOD_INIT; (void) pthread_mutex_unlock(&dp->d_rmod->mod_lock); /* * In addition to inserting the _fmd_stats collection of program-wide * statistics, we also insert a statistic named after each of our * errors and update these counts in fmd_verror() (see fmd_subr.c). */ dp->d_errstats = sp = fmd_zalloc(sizeof (fmd_stat_t) * (EFMD_END - EFMD_UNKNOWN), FMD_SLEEP); for (i = 0; i < EFMD_END - EFMD_UNKNOWN; i++, sp++) { (void) snprintf(sp->fmds_name, sizeof (sp->fmds_name), "err.%s", strrchr(fmd_errclass(EFMD_UNKNOWN + i), '.') + 1); sp->fmds_type = FMD_TYPE_UINT64; } (void) fmd_ustat_insert(dp->d_rmod->mod_ustat, FMD_USTAT_NOALLOC, EFMD_END - EFMD_UNKNOWN, dp->d_errstats, NULL); }
static void topo_snap_destroy(topo_hdl_t *thp) { int i; ttree_t *tp; topo_walk_t *twp; tnode_t *root; topo_nodehash_t *nhp; topo_mod_t *mod; for (tp = topo_list_next(&thp->th_trees); tp != NULL; tp = topo_list_next(tp)) { root = tp->tt_root; twp = tp->tt_walk; /* * Clean-up tree nodes from the bottom-up */ if ((twp->tw_node = topo_child_first(root)) != NULL) { twp->tw_cb = topo_walk_destroy; topo_node_hold(root); topo_node_hold(twp->tw_node); /* released at walk end */ (void) topo_walk_bottomup(twp, TOPO_WALK_CHILD); topo_node_rele(root); } /* * Tidy-up the root node */ while ((nhp = topo_list_next(&root->tn_children)) != NULL) { for (i = 0; i < nhp->th_arrlen; i++) { assert(nhp->th_nodearr[i] == NULL); } mod = nhp->th_enum; topo_mod_strfree(mod, nhp->th_name); topo_mod_free(mod, nhp->th_nodearr, nhp->th_arrlen * sizeof (tnode_t *)); topo_list_delete(&root->tn_children, nhp); topo_mod_free(mod, nhp, sizeof (topo_nodehash_t)); topo_mod_rele(mod); } } /* * Clean-up our cached devinfo and prom tree handles. */ if (thp->th_di != DI_NODE_NIL) { di_fini(thp->th_di); thp->th_di = DI_NODE_NIL; } if (thp->th_pi != DI_PROM_HANDLE_NIL) { di_prom_fini(thp->th_pi); thp->th_pi = DI_PROM_HANDLE_NIL; } if (thp->th_uuid != NULL) { topo_hdl_free(thp, thp->th_uuid, TOPO_UUID_SIZE); thp->th_uuid = NULL; } }
picl_errno_t get_fru_path(char *parent_path, frutree_frunode_t *frup) { picl_errno_t rc = 0; picl_nodehdl_t loch; di_node_t rnode; frutree_devinfo_t *devinfo = NULL; char slot_type[PICL_PROPNAMELEN_MAX]; char probe_path[PICL_PROPNAMELEN_MAX]; char bus_addr[PICL_PROPNAMELEN_MAX]; if ((rc = ptree_get_propval_by_name(frup->frunodeh, PICL_PROP_PARENT, &loch, sizeof (loch))) != PICL_SUCCESS) { return (rc); } if ((rc = ptree_get_propval_by_name(loch, PICL_PROP_SLOT_TYPE, slot_type, sizeof (slot_type))) != PICL_SUCCESS) { return (rc); } if (strcmp(slot_type, SANIBEL_SCSI_SLOT) == 0 || strcmp(slot_type, SANIBEL_IDE_SLOT) == 0) { if (ptree_get_propval_by_name(loch, PICL_PROP_PROBE_PATH, probe_path, sizeof (probe_path)) != PICL_SUCCESS) { return (rc); } (void) strncpy(frup->fru_path, probe_path, sizeof (frup->fru_path)); return (PICL_SUCCESS); } prom_handle = di_prom_init(); rnode = di_init(parent_path, DINFOSUBTREE|DINFOMINOR); if (rnode == DI_NODE_NIL) { di_prom_fini(prom_handle); return (PICL_FAILURE); } devinfo = (frutree_devinfo_t *)malloc(sizeof (frutree_devinfo_t)); if (devinfo == NULL) { di_fini(rnode); di_prom_fini(prom_handle); return (PICL_NOSPACE); } if (ptree_get_propval_by_name(loch, PICL_PROP_BUS_ADDR, bus_addr, sizeof (bus_addr)) != PICL_SUCCESS) { free(devinfo); di_fini(rnode); di_prom_fini(prom_handle); return (rc); } devinfo->rnode = rnode; (void) strncpy(devinfo->bus_addr, bus_addr, sizeof (devinfo->bus_addr)); devinfo->path[0] = '\0'; devinfo->arg = frup; if (di_walk_node(rnode, DI_WALK_SIBFIRST, &devinfo, walk_tree) != 0) { di_fini(rnode); di_prom_fini(prom_handle); free(devinfo); return (PICL_FAILURE); } di_fini(rnode); di_prom_fini(prom_handle); if (devinfo->path[0]) { (void) strncpy(frup->fru_path, devinfo->path, sizeof (frup->fru_path)); free(devinfo); return (PICL_SUCCESS); } else { free(devinfo); return (PICL_NODENOTFOUND); } }
static char * topo_snap_create(topo_hdl_t *thp, int *errp, boolean_t need_force) { uuid_t uuid; char *ustr = NULL; topo_hdl_lock(thp); if (thp->th_uuid != NULL) { *errp = ETOPO_HDL_UUID; topo_hdl_unlock(thp); return (NULL); } if ((thp->th_uuid = topo_hdl_zalloc(thp, TOPO_UUID_SIZE)) == NULL) { *errp = ETOPO_NOMEM; topo_dprintf(thp, TOPO_DBG_ERR, "unable to allocate uuid: %s\n", topo_strerror(*errp)); topo_hdl_unlock(thp); return (NULL); } uuid_generate(uuid); uuid_unparse(uuid, thp->th_uuid); if ((ustr = topo_hdl_strdup(thp, thp->th_uuid)) == NULL) { *errp = ETOPO_NOMEM; topo_hdl_unlock(thp); return (NULL); } if (need_force) { topo_dprintf(thp, TOPO_DBG_FORCE, "taking a DINFOFORCE snapshot\n"); thp->th_di = di_init("/", DINFOFORCE | DINFOSUBTREE | DINFOMINOR | DINFOPROP | DINFOPATH); } else { thp->th_di = di_init("/", DINFOCACHE); } thp->th_pi = di_prom_init(); if (topo_tree_enum_all(thp) < 0) { topo_dprintf(thp, TOPO_DBG_ERR, "enumeration failure: %s\n", topo_hdl_errmsg(thp)); if (topo_hdl_errno(thp) == ETOPO_ENUM_FATAL) { *errp = thp->th_errno; if (thp->th_di != DI_NODE_NIL) { di_fini(thp->th_di); thp->th_di = DI_NODE_NIL; } if (thp->th_pi != DI_PROM_HANDLE_NIL) { di_prom_fini(thp->th_pi); thp->th_pi = DI_PROM_HANDLE_NIL; } topo_hdl_strfree(thp, ustr); topo_hdl_unlock(thp); return (NULL); } } if (thp->th_ipmi != NULL && ipmi_sdr_changed(thp->th_ipmi) && ipmi_sdr_refresh(thp->th_ipmi) != 0) { topo_dprintf(thp, TOPO_DBG_ERR, "failed to refresh IPMI sdr repository: %s\n", ipmi_errmsg(thp->th_ipmi)); } topo_hdl_unlock(thp); return (ustr); }