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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2007 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 /* 30 * Disk & Indicator Monitor configuration file support routines 31 */ 32 33 #include <sys/types.h> 34 #include <sys/stat.h> 35 #include <fcntl.h> 36 #include <unistd.h> 37 #include <string.h> 38 #include <strings.h> 39 #include <errno.h> 40 #include <limits.h> 41 #include <pthread.h> 42 43 #include "disk_monitor.h" 44 #include "util.h" 45 #include "topo_gather.h" 46 47 extern log_class_t g_verbose; 48 49 const char * 50 hotplug_state_string(hotplug_state_t state) 51 { 52 switch (state & ~HPS_FAULTED) { 53 default: 54 case HPS_UNKNOWN: 55 return ("Unknown"); 56 case HPS_ABSENT: 57 return ("Absent"); 58 case HPS_PRESENT: 59 return ("Present"); 60 case HPS_CONFIGURED: 61 return ("Configured"); 62 case HPS_UNCONFIGURED: 63 return ("Unconfigured"); 64 } 65 } 66 67 void 68 conf_error_msg(conf_err_t err, char *buf, int buflen, void *arg) 69 { 70 switch (err) { 71 case E_MULTIPLE_IND_LISTS_DEFINED: 72 (void) snprintf(buf, buflen, "Multiple Indicator lists " 73 "defined"); 74 break; 75 case E_MULTIPLE_INDRULE_LISTS_DEFINED: 76 (void) snprintf(buf, buflen, "Multiple Indicator rule lists " 77 "defined"); 78 break; 79 case E_INVALID_STATE_CHANGE: 80 (void) snprintf(buf, buflen, "Invalid state change"); 81 break; 82 case E_IND_MULTIPLY_DEFINED: 83 (void) snprintf(buf, buflen, 84 "Multiple Indicator definitions (name & state) detected"); 85 break; 86 case E_IND_ACTION_REDUNDANT: 87 (void) snprintf(buf, buflen, "Redundant Indicator actions " 88 "specified"); 89 break; 90 case E_IND_ACTION_CONFLICT: 91 (void) snprintf(buf, buflen, "Indicator action conflict (+/- " 92 "same Indicator) found"); 93 break; 94 case E_IND_MISSING_FAULT_ON: 95 (void) snprintf(buf, buflen, "Missing declaration of `+" 96 INDICATOR_FAULT_IDENTIFIER "'"); 97 break; 98 case E_IND_MISSING_FAULT_OFF: 99 (void) snprintf(buf, buflen, "Missing declaration of `-" 100 INDICATOR_FAULT_IDENTIFIER "'"); 101 break; 102 case E_INDRULE_REFERENCES_NONEXISTENT_IND_ACTION: 103 (void) snprintf(buf, buflen, "`%c%s': Undefined Indicator in " 104 BAY_IND_ACTION " property", 105 (((ind_action_t *)arg)->ind_state == INDICATOR_ON) 106 ? '+' : '-', 107 ((ind_action_t *)arg)->ind_name); 108 break; 109 case E_DUPLICATE_STATE_TRANSITION: 110 (void) snprintf(buf, buflen, "Duplicate state transition " 111 "(%s -> %s)", 112 hotplug_state_string(((state_transition_t *)arg)->begin), 113 hotplug_state_string(((state_transition_t *)arg)->end)); 114 break; 115 default: 116 (void) snprintf(buf, buflen, "Unknown error"); 117 break; 118 } 119 } 120 121 static int 122 string_to_integer(const char *prop, int *value) 123 { 124 long val; 125 126 errno = 0; 127 128 val = strtol(prop, NULL, 0); 129 130 if (val == 0 && errno != 0) 131 return (-1); 132 else if (val > INT_MAX || val < INT_MIN) { 133 errno = ERANGE; 134 return (-1); 135 } 136 137 if (value != NULL) 138 *value = (int)val; 139 140 return (0); 141 } 142 143 const char * 144 dm_prop_lookup(nvlist_t *props, const char *prop_name) 145 { 146 char *str; 147 148 if (nvlist_lookup_string(props, prop_name, &str) == 0) 149 return ((const char *)str); 150 else 151 return (NULL); 152 } 153 154 int 155 dm_prop_lookup_int(nvlist_t *props, const char *prop_name, int *value) 156 { 157 const char *prop = dm_prop_lookup(props, prop_name); 158 159 if (prop == NULL) 160 return (-1); 161 162 return (string_to_integer(prop, value)); 163 } 164 165 nvlist_t * 166 namevalpr_to_nvlist(namevalpr_t *nvprp) 167 { 168 nvlist_t *nvlp = NULL; 169 170 if (nvlist_alloc(&nvlp, NV_UNIQUE_NAME, 0) != 0) { 171 return (NULL); 172 } 173 174 if (nvlist_add_string(nvlp, nvprp->name, nvprp->value) != 0) { 175 nvlist_free(nvlp); 176 return (NULL); 177 } 178 179 return (nvlp); 180 } 181 182 indicator_t * 183 new_indicator(ind_state_t lstate, char *namep, char *actionp) 184 { 185 indicator_t *newindicator = 186 (indicator_t *)dmalloc(sizeof (indicator_t)); 187 newindicator->ind_state = lstate; 188 newindicator->ind_name = namep ? dstrdup(namep) : NULL; 189 newindicator->ind_instr_spec = actionp ? dstrdup(actionp) : NULL; 190 newindicator->next = NULL; 191 return (newindicator); 192 } 193 194 void 195 link_indicator(indicator_t **first, indicator_t *to_add) 196 { 197 indicator_t *travptr; 198 dm_assert(first != NULL); 199 200 if (*first == NULL) 201 *first = to_add; 202 else { 203 travptr = *first; 204 while (travptr->next != NULL) { 205 travptr = travptr->next; 206 } 207 travptr->next = to_add; 208 } 209 } 210 211 void 212 ind_free(indicator_t *indp) 213 { 214 indicator_t *nextp; 215 216 while (indp != NULL) { 217 nextp = indp->next; 218 if (indp->ind_name) 219 dstrfree(indp->ind_name); 220 if (indp->ind_instr_spec) 221 dstrfree(indp->ind_instr_spec); 222 dfree(indp, sizeof (indicator_t)); 223 indp = nextp; 224 } 225 } 226 227 ind_action_t * 228 new_indaction(ind_state_t state, char *namep) 229 { 230 ind_action_t *lap = (ind_action_t *)dmalloc(sizeof (ind_action_t)); 231 lap->ind_state = state; 232 lap->ind_name = namep ? dstrdup(namep) : NULL; 233 lap->next = NULL; 234 return (lap); 235 } 236 237 void 238 link_indaction(ind_action_t **first, ind_action_t *to_add) 239 { 240 ind_action_t *travptr; 241 dm_assert(first != NULL); 242 243 if (*first == NULL) 244 *first = to_add; 245 else { 246 travptr = *first; 247 while (travptr->next != NULL) { 248 travptr = travptr->next; 249 } 250 travptr->next = to_add; 251 } 252 } 253 254 void 255 indaction_free(ind_action_t *lap) 256 { 257 ind_action_t *nextp; 258 259 /* Free the whole list */ 260 while (lap != NULL) { 261 nextp = lap->next; 262 if (lap->ind_name) 263 dstrfree(lap->ind_name); 264 dfree(lap, sizeof (ind_action_t)); 265 lap = nextp; 266 } 267 } 268 269 indrule_t * 270 new_indrule(state_transition_t *st, ind_action_t *actionp) 271 { 272 indrule_t *lrp = (indrule_t *)dmalloc(sizeof (indrule_t)); 273 if (st != NULL) 274 lrp->strans = *st; 275 lrp->action_list = actionp; 276 lrp->next = NULL; 277 return (lrp); 278 } 279 280 void 281 link_indrule(indrule_t **first, indrule_t *to_add) 282 { 283 indrule_t *travptr; 284 dm_assert(first != NULL); 285 286 if (*first == NULL) 287 *first = to_add; 288 else { 289 travptr = *first; 290 while (travptr->next != NULL) { 291 travptr = travptr->next; 292 } 293 travptr->next = to_add; 294 } 295 } 296 297 void 298 indrule_free(indrule_t *lrp) 299 { 300 indrule_t *nextp; 301 302 /* Free the whole list */ 303 while (lrp != NULL) { 304 nextp = lrp->next; 305 if (lrp->action_list) 306 indaction_free(lrp->action_list); 307 dfree(lrp, sizeof (indrule_t)); 308 lrp = nextp; 309 } 310 } 311 312 dm_fru_t * 313 new_dmfru(char *manu, char *modl, char *firmrev, char *serno, uint64_t capa) 314 { 315 dm_fru_t *frup = (dm_fru_t *)dzmalloc(sizeof (dm_fru_t)); 316 317 bcopy(manu, frup->manuf, MIN(sizeof (frup->manuf), strlen(manu) + 1)); 318 bcopy(modl, frup->model, MIN(sizeof (frup->model), strlen(modl) + 1)); 319 bcopy(firmrev, frup->rev, MIN(sizeof (frup->rev), strlen(firmrev) + 1)); 320 bcopy(serno, frup->serial, 321 MIN(sizeof (frup->serial), strlen(serno) + 1)); 322 frup->size_in_bytes = capa; 323 return (frup); 324 } 325 326 void 327 dmfru_free(dm_fru_t *frup) 328 { 329 dfree(frup, sizeof (dm_fru_t)); 330 } 331 332 diskmon_t * 333 new_diskmon(nvlist_t *app_props, indicator_t *indp, indrule_t *indrp, 334 nvlist_t *nvlp) 335 { 336 diskmon_t *dmp = (diskmon_t *)dmalloc(sizeof (diskmon_t)); 337 338 if (nvlp != NULL) 339 dmp->props = nvlp; 340 else 341 (void) nvlist_alloc(&dmp->props, NV_UNIQUE_NAME, 0); 342 343 if (app_props) 344 dmp->app_props = app_props; 345 else 346 (void) nvlist_alloc(&dmp->app_props, NV_UNIQUE_NAME, 0); 347 dmp->ind_list = indp; 348 dmp->indrule_list = indrp; 349 350 dm_assert(pthread_mutex_init(&dmp->manager_mutex, NULL) == 0); 351 352 dmp->state = HPS_UNKNOWN; 353 354 dmp->initial_configuration = B_TRUE; 355 356 dm_assert(pthread_mutex_init(&dmp->fault_indicator_mutex, NULL) == 0); 357 dmp->fault_indicator_state = INDICATOR_UNKNOWN; 358 359 dmp->configured_yet = B_FALSE; 360 dmp->state_change_count = 0; 361 362 dm_assert(pthread_mutex_init(&dmp->fru_mutex, NULL) == 0); 363 dmp->frup = NULL; 364 365 dmp->next = NULL; 366 return (dmp); 367 } 368 369 void 370 diskmon_free(diskmon_t *dmp) 371 { 372 diskmon_t *nextp; 373 374 /* Free the whole list */ 375 while (dmp != NULL) { 376 nextp = dmp->next; 377 378 if (dmp->props) 379 nvlist_free(dmp->props); 380 if (dmp->location) 381 dstrfree(dmp->location); 382 if (dmp->ind_list) 383 ind_free(dmp->ind_list); 384 if (dmp->indrule_list) 385 indrule_free(dmp->indrule_list); 386 if (dmp->app_props) 387 nvlist_free(dmp->app_props); 388 if (dmp->frup) 389 dmfru_free(dmp->frup); 390 dfree(dmp, sizeof (diskmon_t)); 391 392 dmp = nextp; 393 } 394 } 395 396 static cfgdata_t * 397 new_cfgdata(namevalpr_t *nvp, diskmon_t *dmp) 398 { 399 cfgdata_t *cdp = (cfgdata_t *)dzmalloc(sizeof (cfgdata_t)); 400 401 if (nvp != NULL) 402 cdp->props = namevalpr_to_nvlist(nvp); 403 else if (nvlist_alloc(&cdp->props, NV_UNIQUE_NAME, 0) != 0) { 404 return (NULL); 405 } 406 407 if (dmp != NULL) 408 cdp->disk_list = dmp; 409 return (cdp); 410 411 } 412 413 static void 414 cfgdata_add_namevalpr(cfgdata_t *cfgp, namevalpr_t *nvp) 415 { 416 if (cfgp->props == NULL) { 417 (void) nvlist_alloc(&cfgp->props, NV_UNIQUE_NAME, 0); 418 } 419 (void) nvlist_add_string(cfgp->props, nvp->name, nvp->value); 420 } 421 422 void 423 cfgdata_add_diskmon(cfgdata_t *cfgp, diskmon_t *dmp) 424 { 425 if (cfgp->disk_list == NULL) { 426 cfgp->disk_list = dmp; 427 } else { 428 diskmon_t *disklist = cfgp->disk_list; 429 430 while (disklist->next != NULL) 431 disklist = disklist->next; 432 433 disklist->next = dmp; 434 } 435 } 436 437 static void 438 cfgdata_free(cfgdata_t *cdp) 439 { 440 nvlist_free(cdp->props); 441 diskmon_free(cdp->disk_list); 442 dfree(cdp, sizeof (cfgdata_t)); 443 } 444 445 conf_err_t 446 check_indactions(ind_action_t *indrp) 447 { 448 char *buf; 449 conf_err_t rv = E_NO_ERROR; 450 nvlist_t *nvp = NULL; 451 int len; 452 453 (void) nvlist_alloc(&nvp, NV_UNIQUE_NAME, 0); 454 455 /* 456 * Check indicator actions for conflicts 457 */ 458 while (indrp != NULL && rv == E_NO_ERROR) { 459 len = strlen(indrp->ind_name) + 2; 460 buf = dmalloc(len); 461 (void) snprintf(buf, len, "%c%s", 462 indrp->ind_state == INDICATOR_ON ? '+' : '-', 463 indrp->ind_name); 464 switch (nvlist_lookup_boolean(nvp, buf)) { 465 case ENOENT: 466 (void) nvlist_add_boolean(nvp, buf); 467 break; 468 case 0: 469 rv = E_IND_ACTION_REDUNDANT; 470 break; 471 default: 472 break; 473 } 474 475 /* Look for the opposite action. If found, that's an error */ 476 (void) snprintf(buf, len, "%c%s", 477 indrp->ind_state == INDICATOR_ON ? '-' : '+', 478 indrp->ind_name); 479 switch (nvlist_lookup_boolean(nvp, buf)) { 480 case ENOENT: 481 break; 482 case 0: 483 rv = E_IND_ACTION_CONFLICT; 484 break; 485 default: 486 break; 487 } 488 dfree(buf, len); 489 indrp = indrp->next; 490 } 491 492 nvlist_free(nvp); 493 return (rv); 494 } 495 496 conf_err_t 497 check_inds(indicator_t *indp) 498 { 499 char *buf; 500 conf_err_t rv = E_NO_ERROR; 501 nvlist_t *nvp = NULL; 502 int len; 503 boolean_t fault_on = B_FALSE, fault_off = B_FALSE; 504 505 (void) nvlist_alloc(&nvp, NV_UNIQUE_NAME, 0); 506 507 /* 508 * Check inds for multiple definitions (same identifier or same action) 509 */ 510 while (indp != NULL && rv == E_NO_ERROR) { 511 len = strlen(indp->ind_name) + 2; 512 buf = dmalloc(len); 513 (void) snprintf(buf, len, "%c%s", 514 indp->ind_state == INDICATOR_ON ? '+' : '-', 515 indp->ind_name); 516 517 /* Keep track of the +/-FAULT for checking later */ 518 if (strcasecmp(buf, "+" INDICATOR_FAULT_IDENTIFIER) == 0) 519 fault_on = B_TRUE; 520 else if (strcasecmp(buf, "-" INDICATOR_FAULT_IDENTIFIER) == 0) 521 fault_off = B_TRUE; 522 523 switch (nvlist_lookup_boolean(nvp, buf)) { 524 case ENOENT: 525 (void) nvlist_add_boolean(nvp, buf); 526 break; 527 case 0: 528 rv = E_IND_MULTIPLY_DEFINED; 529 break; 530 default: 531 break; 532 } 533 dfree(buf, len); 534 indp = indp->next; 535 } 536 537 /* 538 * Make sure we have a -FAULT and +FAULT 539 */ 540 if (!fault_on) 541 rv = E_IND_MISSING_FAULT_ON; 542 else if (!fault_off) 543 rv = E_IND_MISSING_FAULT_OFF; 544 545 nvlist_free(nvp); 546 return (rv); 547 } 548 549 conf_err_t 550 check_indrules(indrule_t *indrp, state_transition_t **offender) 551 { 552 char buf[32]; 553 conf_err_t rv = E_NO_ERROR; 554 nvlist_t *nvp = NULL; 555 556 /* 557 * Ensure that no two rules have the same state transitions. 558 */ 559 560 (void) nvlist_alloc(&nvp, NV_UNIQUE_NAME, 0); 561 562 while (indrp != NULL && rv == E_NO_ERROR) { 563 (void) snprintf(buf, sizeof (buf), "%d-%d", 564 (int)indrp->strans.begin, (int)indrp->strans.end); 565 switch (nvlist_lookup_boolean(nvp, buf)) { 566 case 0: 567 *offender = &indrp->strans; 568 rv = E_DUPLICATE_STATE_TRANSITION; 569 break; 570 case ENOENT: 571 (void) nvlist_add_boolean(nvp, buf); 572 break; 573 default: 574 break; 575 } 576 indrp = indrp->next; 577 } 578 579 nvlist_free(nvp); 580 return (rv); 581 } 582 583 584 conf_err_t 585 check_consistent_ind_indrules(indicator_t *indp, indrule_t *indrp, 586 ind_action_t **offender) 587 { 588 char *buf; 589 conf_err_t rv = E_NO_ERROR; 590 nvlist_t *nvp = NULL; 591 ind_action_t *alp; 592 int len; 593 594 /* 595 * Ensure that every indicator action referenced in each ruleset 596 * exists in the indicator list given. 597 */ 598 599 (void) nvlist_alloc(&nvp, NV_UNIQUE_NAME, 0); 600 601 while (indp != NULL) { 602 len = strlen(indp->ind_name) + 2; 603 buf = dmalloc(len); 604 (void) snprintf(buf, len, "%c%s", 605 indp->ind_state == INDICATOR_ON ? '+' : '-', 606 indp->ind_name); 607 (void) nvlist_add_boolean(nvp, buf); 608 dfree(buf, len); 609 indp = indp->next; 610 } 611 612 while (indrp != NULL && rv == E_NO_ERROR) { 613 alp = indrp->action_list; 614 while (alp != NULL && rv == E_NO_ERROR) { 615 len = strlen(alp->ind_name) + 2; 616 buf = dmalloc(len); 617 (void) snprintf(buf, len, "%c%s", 618 alp->ind_state == INDICATOR_ON ? '+' : '-', 619 alp->ind_name); 620 621 switch (nvlist_lookup_boolean(nvp, buf)) { 622 case 0: /* Normal case */ 623 break; 624 case ENOENT: 625 *offender = alp; 626 rv = 627 E_INDRULE_REFERENCES_NONEXISTENT_IND_ACTION; 628 break; 629 default: 630 break; 631 } 632 dfree(buf, len); 633 alp = alp->next; 634 } 635 indrp = indrp->next; 636 } 637 638 nvlist_free(nvp); 639 return (rv); 640 } 641 642 conf_err_t 643 check_state_transition(hotplug_state_t s1, hotplug_state_t s2) 644 { 645 /* 646 * The following are valid transitions: 647 * 648 * HPS_ABSENT -> HPS_PRESENT 649 * HPS_ABSENT -> HPS_CONFIGURED 650 * HPS_PRESENT -> HPS_CONFIGURED 651 * HPS_PRESENT -> HPS_ABSENT 652 * HPS_CONFIGURED -> HPS_UNCONFIGURED 653 * HPS_CONFIGURED -> HPS_ABSENT 654 * HPS_UNCONFIGURED -> HPS_ABSENT 655 * HPS_UNCONFIGURED -> HPS_CONFIGURED 656 * 657 */ 658 if (s1 == HPS_ABSENT && s2 != HPS_PRESENT && s2 != HPS_CONFIGURED) 659 return (E_INVALID_STATE_CHANGE); 660 else if (s1 == HPS_PRESENT && (s2 != HPS_CONFIGURED && 661 s2 != HPS_ABSENT)) 662 return (E_INVALID_STATE_CHANGE); 663 else if (s1 == HPS_CONFIGURED && (s2 != HPS_UNCONFIGURED && 664 s2 != HPS_ABSENT)) 665 return (E_INVALID_STATE_CHANGE); 666 else if (s1 == HPS_UNCONFIGURED && (s2 != HPS_ABSENT && 667 s2 != HPS_CONFIGURED)) 668 return (E_INVALID_STATE_CHANGE); 669 else 670 return (E_NO_ERROR); 671 } 672 673 static void 674 print_inds(indicator_t *indp, FILE *fp, char *prefix) 675 { 676 char plusminus; 677 678 (void) fprintf(fp, "%sindicators {\n", prefix); 679 while (indp != NULL) { 680 plusminus = (indp->ind_state == INDICATOR_ON) ? '+' : '-'; 681 (void) fprintf(fp, "%s\t%c%s = \"%s\"\n", prefix, plusminus, 682 indp->ind_name, indp->ind_instr_spec); 683 indp = indp->next; 684 } 685 (void) fprintf(fp, "%s}\n", prefix); 686 } 687 688 static void 689 print_indrules(indrule_t *lrp, FILE *fp, char *prefix) 690 { 691 char plusminus; 692 ind_action_t *lap; 693 694 (void) fprintf(fp, "%sindicator_rules {\n", prefix); 695 while (lrp != NULL) { 696 (void) fprintf(fp, "%s\t%12s -> %12s\t{ ", prefix, 697 hotplug_state_string(lrp->strans.begin), 698 hotplug_state_string(lrp->strans.end)); 699 lap = lrp->action_list; 700 while (lap != NULL) { 701 plusminus = (lap->ind_state == INDICATOR_ON) 702 ? '+' : '-'; 703 (void) fprintf(fp, "%c%s", plusminus, lap->ind_name); 704 lap = lap->next; 705 if (lap != NULL) 706 (void) fprintf(fp, ", "); 707 } 708 (void) fprintf(fp, " }\n"); 709 lrp = lrp->next; 710 } 711 (void) fprintf(fp, "%s}\n", prefix); 712 } 713 714 static void 715 print_props(nvlist_t *nvlp, FILE *fp, char *prefix) 716 { 717 nvpair_t *nvp = nvlist_next_nvpair(nvlp, NULL); 718 char *name, *str; 719 720 while (nvp != NULL) { 721 dm_assert(nvpair_type(nvp) == DATA_TYPE_STRING); 722 name = nvpair_name(nvp); 723 (void) nvlist_lookup_string(nvlp, name, &str); 724 (void) fprintf(fp, "%s%s = \"%s\"\n", prefix, name, str); 725 nvp = nvlist_next_nvpair(nvlp, nvp); 726 } 727 } 728 729 static void 730 print_ap(nvlist_t *dpp, FILE *fp, char *prefix) 731 { 732 int len = strlen(prefix) + 2; 733 char *buf = dmalloc(len); 734 735 (void) snprintf(buf, len, "%s\t", prefix); 736 737 (void) fprintf(fp, "%sap_props {\n", prefix); 738 print_props(dpp, fp, buf); 739 (void) fprintf(fp, "%s}\n", prefix); 740 741 dfree(buf, len); 742 } 743 744 static void 745 print_disks(diskmon_t *dmp, FILE *fp, char *prefix) 746 { 747 int len = strlen(prefix) + 2; 748 char *buf = dmalloc(len); 749 750 (void) snprintf(buf, len, "%s\t", prefix); 751 752 while (dmp != NULL) { 753 (void) fprintf(fp, "%sdisk \"%s\" {\n", prefix, dmp->location); 754 if (dmp->props) { 755 print_props(dmp->props, fp, buf); 756 } 757 if (dmp->app_props) { 758 print_ap(dmp->app_props, fp, buf); 759 } 760 (void) fprintf(fp, "%s\n", prefix); 761 print_inds(dmp->ind_list, fp, buf); 762 (void) fprintf(fp, "%s\n", prefix); 763 print_indrules(dmp->indrule_list, fp, buf); 764 (void) fprintf(fp, "%s}\n", prefix); 765 766 if (dmp->next != NULL) 767 (void) fprintf(fp, "%s\n", prefix); 768 769 dmp = dmp->next; 770 } 771 772 dfree(buf, len); 773 } 774 775 static void 776 print_cfgdata(cfgdata_t *cfgp, FILE *fp, char *prefix) 777 { 778 /* First, print the properties, then the disks */ 779 780 print_props(cfgp->props, fp, prefix); 781 (void) fprintf(fp, "%s\n", prefix); 782 print_disks(cfgp->disk_list, fp, prefix); 783 } 784 785 int 786 config_init(void) 787 { 788 if (init_configuration_from_topo() == 0) { 789 config_data = new_cfgdata(NULL, NULL); 790 return (0); 791 } 792 return (-1); 793 } 794 795 int 796 config_get(fmd_hdl_t *hdl, const fmd_prop_t *fmd_props) 797 { 798 int err, i = 0; 799 char *str = NULL; 800 namevalpr_t nvp; 801 uint64_t u64; 802 boolean_t intfound = B_FALSE, strfound = B_FALSE; 803 #define INT64_BUF_LEN 128 804 char buf[INT64_BUF_LEN]; 805 806 u64 = fmd_prop_get_int32(hdl, GLOBAL_PROP_LOG_LEVEL); 807 g_verbose = (int)u64; 808 809 err = update_configuration_from_topo(hdl, NULL); 810 811 /* Pull in the properties from the DE configuration file */ 812 while (fmd_props[i].fmdp_name != NULL) { 813 814 nvp.name = (char *)fmd_props[i].fmdp_name; 815 816 switch (fmd_props[i].fmdp_type) { 817 case FMD_TYPE_UINT32: 818 case FMD_TYPE_INT32: 819 intfound = B_TRUE; 820 u64 = fmd_prop_get_int32(hdl, fmd_props[i].fmdp_name); 821 break; 822 case FMD_TYPE_UINT64: 823 case FMD_TYPE_INT64: 824 intfound = B_TRUE; 825 u64 = fmd_prop_get_int64(hdl, fmd_props[i].fmdp_name); 826 break; 827 case FMD_TYPE_STRING: 828 strfound = B_TRUE; 829 str = fmd_prop_get_string(hdl, fmd_props[i].fmdp_name); 830 break; 831 832 } 833 834 if (intfound) { 835 (void) snprintf(buf, INT64_BUF_LEN, "0x%llx", u64); 836 nvp.value = buf; 837 intfound = B_FALSE; 838 } else if (strfound) { 839 nvp.value = str; 840 } 841 842 log_msg(MM_CONF, "Adding property `%s' with value `%s'\n", 843 nvp.name, nvp.value); 844 845 cfgdata_add_namevalpr(config_data, &nvp); 846 847 if (strfound) { 848 strfound = B_FALSE; 849 fmd_prop_free_string(hdl, str); 850 } 851 852 853 i++; 854 } 855 856 if ((g_verbose & (MM_CONF|MM_OTHER)) == (MM_CONF|MM_OTHER)) 857 print_cfgdata(config_data, stderr, ""); 858 859 return (err); 860 } 861 862 void 863 config_fini(void) 864 { 865 fini_configuration_from_topo(); 866 cfgdata_free(config_data); 867 config_data = NULL; 868 } 869 870 nvlist_t * 871 dm_global_proplist(void) 872 { 873 return (config_data->props); 874 } 875