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 43 static plwp_t *plwp_tbl[PLWP_TBL_SZ]; 44 45 void 46 lwpid_init() 47 { 48 (void) memset(&plwp_tbl, 0, sizeof (plwp_t *) * PLWP_TBL_SZ); 49 } 50 51 static uid_t 52 pwd_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 61 void 62 pwd_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 73 void 74 add_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 95 int 96 has_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 111 void 112 add_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 123 int 124 has_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 139 int 140 foreach_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 153 void 154 add_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 193 int 194 has_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 */ 212 void 213 convert_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 228 void 229 lwpid_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 241 void 242 lwpid_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 265 static plwp_t * 266 lwpid_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 278 lwp_info_t * 279 lwpid_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 288 int 289 lwpid_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 302 int 303 lwpid_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 312 void 313 lwpid_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