1 /* 2 * top - a top users display for Unix 3 * 4 * SYNOPSIS: For FreeBSD-2.x and later 5 * 6 * DESCRIPTION: 7 * Originally written for BSD4.4 system by Christos Zoulas. 8 * Ported to FreeBSD 2.x by Steven Wallace && Wolfram Schneider 9 * Order support hacked in from top-3.5beta6/machine/m_aix41.c 10 * by Monte Mitzelfelt (for latest top see http://www.groupsys.com/topinfo/) 11 * 12 * This is the machine-dependent module for FreeBSD 2.2 13 * Works for: 14 * FreeBSD 2.2.x, 3.x, 4.x, and probably FreeBSD 2.1.x 15 * 16 * LIBS: -lkvm 17 * 18 * AUTHOR: Christos Zoulas <christos@ee.cornell.edu> 19 * Steven Wallace <swallace@freebsd.org> 20 * Wolfram Schneider <wosch@FreeBSD.org> 21 * Thomas Moestl <tmoestl@gmx.net> 22 * 23 * $FreeBSD$ 24 */ 25 26 #include <sys/param.h> 27 #include <sys/errno.h> 28 #include <sys/file.h> 29 #include <sys/proc.h> 30 #include <sys/resource.h> 31 #include <sys/rtprio.h> 32 #include <sys/signal.h> 33 #include <sys/sysctl.h> 34 #include <sys/time.h> 35 #include <sys/user.h> 36 #include <sys/vmmeter.h> 37 38 #include <kvm.h> 39 #include <math.h> 40 #include <nlist.h> 41 #include <paths.h> 42 #include <pwd.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <unistd.h> 46 47 #include "top.h" 48 #include "machine.h" 49 #include "screen.h" 50 #include "utils.h" 51 52 static void getsysctl(char *, void *, size_t); 53 54 #define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var)) 55 56 extern char* printable(char *); 57 int swapmode(int *retavail, int *retfree); 58 static int smpmode; 59 enum displaymodes displaymode; 60 static int namelength; 61 static int cmdlengthdelta; 62 63 /* Prototypes for top internals */ 64 void quit(int); 65 int compare_pid(const void *a, const void *b); 66 67 /* get_process_info passes back a handle. This is what it looks like: */ 68 69 struct handle 70 { 71 struct kinfo_proc **next_proc; /* points to next valid proc pointer */ 72 int remaining; /* number of pointers remaining */ 73 }; 74 75 /* declarations for load_avg */ 76 #include "loadavg.h" 77 78 /* define what weighted cpu is. */ 79 #define weighted_cpu(pct, pp) ((pp)->ki_swtime == 0 ? 0.0 : \ 80 ((pct) / (1.0 - exp((pp)->ki_swtime * logcpu)))) 81 82 /* what we consider to be process size: */ 83 #define PROCSIZE(pp) ((pp)->ki_size / 1024) 84 85 #define RU(pp) (&(pp)->ki_rusage) 86 #define RUTOT(pp) \ 87 (RU(pp)->ru_inblock + RU(pp)->ru_oublock + RU(pp)->ru_majflt) 88 89 90 /* definitions for indices in the nlist array */ 91 92 /* 93 * These definitions control the format of the per-process area 94 */ 95 96 static char io_header[] = 97 " PID %-*.*s VCSW IVCSW READ WRITE FAULT TOTAL PERCENT COMMAND"; 98 99 #define io_Proc_format \ 100 "%5d %-*.*s %6ld %6ld %6ld %6ld %6ld %6ld %6.2f%% %.*s" 101 102 static char smp_header[] = 103 " PID %-*.*s PRI NICE SIZE RES STATE C TIME WCPU CPU COMMAND"; 104 105 #define smp_Proc_format \ 106 "%5d %-*.*s %3d %4d%7s %6s %-6.6s %1x%7s %5.2f%% %5.2f%% %.*s" 107 108 static char up_header[] = 109 " PID %-*.*s PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND"; 110 111 #define up_Proc_format \ 112 "%5d %-*.*s %3d %4d%7s %6s %-6.6s%.0d%7s %5.2f%% %5.2f%% %.*s" 113 114 115 116 /* process state names for the "STATE" column of the display */ 117 /* the extra nulls in the string "run" are for adding a slash and 118 the processor number when needed */ 119 120 char *state_abbrev[] = 121 { 122 "", "START", "RUN\0\0\0", "SLEEP", "STOP", "ZOMB", "WAIT", "LOCK" 123 }; 124 125 126 static kvm_t *kd; 127 128 /* values that we stash away in _init and use in later routines */ 129 130 static double logcpu; 131 132 /* these are retrieved from the kernel in _init */ 133 134 static load_avg ccpu; 135 136 /* these are used in the get_ functions */ 137 138 static int lastpid; 139 140 /* these are for calculating cpu state percentages */ 141 142 static long cp_time[CPUSTATES]; 143 static long cp_old[CPUSTATES]; 144 static long cp_diff[CPUSTATES]; 145 146 /* these are for detailing the process states */ 147 148 int process_states[8]; 149 char *procstatenames[] = { 150 "", " starting, ", " running, ", " sleeping, ", " stopped, ", 151 " zombie, ", " waiting, ", " lock, ", 152 NULL 153 }; 154 155 /* these are for detailing the cpu states */ 156 157 int cpu_states[CPUSTATES]; 158 char *cpustatenames[] = { 159 "user", "nice", "system", "interrupt", "idle", NULL 160 }; 161 162 /* these are for detailing the memory statistics */ 163 164 int memory_stats[7]; 165 char *memorynames[] = { 166 /* 0 1 2 3 4 5 */ 167 "K Active, ", "K Inact, ", "K Wired, ", "K Cache, ", "K Buf, ", "K Free", 168 NULL 169 }; 170 171 int swap_stats[7]; 172 char *swapnames[] = { 173 /* 0 1 2 3 4 5 */ 174 "K Total, ", "K Used, ", "K Free, ", "% Inuse, ", "K In, ", "K Out", 175 NULL 176 }; 177 178 179 /* these are for keeping track of the proc array */ 180 181 static int nproc; 182 static int onproc = -1; 183 static int pref_len; 184 static struct kinfo_proc *pbase; 185 static struct kinfo_proc **pref; 186 static struct kinfo_proc *previous_procs; 187 static struct kinfo_proc **previous_pref; 188 static int previous_proc_count = 0; 189 static int previous_proc_count_max = 0; 190 191 /* total number of io operations */ 192 static long total_inblock; 193 static long total_oublock; 194 static long total_majflt; 195 196 /* these are for getting the memory statistics */ 197 198 static int pageshift; /* log base 2 of the pagesize */ 199 200 /* define pagetok in terms of pageshift */ 201 202 #define pagetok(size) ((size) << pageshift) 203 204 /* useful externals */ 205 long percentages(); 206 207 #ifdef ORDER 208 /* 209 * Sorting orders. One vector per display mode. 210 * The first element is the default for each mode. 211 */ 212 char *ordernames[] = { 213 "cpu", "size", "res", "time", "pri", 214 "total", "read", "write", "fault", "vcsw", "ivcsw", NULL 215 }; 216 #endif 217 218 int 219 machine_init(struct statics *statics) 220 { 221 int pagesize; 222 size_t modelen; 223 struct passwd *pw; 224 225 modelen = sizeof(smpmode); 226 if ((sysctlbyname("machdep.smp_active", &smpmode, &modelen, NULL, 0) < 0 && 227 sysctlbyname("kern.smp.active", &smpmode, &modelen, NULL, 0) < 0) || 228 modelen != sizeof(smpmode)) 229 smpmode = 0; 230 231 while ((pw = getpwent()) != NULL) { 232 if (strlen(pw->pw_name) > namelength) 233 namelength = strlen(pw->pw_name); 234 } 235 if (namelength < 8) 236 namelength = 8; 237 if (smpmode && namelength > 13) 238 namelength = 13; 239 else if (namelength > 15) 240 namelength = 15; 241 242 kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open"); 243 if (kd == NULL) 244 return (-1); 245 246 GETSYSCTL("kern.ccpu", ccpu); 247 248 /* this is used in calculating WCPU -- calculate it ahead of time */ 249 logcpu = log(loaddouble(ccpu)); 250 251 pbase = NULL; 252 pref = NULL; 253 nproc = 0; 254 onproc = -1; 255 /* get the page size with "getpagesize" and calculate pageshift from it */ 256 pagesize = getpagesize(); 257 pageshift = 0; 258 while (pagesize > 1) { 259 pageshift++; 260 pagesize >>= 1; 261 } 262 263 /* we only need the amount of log(2)1024 for our conversion */ 264 pageshift -= LOG1024; 265 266 /* fill in the statics information */ 267 statics->procstate_names = procstatenames; 268 statics->cpustate_names = cpustatenames; 269 statics->memory_names = memorynames; 270 statics->swap_names = swapnames; 271 #ifdef ORDER 272 statics->order_names = ordernames; 273 #endif 274 275 /* all done! */ 276 return (0); 277 } 278 279 char * 280 format_header(char *uname_field) 281 { 282 static char Header[128]; 283 const char *prehead; 284 285 switch (displaymode) { 286 case DISP_CPU: 287 prehead = smpmode ? smp_header : up_header; 288 break; 289 case DISP_IO: 290 prehead = io_header; 291 break; 292 } 293 294 snprintf(Header, sizeof(Header), prehead, 295 namelength, namelength, uname_field); 296 297 cmdlengthdelta = strlen(Header) - 7; 298 299 return (Header); 300 } 301 302 static int swappgsin = -1; 303 static int swappgsout = -1; 304 extern struct timeval timeout; 305 306 void 307 get_system_info(struct system_info *si) 308 { 309 long total; 310 struct loadavg sysload; 311 int mib[2]; 312 struct timeval boottime; 313 size_t bt_size; 314 int i; 315 316 /* get the cp_time array */ 317 GETSYSCTL("kern.cp_time", cp_time); 318 GETSYSCTL("vm.loadavg", sysload); 319 GETSYSCTL("kern.lastpid", lastpid); 320 321 /* convert load averages to doubles */ 322 for (i = 0; i < 3; i++) 323 si->load_avg[i] = (double)sysload.ldavg[i] / sysload.fscale; 324 325 /* convert cp_time counts to percentages */ 326 total = percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff); 327 328 /* sum memory & swap statistics */ 329 { 330 static unsigned int swap_delay = 0; 331 static int swapavail = 0; 332 static int swapfree = 0; 333 static int bufspace = 0; 334 static int nspgsin, nspgsout; 335 336 GETSYSCTL("vfs.bufspace", bufspace); 337 GETSYSCTL("vm.stats.vm.v_active_count", memory_stats[0]); 338 GETSYSCTL("vm.stats.vm.v_inactive_count", memory_stats[1]); 339 GETSYSCTL("vm.stats.vm.v_wire_count", memory_stats[2]); 340 GETSYSCTL("vm.stats.vm.v_cache_count", memory_stats[3]); 341 GETSYSCTL("vm.stats.vm.v_free_count", memory_stats[5]); 342 GETSYSCTL("vm.stats.vm.v_swappgsin", nspgsin); 343 GETSYSCTL("vm.stats.vm.v_swappgsout", nspgsout); 344 /* convert memory stats to Kbytes */ 345 memory_stats[0] = pagetok(memory_stats[0]); 346 memory_stats[1] = pagetok(memory_stats[1]); 347 memory_stats[2] = pagetok(memory_stats[2]); 348 memory_stats[3] = pagetok(memory_stats[3]); 349 memory_stats[4] = bufspace / 1024; 350 memory_stats[5] = pagetok(memory_stats[5]); 351 memory_stats[6] = -1; 352 353 /* first interval */ 354 if (swappgsin < 0) { 355 swap_stats[4] = 0; 356 swap_stats[5] = 0; 357 } 358 359 /* compute differences between old and new swap statistic */ 360 else { 361 swap_stats[4] = pagetok(((nspgsin - swappgsin))); 362 swap_stats[5] = pagetok(((nspgsout - swappgsout))); 363 } 364 365 swappgsin = nspgsin; 366 swappgsout = nspgsout; 367 368 /* call CPU heavy swapmode() only for changes */ 369 if (swap_stats[4] > 0 || swap_stats[5] > 0 || swap_delay == 0) { 370 swap_stats[3] = swapmode(&swapavail, &swapfree); 371 swap_stats[0] = swapavail; 372 swap_stats[1] = swapavail - swapfree; 373 swap_stats[2] = swapfree; 374 } 375 swap_delay = 1; 376 swap_stats[6] = -1; 377 } 378 379 /* set arrays and strings */ 380 si->cpustates = cpu_states; 381 si->memory = memory_stats; 382 si->swap = swap_stats; 383 384 385 if (lastpid > 0) { 386 si->last_pid = lastpid; 387 } else { 388 si->last_pid = -1; 389 } 390 391 /* 392 * Print how long system has been up. 393 * (Found by looking getting "boottime" from the kernel) 394 */ 395 mib[0] = CTL_KERN; 396 mib[1] = KERN_BOOTTIME; 397 bt_size = sizeof(boottime); 398 if (sysctl(mib, 2, &boottime, &bt_size, NULL, 0) != -1 && 399 boottime.tv_sec != 0) { 400 si->boottime = boottime; 401 } else { 402 si->boottime.tv_sec = -1; 403 } 404 } 405 406 #define NOPROC ((void *)-1) 407 408 /* 409 * We need to compare data from the old process entry with the new 410 * process entry. 411 * To facilitate doing this quickly we stash a pointer in the kinfo_proc 412 * structure to cache the mapping. We also use a negative cache pointer 413 * of NOPROC to avoid duplicate lookups. 414 * XXX: this could be done when the actual processes are fetched, we do 415 * it here out of laziness. 416 */ 417 const struct kinfo_proc * 418 get_old_proc(struct kinfo_proc *pp) 419 { 420 struct kinfo_proc **oldpp, *oldp; 421 422 /* 423 * If this is the first fetch of the kinfo_procs then we don't have 424 * any previous entries. 425 */ 426 if (previous_proc_count == 0) 427 return (NULL); 428 /* negative cache? */ 429 if (pp->ki_udata == NOPROC) 430 return (NULL); 431 /* cached? */ 432 if (pp->ki_udata != NULL) 433 return (pp->ki_udata); 434 /* 435 * Not cached, 436 * 1) look up based on pid. 437 * 2) compare process start. 438 * If we fail here, then setup a negative cache entry, otherwise 439 * cache it. 440 */ 441 oldpp = bsearch(&pp, previous_pref, previous_proc_count, 442 sizeof(*previous_pref), compare_pid); 443 if (oldpp == NULL) { 444 pp->ki_udata = NOPROC; 445 return (NULL); 446 } 447 oldp = *oldpp; 448 if (bcmp(&oldp->ki_start, &pp->ki_start, sizeof(pp->ki_start)) != 0) { 449 pp->ki_udata = NOPROC; 450 return (NULL); 451 } 452 pp->ki_udata = oldp; 453 return (oldp); 454 } 455 456 /* 457 * Return the total amount of IO done in blocks in/out and faults. 458 * store the values individually in the pointers passed in. 459 */ 460 long 461 get_io_stats(struct kinfo_proc *pp, long *inp, long *oup, long *flp, long *vcsw, long *ivcsw) 462 { 463 const struct kinfo_proc *oldp; 464 static struct kinfo_proc dummy; 465 long ret; 466 467 oldp = get_old_proc(pp); 468 if (oldp == NULL) { 469 bzero(&dummy, sizeof(dummy)); 470 oldp = &dummy; 471 } 472 473 *inp = RU(pp)->ru_inblock - RU(oldp)->ru_inblock; 474 *oup = RU(pp)->ru_oublock - RU(oldp)->ru_oublock; 475 *flp = RU(pp)->ru_majflt - RU(oldp)->ru_majflt; 476 *vcsw = RU(pp)->ru_nvcsw - RU(oldp)->ru_nvcsw; 477 *ivcsw = RU(pp)->ru_nivcsw - RU(oldp)->ru_nivcsw; 478 ret = 479 (RU(pp)->ru_inblock - RU(oldp)->ru_inblock) + 480 (RU(pp)->ru_oublock - RU(oldp)->ru_oublock) + 481 (RU(pp)->ru_majflt - RU(oldp)->ru_majflt); 482 return (ret); 483 } 484 485 /* 486 * Return the total number of block in/out and faults by a process. 487 */ 488 long 489 get_io_total(struct kinfo_proc *pp) 490 { 491 long dummy; 492 493 return (get_io_stats(pp, &dummy, &dummy, &dummy, &dummy, &dummy)); 494 } 495 496 static struct handle handle; 497 498 caddr_t 499 get_process_info(struct system_info *si, struct process_select *sel, 500 int (*compare)(const void *, const void *)) 501 { 502 int i; 503 int total_procs; 504 long p_io; 505 long p_inblock, p_oublock, p_majflt, p_vcsw, p_ivcsw; 506 int active_procs; 507 struct kinfo_proc **prefp; 508 struct kinfo_proc *pp; 509 struct kinfo_proc *prev_pp = NULL; 510 511 /* these are copied out of sel for speed */ 512 int show_idle; 513 int show_self; 514 int show_system; 515 int show_uid; 516 int show_command; 517 518 /* 519 * Save the previous process info. 520 */ 521 if (previous_proc_count_max < nproc) { 522 free(previous_procs); 523 previous_procs = malloc(nproc * sizeof(*previous_procs)); 524 free(previous_pref); 525 previous_pref = malloc(nproc * sizeof(*previous_pref)); 526 if (previous_procs == NULL || previous_pref == NULL) { 527 (void) fprintf(stderr, "top: Out of memory.\n"); 528 quit(23); 529 } 530 previous_proc_count_max = nproc; 531 } 532 if (nproc) { 533 for (i = 0; i < nproc; i++) 534 previous_pref[i] = &previous_procs[i]; 535 bcopy(pbase, previous_procs, nproc * sizeof(*previous_procs)); 536 qsort(previous_pref, nproc, sizeof(*previous_pref), compare_pid); 537 } 538 previous_proc_count = nproc; 539 540 pbase = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nproc); 541 if (nproc > onproc) 542 pref = realloc(pref, sizeof(*pref) * (onproc = nproc)); 543 if (pref == NULL || pbase == NULL) { 544 (void) fprintf(stderr, "top: Out of memory.\n"); 545 quit(23); 546 } 547 /* get a pointer to the states summary array */ 548 si->procstates = process_states; 549 550 /* set up flags which define what we are going to select */ 551 show_idle = sel->idle; 552 show_self = sel->self == -1; 553 show_system = sel->system; 554 show_uid = sel->uid != -1; 555 show_command = sel->command != NULL; 556 557 /* count up process states and get pointers to interesting procs */ 558 total_procs = 0; 559 active_procs = 0; 560 total_inblock = 0; 561 total_oublock = 0; 562 total_majflt = 0; 563 memset((char *)process_states, 0, sizeof(process_states)); 564 prefp = pref; 565 for (pp = pbase, i = 0; i < nproc; pp++, i++) { 566 567 if (pp->ki_stat == 0) 568 /* not in use */ 569 continue; 570 571 if (!show_self && pp->ki_pid == sel->self) 572 /* skip self */ 573 continue; 574 575 if (!show_system && (pp->ki_flag & P_SYSTEM)) 576 /* skip system process */ 577 continue; 578 579 p_io = get_io_stats(pp, &p_inblock, &p_oublock, &p_majflt, &p_vcsw, &p_ivcsw); 580 total_inblock += p_inblock; 581 total_oublock += p_oublock; 582 total_majflt += p_majflt; 583 total_procs++; 584 process_states[pp->ki_stat]++; 585 586 if (pp->ki_stat == SZOMB) 587 /* skip zombies */ 588 continue; 589 590 if (displaymode == DISP_CPU && !show_idle && 591 (pp->ki_pctcpu == 0 || pp->ki_stat != SRUN)) 592 /* skip idle or non-running processes */ 593 continue; 594 595 if (displaymode == DISP_IO && !show_idle && p_io == 0) 596 /* skip processes that aren't doing I/O */ 597 continue; 598 599 if (show_uid && pp->ki_ruid != (uid_t)sel->uid) 600 /* skip processes which don't belong to the selected UID */ 601 continue; 602 603 /* 604 * When not showing threads, take the first thread 605 * for output and add the fields that we can from 606 * the rest of the process's threads rather than 607 * using the system's mostly-broken KERN_PROC_PROC. 608 */ 609 if (sel->thread || prev_pp == NULL || 610 prev_pp->ki_pid != pp->ki_pid) { 611 *prefp++ = pp; 612 active_procs++; 613 prev_pp = pp; 614 } else { 615 prev_pp->ki_pctcpu += pp->ki_pctcpu; 616 } 617 } 618 619 /* if requested, sort the "interesting" processes */ 620 if (compare != NULL) 621 qsort(pref, active_procs, sizeof(*pref), compare); 622 623 /* remember active and total counts */ 624 si->p_total = total_procs; 625 si->p_active = pref_len = active_procs; 626 627 /* pass back a handle */ 628 handle.next_proc = pref; 629 handle.remaining = active_procs; 630 return ((caddr_t)&handle); 631 } 632 633 static char fmt[128]; /* static area where result is built */ 634 635 char * 636 format_next_process(caddr_t handle, char *(*get_userid)(int)) 637 { 638 struct kinfo_proc *pp; 639 const struct kinfo_proc *oldp; 640 long cputime; 641 double pct; 642 struct handle *hp; 643 char status[16]; 644 int state; 645 struct rusage ru, *rup; 646 long p_tot, s_tot; 647 648 /* find and remember the next proc structure */ 649 hp = (struct handle *)handle; 650 pp = *(hp->next_proc++); 651 hp->remaining--; 652 653 /* get the process's command name */ 654 if ((pp->ki_sflag & PS_INMEM) == 0) { 655 /* 656 * Print swapped processes as <pname> 657 */ 658 size_t len = strlen(pp->ki_comm); 659 if (len > sizeof(pp->ki_comm) - 3) 660 len = sizeof(pp->ki_comm) - 3; 661 memmove(pp->ki_comm + 1, pp->ki_comm, len); 662 pp->ki_comm[0] = '<'; 663 pp->ki_comm[len + 1] = '>'; 664 pp->ki_comm[len + 2] = '\0'; 665 } 666 667 /* 668 * Convert the process's runtime from microseconds to seconds. This 669 * time includes the interrupt time although that is not wanted here. 670 * ps(1) is similarly sloppy. 671 */ 672 cputime = (pp->ki_runtime + 500000) / 1000000; 673 674 /* calculate the base for cpu percentages */ 675 pct = pctdouble(pp->ki_pctcpu); 676 677 /* generate "STATE" field */ 678 switch (state = pp->ki_stat) { 679 case SRUN: 680 if (smpmode && pp->ki_oncpu != 0xff) 681 sprintf(status, "CPU%d", pp->ki_oncpu); 682 else 683 strcpy(status, "RUN"); 684 break; 685 case SLOCK: 686 if (pp->ki_kiflag & KI_LOCKBLOCK) { 687 sprintf(status, "*%.6s", pp->ki_lockname); 688 break; 689 } 690 /* fall through */ 691 case SSLEEP: 692 if (pp->ki_wmesg != NULL) { 693 sprintf(status, "%.6s", pp->ki_wmesg); 694 break; 695 } 696 /* FALLTHROUGH */ 697 default: 698 699 if (state >= 0 && 700 state < sizeof(state_abbrev) / sizeof(*state_abbrev)) 701 sprintf(status, "%.6s", state_abbrev[state]); 702 else 703 sprintf(status, "?%5d", state); 704 break; 705 } 706 707 if (displaymode == DISP_IO) { 708 oldp = get_old_proc(pp); 709 if (oldp != NULL) { 710 ru.ru_inblock = RU(pp)->ru_inblock - RU(oldp)->ru_inblock; 711 ru.ru_oublock = RU(pp)->ru_oublock - RU(oldp)->ru_oublock; 712 ru.ru_majflt = RU(pp)->ru_majflt - RU(oldp)->ru_majflt; 713 ru.ru_nvcsw = RU(pp)->ru_nvcsw - RU(oldp)->ru_nvcsw; 714 ru.ru_nivcsw = RU(pp)->ru_nivcsw - RU(oldp)->ru_nivcsw; 715 rup = &ru; 716 } else { 717 rup = RU(pp); 718 } 719 p_tot = rup->ru_inblock + rup->ru_oublock + rup->ru_majflt; 720 s_tot = total_inblock + total_oublock + total_majflt; 721 722 sprintf(fmt, io_Proc_format, 723 pp->ki_pid, 724 namelength, namelength, 725 (*get_userid)(pp->ki_ruid), 726 rup->ru_nvcsw, 727 rup->ru_nivcsw, 728 rup->ru_inblock, 729 rup->ru_oublock, 730 rup->ru_majflt, 731 p_tot, 732 s_tot == 0 ? 0.0 : (p_tot * 100.0 / s_tot), 733 screen_width > cmdlengthdelta ? 734 screen_width - cmdlengthdelta : 0, 735 printable(pp->ki_comm)); 736 return (fmt); 737 } 738 /* format this entry */ 739 sprintf(fmt, 740 smpmode ? smp_Proc_format : up_Proc_format, 741 pp->ki_pid, 742 namelength, namelength, 743 (*get_userid)(pp->ki_ruid), 744 pp->ki_pri.pri_level - PZERO, 745 746 /* 747 * normal time -> nice value -20 - +20 748 * real time 0 - 31 -> nice value -52 - -21 749 * idle time 0 - 31 -> nice value +21 - +52 750 */ 751 (pp->ki_pri.pri_class == PRI_TIMESHARE ? 752 pp->ki_nice - NZERO : 753 (PRI_IS_REALTIME(pp->ki_pri.pri_class) ? 754 (PRIO_MIN - 1 - (PRI_MAX_REALTIME - pp->ki_pri.pri_level)) : 755 (PRIO_MAX + 1 + pp->ki_pri.pri_level - PRI_MIN_IDLE))), 756 format_k2(PROCSIZE(pp)), 757 format_k2(pagetok(pp->ki_rssize)), 758 status, 759 smpmode ? pp->ki_lastcpu : 0, 760 format_time(cputime), 761 100.0 * weighted_cpu(pct, pp), 762 100.0 * pct, 763 screen_width > cmdlengthdelta ? 764 screen_width - cmdlengthdelta : 765 0, 766 printable(pp->ki_comm)); 767 768 /* return the result */ 769 return (fmt); 770 } 771 772 static void 773 getsysctl(char *name, void *ptr, size_t len) 774 { 775 size_t nlen = len; 776 777 if (sysctlbyname(name, ptr, &nlen, NULL, 0) == -1) { 778 fprintf(stderr, "top: sysctl(%s...) failed: %s\n", name, 779 strerror(errno)); 780 quit(23); 781 } 782 if (nlen != len) { 783 fprintf(stderr, "top: sysctl(%s...) expected %lu, got %lu\n", name, 784 (unsigned long)len, (unsigned long)nlen); 785 quit(23); 786 } 787 } 788 789 /* comparison routines for qsort */ 790 791 int 792 compare_pid(const void *p1, const void *p2) 793 { 794 const struct kinfo_proc * const *pp1 = p1; 795 const struct kinfo_proc * const *pp2 = p2; 796 797 if ((*pp2)->ki_pid < 0 || (*pp1)->ki_pid < 0) 798 abort(); 799 800 return ((*pp1)->ki_pid - (*pp2)->ki_pid); 801 } 802 803 /* 804 * proc_compare - comparison function for "qsort" 805 * Compares the resource consumption of two processes using five 806 * distinct keys. The keys (in descending order of importance) are: 807 * percent cpu, cpu ticks, state, resident set size, total virtual 808 * memory usage. The process states are ordered as follows (from least 809 * to most important): WAIT, zombie, sleep, stop, start, run. The 810 * array declaration below maps a process state index into a number 811 * that reflects this ordering. 812 */ 813 814 static int sorted_state[] = 815 { 816 0, /* not used */ 817 3, /* sleep */ 818 1, /* ABANDONED (WAIT) */ 819 6, /* run */ 820 5, /* start */ 821 2, /* zombie */ 822 4 /* stop */ 823 }; 824 825 826 #define ORDERKEY_PCTCPU(a, b) do { \ 827 long diff = (long)(b)->ki_pctcpu - (long)(a)->ki_pctcpu; \ 828 if (diff != 0) \ 829 return (diff > 0 ? 1 : -1); \ 830 } while (0) 831 832 #define ORDERKEY_CPTICKS(a, b) do { \ 833 int64_t diff = (int64_t)(b)->ki_runtime - (int64_t)(a)->ki_runtime; \ 834 if (diff != 0) \ 835 return (diff > 0 ? 1 : -1); \ 836 } while (0) 837 838 #define ORDERKEY_STATE(a, b) do { \ 839 int diff = sorted_state[(b)->ki_stat] - sorted_state[(a)->ki_stat]; \ 840 if (diff != 0) \ 841 return (diff > 0 ? 1 : -1); \ 842 } while (0) 843 844 #define ORDERKEY_PRIO(a, b) do { \ 845 int diff = (int)(b)->ki_pri.pri_level - (int)(a)->ki_pri.pri_level; \ 846 if (diff != 0) \ 847 return (diff > 0 ? 1 : -1); \ 848 } while (0) 849 850 #define ORDERKEY_RSSIZE(a, b) do { \ 851 long diff = (long)(b)->ki_rssize - (long)(a)->ki_rssize; \ 852 if (diff != 0) \ 853 return (diff > 0 ? 1 : -1); \ 854 } while (0) 855 856 #define ORDERKEY_MEM(a, b) do { \ 857 long diff = (long)PROCSIZE((b)) - (long)PROCSIZE((a)); \ 858 if (diff != 0) \ 859 return (diff > 0 ? 1 : -1); \ 860 } while (0) 861 862 /* compare_cpu - the comparison function for sorting by cpu percentage */ 863 864 int 865 #ifdef ORDER 866 compare_cpu(void *arg1, void *arg2) 867 #else 868 proc_compare(void *arg1, void *arg2) 869 #endif 870 { 871 struct kinfo_proc *p1 = *(struct kinfo_proc **)arg1; 872 struct kinfo_proc *p2 = *(struct kinfo_proc **)arg2; 873 874 ORDERKEY_PCTCPU(p1, p2); 875 ORDERKEY_CPTICKS(p1, p2); 876 ORDERKEY_STATE(p1, p2); 877 ORDERKEY_PRIO(p1, p2); 878 ORDERKEY_RSSIZE(p1, p2); 879 ORDERKEY_MEM(p1, p2); 880 881 return (0); 882 } 883 884 #ifdef ORDER 885 /* compare routines */ 886 int compare_size(), compare_res(), compare_time(), compare_prio(); 887 /* io compare routines */ 888 int compare_iototal(), compare_ioread(), compare_iowrite(), compare_iofault(), compare_vcsw(), compare_ivcsw(); 889 890 int (*compares[])() = { 891 compare_cpu, 892 compare_size, 893 compare_res, 894 compare_time, 895 compare_prio, 896 compare_iototal, 897 compare_ioread, 898 compare_iowrite, 899 compare_iofault, 900 compare_vcsw, 901 compare_ivcsw, 902 NULL 903 }; 904 905 /* compare_size - the comparison function for sorting by total memory usage */ 906 907 int 908 compare_size(void *arg1, void *arg2) 909 { 910 struct kinfo_proc *p1 = *(struct kinfo_proc **)arg1; 911 struct kinfo_proc *p2 = *(struct kinfo_proc **)arg2; 912 913 ORDERKEY_MEM(p1, p2); 914 ORDERKEY_RSSIZE(p1, p2); 915 ORDERKEY_PCTCPU(p1, p2); 916 ORDERKEY_CPTICKS(p1, p2); 917 ORDERKEY_STATE(p1, p2); 918 ORDERKEY_PRIO(p1, p2); 919 920 return (0); 921 } 922 923 /* compare_res - the comparison function for sorting by resident set size */ 924 925 int 926 compare_res(void *arg1, void *arg2) 927 { 928 struct kinfo_proc *p1 = *(struct kinfo_proc **)arg1; 929 struct kinfo_proc *p2 = *(struct kinfo_proc **)arg2; 930 931 ORDERKEY_RSSIZE(p1, p2); 932 ORDERKEY_MEM(p1, p2); 933 ORDERKEY_PCTCPU(p1, p2); 934 ORDERKEY_CPTICKS(p1, p2); 935 ORDERKEY_STATE(p1, p2); 936 ORDERKEY_PRIO(p1, p2); 937 938 return (0); 939 } 940 941 /* compare_time - the comparison function for sorting by total cpu time */ 942 943 int 944 compare_time(void *arg1, void *arg2) 945 { 946 struct kinfo_proc *p1 = *(struct kinfo_proc **)arg1; 947 struct kinfo_proc *p2 = *(struct kinfo_proc **)arg2; 948 949 ORDERKEY_CPTICKS(p1, p2); 950 ORDERKEY_PCTCPU(p1, p2); 951 ORDERKEY_STATE(p1, p2); 952 ORDERKEY_PRIO(p1, p2); 953 ORDERKEY_RSSIZE(p1, p2); 954 ORDERKEY_MEM(p1, p2); 955 956 return (0); 957 } 958 959 /* compare_prio - the comparison function for sorting by priority */ 960 961 int 962 compare_prio(void *arg1, void *arg2) 963 { 964 struct kinfo_proc *p1 = *(struct kinfo_proc **)arg1; 965 struct kinfo_proc *p2 = *(struct kinfo_proc **)arg2; 966 967 ORDERKEY_PRIO(p1, p2); 968 ORDERKEY_CPTICKS(p1, p2); 969 ORDERKEY_PCTCPU(p1, p2); 970 ORDERKEY_STATE(p1, p2); 971 ORDERKEY_RSSIZE(p1, p2); 972 ORDERKEY_MEM(p1, p2); 973 974 return (0); 975 } 976 #endif 977 978 /* compare_io - the comparison function for sorting by total io */ 979 980 int 981 #ifdef ORDER 982 compare_iototal(void *arg1, void *arg2) 983 #else 984 io_compare(void *arg1, void *arg2) 985 #endif 986 { 987 struct kinfo_proc *p1 = *(struct kinfo_proc **)arg1; 988 struct kinfo_proc *p2 = *(struct kinfo_proc **)arg2; 989 990 return (get_io_total(p2) - get_io_total(p1)); 991 } 992 993 #ifdef ORDER 994 995 int 996 compare_ioread(void *arg1, void *arg2) 997 { 998 struct kinfo_proc *p1 = *(struct kinfo_proc **)arg1; 999 struct kinfo_proc *p2 = *(struct kinfo_proc **)arg2; 1000 long dummy, inp1, inp2; 1001 1002 (void) get_io_stats(p1, &inp1, &dummy, &dummy, &dummy, &dummy); 1003 (void) get_io_stats(p2, &inp2, &dummy, &dummy, &dummy, &dummy); 1004 1005 return (inp2 - inp1); 1006 } 1007 1008 int 1009 compare_iowrite(void *arg1, void *arg2) 1010 { 1011 struct kinfo_proc *p1 = *(struct kinfo_proc **)arg1; 1012 struct kinfo_proc *p2 = *(struct kinfo_proc **)arg2; 1013 long dummy, oup1, oup2; 1014 1015 (void) get_io_stats(p1, &dummy, &oup1, &dummy, &dummy, &dummy); 1016 (void) get_io_stats(p2, &dummy, &oup2, &dummy, &dummy, &dummy); 1017 1018 return (oup2 - oup1); 1019 } 1020 1021 int 1022 compare_iofault(void *arg1, void *arg2) 1023 { 1024 struct kinfo_proc *p1 = *(struct kinfo_proc **)arg1; 1025 struct kinfo_proc *p2 = *(struct kinfo_proc **)arg2; 1026 long dummy, flp1, flp2; 1027 1028 (void) get_io_stats(p1, &dummy, &dummy, &flp1, &dummy, &dummy); 1029 (void) get_io_stats(p2, &dummy, &dummy, &flp2, &dummy, &dummy); 1030 1031 return (flp2 - flp1); 1032 } 1033 1034 int 1035 compare_vcsw(void *arg1, void *arg2) 1036 { 1037 struct kinfo_proc *p1 = *(struct kinfo_proc **)arg1; 1038 struct kinfo_proc *p2 = *(struct kinfo_proc **)arg2; 1039 long dummy, flp1, flp2; 1040 1041 (void) get_io_stats(p1, &dummy, &dummy, &dummy, &flp1, &dummy); 1042 (void) get_io_stats(p2, &dummy, &dummy, &dummy, &flp2, &dummy); 1043 1044 return (flp2 - flp1); 1045 } 1046 1047 int 1048 compare_ivcsw(void *arg1, void *arg2) 1049 { 1050 struct kinfo_proc *p1 = *(struct kinfo_proc **)arg1; 1051 struct kinfo_proc *p2 = *(struct kinfo_proc **)arg2; 1052 long dummy, flp1, flp2; 1053 1054 (void) get_io_stats(p1, &dummy, &dummy, &dummy, &dummy, &flp1); 1055 (void) get_io_stats(p2, &dummy, &dummy, &dummy, &dummy, &flp2); 1056 1057 return (flp2 - flp1); 1058 } 1059 1060 #endif /* ORDER */ 1061 1062 /* 1063 * proc_owner(pid) - returns the uid that owns process "pid", or -1 if 1064 * the process does not exist. 1065 * It is EXTREMLY IMPORTANT that this function work correctly. 1066 * If top runs setuid root (as in SVR4), then this function 1067 * is the only thing that stands in the way of a serious 1068 * security problem. It validates requests for the "kill" 1069 * and "renice" commands. 1070 */ 1071 1072 int 1073 proc_owner(int pid) 1074 { 1075 int cnt; 1076 struct kinfo_proc **prefp; 1077 struct kinfo_proc *pp; 1078 1079 prefp = pref; 1080 cnt = pref_len; 1081 while (--cnt >= 0) { 1082 pp = *prefp++; 1083 if (pp->ki_pid == (pid_t)pid) 1084 return ((int)pp->ki_ruid); 1085 } 1086 return (-1); 1087 } 1088 1089 int 1090 swapmode(int *retavail, int *retfree) 1091 { 1092 int n; 1093 int pagesize = getpagesize(); 1094 struct kvm_swap swapary[1]; 1095 1096 *retavail = 0; 1097 *retfree = 0; 1098 1099 #define CONVERT(v) ((quad_t)(v) * pagesize / 1024) 1100 1101 n = kvm_getswapinfo(kd, swapary, 1, 0); 1102 if (n < 0 || swapary[0].ksw_total == 0) 1103 return (0); 1104 1105 *retavail = CONVERT(swapary[0].ksw_total); 1106 *retfree = CONVERT(swapary[0].ksw_total - swapary[0].ksw_used); 1107 1108 n = (int)(swapary[0].ksw_used * 100.0 / swapary[0].ksw_total); 1109 return (n); 1110 } 1111