pdb.c (169670) | pdb.c (169857) |
---|---|
1/* 2 * Copyright (c) 1994 Christopher G. Demetriou 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include <sys/cdefs.h> | 1/* 2 * Copyright (c) 1994 Christopher G. Demetriou 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include <sys/cdefs.h> |
32__FBSDID("$FreeBSD: head/usr.sbin/sa/pdb.c 169670 2007-05-18 12:36:10Z dds $"); | 32__FBSDID("$FreeBSD: head/usr.sbin/sa/pdb.c 169857 2007-05-22 06:51:38Z dds $"); |
33 34#include <sys/types.h> 35#include <sys/acct.h> 36#include <err.h> 37#include <errno.h> 38#include <fcntl.h> | 33 34#include <sys/types.h> 35#include <sys/acct.h> 36#include <err.h> 37#include <errno.h> 38#include <fcntl.h> |
39#include <stdbool.h> |
|
39#include <stdint.h> 40#include <stdio.h> 41#include <string.h> 42#include "extern.h" 43#include "pathnames.h" 44 45static int check_junk(const struct cmdinfo *); 46static void add_ci(const struct cmdinfo *, struct cmdinfo *); 47static void print_ci(const struct cmdinfo *, const struct cmdinfo *); 48 49static DB *pacct_db; 50 | 40#include <stdint.h> 41#include <stdio.h> 42#include <string.h> 43#include "extern.h" 44#include "pathnames.h" 45 46static int check_junk(const struct cmdinfo *); 47static void add_ci(const struct cmdinfo *, struct cmdinfo *); 48static void print_ci(const struct cmdinfo *, const struct cmdinfo *); 49 50static DB *pacct_db; 51 |
51int 52pacct_init() | 52/* Legacy format in AHZV1 units. */ 53struct cmdinfov1 { 54 char ci_comm[MAXCOMLEN+2]; /* command name (+ '*') */ 55 uid_t ci_uid; /* user id */ 56 u_quad_t ci_calls; /* number of calls */ 57 u_quad_t ci_etime; /* elapsed time */ 58 u_quad_t ci_utime; /* user time */ 59 u_quad_t ci_stime; /* system time */ 60 u_quad_t ci_mem; /* memory use */ 61 u_quad_t ci_io; /* number of disk i/o ops */ 62 u_int ci_flags; /* flags; see below */ 63}; 64 65/* 66 * Convert a v1 data record into the current version. 67 * Return 0 if OK, -1 on error, setting errno. 68 */ 69static int 70v1_to_v2(DBT *key __unused, DBT *data) |
53{ | 71{ |
54 DB *saved_pacct_db; 55 int error; | 72 struct cmdinfov1 civ1; 73 static struct cmdinfo civ2; |
56 | 74 |
57 pacct_db = dbopen(NULL, O_RDWR, 0, DB_BTREE, NULL); 58 if (pacct_db == NULL) | 75 if (data->size != sizeof(civ1)) { 76 errno = EFTYPE; |
59 return (-1); | 77 return (-1); |
60 61 error = 0; 62 if (!iflag) { 63 DBT key, data; 64 int serr, nerr; 65 66 saved_pacct_db = dbopen(pdb_file, O_RDONLY, 0, DB_BTREE, 67 NULL); 68 if (saved_pacct_db == NULL) { 69 error = errno == ENOENT ? 0 : -1; 70 if (error) 71 warn("retrieving process accounting summary"); 72 goto out; 73 } 74 75 serr = DB_SEQ(saved_pacct_db, &key, &data, R_FIRST); 76 if (serr < 0) { 77 warn("retrieving process accounting summary"); 78 error = -1; 79 goto closeout; 80 } 81 while (serr == 0) { 82 nerr = DB_PUT(pacct_db, &key, &data, 0); 83 if (nerr < 0) { 84 warn("initializing process accounting stats"); 85 error = -1; 86 break; 87 } 88 89 serr = DB_SEQ(saved_pacct_db, &key, &data, R_NEXT); 90 if (serr < 0) { 91 warn("retrieving process accounting summary"); 92 error = -1; 93 break; 94 } 95 } 96 97closeout: if (DB_CLOSE(saved_pacct_db) < 0) { 98 warn("closing process accounting summary"); 99 error = -1; 100 } | |
101 } | 78 } |
79 memcpy(&civ1, data->data, data->size); 80 memset(&civ2, 0, sizeof(civ2)); 81 memcpy(civ2.ci_comm, civ1.ci_comm, sizeof(civ2.ci_comm)); 82 civ2.ci_uid = civ1.ci_uid; 83 civ2.ci_calls = civ1.ci_calls; 84 civ2.ci_etime = ((double)civ1.ci_etime / AHZV1) * 1000000; 85 civ2.ci_utime = ((double)civ1.ci_utime / AHZV1) * 1000000; 86 civ2.ci_stime = ((double)civ1.ci_stime / AHZV1) * 1000000; 87 civ2.ci_mem = civ1.ci_mem; 88 civ2.ci_io = civ1.ci_io; 89 civ2.ci_flags = civ1.ci_flags; 90 data->size = sizeof(civ2); 91 data->data = &civ2; 92 return (0); 93} |
|
102 | 94 |
103out: if (error != 0) 104 pacct_destroy(); 105 return (error); | 95/* Copy pdb_file to in-memory pacct_db. */ 96int 97pacct_init() 98{ 99 return (db_copy_in(&pacct_db, pdb_file, "process accounting", 100 NULL, v1_to_v2)); |
106} 107 108void 109pacct_destroy() 110{ | 101} 102 103void 104pacct_destroy() 105{ |
111 if (DB_CLOSE(pacct_db) < 0) 112 warn("destroying process accounting stats"); | 106 db_destroy(pacct_db, "process accounting"); |
113} 114 115int 116pacct_add(const struct cmdinfo *ci) 117{ 118 DBT key, data; 119 struct cmdinfo newci; 120 char keydata[sizeof ci->ci_comm]; --- 28 unchanged lines hidden (view full) --- 149 warnx("duplicate key %s in process accounting stats", 150 ci->ci_comm); 151 return (-1); 152 } 153 154 return (0); 155} 156 | 107} 108 109int 110pacct_add(const struct cmdinfo *ci) 111{ 112 DBT key, data; 113 struct cmdinfo newci; 114 char keydata[sizeof ci->ci_comm]; --- 28 unchanged lines hidden (view full) --- 143 warnx("duplicate key %s in process accounting stats", 144 ci->ci_comm); 145 return (-1); 146 } 147 148 return (0); 149} 150 |
151/* Copy in-memory pacct_db to pdb_file. */ |
|
157int 158pacct_update() 159{ | 152int 153pacct_update() 154{ |
160 DB *saved_pacct_db; 161 DBT key, data; 162 int error, serr, nerr; 163 164 saved_pacct_db = dbopen(pdb_file, O_RDWR|O_CREAT|O_TRUNC, 0644, 165 DB_BTREE, NULL); 166 if (saved_pacct_db == NULL) { 167 warn("creating process accounting summary"); 168 return (-1); 169 } 170 171 error = 0; 172 173 serr = DB_SEQ(pacct_db, &key, &data, R_FIRST); 174 if (serr < 0) { 175 warn("retrieving process accounting stats"); 176 error = -1; 177 } 178 while (serr == 0) { 179 nerr = DB_PUT(saved_pacct_db, &key, &data, 0); 180 if (nerr < 0) { 181 warn("saving process accounting summary"); 182 error = -1; 183 break; 184 } 185 186 serr = DB_SEQ(pacct_db, &key, &data, R_NEXT); 187 if (serr < 0) { 188 warn("retrieving process accounting stats"); 189 error = -1; 190 break; 191 } 192 } 193 194 if (DB_SYNC(saved_pacct_db, 0) < 0) { 195 warn("syncing process accounting summary"); 196 error = -1; 197 } 198 if (DB_CLOSE(saved_pacct_db) < 0) { 199 warn("closing process accounting summary"); 200 error = -1; 201 } 202 return error; | 155 return (db_copy_out(pacct_db, pdb_file, "process accounting", 156 NULL)); |
203} 204 205void 206pacct_print() 207{ 208 BTREEINFO bti; 209 DBT key, data, ndata; 210 DB *output_pacct_db; --- 114 unchanged lines hidden (view full) --- 325 326static void 327print_ci(const struct cmdinfo *cip, const struct cmdinfo *totalcip) 328{ 329 double t, c; 330 int uflow; 331 332 c = cip->ci_calls ? cip->ci_calls : 1; | 157} 158 159void 160pacct_print() 161{ 162 BTREEINFO bti; 163 DBT key, data, ndata; 164 DB *output_pacct_db; --- 114 unchanged lines hidden (view full) --- 279 280static void 281print_ci(const struct cmdinfo *cip, const struct cmdinfo *totalcip) 282{ 283 double t, c; 284 int uflow; 285 286 c = cip->ci_calls ? cip->ci_calls : 1; |
333 t = (cip->ci_utime + cip->ci_stime) / (double) AHZ; | 287 t = (cip->ci_utime + cip->ci_stime) / 1000000; |
334 if (t < 0.01) { 335 t = 0.01; 336 uflow = 1; 337 } else 338 uflow = 0; 339 340 printf("%8ju ", (uintmax_t)cip->ci_calls); 341 if (cflag) { 342 if (cip != totalcip) 343 printf(" %4.1f%% ", cip->ci_calls / 344 (double)totalcip->ci_calls * 100); 345 else 346 printf(" %4s ", ""); 347 } 348 349 if (jflag) | 288 if (t < 0.01) { 289 t = 0.01; 290 uflow = 1; 291 } else 292 uflow = 0; 293 294 printf("%8ju ", (uintmax_t)cip->ci_calls); 295 if (cflag) { 296 if (cip != totalcip) 297 printf(" %4.1f%% ", cip->ci_calls / 298 (double)totalcip->ci_calls * 100); 299 else 300 printf(" %4s ", ""); 301 } 302 303 if (jflag) |
350 printf("%11.2fre ", cip->ci_etime / (double) (AHZ * c)); | 304 printf("%11.3fre ", cip->ci_etime / (1000000 * c)); |
351 else | 305 else |
352 printf("%11.2fre ", cip->ci_etime / (60.0 * AHZ)); | 306 printf("%11.3fre ", cip->ci_etime / (60.0 * 1000000)); |
353 if (cflag) { 354 if (cip != totalcip) 355 printf(" %4.1f%% ", cip->ci_etime / | 307 if (cflag) { 308 if (cip != totalcip) 309 printf(" %4.1f%% ", cip->ci_etime / |
356 (double)totalcip->ci_etime * 100); | 310 totalcip->ci_etime * 100); |
357 else 358 printf(" %4s ", ""); 359 } 360 361 if (!lflag) { 362 if (jflag) | 311 else 312 printf(" %4s ", ""); 313 } 314 315 if (!lflag) { 316 if (jflag) |
363 printf("%11.2fcp ", t / (double) cip->ci_calls); | 317 printf("%11.3fcp ", t / (double) cip->ci_calls); |
364 else 365 printf("%11.2fcp ", t / 60.0); 366 if (cflag) { 367 if (cip != totalcip) 368 printf(" %4.1f%% ", | 318 else 319 printf("%11.2fcp ", t / 60.0); 320 if (cflag) { 321 if (cip != totalcip) 322 printf(" %4.1f%% ", |
369 (double)(cip->ci_utime + cip->ci_stime) / | 323 (cip->ci_utime + cip->ci_stime) / |
370 (totalcip->ci_utime + totalcip->ci_stime) * 371 100); 372 else 373 printf(" %4s ", ""); 374 } 375 } else { 376 if (jflag) | 324 (totalcip->ci_utime + totalcip->ci_stime) * 325 100); 326 else 327 printf(" %4s ", ""); 328 } 329 } else { 330 if (jflag) |
377 printf("%11.2fu ", cip->ci_utime / (double) (AHZ * c)); | 331 printf("%11.3fu ", cip->ci_utime / (1000000 * c)); |
378 else | 332 else |
379 printf("%11.2fu ", cip->ci_utime / (60.0 * AHZ)); | 333 printf("%11.2fu ", cip->ci_utime / (60.0 * 1000000)); |
380 if (cflag) { 381 if (cip != totalcip) 382 printf(" %4.1f%% ", cip->ci_utime / 383 (double)totalcip->ci_utime * 100); 384 else 385 printf(" %4s ", ""); 386 } 387 if (jflag) | 334 if (cflag) { 335 if (cip != totalcip) 336 printf(" %4.1f%% ", cip->ci_utime / 337 (double)totalcip->ci_utime * 100); 338 else 339 printf(" %4s ", ""); 340 } 341 if (jflag) |
388 printf("%11.2fs ", cip->ci_stime / (double) (AHZ * c)); | 342 printf("%11.3fs ", cip->ci_stime / (1000000 * c)); |
389 else | 343 else |
390 printf("%11.2fs ", cip->ci_stime / (60.0 * AHZ)); | 344 printf("%11.2fs ", cip->ci_stime / (60.0 * 1000000)); |
391 if (cflag) { 392 if (cip != totalcip) 393 printf(" %4.1f%% ", cip->ci_stime / 394 (double)totalcip->ci_stime * 100); 395 else 396 printf(" %4s ", ""); 397 } 398 } 399 400 if (tflag) { 401 if (!uflow) 402 printf("%8.2fre/cp ", 403 cip->ci_etime / | 345 if (cflag) { 346 if (cip != totalcip) 347 printf(" %4.1f%% ", cip->ci_stime / 348 (double)totalcip->ci_stime * 100); 349 else 350 printf(" %4s ", ""); 351 } 352 } 353 354 if (tflag) { 355 if (!uflow) 356 printf("%8.2fre/cp ", 357 cip->ci_etime / |
404 (double) (cip->ci_utime + cip->ci_stime)); | 358 (cip->ci_utime + cip->ci_stime)); |
405 else 406 printf("*ignore* "); 407 } 408 409 if (Dflag) | 359 else 360 printf("*ignore* "); 361 } 362 363 if (Dflag) |
410 printf("%10jutio ", (uintmax_t)cip->ci_io); | 364 printf("%10.0fio ", cip->ci_io); |
411 else 412 printf("%8.0favio ", cip->ci_io / c); 413 414 if (Kflag) | 365 else 366 printf("%8.0favio ", cip->ci_io / c); 367 368 if (Kflag) |
415 printf("%10juk*sec ", (uintmax_t)cip->ci_mem); | 369 printf("%10.0fk*sec ", cip->ci_mem); |
416 else 417 printf("%8.0fk ", cip->ci_mem / t); 418 419 printf(" %s\n", cip->ci_comm); 420} | 370 else 371 printf("%8.0fk ", cip->ci_mem / t); 372 373 printf(" %s\n", cip->ci_comm); 374} |