~ubuntu-branches/ubuntu/utopic/acct/utopic

« back to all changes in this revision

Viewing changes to sa.c

  • Committer: Bazaar Package Importer
  • Author(s): Artur Rona
  • Date: 2010-08-05 00:08:34 UTC
  • mfrom: (3.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20100805000834-y9k7nlasjm3t5che
Tags: 6.5.4-2ubuntu1
* Merge from Debian testing, remaining changes: (LP: #609754)
  - Remove stop links from rc0 and rc6. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* sa.c -- everyone's favorite hairball */
2
2
 
3
3
/*
4
 
Copyright (C) 1993, 1996, 1997, 2008, 2009 Free Software Foundation, Inc.
 
4
Copyright (C) 1993, 1996, 1997, 2008, 2009, 2010 Free Software Foundation, Inc.
5
5
 
6
6
This file is part of the GNU Accounting Utilities
7
7
 
73
73
#include <pwd.h>
74
74
 
75
75
#include "common.h"
 
76
#include "files.h"
76
77
#include "pacct_rd.h"
77
78
#include "utmp_rd.h"
78
79
#ifdef HAVE_GETOPT_LONG_ONLY
90
91
/* This is the struct we read/write from/to usracct and savacct. */
91
92
 
92
93
struct stats
93
 
  {
94
 
    unsigned long num_calls;    /* how many times this command called */
 
94
{
 
95
  unsigned long num_calls;      /* how many times this command called */
95
96
#ifdef HAVE_ACUTIME
96
 
    double user_time;           /* user time */
 
97
  double user_time;             /* user time */
97
98
#endif
98
99
#ifdef HAVE_ACSTIME
99
 
    double sys_time;            /* system time */
 
100
  double sys_time;              /* system time */
100
101
#endif
101
102
#ifdef HAVE_ACETIME
102
 
    double elapsed_time;                /* real time */
 
103
  double elapsed_time;          /* real time */
103
104
#endif
104
105
#ifdef HAVE_ACMEM
105
 
    double mem_usage;           /* total memory usage */
 
106
  double mem_usage;             /* total memory usage */
106
107
#endif
107
108
#ifdef HAVE_ACIO
108
 
    double disk_io;             /* how many disk I/O operations */
 
109
  double disk_io;               /* how many disk I/O operations */
109
110
#endif
110
111
#ifdef HAVE_PAGING
111
 
    double minor_faults;
112
 
    double major_faults;
113
 
    double swap_count;
 
112
  double minor_faults;
 
113
  double major_faults;
 
114
  double swap_count;
114
115
#endif
115
 
  };
 
116
};
116
117
 
117
118
struct usracct
118
 
  {
119
 
    char name[NAME_LEN];                /* should we be using the val from utmp_rd? */
120
 
    struct stats s;
121
 
  };
 
119
{
 
120
  char name[NAME_LEN];          /* should we be using the val from utmp_rd? */
 
121
  struct stats s;
 
122
};
122
123
 
123
124
#ifndef HAVE_GETPAGESIZE
124
125
#define getpagesize() 4096
138
139
struct hashtab *user_table;
139
140
 
140
141
struct user_data
141
 
  {
142
 
    struct stats s;
143
 
  };
 
142
{
 
143
  struct stats s;
 
144
};
144
145
 
145
146
/* Hash table of entries broken down by command */
146
147
 
147
148
struct hashtab *command_table;
148
149
 
149
150
struct command_key
150
 
  {
151
 
    char comm[COMM_LEN];                /* command name */
152
 
    short fork_flag;            /* nonzero if fork but no exec */
153
 
  };
 
151
{
 
152
  char comm[COMM_LEN];          /* command name */
 
153
  short fork_flag;              /* nonzero if fork but no exec */
 
154
};
154
155
 
155
156
struct command_data
156
 
  {
157
 
    struct stats s;
158
 
    short junked;
159
 
  };
 
157
{
 
158
  struct stats s;
 
159
  short junked;
 
160
};
160
161
 
161
162
struct savacct
162
 
  {
163
 
    struct command_key c;
164
 
    struct stats s;
165
 
  };
 
163
{
 
164
  struct command_key c;
 
165
  struct stats s;
 
166
};
166
167
 
167
168
 
168
169
struct stats stats_totals;      /* total of all commands */
253
254
                                   "***other" category */
254
255
int always_yes = 0;             /* nonzero means always answer yes to
255
256
                                   a query */
256
 
 
257
 
/* prototypes */
258
 
 
259
 
void give_usage PARAMS((void));
260
 
void write_savacct_file PARAMS((char *));
261
 
void write_usracct_file PARAMS((char *));
262
 
void parse_savacct_entries PARAMS((char *));
263
 
void parse_usracct_entries PARAMS((char *));
264
 
void parse_acct_entries PARAMS((void));
265
 
void init_flags_and_data PARAMS((void));
266
 
unsigned long hash_name PARAMS((char *));
267
 
void update_command_list PARAMS((char *, struct stats *, short fork_flag));
268
 
void update_user_list PARAMS((char *, struct stats *));
269
 
int compare_sum_entry PARAMS((struct hashtab_elem **, struct hashtab_elem **));
270
 
int compare_user_entry PARAMS((struct hashtab_elem **,
271
 
                               struct hashtab_elem **));
272
 
int compare_stats_entry PARAMS((struct stats *, struct stats *));
273
 
void print_command_list PARAMS((void));
274
 
void print_user_list PARAMS((void));
275
 
int non_printable PARAMS((char *, int));
276
 
int ask_if_junkable PARAMS((char *, int));
 
257
static unsigned int hzval;
 
258
 
 
259
void write_savacct_file (char *);
 
260
void write_usracct_file (char *);
 
261
void parse_savacct_entries (char *);
 
262
void parse_usracct_entries (char *);
 
263
void parse_acct_entries (void);
 
264
void init_flags_and_data (void);
 
265
unsigned long hash_name (char *);
 
266
void update_command_list (char *, struct stats *, short fork_flag);
 
267
void update_user_list (char *, struct stats *);
 
268
int compare_sum_entry (struct hashtab_elem **, struct hashtab_elem **);
 
269
int compare_user_entry (struct hashtab_elem **,
 
270
                        struct hashtab_elem **);
 
271
int compare_stats_entry (struct stats *, struct stats *);
 
272
void print_command_list (void);
 
273
void print_user_list (void);
 
274
int non_printable (char *, int);
 
275
int ask_if_junkable (char *, int);
277
276
 
278
277
/* code */
279
278
 
281
280
{
282
281
  int c;
283
282
 
 
283
  static unsigned int hzval;
284
284
  program_name = argv[0];
285
285
 
286
286
  /* Cache the page size of the machine for the PAGES_TO_KB macro */
302
302
      int option_index = 0;
303
303
 
304
304
      static struct option long_options[] =
305
 
        {
306
 
          { "debug", no_argument, NULL, 1
307
 
          },
308
 
          { "version", no_argument, NULL, 2 },
309
 
          { "help", no_argument, NULL, 3 },
310
 
          { "other-acct-file", required_argument, NULL, 4 },
311
 
          { "print-seconds", no_argument, NULL, 5 },
312
 
          { "dont-read-summary-files", no_argument, NULL, 6 },
313
 
          { "list-all-names", no_argument, NULL, 7 },
314
 
          { "other-savacct-file", 1, NULL, 9 },
315
 
          { "print-users", no_argument, NULL, 12 },
316
 
          { "percentages", no_argument, NULL, 14 },
317
 
          { "not-interactive", no_argument, NULL, 19 },
318
 
          { "user-summary", no_argument, NULL, 20 },
319
 
          { "reverse-sort", no_argument, NULL, 21 },
320
 
          { "merge", no_argument, NULL, 22 },
321
 
          { "threshold", required_argument, NULL, 23 },
322
 
          { "separate-forks", no_argument, NULL, 24 },
323
 
          { "other-usracct-file", required_argument, NULL, 25 },
 
305
      {
 
306
        { "debug", no_argument, NULL, 1
 
307
        },
 
308
        { "version", no_argument, NULL, 2 },
 
309
        { "help", no_argument, NULL, 3 },
 
310
        { "other-acct-file", required_argument, NULL, 4 },
 
311
        { "print-seconds", no_argument, NULL, 5 },
 
312
        { "dont-read-summary-files", no_argument, NULL, 6 },
 
313
        { "list-all-names", no_argument, NULL, 7 },
 
314
        { "other-savacct-file", 1, NULL, 9 },
 
315
        { "print-users", no_argument, NULL, 12 },
 
316
        { "percentages", no_argument, NULL, 14 },
 
317
        { "not-interactive", no_argument, NULL, 19 },
 
318
        { "user-summary", no_argument, NULL, 20 },
 
319
        { "reverse-sort", no_argument, NULL, 21 },
 
320
        { "merge", no_argument, NULL, 22 },
 
321
        { "threshold", required_argument, NULL, 23 },
 
322
        { "separate-forks", no_argument, NULL, 24 },
 
323
        { "other-usracct-file", required_argument, NULL, 25 },
324
324
 
325
325
#if defined(HAVE_ACUTIME) && defined(HAVE_ACSTIME)
326
 
          { "separate-times", no_argument, NULL, 8
327
 
          },
 
326
        { "separate-times", no_argument, NULL, 8
 
327
        },
328
328
#endif
329
329
 
330
330
#if defined(HAVE_ACSTIME) && defined(HAVE_ACUTIME) && defined(HAVE_ACMEM)
331
 
          { "sort-ksec", no_argument, NULL, 10
332
 
          },
 
331
        { "sort-ksec", no_argument, NULL, 10
 
332
        },
333
333
#endif
334
334
 
335
335
#if defined(HAVE_ACUTIME) && defined(HAVE_ACSTIME) && defined(HAVE_ACETIME)
336
 
          { "print-ratio", no_argument, NULL, 11
337
 
          },
 
336
        { "print-ratio", no_argument, NULL, 11
 
337
        },
338
338
#endif
339
339
 
340
340
#ifdef HAVE_ACIO
341
 
          { "sort-tio", no_argument, NULL, 13 },
 
341
        { "sort-tio", no_argument, NULL, 13 },
342
342
#endif
343
343
 
344
344
#if defined(HAVE_ACSTIME) && defined(HAVE_ACUTIME)
345
 
          { "sort-sys-user-div-calls", no_argument, NULL, 15
346
 
          },
 
345
        { "sort-sys-user-div-calls", no_argument, NULL, 15
 
346
        },
347
347
#endif
348
348
 
349
349
#ifdef HAVE_ACIO
350
 
          { "sort-avio", no_argument, NULL, 16 },
 
350
        { "sort-avio", no_argument, NULL, 16 },
351
351
#endif
352
352
 
353
353
#ifdef HAVE_ACMEM
354
 
          { "sort-cpu-avmem", no_argument, NULL, 17 },
 
354
        { "sort-cpu-avmem", no_argument, NULL, 17 },
355
355
#endif
356
356
 
357
357
#if defined(HAVE_ACSTIME) && defined(HAVE_ACUTIME)
358
 
          /* Don't want this if it's the default */
359
 
          { "sort-num-calls", no_argument, NULL, 18
360
 
          },
 
358
        /* Don't want this if it's the default */
 
359
        { "sort-num-calls", no_argument, NULL, 18
 
360
        },
361
361
#endif
362
362
#ifdef HAVE_ACETIME
363
 
          { "sort-real-time", no_argument, NULL, 26 },
 
363
        { "sort-real-time", no_argument, NULL, 26 },
364
364
#endif
365
 
          { "ahz", required_argument, NULL, 27 },
 
365
        { "ahz", required_argument, NULL, 27 },
366
366
#ifdef HAVE_PAGING
367
 
          { "show-paging", no_argument, NULL, 28 },
368
 
          { "show-paging-avg", no_argument, NULL, 29 },
 
367
        { "show-paging", no_argument, NULL, 28 },
 
368
        { "show-paging-avg", no_argument, NULL, 29 },
369
369
#endif
370
 
          { 0, 0, 0, 0 }
371
 
        };
 
370
        { 0, 0, 0, 0 }
 
371
      };
372
372
 
373
373
      c = getopt_long (argc, argv,
374
374
                       "ahV"
417
417
          (void)printf("%s: GNU Accounting Utilities (release %s)\n",
418
418
                       program_name, VERSION_STRING);
419
419
          exit(EXIT_SUCCESS);
420
 
        case 4:
421
420
          acct_file_name = optarg;
422
421
          break;
423
422
        case 'j':
594
593
      exit(EXIT_FAILURE);
595
594
    }
596
595
 
 
596
    /* Set HZ value from system */
 
597
    hzval = sysconf(_SC_CLK_TCK);
 
598
    
597
599
  /* Print out some debugging information. */
598
 
 
 
600
  
599
601
  if (debugging_enabled)
600
602
    {
601
 
      (void)fprintf (stddebug, "AHZ -> %d\n", ahz);
 
603
      (void)fprintf (stddebug, "hzval -> %d\n", hzval);
602
604
      (void)fprintf (stddebug, "getpagesize() -> %d\n", getpagesize ());
603
605
      (void)fprintf (stddebug, "system_page_size == %.2f\n", system_page_size);
604
606
    }
629
631
  parse_acct_entries ();
630
632
 
631
633
  if (print_users)
632
 
    exit (0);
 
634
    exit(EXIT_SUCCESS);
633
635
 
634
636
  if (merge_files)
635
637
    {
644
646
        print_command_list ();
645
647
    }
646
648
 
647
 
  exit (0);                     /* guarantee the proper return value */
 
649
  exit(EXIT_SUCCESS);                   /* guarantee the proper return value */
648
650
}
649
651
 
650
652
 
736
738
}
737
739
 
738
740
 
739
 
static
740
 
void
741
 
add_stats (struct stats *accum, struct stats *s)
 
741
static void add_stats (struct stats *accum, struct stats *s)
742
742
{
743
743
#define ADDIT(x); accum->x += s->x;
744
744
 
962
962
      /* Christoph Badura <bad@flatlin.ka.sub.org> says:
963
963
      *
964
964
      * The k*sec statistic is computed as
965
 
      * ((ac_utime+ac_stime)*pages_to_kbytes(ac_mem))/AHZ.  Of course you
 
965
      * ((ac_utime+ac_stime)*pages_to_kbytes(ac_mem))/hzval.  Of course you
966
966
      * need to expand the comp_t values.
967
967
      *
968
968
      * PAGES_TO_KBYTES(x) simply divides x by (getpagesize()/1024).  Of
1164
1164
# define CURR_AHZ ((double)(ahz))
1165
1165
#endif
1166
1166
 
1167
 
 
1168
1167
  if (debugging_enabled)
1169
1168
    fprintf (stddebug, "\
1170
1169
             ----------------------------------------------------------------------\n\
1171
1170
             acct entries\n\
1172
1171
             ----------------------------------------------------------------------\n\
1173
1172
             ");
1174
 
 
 
1173
             
1175
1174
  /* loop while there are entries to be had */
1176
1175
  while ((rec = pacct_get_entry ()) != NULL)
1177
1176
    {
1284
1283
  strncpy (ck.comm, comm, COMM_LEN);
1285
1284
  ck.fork_flag = fork_flag;
1286
1285
 
1287
 
  he = hashtab_find (command_table, &ck, sizeof (ck));
 
1286
  he = hashtab_find (command_table, &ck, (unsigned int)sizeof (ck));
1288
1287
  if (he == NULL)
1289
1288
    {
1290
1289
      struct command_data cd;
1325
1324
      print_stats_raw (s, stddebug);
1326
1325
    }
1327
1326
 
1328
 
  he = hashtab_find (user_table, name, NAME_LEN);
 
1327
  he = hashtab_find (user_table, name, (unsigned int)NAME_LEN);
1329
1328
 
1330
1329
  if (he == NULL)
1331
1330
    {