Print this page
4823 don't open-code NSEC2MSEC and MSEC2NSEC
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/mdb/common/modules/svc.configd/configd.c
+++ new/usr/src/cmd/mdb/common/modules/svc.configd/configd.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License, Version 1.0 only
6 6 * (the "License"). You may not use this file except in compliance
7 7 * with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
12 12 * and limitations under the License.
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 19 *
20 20 * CDDL HEADER END
21 21 */
22 22 /*
23 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 -#pragma ident "%Z%%M% %I% %E% SMI"
28 -
29 27 #include <mdb/mdb_modapi.h>
30 28 #include <mdb/mdb_ctf.h>
31 29
32 30 #include <configd.h>
33 31
34 32 mdb_ctf_id_t request_enum;
35 33 mdb_ctf_id_t response_enum;
36 34 mdb_ctf_id_t ptr_type_enum;
37 35 mdb_ctf_id_t thread_state_enum;
38 36
39 37 hrtime_t max_time_seen;
40 38
41 39 static void
42 40 enum_lookup(char *out, size_t size, mdb_ctf_id_t id, int val,
43 41 const char *prefix, const char *prefix2)
44 42 {
45 43 const char *cp;
46 44 size_t len = strlen(prefix);
47 45 size_t len2 = strlen(prefix2);
48 46
49 47 if ((cp = mdb_ctf_enum_name(id, val)) != NULL) {
50 48 if (strncmp(cp, prefix, len) == 0)
51 49 cp += len;
52 50 if (strncmp(cp, prefix2, len2) == 0)
53 51 cp += len2;
54 52 (void) strlcpy(out, cp, size);
55 53 } else {
56 54 mdb_snprintf(out, size, "? (%d)", val);
57 55 }
58 56 }
59 57
60 58 static void
61 59 make_lower(char *out, size_t sz)
62 60 {
63 61 while (*out != 0 && sz > 0) {
64 62 if (*out >= 'A' && *out <= 'Z')
65 63 *out += 'a' - 'A';
66 64 out++;
67 65 sz--;
68 66 }
69 67 }
70 68
71 69 /*ARGSUSED*/
72 70 static int
73 71 configd_status(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
74 72 {
75 73 int num_servers;
76 74 int num_started;
77 75
78 76 if (argc != 0)
79 77 return (DCMD_USAGE);
80 78
81 79 if (mdb_readvar(&num_servers, "num_servers") == -1) {
82 80 mdb_warn("unable to read num_servers");
83 81 return (DCMD_ERR);
84 82 }
85 83 if (mdb_readvar(&num_started, "num_started") == -1) {
86 84 mdb_warn("unable to read num_started");
87 85 return (DCMD_ERR);
88 86 }
89 87 mdb_printf(
90 88 "\nserver threads:\t%d running, %d starting\n\n", num_servers,
91 89 num_started - num_servers);
92 90
93 91 if (mdb_walk_dcmd("configd_threads", "configd_thread", argc,
94 92 argv) == -1) {
95 93 mdb_warn("can't walk 'configd_threads'");
96 94 return (DCMD_ERR);
97 95 }
98 96 return (DCMD_OK);
99 97 }
100 98
101 99 /*ARGSUSED*/
102 100 static int
103 101 configd_thread(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
104 102 {
105 103 thread_info_t t;
106 104 char state[20];
107 105 char oldstate[20];
108 106
109 107 if (!(flags & DCMD_ADDRSPEC)) {
110 108 if (mdb_walk_dcmd("configd_threads", "configd_thread", argc,
111 109 argv) == -1) {
112 110 mdb_warn("can't walk 'configd_threads'");
113 111 return (DCMD_ERR);
114 112 }
115 113 return (DCMD_OK);
116 114 }
117 115
118 116 if (argc != 0)
119 117 return (DCMD_USAGE);
120 118
121 119 if (DCMD_HDRSPEC(flags)) {
122 120 mdb_printf("%<u>%-?s %5s %-12s %-12s %-?s %-?s %-?s%</u>\n",
123 121 "ADDR", "TID", "STATE", "PREV_STATE", "CLIENT", "CLIENTRQ",
124 122 "MAINREQ");
125 123 }
126 124
127 125 if (mdb_vread(&t, sizeof (t), addr) == -1) {
128 126 mdb_warn("failed to read thread_info_t at %p", addr);
129 127 return (DCMD_ERR);
130 128 }
131 129
132 130 enum_lookup(state, sizeof (state), thread_state_enum,
133 131 t.ti_state, "TI_", "");
134 132 make_lower(state, sizeof (state));
135 133
136 134 enum_lookup(oldstate, sizeof (oldstate), thread_state_enum,
137 135 t.ti_prev_state, "TI_", "");
138 136 make_lower(oldstate, sizeof (oldstate));
139 137
140 138 mdb_printf("%0?p %5d %-12s %-12s %?p %?p %?p\n",
141 139 (void *)addr, t.ti_thread, state, oldstate,
142 140 t.ti_active_client, t.ti_client_request, t.ti_main_door_request);
143 141
144 142 return (DCMD_OK);
145 143 }
146 144
147 145 static int
148 146 walk_thread_info_init(mdb_walk_state_t *wsp)
149 147 {
150 148 if (mdb_readvar(&wsp->walk_addr, "thread_list") == -1) {
151 149 mdb_warn("unable to read thread_list");
152 150 return (WALK_ERR);
153 151 }
154 152
155 153 if (mdb_layered_walk("uu_list_node", wsp) == -1) {
156 154 mdb_warn("couldn't walk 'uu_list_node'");
157 155 return (WALK_ERR);
158 156 }
159 157
160 158 return (WALK_NEXT);
161 159 }
162 160
163 161 static int
164 162 walk_thread_info_step(mdb_walk_state_t *wsp)
165 163 {
166 164 uintptr_t addr = wsp->walk_addr;
167 165 thread_info_t ti;
168 166
169 167 if (mdb_vread(&ti, sizeof (ti), addr) == -1) {
170 168 mdb_warn("unable to read thread_info_t at %p", addr);
171 169 return (WALK_ERR);
172 170 }
173 171
174 172 return (wsp->walk_callback(addr, &ti, wsp->walk_cbdata));
175 173 }
176 174
177 175 static int
178 176 request_log(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
179 177 {
180 178 request_log_entry_t cur;
181 179 hrtime_t dur;
182 180 hrtime_t dursec;
183 181 hrtime_t durnsec;
184 182 char durstr[20];
185 183 char stampstr[20];
186 184 char requstr[30];
187 185 char respstr[30];
188 186 char typestr[30];
189 187 uintptr_t node = 0;
190 188 uintptr_t client = 0;
191 189 uint64_t clientid = 0;
192 190
193 191 int idx;
194 192 int opt_v = FALSE; /* verbose */
195 193
196 194 if (!(flags & DCMD_ADDRSPEC)) {
197 195 if (mdb_walk_dcmd("configd_log", "configd_log", argc,
198 196 argv) == -1) {
199 197 mdb_warn("can't walk 'configd_log'");
200 198 return (DCMD_ERR);
201 199 }
202 200 return (DCMD_OK);
203 201 }
204 202
205 203 if (mdb_getopts(argc, argv,
206 204 'c', MDB_OPT_UINTPTR, &client,
207 205 'i', MDB_OPT_UINT64, &clientid,
208 206 'n', MDB_OPT_UINTPTR, &node,
209 207 'v', MDB_OPT_SETBITS, TRUE, &opt_v, NULL) != argc)
210 208 return (DCMD_USAGE);
211 209
212 210 if (DCMD_HDRSPEC(flags)) {
213 211 mdb_printf("%<u>%-?s %-4s %-14s %9s %-22s %-17s\n%</u>",
214 212 "ADDR", "THRD", "START", "DURATION", "REQUEST",
215 213 "RESPONSE");
216 214 }
217 215
218 216 if (mdb_vread(&cur, sizeof (cur), addr) == -1) {
219 217 mdb_warn("couldn't read log entry at %p", addr);
220 218 return (DCMD_ERR);
221 219 }
222 220
223 221 /*
224 222 * apply filters, if any.
225 223 */
226 224 if (clientid != 0 && clientid != cur.rl_clientid)
227 225 return (DCMD_OK);
228 226
229 227 if (client != 0 && client != (uintptr_t)cur.rl_client)
230 228 return (DCMD_OK);
231 229
232 230 if (node != 0) {
233 231 for (idx = 0; idx < MIN(MAX_PTRS, cur.rl_num_ptrs); idx++) {
234 232 if ((uintptr_t)cur.rl_ptrs[idx].rlp_data == node) {
235 233 node = 0; /* found it */
236 234 break;
237 235 }
238 236 }
239 237 if (node != 0)
240 238 return (DCMD_OK);
241 239 }
242 240
243 241 enum_lookup(requstr, sizeof (requstr), request_enum, cur.rl_request,
244 242 "REP_PROTOCOL_", "");
245 243
246 244 if (cur.rl_end != 0) {
247 245 enum_lookup(respstr, sizeof (respstr), response_enum,
248 246 cur.rl_response, "REP_PROTOCOL_", "FAIL_");
249 247
250 248 dur = cur.rl_end - cur.rl_start;
↓ open down ↓ |
212 lines elided |
↑ open up ↑ |
251 249 dursec = dur / NANOSEC;
252 250 durnsec = dur % NANOSEC;
253 251
254 252 if (dursec <= 9)
255 253 mdb_snprintf(durstr, sizeof (durstr),
256 254 "%lld.%06lld",
257 255 dursec, durnsec / (NANOSEC / MICROSEC));
258 256 else if (dursec <= 9999)
259 257 mdb_snprintf(durstr, sizeof (durstr),
260 258 "%lld.%03lld",
261 - dursec, durnsec / (NANOSEC / MILLISEC));
259 + dursec, NSEC2MSEC(durnsec));
262 260 else
263 261 mdb_snprintf(durstr, sizeof (durstr),
264 262 "%lld", dursec);
265 263 } else {
266 264 (void) strcpy(durstr, "-");
267 265 (void) strcpy(respstr, "-");
268 266 }
269 267
270 268 if (max_time_seen != 0 && max_time_seen >= cur.rl_start) {
271 269 dur = max_time_seen - cur.rl_start;
272 270 dursec = dur / NANOSEC;
273 271 durnsec = dur % NANOSEC;
274 272
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
275 273 if (dursec <= 99ULL)
276 274 mdb_snprintf(stampstr, sizeof (stampstr),
277 275 "-%lld.%09lld", dursec, durnsec);
278 276 else if (dursec <= 99999ULL)
279 277 mdb_snprintf(stampstr, sizeof (stampstr),
280 278 "-%lld.%06lld",
281 279 dursec, durnsec / (NANOSEC / MICROSEC));
282 280 else if (dursec <= 99999999ULL)
283 281 mdb_snprintf(stampstr, sizeof (stampstr),
284 282 "-%lld.%03lld",
285 - dursec, durnsec / (NANOSEC / MILLISEC));
283 + dursec, NSEC2MSEC(durnsec));
286 284 else
287 285 mdb_snprintf(stampstr, sizeof (stampstr),
288 286 "-%lld", dursec);
289 287 } else {
290 288 (void) strcpy(stampstr, "-");
291 289 }
292 290
293 291 mdb_printf("%0?x %4d T%13s %9s %-22s %-17s\n",
294 292 addr, cur.rl_tid, stampstr, durstr, requstr, respstr);
295 293
296 294 if (opt_v) {
297 295 mdb_printf("\tclient: %?p (%d)\tptrs: %d\tstamp: %llx\n",
298 296 cur.rl_client, cur.rl_clientid, cur.rl_num_ptrs,
299 297 cur.rl_start);
300 298 for (idx = 0; idx < MIN(MAX_PTRS, cur.rl_num_ptrs); idx++) {
301 299 enum_lookup(typestr, sizeof (typestr), ptr_type_enum,
302 300 cur.rl_ptrs[idx].rlp_type, "RC_PTR_TYPE_", "");
303 301 mdb_printf("\t\t%-7s %5d %?p %?p\n", typestr,
304 302 cur.rl_ptrs[idx].rlp_id, cur.rl_ptrs[idx].rlp_ptr,
305 303 cur.rl_ptrs[idx].rlp_data);
306 304 }
307 305 mdb_printf("\n");
308 306 }
309 307 return (DCMD_OK);
310 308 }
311 309
312 310 struct request_log_walk {
313 311 size_t rlw_max;
314 312 size_t rlw_count;
315 313 size_t rlw_cur;
316 314 struct request_entry {
317 315 hrtime_t timestamp;
318 316 uintptr_t addr;
319 317 } *rlw_list;
320 318 };
321 319
322 320 /*
323 321 * we want newer items at the top
324 322 */
325 323 static int
326 324 request_entry_compare(const void *l, const void *r)
327 325 {
328 326 const struct request_entry *lp = l;
329 327 const struct request_entry *rp = r;
330 328
331 329 if (rp->timestamp == lp->timestamp)
332 330 return (0);
333 331
334 332 /*
335 333 * 0 timestamps go first.
336 334 */
337 335 if (rp->timestamp == 0)
338 336 return (1);
339 337 if (lp->timestamp == 0)
340 338 return (-1);
341 339
342 340 if (lp->timestamp < rp->timestamp)
343 341 return (1);
344 342 return (-1);
345 343 }
346 344
347 345 /*ARGSUSED*/
348 346 static int
349 347 request_log_count_thread(uintptr_t addr, thread_info_t *tip, uint_t *arg)
350 348 {
351 349 (*arg)++;
352 350
353 351 return (WALK_NEXT);
354 352 }
355 353
356 354 static int
357 355 request_log_add_thread(uintptr_t addr, thread_info_t *tip,
358 356 struct request_entry **arg)
359 357 {
360 358 if (max_time_seen < tip->ti_log.rl_start)
361 359 max_time_seen = tip->ti_log.rl_start;
362 360
363 361 if (max_time_seen < tip->ti_log.rl_end)
364 362 max_time_seen = tip->ti_log.rl_end;
365 363
366 364 if (tip->ti_log.rl_start != 0) {
367 365 if (tip->ti_log.rl_end)
368 366 (*arg)->timestamp = tip->ti_log.rl_start;
369 367 else
370 368 (*arg)->timestamp = 0; /* sort to the top */
371 369
372 370 (*arg)->addr = addr + offsetof(thread_info_t, ti_log);
373 371 ++*arg;
374 372 }
375 373 return (WALK_NEXT);
376 374 }
377 375
378 376 static int
379 377 request_log_walk_init(mdb_walk_state_t *wsp)
380 378 {
381 379 struct request_log_walk *rlw;
382 380 struct request_entry *list, *listp;
383 381
384 382 uint_t log_size;
385 383 uint_t size;
386 384 uint_t idx;
387 385 uint_t pos;
388 386 request_log_entry_t *base;
389 387 request_log_entry_t cur;
390 388
391 389 if (mdb_readvar(&base, "request_log") == -1) {
392 390 mdb_warn("couldn't read 'request_log'");
393 391 return (WALK_ERR);
394 392 }
395 393 if (mdb_readvar(&log_size, "request_log_size") == -1) {
396 394 mdb_warn("couldn't read 'request_log_size'");
397 395 return (WALK_ERR);
398 396 }
399 397 size = log_size;
400 398
401 399 if (mdb_walk("configd_threads", (mdb_walk_cb_t)request_log_count_thread,
402 400 &size) == -1) {
403 401 mdb_warn("couldn't walk 'configd_threads'");
404 402 return (WALK_ERR);
405 403 }
406 404
407 405 list = mdb_zalloc(sizeof (*list) * size, UM_SLEEP);
408 406 listp = list;
409 407
410 408 if (mdb_walk("configd_threads", (mdb_walk_cb_t)request_log_add_thread,
411 409 &listp) == -1) {
412 410 mdb_warn("couldn't walk 'configd_threads'");
413 411 mdb_free(list, sizeof (*list) * size);
414 412 return (WALK_ERR);
415 413 }
416 414
417 415 pos = listp - list;
418 416 for (idx = 0; idx < log_size; idx++) {
419 417 uintptr_t addr = (uintptr_t)&base[idx];
420 418 if (mdb_vread(&cur, sizeof (cur), addr) == -1) {
421 419 mdb_warn("couldn't read log entry at %p", addr);
422 420 mdb_free(list, sizeof (*list) * size);
423 421 return (WALK_ERR);
424 422 }
425 423
426 424 if (max_time_seen < cur.rl_start)
427 425 max_time_seen = cur.rl_start;
428 426
429 427 if (max_time_seen < cur.rl_end)
430 428 max_time_seen = cur.rl_end;
431 429
432 430 if (cur.rl_start != 0) {
433 431 list[pos].timestamp = cur.rl_start;
434 432 list[pos].addr = addr;
435 433 pos++;
436 434 }
437 435 }
438 436 qsort(list, pos, sizeof (*list), &request_entry_compare);
439 437
440 438 rlw = mdb_zalloc(sizeof (*rlw), UM_SLEEP);
441 439 rlw->rlw_max = size;
442 440 rlw->rlw_count = pos;
443 441 rlw->rlw_cur = 0;
444 442 rlw->rlw_list = list;
445 443
446 444 wsp->walk_data = rlw;
447 445
448 446 return (WALK_NEXT);
449 447 }
450 448
451 449 static int
452 450 request_log_walk_step(mdb_walk_state_t *wsp)
453 451 {
454 452 struct request_log_walk *rlw = wsp->walk_data;
455 453 uintptr_t addr;
456 454 request_log_entry_t cur;
457 455
458 456 if (rlw->rlw_cur >= rlw->rlw_count)
459 457 return (WALK_DONE);
460 458
461 459 addr = rlw->rlw_list[rlw->rlw_cur++].addr;
462 460
463 461 if (mdb_vread(&cur, sizeof (cur), addr) == -1) {
464 462 mdb_warn("couldn't read log entry at %p", addr);
465 463 return (WALK_ERR);
466 464 }
467 465 return (wsp->walk_callback(addr, &cur, wsp->walk_cbdata));
468 466 }
469 467
470 468 static void
471 469 request_log_walk_fini(mdb_walk_state_t *wsp)
472 470 {
473 471 struct request_log_walk *rlw = wsp->walk_data;
474 472
475 473 mdb_free(rlw->rlw_list, sizeof (*rlw->rlw_list) * rlw->rlw_max);
476 474 mdb_free(rlw, sizeof (*rlw));
477 475 }
478 476
479 477 static const mdb_dcmd_t dcmds[] = {
480 478 { "configd_status", NULL, "svc.configd status summary",
481 479 configd_status },
482 480 { "configd_thread", "?", "Print a thread_info_t tabularly",
483 481 configd_thread },
484 482 { "configd_log", "?[-v] [-c clientptr] [-i clientid]",
485 483 "Print the request log, or a single entry", request_log },
486 484 { NULL }
487 485 };
488 486
489 487 static const mdb_walker_t walkers[] = {
490 488 { "configd_threads", "walks the thread_info_ts for all "
491 489 "threads", walk_thread_info_init, walk_thread_info_step },
492 490 { "configd_log", "walks the request_log_entry_ts",
493 491 request_log_walk_init, request_log_walk_step,
494 492 request_log_walk_fini},
495 493 { NULL }
496 494 };
497 495
498 496 static const mdb_modinfo_t modinfo = {
499 497 MDB_API_VERSION, dcmds, walkers
500 498 };
501 499
502 500 const mdb_modinfo_t *
503 501 _mdb_init(void)
504 502 {
505 503 if (mdb_ctf_lookup_by_name("enum rep_protocol_requestid",
506 504 &request_enum) == -1) {
507 505 mdb_warn("enum rep_protocol_requestid not found");
508 506 }
509 507 if (mdb_ctf_lookup_by_name("enum rep_protocol_responseid",
510 508 &response_enum) == -1) {
511 509 mdb_warn("enum rep_protocol_responseid not found");
512 510 }
513 511 if (mdb_ctf_lookup_by_name("enum rc_ptr_type",
514 512 &ptr_type_enum) == -1) {
515 513 mdb_warn("enum rc_ptr_type not found");
516 514 }
517 515 if (mdb_ctf_lookup_by_name("enum thread_state",
518 516 &thread_state_enum) == -1) {
519 517 mdb_warn("enum thread_state not found");
520 518 }
521 519 return (&modinfo);
522 520 }
↓ open down ↓ |
227 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX