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 (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25 /*
26 * Copyright 2020 Joyent, Inc.
27 * Copyright 2024 Oxide Computer Company
28 */
29
30 #include <alloca.h>
31 #include <ctype.h>
32 #include <limits.h>
33 #include <syslog.h>
34 #include <strings.h>
35 #include <unistd.h>
36 #include <sys/fm/protocol.h>
37 #include <sys/systeminfo.h>
38 #include <sys/utsname.h>
39
40 #include <topo_error.h>
41 #include <topo_digraph.h>
42 #include <topo_subr.h>
43
44 void
topo_hdl_lock(topo_hdl_t * thp)45 topo_hdl_lock(topo_hdl_t *thp)
46 {
47 (void) pthread_mutex_lock(&thp->th_lock);
48 }
49
50 void
topo_hdl_unlock(topo_hdl_t * thp)51 topo_hdl_unlock(topo_hdl_t *thp)
52 {
53 (void) pthread_mutex_unlock(&thp->th_lock);
54 }
55
56 const char *
topo_stability2name(topo_stability_t s)57 topo_stability2name(topo_stability_t s)
58 {
59 switch (s) {
60 case TOPO_STABILITY_INTERNAL: return (TOPO_STABSTR_INTERNAL);
61 case TOPO_STABILITY_PRIVATE: return (TOPO_STABSTR_PRIVATE);
62 case TOPO_STABILITY_OBSOLETE: return (TOPO_STABSTR_OBSOLETE);
63 case TOPO_STABILITY_EXTERNAL: return (TOPO_STABSTR_EXTERNAL);
64 case TOPO_STABILITY_UNSTABLE: return (TOPO_STABSTR_UNSTABLE);
65 case TOPO_STABILITY_EVOLVING: return (TOPO_STABSTR_EVOLVING);
66 case TOPO_STABILITY_STABLE: return (TOPO_STABSTR_STABLE);
67 case TOPO_STABILITY_STANDARD: return (TOPO_STABSTR_STANDARD);
68 default: return (TOPO_STABSTR_UNKNOWN);
69 }
70 }
71
72 topo_stability_t
topo_name2stability(const char * name)73 topo_name2stability(const char *name)
74 {
75 if (strcmp(name, TOPO_STABSTR_INTERNAL) == 0)
76 return (TOPO_STABILITY_INTERNAL);
77 else if (strcmp(name, TOPO_STABSTR_PRIVATE) == 0)
78 return (TOPO_STABILITY_PRIVATE);
79 else if (strcmp(name, TOPO_STABSTR_OBSOLETE) == 0)
80 return (TOPO_STABILITY_OBSOLETE);
81 else if (strcmp(name, TOPO_STABSTR_EXTERNAL) == 0)
82 return (TOPO_STABILITY_EXTERNAL);
83 else if (strcmp(name, TOPO_STABSTR_UNSTABLE) == 0)
84 return (TOPO_STABILITY_UNSTABLE);
85 else if (strcmp(name, TOPO_STABSTR_EVOLVING) == 0)
86 return (TOPO_STABILITY_EVOLVING);
87 else if (strcmp(name, TOPO_STABSTR_STABLE) == 0)
88 return (TOPO_STABILITY_STABLE);
89 else if (strcmp(name, TOPO_STABSTR_STANDARD) == 0)
90 return (TOPO_STABILITY_STANDARD);
91
92 return (TOPO_STABILITY_UNKNOWN);
93 }
94
95 static const topo_debug_mode_t _topo_dbout_modes[] = {
96 { "stderr", "send debug messages to stderr", TOPO_DBOUT_STDERR },
97 { "syslog", "send debug messages to syslog", TOPO_DBOUT_SYSLOG },
98 { NULL, NULL, 0 }
99 };
100
101 static const topo_debug_mode_t _topo_dbflag_modes[] = {
102 { "error", "error handling debug messages enabled", TOPO_DBG_ERR },
103 { "module", "module debug messages enabled", TOPO_DBG_MOD },
104 { "modulesvc", "module services debug messages enabled",
105 TOPO_DBG_MODSVC },
106 { "walk", "walker subsystem debug messages enabled", TOPO_DBG_WALK },
107 { "xml", "xml file parsing messages enabled", TOPO_DBG_XML },
108 { "devinfoforce", "devinfo DINFOFORCE snapshot used", TOPO_DBG_FORCE },
109 { "all", "all debug modes enabled", TOPO_DBG_ALL},
110 { NULL, NULL, 0 }
111 };
112
113 void
env_process_value(topo_hdl_t * thp,const char * begin,const char * end)114 env_process_value(topo_hdl_t *thp, const char *begin, const char *end)
115 {
116 char buf[MAXNAMELEN];
117 size_t count;
118 topo_debug_mode_t *dbp;
119
120 while (begin < end && isspace(*begin))
121 begin++;
122
123 while (begin < end && isspace(*(end - 1)))
124 end--;
125
126 if (begin >= end)
127 return;
128
129 count = end - begin;
130 count += 1;
131
132 if (count > sizeof (buf))
133 return;
134
135 (void) snprintf(buf, count, "%s", begin);
136
137 for (dbp = (topo_debug_mode_t *)_topo_dbflag_modes;
138 dbp->tdm_name != NULL; ++dbp) {
139 if (strcmp(buf, dbp->tdm_name) == 0)
140 thp->th_debug |= dbp->tdm_mode;
141 }
142 }
143
144 void
topo_debug_set(topo_hdl_t * thp,const char * dbmode,const char * dout)145 topo_debug_set(topo_hdl_t *thp, const char *dbmode, const char *dout)
146 {
147 char *end, *value, *next;
148 topo_debug_mode_t *dbp;
149
150 topo_hdl_lock(thp);
151 value = (char *)dbmode;
152
153 for (end = (char *)dbmode; *end != '\0'; value = next) {
154 end = strchr(value, ',');
155 if (end != NULL)
156 next = end + 1; /* skip the comma */
157 else
158 next = end = value + strlen(value);
159
160 env_process_value(thp, value, end);
161 }
162
163 if (dout == NULL) {
164 topo_hdl_unlock(thp);
165 return;
166 }
167
168 for (dbp = (topo_debug_mode_t *)_topo_dbout_modes;
169 dbp->tdm_name != NULL; ++dbp) {
170 if (strcmp(dout, dbp->tdm_name) == 0)
171 thp->th_dbout = dbp->tdm_mode;
172 }
173 topo_hdl_unlock(thp);
174 }
175
176 void
topo_vdprintf(topo_hdl_t * thp,const char * mod,const char * format,va_list ap)177 topo_vdprintf(topo_hdl_t *thp, const char *mod, const char *format, va_list ap)
178 {
179 char *msg;
180 size_t len;
181 char c;
182
183 len = vsnprintf(&c, 1, format, ap);
184 msg = alloca(len + 2);
185 (void) vsnprintf(msg, len + 1, format, ap);
186
187 if (msg[len - 1] != '\n')
188 (void) strcpy(&msg[len], "\n");
189
190 if (thp->th_dbout == TOPO_DBOUT_SYSLOG) {
191 if (mod == NULL) {
192 syslog(LOG_DEBUG | LOG_USER, "libtopo DEBUG: %s", msg);
193 } else {
194 syslog(LOG_DEBUG | LOG_USER, "libtopo DEBUG: %s: %s",
195 mod, msg);
196 }
197 } else {
198 if (mod == NULL) {
199 (void) fprintf(stderr, "libtopo DEBUG: %s", msg);
200 } else {
201 (void) fprintf(stderr, "libtopo DEBUG: %s: %s", mod,
202 msg);
203 }
204 }
205 }
206
207 /*PRINTFLIKE3*/
208 void
topo_dprintf(topo_hdl_t * thp,int mask,const char * format,...)209 topo_dprintf(topo_hdl_t *thp, int mask, const char *format, ...)
210 {
211 va_list ap;
212
213 if (!(thp->th_debug & mask))
214 return;
215
216 va_start(ap, format);
217 topo_vdprintf(thp, NULL, format, ap);
218 va_end(ap);
219 }
220
221 tnode_t *
topo_hdl_root(topo_hdl_t * thp,const char * scheme)222 topo_hdl_root(topo_hdl_t *thp, const char *scheme)
223 {
224 ttree_t *tp;
225 topo_digraph_t *tdg;
226
227 for (tp = topo_list_next(&thp->th_trees); tp != NULL;
228 tp = topo_list_next(tp)) {
229 if (strcmp(scheme, tp->tt_scheme) == 0)
230 return (tp->tt_root);
231 }
232 for (tdg = topo_list_next(&thp->th_digraphs); tdg != NULL;
233 tdg = topo_list_next(tdg)) {
234 if (strcmp(scheme, tdg->tdg_scheme) == 0)
235 return (tdg->tdg_rootnode);
236 }
237
238 return (NULL);
239 }
240
241 /*
242 * buf_append -- Append str to buf (if it's non-NULL). Place prepend
243 * in buf in front of str and append behind it (if they're non-NULL).
244 * Continue to update size even if we run out of space to actually
245 * stuff characters in the buffer.
246 */
247 void
topo_fmristr_build(ssize_t * sz,char * buf,size_t buflen,char * str,char * prepend,char * append)248 topo_fmristr_build(ssize_t *sz, char *buf, size_t buflen, char *str,
249 char *prepend, char *append)
250 {
251 ssize_t left;
252
253 if (str == NULL)
254 return;
255
256 if (buflen == 0 || (left = buflen - *sz) < 0)
257 left = 0;
258
259 if (buf != NULL && left != 0)
260 buf += *sz;
261
262 if (prepend == NULL && append == NULL)
263 *sz += snprintf(buf, left, "%s", str);
264 else if (append == NULL)
265 *sz += snprintf(buf, left, "%s%s", prepend, str);
266 else if (prepend == NULL)
267 *sz += snprintf(buf, left, "%s%s", str, append);
268 else
269 *sz += snprintf(buf, left, "%s%s%s", prepend, str, append);
270 }
271
272 #define TOPO_PLATFORM_PATH "%s/usr/platform/%s/lib/fm/topo/%s"
273 #define TOPO_COMMON_PATH "%s/usr/lib/fm/topo/%s"
274
275 char *
topo_search_path(topo_mod_t * mod,const char * rootdir,const char * file)276 topo_search_path(topo_mod_t *mod, const char *rootdir, const char *file)
277 {
278 char *pp, sp[PATH_MAX];
279 topo_hdl_t *thp = mod->tm_hdl;
280
281 /*
282 * Search for file name in order of platform, machine and common
283 * topo directories
284 */
285 (void) snprintf(sp, PATH_MAX, TOPO_PLATFORM_PATH, rootdir,
286 thp->th_platform, file);
287 if (access(sp, F_OK) != 0) {
288 (void) snprintf(sp, PATH_MAX, TOPO_PLATFORM_PATH,
289 thp->th_rootdir, thp->th_machine, file);
290 if (access(sp, F_OK) != 0) {
291 (void) snprintf(sp, PATH_MAX, TOPO_COMMON_PATH,
292 thp->th_rootdir, file);
293 if (access(sp, F_OK) != 0) {
294 return (NULL);
295 }
296 }
297 }
298
299 pp = topo_mod_strdup(mod, sp);
300
301 return (pp);
302 }
303
304 /*
305 * SMBIOS serial numbers (and many other strings from devices) can contain
306 * characters (particularly ':' and ' ') that are invalid for the authority and
307 * can break FMRI parsing. We translate any invalid characters to a safe '-',
308 * as well as trimming any leading or trailing whitespace. Similarly, '/' can
309 * be found in some product names so we translate that to '-'.
310 */
311 char *
topo_cleanup_strn(topo_hdl_t * thp,const char * begin,size_t max)312 topo_cleanup_strn(topo_hdl_t *thp, const char *begin, size_t max)
313 {
314 char buf[MAXNAMELEN];
315 const char *end, *cp;
316 char *pp;
317 char c;
318 size_t i;
319
320 end = begin + max;
321
322 while (begin < end && isspace(*begin))
323 begin++;
324 while (begin < end && (isspace(*(end - 1)) || *(end - 1) == '\0'))
325 end--;
326
327 if (begin >= end)
328 return (NULL);
329
330 cp = begin;
331 for (i = 0; i < MAXNAMELEN - 1; i++) {
332 if (cp >= end)
333 break;
334 c = *cp;
335 if (c == ':' || c == '=' || c == '/' || isspace(c) ||
336 !isprint(c))
337 buf[i] = '-';
338 else
339 buf[i] = c;
340 cp++;
341 }
342 buf[i] = 0;
343
344 pp = topo_hdl_strdup(thp, buf);
345 return (pp);
346 }
347
348 char *
topo_cleanup_auth_str(topo_hdl_t * thp,const char * begin)349 topo_cleanup_auth_str(topo_hdl_t *thp, const char *begin)
350 {
351 return (topo_cleanup_strn(thp, begin, strlen(begin)));
352 }
353
354 void
topo_sensor_type_name(uint32_t type,char * buf,size_t len)355 topo_sensor_type_name(uint32_t type, char *buf, size_t len)
356 {
357 topo_name_trans_t *ntp;
358
359 for (ntp = &topo_sensor_type_table[0]; ntp->int_name != NULL; ntp++) {
360 if (ntp->int_value == type) {
361 (void) strlcpy(buf, ntp->int_name, len);
362 return;
363 }
364 }
365
366 (void) snprintf(buf, len, "0x%02x", type);
367 }
368
369 void
topo_sensor_units_name(uint32_t type,char * buf,size_t len)370 topo_sensor_units_name(uint32_t type, char *buf, size_t len)
371 {
372 topo_name_trans_t *ntp;
373
374 for (ntp = &topo_units_type_table[0]; ntp->int_name != NULL; ntp++) {
375 if (ntp->int_value == type) {
376 (void) strlcpy(buf, ntp->int_name, len);
377 return;
378 }
379 }
380
381 (void) snprintf(buf, len, "0x%02x", type);
382 }
383
384 void
topo_led_type_name(uint32_t type,char * buf,size_t len)385 topo_led_type_name(uint32_t type, char *buf, size_t len)
386 {
387 topo_name_trans_t *ntp;
388
389 for (ntp = &topo_led_type_table[0]; ntp->int_name != NULL; ntp++) {
390 if (ntp->int_value == type) {
391 (void) strlcpy(buf, ntp->int_name, len);
392 return;
393 }
394 }
395
396 (void) snprintf(buf, len, "0x%02x", type);
397 }
398
399 void
topo_led_state_name(uint32_t type,char * buf,size_t len)400 topo_led_state_name(uint32_t type, char *buf, size_t len)
401 {
402 topo_name_trans_t *ntp;
403
404 for (ntp = &topo_led_states_table[0]; ntp->int_name != NULL; ntp++) {
405 if (ntp->int_value == type) {
406 (void) strlcpy(buf, ntp->int_name, len);
407 return;
408 }
409 }
410
411 (void) snprintf(buf, len, "0x%02x", type);
412 }
413
414 void
topo_sensor_state_name(uint32_t sensor_type,uint32_t state,char * buf,size_t len)415 topo_sensor_state_name(uint32_t sensor_type, uint32_t state, char *buf,
416 size_t len)
417 {
418 topo_name_trans_t *ntp;
419
420 switch (sensor_type) {
421 case TOPO_SENSOR_TYPE_PHYSICAL:
422 ntp = &topo_sensor_states_physical_table[0];
423 break;
424 case TOPO_SENSOR_TYPE_PLATFORM:
425 ntp = &topo_sensor_states_platform_table[0];
426 break;
427 case TOPO_SENSOR_TYPE_PROCESSOR:
428 ntp = &topo_sensor_states_processor_table[0];
429 break;
430 case TOPO_SENSOR_TYPE_POWER_SUPPLY:
431 ntp = &topo_sensor_states_power_supply_table[0];
432 break;
433 case TOPO_SENSOR_TYPE_POWER_UNIT:
434 ntp = &topo_sensor_states_power_unit_table[0];
435 break;
436 case TOPO_SENSOR_TYPE_MEMORY:
437 ntp = &topo_sensor_states_memory_table[0];
438 break;
439 case TOPO_SENSOR_TYPE_BAY:
440 ntp = &topo_sensor_states_bay_table[0];
441 break;
442 case TOPO_SENSOR_TYPE_FIRMWARE:
443 ntp = &topo_sensor_states_firmware_table[0];
444 break;
445 case TOPO_SENSOR_TYPE_EVENT_LOG:
446 ntp = &topo_sensor_states_event_log_table[0];
447 break;
448 case TOPO_SENSOR_TYPE_WATCHDOG1:
449 ntp = &topo_sensor_states_watchdog1_table[0];
450 break;
451 case TOPO_SENSOR_TYPE_SYSTEM:
452 ntp = &topo_sensor_states_system_table[0];
453 break;
454 case TOPO_SENSOR_TYPE_CRITICAL:
455 ntp = &topo_sensor_states_critical_table[0];
456 break;
457 case TOPO_SENSOR_TYPE_BUTTON:
458 ntp = &topo_sensor_states_button_table[0];
459 break;
460 case TOPO_SENSOR_TYPE_CABLE:
461 ntp = &topo_sensor_states_cable_table[0];
462 break;
463 case TOPO_SENSOR_TYPE_BOOT_STATE:
464 ntp = &topo_sensor_states_boot_state_table[0];
465 break;
466 case TOPO_SENSOR_TYPE_BOOT_ERROR:
467 ntp = &topo_sensor_states_boot_error_table[0];
468 break;
469 case TOPO_SENSOR_TYPE_BOOT_OS:
470 ntp = &topo_sensor_states_boot_os_table[0];
471 break;
472 case TOPO_SENSOR_TYPE_OS_SHUTDOWN:
473 ntp = &topo_sensor_states_os_table[0];
474 break;
475 case TOPO_SENSOR_TYPE_SLOT:
476 ntp = &topo_sensor_states_slot_table[0];
477 break;
478 case TOPO_SENSOR_TYPE_ACPI:
479 ntp = &topo_sensor_states_acpi_table[0];
480 break;
481 case TOPO_SENSOR_TYPE_WATCHDOG2:
482 ntp = &topo_sensor_states_watchdog2_table[0];
483 break;
484 case TOPO_SENSOR_TYPE_ALERT:
485 ntp = &topo_sensor_states_alert_table[0];
486 break;
487 case TOPO_SENSOR_TYPE_PRESENCE:
488 ntp = &topo_sensor_states_presence_table[0];
489 break;
490 case TOPO_SENSOR_TYPE_LAN:
491 ntp = &topo_sensor_states_lan_table[0];
492 break;
493 case TOPO_SENSOR_TYPE_HEALTH:
494 ntp = &topo_sensor_states_health_table[0];
495 break;
496 case TOPO_SENSOR_TYPE_BATTERY:
497 ntp = &topo_sensor_states_battery_table[0];
498 break;
499 case TOPO_SENSOR_TYPE_AUDIT:
500 ntp = &topo_sensor_states_audit_table[0];
501 break;
502 case TOPO_SENSOR_TYPE_VERSION:
503 ntp = &topo_sensor_states_version_table[0];
504 break;
505 case TOPO_SENSOR_TYPE_FRU_STATE:
506 ntp = &topo_sensor_states_fru_state_table[0];
507 break;
508 case TOPO_SENSOR_TYPE_THRESHOLD_STATE:
509 ntp = &topo_sensor_states_thresh_table[0];
510 break;
511 case TOPO_SENSOR_TYPE_GENERIC_USAGE:
512 ntp = &topo_sensor_states_generic_usage_table[0];
513 break;
514 case TOPO_SENSOR_TYPE_GENERIC_STATE:
515 ntp = &topo_sensor_states_generic_state_table[0];
516 break;
517 case TOPO_SENSOR_TYPE_GENERIC_PREDFAIL:
518 ntp = &topo_sensor_states_generic_predfail_table[0];
519 break;
520 case TOPO_SENSOR_TYPE_GENERIC_LIMIT:
521 ntp = &topo_sensor_states_generic_limit_table[0];
522 break;
523 case TOPO_SENSOR_TYPE_GENERIC_PERFORMANCE:
524 ntp = &topo_sensor_states_generic_perf_table[0];
525 break;
526 case TOPO_SENSOR_TYPE_SEVERITY:
527 ntp = &topo_sensor_states_severity_table[0];
528 break;
529 case TOPO_SENSOR_TYPE_GENERIC_PRESENCE:
530 ntp = &topo_sensor_states_generic_presence_table[0];
531 break;
532 case TOPO_SENSOR_TYPE_GENERIC_AVAILABILITY:
533 ntp = &topo_sensor_states_generic_avail_table[0];
534 break;
535 case TOPO_SENSOR_TYPE_GENERIC_STATUS:
536 ntp = &topo_sensor_states_generic_status_table[0];
537 break;
538 case TOPO_SENSOR_TYPE_GENERIC_ACPI:
539 ntp = &topo_sensor_states_generic_acpi_pwr_table[0];
540 break;
541 case TOPO_SENSOR_TYPE_GENERIC_FAILURE:
542 ntp = &topo_sensor_states_generic_failure_table[0];
543 break;
544 case TOPO_SENSOR_TYPE_GENERIC_OK:
545 ntp = &topo_sensor_states_generic_ok_table[0];
546 break;
547 default:
548 (void) snprintf(buf, len, "0x%02x", state);
549 return;
550 }
551 if (state == 0) {
552 (void) snprintf(buf, len, "NO_STATES_ASSERTED");
553 return;
554 }
555 buf[0] = '\0';
556 for (; ntp->int_name != NULL; ntp++) {
557 if (state & ntp->int_value) {
558 if (buf[0] != '\0')
559 (void) strlcat(buf, "|", len);
560 (void) strlcat(buf, ntp->int_name, len);
561 }
562 }
563
564 if (buf[0] == '\0')
565 (void) snprintf(buf, len, "0x%02x", state);
566 }
567
568 static const topo_pgroup_info_t sys_pgroup = {
569 TOPO_PGROUP_SYSTEM,
570 TOPO_STABILITY_PRIVATE,
571 TOPO_STABILITY_PRIVATE,
572 1
573 };
574 static const topo_pgroup_info_t auth_pgroup = {
575 FM_FMRI_AUTHORITY,
576 TOPO_STABILITY_PRIVATE,
577 TOPO_STABILITY_PRIVATE,
578 1
579 };
580
581 void
topo_pgroup_hcset(tnode_t * node,nvlist_t * auth)582 topo_pgroup_hcset(tnode_t *node, nvlist_t *auth)
583 {
584 int err;
585 char isa[MAXNAMELEN];
586 struct utsname uts;
587 char *prod, *psn, *csn, *server;
588
589 if (auth == NULL)
590 return;
591
592 if (topo_pgroup_create(node, &auth_pgroup, &err) != 0) {
593 if (err != ETOPO_PROP_DEFD)
594 return;
595 }
596
597 /*
598 * Inherit if we can, it saves memory
599 */
600 if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT,
601 &err) != 0) && (err != ETOPO_PROP_DEFD)) {
602 if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT, &prod) ==
603 0)
604 (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
605 FM_FMRI_AUTH_PRODUCT, TOPO_PROP_IMMUTABLE, prod,
606 &err);
607 }
608 if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT_SN,
609 &err) != 0) && (err != ETOPO_PROP_DEFD)) {
610 if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN, &psn) ==
611 0)
612 (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
613 FM_FMRI_AUTH_PRODUCT_SN, TOPO_PROP_IMMUTABLE, psn,
614 &err);
615 }
616 if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS,
617 &err) != 0) && (err != ETOPO_PROP_DEFD)) {
618 if (nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS, &csn) == 0)
619 (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
620 FM_FMRI_AUTH_CHASSIS, TOPO_PROP_IMMUTABLE, csn,
621 &err);
622 }
623 if ((topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_SERVER,
624 &err) != 0) && (err != ETOPO_PROP_DEFD)) {
625 if (nvlist_lookup_string(auth, FM_FMRI_AUTH_SERVER, &server) ==
626 0)
627 (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY,
628 FM_FMRI_AUTH_SERVER, TOPO_PROP_IMMUTABLE, server,
629 &err);
630 }
631
632 if (topo_pgroup_create(node, &sys_pgroup, &err) != 0)
633 return;
634
635 if (sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)) != -1)
636 (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM,
637 TOPO_PROP_ISA, TOPO_PROP_IMMUTABLE, isa, &err);
638
639 if (uname(&uts) != -1)
640 (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM,
641 TOPO_PROP_MACHINE, TOPO_PROP_IMMUTABLE, uts.machine, &err);
642 }
643