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