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 2006 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 #include <alloca.h> 30 #include <syslog.h> 31 #include <strings.h> 32 33 #include <topo_error.h> 34 #include <topo_subr.h> 35 36 struct _rwlock; 37 struct _lwp_mutex; 38 39 int _topo_debug = 0; /* debug messages enabled (off) */ 40 int _topo_dbout = 0; /* debug messages output mode */ 41 42 int 43 topo_rw_read_held(pthread_rwlock_t *lock) 44 { 45 extern int _rw_read_held(struct _rwlock *); 46 return (_rw_read_held((struct _rwlock *)lock)); 47 } 48 49 int 50 topo_rw_write_held(pthread_rwlock_t *lock) 51 { 52 extern int _rw_write_held(struct _rwlock *); 53 return (_rw_write_held((struct _rwlock *)lock)); 54 } 55 56 int 57 topo_mutex_held(pthread_mutex_t *lock) 58 { 59 extern int _mutex_held(struct _lwp_mutex *); 60 return (_mutex_held((struct _lwp_mutex *)lock)); 61 } 62 63 void 64 topo_hdl_lock(topo_hdl_t *thp) 65 { 66 (void) pthread_mutex_lock(&thp->th_lock); 67 } 68 69 void 70 topo_hdl_unlock(topo_hdl_t *thp) 71 { 72 (void) pthread_mutex_unlock(&thp->th_lock); 73 } 74 75 const char * 76 topo_stability_name(topo_stability_t s) 77 { 78 switch (s) { 79 case TOPO_STABILITY_INTERNAL: return ("Internal"); 80 case TOPO_STABILITY_PRIVATE: return ("Private"); 81 case TOPO_STABILITY_OBSOLETE: return ("Obsolete"); 82 case TOPO_STABILITY_EXTERNAL: return ("External"); 83 case TOPO_STABILITY_UNSTABLE: return ("Unstable"); 84 case TOPO_STABILITY_EVOLVING: return ("Evolving"); 85 case TOPO_STABILITY_STABLE: return ("Stable"); 86 case TOPO_STABILITY_STANDARD: return ("Standard"); 87 default: return (NULL); 88 } 89 } 90 91 static const topo_debug_mode_t _topo_dbout_modes[] = { 92 { "stderr", "send debug messages to stderr", TOPO_DBOUT_STDERR }, 93 { "syslog", "send debug messages to syslog", TOPO_DBOUT_SYSLOG }, 94 { NULL, NULL, 0 } 95 }; 96 97 void 98 topo_debug_set(topo_hdl_t *thp, int mask, char *dout) 99 { 100 int i; 101 102 for (i = 0; i < 2; ++i) { 103 if (strcmp(_topo_dbout_modes[i].tdm_name, dout) == 0) { 104 thp->th_dbout = _topo_dbout = 105 _topo_dbout_modes[i].tdm_mode; 106 thp->th_debug = _topo_debug = mask; 107 topo_dprintf(mask, _topo_dbout_modes[i].tdm_desc); 108 } 109 } 110 } 111 112 void 113 topo_vdprintf(int mask, const char *format, va_list ap) 114 { 115 char *msg; 116 size_t len; 117 char c; 118 119 if (!(_topo_debug & mask)) 120 return; 121 122 len = vsnprintf(&c, 1, format, ap); 123 msg = alloca(len + 2); 124 (void) vsnprintf(msg, len + 1, format, ap); 125 126 if (msg[len - 1] != '\n') 127 (void) strcpy(&msg[len], "\n"); 128 129 if (_topo_dbout == TOPO_DBOUT_STDERR) 130 (void) fprintf(stderr, "libtopo DEBUG: %s", msg); 131 132 if (_topo_dbout == TOPO_DBOUT_SYSLOG) 133 syslog(LOG_DEBUG | LOG_USER, "libtopo DEBUG: %s", msg); 134 } 135 136 /*PRINTFLIKE2*/ 137 void 138 topo_dprintf(int mask, const char *format, ...) 139 { 140 va_list ap; 141 142 if (!(_topo_debug & mask)) 143 return; 144 145 va_start(ap, format); 146 topo_vdprintf(mask, format, ap); 147 va_end(ap); 148 } 149 150 tnode_t * 151 topo_hdl_root(topo_hdl_t *thp, const char *scheme) 152 { 153 ttree_t *tp; 154 155 for (tp = topo_list_next(&thp->th_trees); tp != NULL; 156 tp = topo_list_next(tp)) { 157 if (strcmp(scheme, tp->tt_scheme) == 0) 158 return (tp->tt_root); 159 } 160 161 return (NULL); 162 } 163 164 /* 165 * buf_append -- Append str to buf (if it's non-NULL). Place prepend 166 * in buf in front of str and append behind it (if they're non-NULL). 167 * Continue to update size even if we run out of space to actually 168 * stuff characters in the buffer. 169 */ 170 void 171 topo_fmristr_build(ssize_t *sz, char *buf, size_t buflen, char *str, 172 char *prepend, char *append) 173 { 174 ssize_t left; 175 176 if (str == NULL) 177 return; 178 179 if (buflen == 0 || (left = buflen - *sz) < 0) 180 left = 0; 181 182 if (buf != NULL && left != 0) 183 buf += *sz; 184 185 if (prepend == NULL && append == NULL) 186 *sz += snprintf(buf, left, "%s", str); 187 else if (append == NULL) 188 *sz += snprintf(buf, left, "%s%s", prepend, str); 189 else if (prepend == NULL) 190 *sz += snprintf(buf, left, "%s%s", str, append); 191 else 192 *sz += snprintf(buf, left, "%s%s%s", prepend, str, append); 193 } 194