1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29#include <unistd.h> 30#include <picl.h> 31#include <picltree.h> 32#include <picldefs.h> 33#include <pthread.h> 34#include <syslog.h> 35#include <string.h> 36#include <libnvpair.h> 37#include <libintl.h> 38#include "piclenvmond.h" 39 40/* external funcs and varaibles */ 41extern void env_handle_event(const char *, const void *, size_t); 42extern picl_errno_t env_init(); 43extern void env_platmod_fini(); 44extern int sensor_fd; 45extern pthread_t env_temp_thr_tid; 46 47/* local defines */ 48#define TIMEOUT (10) 49 50#pragma init(piclenvmond_register) 51 52/* 53 * Plugin registration entry points 54 */ 55static void piclenvmond_register(void); 56static void piclenvmond_init(void); 57static void piclenvmond_fini(void); 58static void piclenvmond_evhandler(const char *, const void *, size_t, void *); 59 60int env_debug = 0x0; 61 62static picld_plugin_reg_t envmond_reg_info = { 63 PICLD_PLUGIN_VERSION_1, 64 PICLD_PLUGIN_CRITICAL, 65 "SUNW_piclenvmond", 66 piclenvmond_init, 67 piclenvmond_fini 68}; 69 70typedef struct { 71 picl_nodehdl_t nodehdl; 72 char node_name[PICL_PROPNAMELEN_MAX]; 73} env_callback_args_t; 74 75/* 76 * picld entry points 77 */ 78static void 79piclenvmond_register(void) 80{ 81 (void) picld_plugin_register(&envmond_reg_info); 82} 83 84/* 85 * picld entry point 86 * - do all the initialization 87 * - register for interested picl events 88 */ 89static void 90piclenvmond_init(void) 91{ 92 picl_errno_t rc = PICL_SUCCESS; 93 94 if ((rc = env_init()) != PICL_SUCCESS) { 95 syslog(LOG_ERR, gettext("SUNW_envmond:envmond init failed, " 96 "error = %d"), rc); 97 return; 98 } 99 100 /* register handler for state change events */ 101 (void) ptree_register_handler(PICLEVENT_STATE_CHANGE, 102 piclenvmond_evhandler, NULL); 103 /* register handler for condition change events */ 104 (void) ptree_register_handler(PICLEVENT_CONDITION_CHANGE, 105 piclenvmond_evhandler, NULL); 106 107} 108 109static void 110piclenvmond_fini(void) 111{ 112 void *exitval; 113 114 /* unregister event handler */ 115 (void) ptree_unregister_handler(PICLEVENT_STATE_CHANGE, 116 piclenvmond_evhandler, NULL); 117 (void) ptree_unregister_handler(PICLEVENT_CONDITION_CHANGE, 118 piclenvmond_evhandler, NULL); 119 120 /* cancel all the threads */ 121 (void) pthread_cancel(env_temp_thr_tid); 122 (void) pthread_join(env_temp_thr_tid, &exitval); 123 124 /* do any platform specific cleanups required */ 125 env_platmod_fini(); 126 (void) close(sensor_fd); 127} 128 129/*ARGSUSED*/ 130static void 131piclenvmond_evhandler(const char *ename, const void *earg, size_t size, 132 void *cookie) 133{ 134 env_handle_event(ename, earg, size); 135} 136 137/* 138 * Utility functions 139 */ 140 141/* 142 * create_property -- Create a PICL property 143 */ 144picl_errno_t 145env_create_property(int ptype, int pmode, size_t psize, char *pname, 146 int (*readfn)(ptree_rarg_t *, void *), 147 int (*writefn)(ptree_warg_t *, const void *), 148 picl_nodehdl_t nodeh, picl_prophdl_t *propp, void *vbuf) 149{ 150 picl_errno_t rc; /* return code */ 151 ptree_propinfo_t propinfo; /* propinfo structure */ 152 picl_prophdl_t proph; 153 154 rc = ptree_get_prop_by_name(nodeh, pname, &proph); 155 if (rc == PICL_SUCCESS) { /* prop. already exists */ 156 return (rc); 157 } 158 159 rc = ptree_init_propinfo(&propinfo, PTREE_PROPINFO_VERSION, 160 ptype, pmode, psize, pname, readfn, writefn); 161 if (rc != PICL_SUCCESS) { 162 syslog(LOG_ERR, PTREE_INIT_PROPINFO_FAILED_MSG, rc); 163 return (rc); 164 } 165 166 rc = ptree_create_and_add_prop(nodeh, &propinfo, vbuf, propp); 167 if (rc != PICL_SUCCESS) { 168 syslog(LOG_ERR, PTREE_CREATE_AND_ADD_PROP_FAILED_MSG, rc); 169 return (rc); 170 } 171 return (PICL_SUCCESS); 172} 173 174/* 175 * The picl event completion handler. 176 */ 177/* ARGSUSED */ 178static void 179event_completion_handler(char *ename, void *earg, size_t size) 180{ 181 free(earg); 182 free(ename); 183} 184 185/* 186 * utility routine to post PICL events 187 */ 188/*ARGSUSED*/ 189static int 190post_picl_event(const char *ename, char *envl, size_t elen, 191 picl_nodehdl_t nodeh, int cond_wait) 192{ 193 nvlist_t *nvlp; 194 size_t nvl_size; 195 char *pack_buf = NULL; 196 char *evname; 197 198 if (nodeh == 0) { 199 return (PICL_FAILURE); 200 } 201 if ((evname = strdup(ename)) == NULL) 202 return (PICL_FAILURE); 203 if (envl) { 204 if (nvlist_unpack(envl, elen, &nvlp, 0) < 0) { 205 nvlist_free(nvlp); 206 free(evname); 207 return (PICL_FAILURE); 208 } 209 } else { 210 if (nvlist_alloc(&nvlp, NV_UNIQUE_NAME_TYPE, NULL)) { 211 free(evname); 212 return (PICL_FAILURE); 213 } 214 } 215 216 if (nvlist_add_uint64(nvlp, PICLEVENTARG_NODEHANDLE, nodeh) == -1) { 217 nvlist_free(nvlp); 218 free(evname); 219 return (PICL_FAILURE); 220 } 221 222 if (nvlist_pack(nvlp, &pack_buf, &nvl_size, NV_ENCODE_NATIVE, NULL)) { 223 nvlist_free(nvlp); 224 free(evname); 225 return (PICL_FAILURE); 226 } 227 nvlist_free(nvlp); 228 229 if (env_debug & EVENTS) { 230 char enodename[PICL_PROPNAMELEN_MAX]; 231 if (ptree_get_propval_by_name(nodeh, PICL_PROP_NAME, 232 enodename, sizeof (enodename)) == PICL_SUCCESS) 233 syslog(LOG_INFO, "envmond:Posting %s on %s\n", 234 ename, enodename); 235 } 236 237 if (ptree_post_event(evname, pack_buf, nvl_size, 238 event_completion_handler) != 0) { 239 syslog(LOG_ERR, gettext("SUNW_envmond: Error posting %s PICL" 240 " event."), ename); 241 free(pack_buf); 242 free(evname); 243 return (PICL_FAILURE); 244 } 245 return (PICL_SUCCESS); 246} 247 248/* 249 * post dr_req events 250 */ 251picl_errno_t 252post_dr_req_event(picl_nodehdl_t fruh, char *dr_req_type, uint8_t wait) 253{ 254 nvlist_t *nvlp; /* nvlist of event specific args */ 255 size_t nvl_size; 256 char *pack_buf = NULL; 257 char dr_ap_id[PICL_PROPNAMELEN_MAX]; 258 int rc = PICL_SUCCESS; 259 260 if (env_debug & DEBUG) 261 syslog(LOG_DEBUG, "Post %s on %llx", dr_req_type, fruh); 262 if (fruh == 0) { 263 return (PICL_INVALIDARG); 264 } 265 if ((rc = ptree_get_propval_by_name(fruh, PICL_PROP_NAME, 266 dr_ap_id, sizeof (dr_ap_id))) != PICL_SUCCESS) { 267 return (rc); 268 } 269 270 if (nvlist_alloc(&nvlp, NV_UNIQUE_NAME_TYPE, NULL)) { 271 return (PICL_FAILURE); 272 } 273 274 if (nvlist_add_string(nvlp, PICLEVENTARG_AP_ID, dr_ap_id) == -1) { 275 nvlist_free(nvlp); 276 return (PICL_FAILURE); 277 } 278 if (nvlist_add_string(nvlp, PICLEVENTARG_DR_REQ_TYPE, dr_req_type) 279 == -1) { 280 nvlist_free(nvlp); 281 return (PICL_FAILURE); 282 } 283 if (nvlist_pack(nvlp, &pack_buf, &nvl_size, NV_ENCODE_NATIVE, NULL)) { 284 nvlist_free(nvlp); 285 return (PICL_FAILURE); 286 } 287 nvlist_free(nvlp); 288 289 if (env_debug & DEBUG) 290 syslog(LOG_DEBUG, "Posting %s on %s", dr_req_type, dr_ap_id); 291 rc = post_picl_event(PICLEVENT_DR_REQ, pack_buf, nvl_size, fruh, 292 wait); 293 294 free(pack_buf); 295 return (rc); 296} 297 298/* 299 * routine to post dr_ap_state change events 300 */ 301picl_errno_t 302post_dr_ap_state_change_event(picl_nodehdl_t nodehdl, char *dr_hint, 303 uint8_t wait) 304{ 305 nvlist_t *nvlp; /* nvlist of event specific args */ 306 size_t nvl_size; 307 char *pack_buf = NULL; 308 char dr_ap_id[PICL_PROPNAMELEN_MAX]; 309 int rc = PICL_SUCCESS; 310 311 if (nodehdl == 0) { 312 return (PICL_FAILURE); 313 } 314 if ((rc = ptree_get_propval_by_name(nodehdl, PICL_PROP_NAME, 315 dr_ap_id, sizeof (dr_ap_id))) != PICL_SUCCESS) { 316 return (rc); 317 } 318 if (nvlist_alloc(&nvlp, NV_UNIQUE_NAME_TYPE, NULL)) { 319 return (PICL_FAILURE); 320 } 321 322 if (nvlist_add_string(nvlp, PICLEVENTARG_AP_ID, dr_ap_id) == -1) { 323 nvlist_free(nvlp); 324 return (PICL_FAILURE); 325 } 326 if (nvlist_add_string(nvlp, PICLEVENTARG_HINT, dr_hint) == -1) { 327 nvlist_free(nvlp); 328 return (PICL_FAILURE); 329 } 330 if (nvlist_pack(nvlp, &pack_buf, &nvl_size, NV_ENCODE_NATIVE, NULL)) { 331 nvlist_free(nvlp); 332 return (PICL_FAILURE); 333 } 334 nvlist_free(nvlp); 335 rc = post_picl_event(PICLEVENT_DR_AP_STATE_CHANGE, pack_buf, 336 nvl_size, nodehdl, wait); 337 free(pack_buf); 338 return (rc); 339} 340 341picl_errno_t 342post_cpu_state_change_event(picl_nodehdl_t fruh, char *event_type, uint8_t wait) 343{ 344 nvlist_t *nvlp; /* nvlist of event specific args */ 345 size_t nvl_size; 346 char *pack_buf = NULL; 347 int rc = PICL_SUCCESS; 348 349 if (fruh == 0) { 350 return (PICL_FAILURE); 351 } 352 353 if (nvlist_alloc(&nvlp, NV_UNIQUE_NAME_TYPE, NULL)) 354 return (PICL_FAILURE); 355 356 if (nvlist_add_int64(nvlp, PICLEVENTARG_NODEHANDLE, fruh)) { 357 nvlist_free(nvlp); 358 return (PICL_FAILURE); 359 } 360 361 if (nvlist_add_string(nvlp, PICLEVENTARG_CPU_EV_TYPE, 362 event_type) == -1) { 363 nvlist_free(nvlp); 364 return (PICL_FAILURE); 365 } 366 367 if (nvlist_pack(nvlp, &pack_buf, &nvl_size, NV_ENCODE_NATIVE, NULL)) { 368 nvlist_free(nvlp); 369 return (PICL_FAILURE); 370 } 371 nvlist_free(nvlp); 372 rc = post_picl_event(PICLEVENT_CPU_STATE_CHANGE, pack_buf, 373 nvl_size, fruh, wait); 374 free(pack_buf); 375 return (rc); 376} 377 378int 379post_sensor_event(picl_nodehdl_t hdl, char *sensor_evalue, uint8_t wait) 380{ 381 nvlist_t *nvlp; /* nvlist of event specific args */ 382 size_t nvl_size; 383 char *pack_buf = NULL; 384 char dr_ap_id[PICL_PROPNAMELEN_MAX]; 385 int rc = PICL_SUCCESS; 386 387 if (env_debug & DEBUG) 388 syslog(LOG_DEBUG, "Post %s on %llx", sensor_evalue, hdl); 389 if (hdl == 0) 390 return (PICL_FAILURE); 391 392 if (nvlist_alloc(&nvlp, NV_UNIQUE_NAME_TYPE, NULL)) 393 return (PICL_FAILURE); 394 395 if (nvlist_add_string(nvlp, PICLEVENTARG_CONDITION, 396 sensor_evalue) == -1) { 397 nvlist_free(nvlp); 398 return (PICL_FAILURE); 399 } 400 if (nvlist_pack(nvlp, &pack_buf, &nvl_size, NV_ENCODE_NATIVE, NULL)) { 401 nvlist_free(nvlp); 402 return (PICL_FAILURE); 403 } 404 nvlist_free(nvlp); 405 406 if (env_debug & DEBUG) { 407 if (ptree_get_propval_by_name(hdl, PICL_PROP_NAME, dr_ap_id, 408 sizeof (dr_ap_id)) == PICL_SUCCESS) 409 syslog(LOG_DEBUG, "Posting %s on %s", sensor_evalue, 410 dr_ap_id); 411 } 412 rc = post_picl_event(PICLEVENT_CONDITION_CHANGE, pack_buf, nvl_size, 413 hdl, wait); 414 free(pack_buf); 415 return (rc); 416} 417 418/* 419 * return B_TRUE if admin lock is enabled 420 * return B_FALSE if admin lock is disabled 421 */ 422boolean_t 423env_admin_lock_enabled(picl_nodehdl_t fruh) 424{ 425 char adminlock[PICL_PROPNAMELEN_MAX]; 426 427 if (ptree_get_propval_by_name(fruh, PICL_PROP_ADMIN_LOCK, 428 adminlock, sizeof (adminlock)) 429 != PICL_SUCCESS) { 430 return (B_FALSE); 431 } 432 if (strcmp(adminlock, PICL_ADMINLOCK_ENABLED) == 0) { 433 return (B_TRUE); 434 } 435 return (B_FALSE); 436} 437