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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 /* 33 * acctprc 34 * reads std. input (acct.h format), 35 * writes std. output (tacct format) 36 * sorted by uid 37 * adds login names 38 */ 39 40 #include <stdio.h> 41 #include <sys/types.h> 42 #include <sys/param.h> 43 #include "acctdef.h" 44 #include <sys/acct.h> 45 #include <string.h> 46 #include <search.h> 47 #include <stdlib.h> 48 49 struct acct ab; 50 struct ptmp pb; 51 struct tacct tb; 52 53 struct utab { 54 uid_t ut_uid; 55 char ut_name[NSZ]; 56 float ut_cpu[2]; /* cpu time (mins) */ 57 float ut_kcore[2]; /* kcore-mins */ 58 long ut_pc; /* # processes */ 59 } * ub; 60 static int usize; 61 void **root = NULL; 62 63 void output(void); 64 void enter(struct ptmp *); 65 66 int 67 main(int argc, char **argv) 68 { 69 long elaps[2]; 70 ulong_t etime, stime; 71 unsigned long mem; 72 #ifdef uts 73 float expand(); 74 #else 75 ulong_t expand(); 76 #endif 77 78 while (fread(&ab, sizeof(ab), 1, stdin) == 1) { 79 if (!MYKIND(ab.ac_flag)) 80 continue; 81 pb.pt_uid = ab.ac_uid; 82 CPYN(pb.pt_name, NULL); 83 /* 84 * approximate cpu P/NP split as same as elapsed time 85 */ 86 if ((etime = SECS(expand(ab.ac_etime))) == 0) 87 etime = 1; 88 stime = expand(ab.ac_stime) + expand(ab.ac_utime); 89 mem = expand(ab.ac_mem); 90 if(pnpsplit(ab.ac_btime, etime, elaps) == 0) { 91 fprintf(stderr, "acctprc: could not calculate prime/non-prime hours\n"); 92 93 exit(1); 94 } 95 pb.pt_cpu[0] = (double)stime * (double)elaps[0] / etime; 96 pb.pt_cpu[1] = (stime > pb.pt_cpu[0])? stime - pb.pt_cpu[0] : 0; 97 pb.pt_cpu[1] = stime - pb.pt_cpu[0]; 98 if (stime) 99 pb.pt_mem = (mem + stime - 1) / stime; 100 else 101 pb.pt_mem = 0; /* unlikely */ 102 enter(&pb); 103 } 104 output(); 105 exit(0); 106 } 107 108 int node_compare(const void *node1, const void *node2) 109 { 110 if (((const struct utab *)node1)->ut_uid > \ 111 ((const struct utab *)node2)->ut_uid) 112 return(1); 113 else if (((const struct utab *)node1)->ut_uid < \ 114 ((const struct utab *)node2)->ut_uid) 115 return(-1); 116 else return(0); 117 } 118 119 void 120 enter(struct ptmp *p) 121 { 122 double memk; 123 struct utab **pt; 124 125 if ((ub = (struct utab *)malloc(sizeof (struct utab))) == NULL) { 126 fprintf(stderr, "acctprc: malloc fail!\n"); 127 exit(2); 128 } 129 130 ub->ut_uid = p->pt_uid; 131 CPYN(ub->ut_name, p->pt_name); 132 ub->ut_cpu[0] = MINT(p->pt_cpu[0]); 133 ub->ut_cpu[1] = MINT(p->pt_cpu[1]); 134 memk = KCORE(pb.pt_mem); 135 ub->ut_kcore[0] = memk * MINT(p->pt_cpu[0]); 136 ub->ut_kcore[1] = memk * MINT(p->pt_cpu[1]); 137 ub->ut_pc = 1; 138 139 if (*(pt = (struct utab **)tsearch((void *)ub, (void **)&root, \ 140 node_compare)) == NULL) { 141 fprintf(stderr, "Not enough space available to build tree\n"); 142 exit(1); 143 } 144 145 if (*pt != ub) { 146 (*pt)->ut_cpu[0] += MINT(p->pt_cpu[0]); 147 (*pt)->ut_cpu[1] += MINT(p->pt_cpu[1]); 148 (*pt)->ut_kcore[0] += memk * MINT(p->pt_cpu[0]); 149 (*pt)->ut_kcore[1] += memk * MINT(p->pt_cpu[1]); 150 (*pt)->ut_pc++; 151 free(ub); 152 } 153 } 154 155 void print_node(const void *node, VISIT order, int level) { 156 157 if (order == postorder || order == leaf) { 158 tb.ta_uid = (*(struct utab **)node)->ut_uid; 159 CPYN(tb.ta_name, (char *)uidtonam((*(struct utab **)node)->ut_uid)); 160 tb.ta_cpu[0] = (*(struct utab **)node)->ut_cpu[0]; 161 tb.ta_cpu[1] = (*(struct utab **)node)->ut_cpu[1]; 162 tb.ta_kcore[0] = (*(struct utab **)node)->ut_kcore[0]; 163 tb.ta_kcore[1] = (*(struct utab **)node)->ut_kcore[1]; 164 tb.ta_pc = (*(struct utab **)node)->ut_pc; 165 fwrite(&tb, sizeof(tb), 1, stdout); 166 } 167 } 168 169 void 170 output(void) 171 { 172 twalk((struct utab *)root, print_node); 173 } 174