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