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