6659 nvlist_free(NULL) is a no-op
[illumos-gate.git] / usr / src / cmd / fm / modules / common / disk-monitor / diskmon_conf.c
blob4a4c5aa8c33cc9cf6c96d75c54d8e65b8d1d9718
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Disk & Indicator Monitor configuration file support routines
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>
41 #include "disk_monitor.h"
42 #include "util.h"
43 #include "topo_gather.h"
45 extern log_class_t g_verbose;
47 const char *
48 hotplug_state_string(hotplug_state_t state)
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");
65 void
66 conf_error_msg(conf_err_t err, char *buf, int buflen, void *arg)
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;
119 static int
120 string_to_integer(const char *prop, int *value)
122 long val;
124 errno = 0;
126 val = strtol(prop, NULL, 0);
128 if (val == 0 && errno != 0)
129 return (-1);
130 else if (val > INT_MAX || val < INT_MIN) {
131 errno = ERANGE;
132 return (-1);
135 if (value != NULL)
136 *value = (int)val;
138 return (0);
141 const char *
142 dm_prop_lookup(nvlist_t *props, const char *prop_name)
144 char *str;
146 if (nvlist_lookup_string(props, prop_name, &str) == 0)
147 return ((const char *)str);
148 else
149 return (NULL);
153 dm_prop_lookup_int(nvlist_t *props, const char *prop_name, int *value)
155 const char *prop = dm_prop_lookup(props, prop_name);
157 if (prop == NULL)
158 return (-1);
160 return (string_to_integer(prop, value));
163 nvlist_t *
164 namevalpr_to_nvlist(namevalpr_t *nvprp)
166 nvlist_t *nvlp = NULL;
168 if (nvlist_alloc(&nvlp, NV_UNIQUE_NAME, 0) != 0) {
169 return (NULL);
172 if (nvlist_add_string(nvlp, nvprp->name, nvprp->value) != 0) {
173 nvlist_free(nvlp);
174 return (NULL);
177 return (nvlp);
180 indicator_t *
181 new_indicator(ind_state_t lstate, char *namep, char *actionp)
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);
192 void
193 link_indicator(indicator_t **first, indicator_t *to_add)
195 indicator_t *travptr;
196 dm_assert(first != NULL);
198 if (*first == NULL)
199 *first = to_add;
200 else {
201 travptr = *first;
202 while (travptr->next != NULL) {
203 travptr = travptr->next;
205 travptr->next = to_add;
209 void
210 ind_free(indicator_t *indp)
212 indicator_t *nextp;
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;
225 ind_action_t *
226 new_indaction(ind_state_t state, char *namep)
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);
235 void
236 link_indaction(ind_action_t **first, ind_action_t *to_add)
238 ind_action_t *travptr;
239 dm_assert(first != NULL);
241 if (*first == NULL)
242 *first = to_add;
243 else {
244 travptr = *first;
245 while (travptr->next != NULL) {
246 travptr = travptr->next;
248 travptr->next = to_add;
252 void
253 indaction_free(ind_action_t *lap)
255 ind_action_t *nextp;
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;
267 indrule_t *
268 new_indrule(state_transition_t *st, ind_action_t *actionp)
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);
278 void
279 link_indrule(indrule_t **first, indrule_t *to_add)
281 indrule_t *travptr;
282 dm_assert(first != NULL);
284 if (*first == NULL)
285 *first = to_add;
286 else {
287 travptr = *first;
288 while (travptr->next != NULL) {
289 travptr = travptr->next;
291 travptr->next = to_add;
295 void
296 indrule_free(indrule_t *lrp)
298 indrule_t *nextp;
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;
310 dm_fru_t *
311 new_dmfru(char *manu, char *modl, char *firmrev, char *serno, uint64_t capa)
313 dm_fru_t *frup = (dm_fru_t *)dzmalloc(sizeof (dm_fru_t));
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);
324 void
325 dmfru_free(dm_fru_t *frup)
327 dfree(frup, sizeof (dm_fru_t));
330 diskmon_t *
331 new_diskmon(nvlist_t *app_props, indicator_t *indp, indrule_t *indrp,
332 nvlist_t *nvlp)
334 diskmon_t *dmp = (diskmon_t *)dmalloc(sizeof (diskmon_t));
336 if (nvlp != NULL)
337 dmp->props = nvlp;
338 else
339 (void) nvlist_alloc(&dmp->props, NV_UNIQUE_NAME, 0);
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;
348 dm_assert(pthread_mutex_init(&dmp->manager_mutex, NULL) == 0);
350 dmp->state = HPS_UNKNOWN;
352 dmp->initial_configuration = B_TRUE;
354 dm_assert(pthread_mutex_init(&dmp->fault_indicator_mutex, NULL) == 0);
355 dmp->fault_indicator_state = INDICATOR_UNKNOWN;
357 dmp->configured_yet = B_FALSE;
358 dmp->state_change_count = 0;
360 dm_assert(pthread_mutex_init(&dmp->fru_mutex, NULL) == 0);
361 dmp->frup = NULL;
363 dmp->next = NULL;
364 return (dmp);
367 void
368 diskmon_free(diskmon_t *dmp)
370 diskmon_t *nextp;
372 /* Free the whole list */
373 while (dmp != NULL) {
374 nextp = dmp->next;
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));
388 dmp = nextp;
392 static cfgdata_t *
393 new_cfgdata(namevalpr_t *nvp, diskmon_t *dmp)
395 cfgdata_t *cdp = (cfgdata_t *)dzmalloc(sizeof (cfgdata_t));
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);
403 if (dmp != NULL)
404 cdp->disk_list = dmp;
405 return (cdp);
409 static void
410 cfgdata_add_namevalpr(cfgdata_t *cfgp, namevalpr_t *nvp)
412 if (cfgp->props == NULL) {
413 (void) nvlist_alloc(&cfgp->props, NV_UNIQUE_NAME, 0);
415 (void) nvlist_add_string(cfgp->props, nvp->name, nvp->value);
418 void
419 cfgdata_add_diskmon(cfgdata_t *cfgp, diskmon_t *dmp)
421 if (cfgp->disk_list == NULL) {
422 cfgp->disk_list = dmp;
423 } else {
424 diskmon_t *disklist = cfgp->disk_list;
426 while (disklist->next != NULL)
427 disklist = disklist->next;
429 disklist->next = dmp;
433 static void
434 cfgdata_free(cfgdata_t *cdp)
436 nvlist_free(cdp->props);
437 diskmon_free(cdp->disk_list);
438 dfree(cdp, sizeof (cfgdata_t));
441 conf_err_t
442 check_indactions(ind_action_t *indrp)
444 char *buf;
445 conf_err_t rv = E_NO_ERROR;
446 nvlist_t *nvp = NULL;
447 int len;
449 (void) nvlist_alloc(&nvp, NV_UNIQUE_NAME, 0);
452 * Check indicator actions for conflicts
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;
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;
484 dfree(buf, len);
485 indrp = indrp->next;
488 nvlist_free(nvp);
489 return (rv);
492 conf_err_t
493 check_inds(indicator_t *indp)
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;
501 (void) nvlist_alloc(&nvp, NV_UNIQUE_NAME, 0);
504 * Check inds for multiple definitions (same identifier or same action)
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);
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;
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;
529 dfree(buf, len);
530 indp = indp->next;
534 * Make sure we have a -FAULT and +FAULT
536 if (!fault_on)
537 rv = E_IND_MISSING_FAULT_ON;
538 else if (!fault_off)
539 rv = E_IND_MISSING_FAULT_OFF;
541 nvlist_free(nvp);
542 return (rv);
545 conf_err_t
546 check_indrules(indrule_t *indrp, state_transition_t **offender)
548 char buf[32];
549 conf_err_t rv = E_NO_ERROR;
550 nvlist_t *nvp = NULL;
553 * Ensure that no two rules have the same state transitions.
556 (void) nvlist_alloc(&nvp, NV_UNIQUE_NAME, 0);
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;
572 indrp = indrp->next;
575 nvlist_free(nvp);
576 return (rv);
580 conf_err_t
581 check_consistent_ind_indrules(indicator_t *indp, indrule_t *indrp,
582 ind_action_t **offender)
584 char *buf;
585 conf_err_t rv = E_NO_ERROR;
586 nvlist_t *nvp = NULL;
587 ind_action_t *alp;
588 int len;
591 * Ensure that every indicator action referenced in each ruleset
592 * exists in the indicator list given.
595 (void) nvlist_alloc(&nvp, NV_UNIQUE_NAME, 0);
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;
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);
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;
628 dfree(buf, len);
629 alp = alp->next;
631 indrp = indrp->next;
634 nvlist_free(nvp);
635 return (rv);
638 conf_err_t
639 check_state_transition(hotplug_state_t s1, hotplug_state_t s2)
642 * The following are valid transitions:
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
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);
669 static void
670 print_inds(indicator_t *indp, FILE *fp, char *prefix)
672 char plusminus;
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;
681 (void) fprintf(fp, "%s}\n", prefix);
684 static void
685 print_indrules(indrule_t *lrp, FILE *fp, char *prefix)
687 char plusminus;
688 ind_action_t *lap;
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, ", ");
704 (void) fprintf(fp, " }\n");
705 lrp = lrp->next;
707 (void) fprintf(fp, "%s}\n", prefix);
710 static void
711 print_props(nvlist_t *nvlp, FILE *fp, char *prefix)
713 nvpair_t *nvp = nvlist_next_nvpair(nvlp, NULL);
714 char *name, *str;
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);
725 static void
726 print_ap(nvlist_t *dpp, FILE *fp, char *prefix)
728 int len = strlen(prefix) + 2;
729 char *buf = dmalloc(len);
731 (void) snprintf(buf, len, "%s\t", prefix);
733 (void) fprintf(fp, "%sap_props {\n", prefix);
734 print_props(dpp, fp, buf);
735 (void) fprintf(fp, "%s}\n", prefix);
737 dfree(buf, len);
740 static void
741 print_disks(diskmon_t *dmp, FILE *fp, char *prefix)
743 int len = strlen(prefix) + 2;
744 char *buf = dmalloc(len);
746 (void) snprintf(buf, len, "%s\t", prefix);
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);
753 if (dmp->app_props) {
754 print_ap(dmp->app_props, fp, buf);
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);
762 if (dmp->next != NULL)
763 (void) fprintf(fp, "%s\n", prefix);
765 dmp = dmp->next;
768 dfree(buf, len);
771 static void
772 print_cfgdata(cfgdata_t *cfgp, FILE *fp, char *prefix)
774 /* First, print the properties, then the disks */
776 print_props(cfgp->props, fp, prefix);
777 (void) fprintf(fp, "%s\n", prefix);
778 print_disks(cfgp->disk_list, fp, prefix);
782 config_init(void)
784 if (init_configuration_from_topo() == 0) {
785 config_data = new_cfgdata(NULL, NULL);
786 return (0);
788 return (-1);
792 config_get(fmd_hdl_t *hdl, const fmd_prop_t *fmd_props)
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];
802 u64 = fmd_prop_get_int32(hdl, GLOBAL_PROP_LOG_LEVEL);
803 g_verbose = (int)u64;
805 err = update_configuration_from_topo(hdl, NULL);
807 /* Pull in the properties from the DE configuration file */
808 while (fmd_props[i].fmdp_name != NULL) {
810 nvp.name = (char *)fmd_props[i].fmdp_name;
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;
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;
838 log_msg(MM_CONF, "Adding property `%s' with value `%s'\n",
839 nvp.name, nvp.value);
841 cfgdata_add_namevalpr(config_data, &nvp);
843 if (strfound) {
844 strfound = B_FALSE;
845 fmd_prop_free_string(hdl, str);
849 i++;
852 if ((g_verbose & (MM_CONF|MM_OTHER)) == (MM_CONF|MM_OTHER))
853 print_cfgdata(config_data, stderr, "");
855 return (err);
858 void
859 config_fini(void)
861 fini_configuration_from_topo();
862 cfgdata_free(config_data);
863 config_data = NULL;
866 nvlist_t *
867 dm_global_proplist(void)
869 return (config_data->props);