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 *
hotplug_state_string(hotplug_state_t state)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
conf_error_msg(conf_err_t err,char * buf,int buflen,void * arg)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
string_to_integer(const char * prop,int * value)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 *
dm_prop_lookup(nvlist_t * props,const char * prop_name)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
dm_prop_lookup_int(nvlist_t * props,const char * prop_name,int * value)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 *
namevalpr_to_nvlist(namevalpr_t * nvprp)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 *
new_indicator(ind_state_t lstate,char * namep,char * actionp)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
link_indicator(indicator_t ** first,indicator_t * to_add)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
ind_free(indicator_t * indp)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 *
new_indaction(ind_state_t state,char * namep)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
link_indaction(ind_action_t ** first,ind_action_t * to_add)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
indaction_free(ind_action_t * lap)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 *
new_indrule(state_transition_t * st,ind_action_t * actionp)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
link_indrule(indrule_t ** first,indrule_t * to_add)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
indrule_free(indrule_t * lrp)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 *
new_dmfru(char * manu,char * modl,char * firmrev,char * serno,uint64_t capa)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
dmfru_free(dm_fru_t * frup)327 dmfru_free(dm_fru_t *frup)
328 {
329 dfree(frup, sizeof (dm_fru_t));
330 }
331
332 diskmon_t *
new_diskmon(nvlist_t * app_props,indicator_t * indp,indrule_t * indrp,nvlist_t * nvlp)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
diskmon_free(diskmon_t * dmp)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 *
new_cfgdata(namevalpr_t * nvp,diskmon_t * dmp)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
cfgdata_add_namevalpr(cfgdata_t * cfgp,namevalpr_t * nvp)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
cfgdata_add_diskmon(cfgdata_t * cfgp,diskmon_t * dmp)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
cfgdata_free(cfgdata_t * cdp)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
check_indactions(ind_action_t * indrp)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
check_inds(indicator_t * indp)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
check_indrules(indrule_t * indrp,state_transition_t ** offender)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
check_consistent_ind_indrules(indicator_t * indp,indrule_t * indrp,ind_action_t ** offender)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
check_state_transition(hotplug_state_t s1,hotplug_state_t s2)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
print_inds(indicator_t * indp,FILE * fp,char * prefix)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
print_indrules(indrule_t * lrp,FILE * fp,char * prefix)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
print_props(nvlist_t * nvlp,FILE * fp,char * prefix)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
print_ap(nvlist_t * dpp,FILE * fp,char * prefix)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
print_disks(diskmon_t * dmp,FILE * fp,char * prefix)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
print_cfgdata(cfgdata_t * cfgp,FILE * fp,char * prefix)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
config_init(void)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
config_get(fmd_hdl_t * hdl,const fmd_prop_t * fmd_props)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
config_fini(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 *
dm_global_proplist(void)871 dm_global_proplist(void)
872 {
873 return (config_data->props);
874 }
875