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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 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 <procfs.h> 30 #include <unistd.h> 31 #include <stdlib.h> 32 #include <pwd.h> 33 #include <ctype.h> 34 #include <string.h> 35 #include <libintl.h> 36 #include <errno.h> 37 #include <zone.h> 38 #include <libzonecfg.h> 39 40 #include "prstat.h" 41 #include "prutil.h" 42 #include "prtable.h" 43 44 static plwp_t *plwp_tbl[PLWP_TBL_SZ]; 45 46 void 47 lwpid_init() 48 { 49 (void) memset(&plwp_tbl, 0, sizeof (plwp_t *) * PLWP_TBL_SZ); 50 } 51 52 static int 53 pwd_getid(char *name) 54 { 55 struct passwd *pwd; 56 57 if ((pwd = getpwnam(name)) == NULL) 58 Die(gettext("invalid user name: %s\n"), name); 59 return (pwd->pw_uid); 60 } 61 62 void 63 pwd_getname(int uid, char *name, int length) 64 { 65 struct passwd *pwd; 66 67 if ((pwd = getpwuid(uid)) == NULL) { 68 (void) snprintf(name, length, "%d", uid); 69 } else { 70 (void) snprintf(name, length, "%s", pwd->pw_name); 71 } 72 } 73 74 void 75 add_uid(nametbl_t *tbl, char *name) 76 { 77 name_t *entp; 78 79 if (tbl->n_size == tbl->n_nent) { /* reallocation */ 80 if ((tbl->n_size *= 2) == 0) 81 tbl->n_size = 4; /* first time */ 82 tbl->n_list = Realloc(tbl->n_list, tbl->n_size*sizeof (name_t)); 83 } 84 85 entp = &tbl->n_list[tbl->n_nent++]; 86 87 if (isdigit(name[0])) { 88 entp->u_id = Atoi(name); 89 pwd_getname(entp->u_id, entp->u_name, LOGNAME_MAX); 90 } else { 91 entp->u_id = pwd_getid(name); 92 (void) snprintf(entp->u_name, LOGNAME_MAX, "%s", name); 93 } 94 } 95 96 int 97 has_uid(nametbl_t *tbl, uid_t uid) 98 { 99 size_t i; 100 101 if (tbl->n_nent) { /* do linear search if table is not empty */ 102 for (i = 0; i < tbl->n_nent; i++) 103 if (tbl->n_list[i].u_id == uid) 104 return (1); 105 } else { 106 return (1); /* if table is empty return true */ 107 } 108 109 return (0); /* nothing has been found */ 110 } 111 112 void 113 add_element(table_t *table, long element) 114 { 115 if (table->t_size == table->t_nent) { 116 if ((table->t_size *= 2) == 0) 117 table->t_size = 4; 118 table->t_list = Realloc(table->t_list, 119 table->t_size * sizeof (long)); 120 } 121 table->t_list[table->t_nent++] = element; 122 } 123 124 int 125 has_element(table_t *table, long element) 126 { 127 size_t i; 128 129 if (table->t_nent) { /* do linear search if table is not empty */ 130 for (i = 0; i < table->t_nent; i++) 131 if (table->t_list[i] == element) 132 return (1); 133 } else { /* if table is empty then */ 134 return (1); /* pretend that element was found */ 135 } 136 137 return (0); /* element was not found */ 138 } 139 140 int 141 foreach_element(table_t *table, void *buf, void (*walker)(long, void *)) 142 { 143 size_t i; 144 145 if (table->t_nent) { 146 for (i = 0; i < table->t_nent; i++) 147 walker(table->t_list[i], buf); 148 } else { 149 return (0); 150 } 151 return (1); 152 } 153 154 void 155 add_zone(zonetbl_t *tbl, char *str) 156 { 157 zonename_t *entp; 158 zoneid_t id; 159 char *cp; 160 161 /* 162 * str should be either the name of a configured zone, or the 163 * id of a running zone. If str is a zone name, store the name 164 * in the table; otherwise, just store the id. 165 */ 166 if (zone_get_id(str, &id) != 0) { 167 Die(gettext("unknown zone -- %s\n"), str); 168 /*NOTREACHED*/ 169 } 170 171 /* was zone specified by name or id? */ 172 errno = 0; 173 if (id == (zoneid_t)strtol(str, &cp, 0) && errno == 0 && cp != str && 174 *cp == '\0') { 175 /* found it by id, don't store the name */ 176 str = NULL; 177 } 178 179 if (tbl->z_size == tbl->z_nent) { /* reallocation */ 180 if ((tbl->z_size *= 2) == 0) 181 tbl->z_size = 4; /* first time */ 182 tbl->z_list = 183 Realloc(tbl->z_list, tbl->z_size * sizeof (zonename_t)); 184 } 185 186 entp = &tbl->z_list[tbl->z_nent++]; 187 if (str) 188 (void) strlcpy(entp->z_name, str, ZONENAME_MAX); 189 else 190 entp->z_name[0] = '\0'; 191 entp->z_id = id; 192 } 193 194 int 195 has_zone(zonetbl_t *tbl, zoneid_t id) 196 { 197 long i; 198 199 if (tbl->z_nent) { /* do linear search if table is not empty */ 200 for (i = 0; i < tbl->z_nent; i++) 201 if (tbl->z_list[i].z_id == id) 202 return (1); 203 return (0); /* nothing has been found */ 204 } 205 206 return (1); /* if table is empty return true */ 207 } 208 209 /* 210 * Lookup ids for each zone name; this is done once each time /proc 211 * is scanned to avoid calling getzoneidbyname for each process. 212 */ 213 void 214 convert_zone(zonetbl_t *tbl) 215 { 216 long i; 217 zoneid_t id; 218 char *name; 219 220 for (i = 0; i < tbl->z_nent; i++) { 221 name = tbl->z_list[i].z_name; 222 if (name != NULL) { 223 if ((id = getzoneidbyname(name)) != -1) 224 tbl->z_list[i].z_id = id; 225 } 226 } 227 } 228 229 void 230 lwpid_add(lwp_info_t *lwp, pid_t pid, id_t lwpid) 231 { 232 plwp_t *elm = Zalloc(sizeof (plwp_t)); 233 int hash = pid % PLWP_TBL_SZ; 234 235 elm->l_pid = pid; 236 elm->l_lwpid = lwpid; 237 elm->l_lwp = lwp; 238 elm->l_next = plwp_tbl[hash]; /* add in front of chain */ 239 plwp_tbl[hash] = elm; 240 } 241 242 void 243 lwpid_del(pid_t pid, id_t lwpid) 244 { 245 plwp_t *elm, *elm_prev; 246 int hash = pid % PLWP_TBL_SZ; 247 248 elm = plwp_tbl[hash]; 249 elm_prev = NULL; 250 251 while (elm) { 252 if ((elm->l_pid == pid) && (elm->l_lwpid == lwpid)) { 253 if (!elm_prev) /* first chain element */ 254 plwp_tbl[hash] = elm->l_next; 255 else 256 elm_prev->l_next = elm->l_next; 257 free(elm); 258 break; 259 } else { 260 elm_prev = elm; 261 elm = elm->l_next; 262 } 263 } 264 } 265 266 static plwp_t * 267 lwpid_getptr(pid_t pid, id_t lwpid) 268 { 269 plwp_t *elm = plwp_tbl[pid % PLWP_TBL_SZ]; 270 while (elm) { 271 if ((elm->l_pid == pid) && (elm->l_lwpid == lwpid)) 272 return (elm); 273 else 274 elm = elm->l_next; 275 } 276 return (NULL); 277 } 278 279 lwp_info_t * 280 lwpid_get(pid_t pid, id_t lwpid) 281 { 282 plwp_t *elm = lwpid_getptr(pid, lwpid); 283 if (elm) 284 return (elm->l_lwp); 285 else 286 return (NULL); 287 } 288 289 int 290 lwpid_pidcheck(pid_t pid) 291 { 292 plwp_t *elm; 293 elm = plwp_tbl[pid % PLWP_TBL_SZ]; 294 while (elm) { 295 if (elm->l_pid == pid) 296 return (1); 297 else 298 elm = elm->l_next; 299 } 300 return (0); 301 } 302 303 int 304 lwpid_is_active(pid_t pid, id_t lwpid) 305 { 306 plwp_t *elm = lwpid_getptr(pid, lwpid); 307 if (elm) 308 return (elm->l_active); 309 else 310 return (0); 311 } 312 313 void 314 lwpid_set_active(pid_t pid, id_t lwpid) 315 { 316 plwp_t *elm = lwpid_getptr(pid, lwpid); 317 if (elm) 318 elm->l_active = LWP_ACTIVE; 319 } 320