~ubuntu-branches/ubuntu/edgy/sysstat/edgy

« back to all changes in this revision

Viewing changes to sar.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Luberda
  • Date: 2005-10-05 20:44:33 UTC
  • mfrom: (1.1.2 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20051005204433-v20r8ptt8ms2690u
Tags: 6.0.1-3
Swedish debconf templates translation (closes: #331184).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * sar: report system activity
3
 
 * (C) 1999-2004 by Sebastien GODARD (sysstat <at> wanadoo.fr)
 
3
 * (C) 1999-2005 by Sebastien GODARD (sysstat <at> wanadoo.fr)
4
4
 *
5
5
 ***************************************************************************
6
6
 * This program is free software; you can redistribute it and/or modify it *
15
15
 *                                                                         *
16
16
 * You should have received a copy of the GNU General Public License along *
17
17
 * with this program; if not, write to the Free Software Foundation, Inc., *
18
 
 * 675 Mass Ave, Cambridge, MA 02139, USA.                                 *
 
18
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                   *
19
19
 ***************************************************************************
20
20
 */
21
21
 
25
25
#include <unistd.h>
26
26
#include <time.h>
27
27
#include <errno.h>
28
 
#include <fcntl.h>
29
 
#include <sys/types.h>
30
28
#include <sys/param.h>  /* for HZ */
31
29
 
32
30
#include "version.h"
33
31
#include "sa.h"
34
32
#include "common.h"
35
 
#include "sapath.h"
36
33
 
37
34
 
38
35
#ifdef USE_NLS
43
40
#define _(string) (string)
44
41
#endif
45
42
 
46
 
 
47
 
long interval = 0, count = 0;
 
43
long interval = -1, count = 0;
48
44
unsigned int sar_actflag = 0;
49
45
unsigned int flags = 0;
50
46
unsigned char irq_bitmap[(NR_IRQS / 8) + 1];
54
50
struct stats_sum asum;
55
51
struct file_hdr file_hdr;
56
52
struct file_stats file_stats[DIM];
57
 
struct stats_one_cpu *st_cpu[DIM];
58
 
struct stats_serial *st_serial[DIM];
59
 
struct stats_irq_cpu *st_irq_cpu[DIM];
60
 
struct stats_net_dev *st_net_dev[DIM];
61
 
struct disk_stats *st_disk[DIM];
 
53
struct stats_one_cpu *st_cpu[DIM] = {NULL, NULL, NULL};
 
54
struct stats_serial *st_serial[DIM] = {NULL, NULL, NULL};
 
55
struct stats_irq_cpu *st_irq_cpu[DIM] = {NULL, NULL, NULL};
 
56
struct stats_net_dev *st_net_dev[DIM] = {NULL, NULL, NULL};
 
57
struct disk_stats *st_disk[DIM] = {NULL, NULL, NULL};
62
58
 
63
59
/* Array members of common types are always packed */
64
60
unsigned int interrupts[DIM][NR_IRQS];
84
80
                   "(C) Sebastien Godard\n"
85
81
                   "Usage: %s [ options... ] [ <interval> [ <count> ] ]\n"
86
82
                   "Options are:\n"
87
 
                   "[ -A ] [ -b ] [ -B ] [ -c ] [ -d ] [ -H ] [ -h ] [ -i <interval> ] [ -q ]\n"
 
83
                   "[ -A ] [ -b ] [ -B ] [ -c ] [ -d ] [ -i <interval> ] [ -p ] [ -q ]\n"
88
84
                   "[ -r ] [ -R ] [ -t ] [ -u ] [ -v ] [ -V ] [ -w ] [ -W ] [ -y ]\n"
89
85
                   "[ -I { <irq> | SUM | ALL | XALL } ] [ -P { <cpu> | ALL } ]\n"
90
 
                   "[ -n { DEV | EDEV | SOCK | FULL } ]\n"
 
86
                   "[ -n { DEV | EDEV | NFS | NFSD | SOCK | FULL } ]\n"
91
87
                   "[ -x { <pid> | SELF | ALL } ] [ -X { <pid> | SELF | ALL } ]\n"
92
88
                   "[ -o [ <filename> ] | -f [ <filename> ] ]\n"
93
89
                   "[ -s [ <hh:mm:ss> ] ] [ -e [ <hh:mm:ss> ] ]\n"),
98
94
 
99
95
/*
100
96
 ***************************************************************************
101
 
 * Init irqs array
102
 
 ***************************************************************************
103
 
 */
104
 
void init_irq_bitmap(unsigned char value)
105
 
{
106
 
   register int i;
107
 
 
108
 
   for (i = 0; i <= NR_IRQS >> 3; i++)
109
 
     irq_bitmap[i] = value;
110
 
}
111
 
 
112
 
 
113
 
/*
114
 
 ***************************************************************************
115
 
 * Init CPUs array
116
 
 ***************************************************************************
117
 
 */
118
 
void init_cpu_bitmap(unsigned char value)
119
 
{
120
 
   register int i;
121
 
 
122
 
   for (i = 0; i <= NR_CPUS >> 3; i++)
123
 
     cpu_bitmap[i] = value;
124
 
}
125
 
 
126
 
 
127
 
/*
128
 
 ***************************************************************************
129
 
 * Init stats_sum structure
130
 
 ***************************************************************************
131
 
 */
132
 
void init_stats_sum(void)
133
 
{
 
97
 * Init stats structures
 
98
 ***************************************************************************
 
99
 */
 
100
void init_all_stats(void)
 
101
{
 
102
   int i;
 
103
 
 
104
   init_stats(file_stats, interrupts);
134
105
   memset(&asum, 0, STATS_SUM_SIZE);
135
 
}
136
 
 
137
 
 
138
 
/*
139
 
 ***************************************************************************
140
 
 * Init stats structures
141
 
 ***************************************************************************
142
 
 */
143
 
void init_stats(void)
144
 
{
145
 
   int i;
146
 
 
147
 
   for (i = 0; i < DIM; i++) {
148
 
      memset(&file_stats[i], 0, FILE_STATS_SIZE);
149
 
      memset(interrupts[i], 0, STATS_ONE_IRQ_SIZE);
150
 
   }
151
 
   init_stats_sum();
 
106
 
 
107
   for (i = 0; i < DIM; i++)
 
108
      pid_stats[i][0] = NULL;
152
109
}
153
110
 
154
111
 
169
126
 
170
127
/*
171
128
 ***************************************************************************
172
 
 * Allocate stats_one_cpu structures
173
 
 * (only on SMP machines)
174
 
 ***************************************************************************
175
 
 */
176
 
void salloc_cpu(unsigned int nr_cpu)
177
 
{
178
 
   int i;
179
 
 
180
 
   for (i = 0; i < DIM; i++) {
181
 
      if ((st_cpu[i] = (struct stats_one_cpu *) malloc(STATS_ONE_CPU_SIZE * nr_cpu)) == NULL) {
182
 
         perror("malloc");
183
 
         exit(4);
184
 
      }
185
 
 
186
 
      memset(st_cpu[i], 0, STATS_ONE_CPU_SIZE * nr_cpu);
187
 
   }
188
 
}
189
 
 
190
 
 
191
 
/*
192
 
 ***************************************************************************
193
 
 * Allocate stats_serial structures
194
 
 ***************************************************************************
195
 
 */
196
 
void salloc_serial(int nr_serial)
197
 
{
198
 
   int i;
199
 
 
200
 
   for (i = 0; i < DIM; i++) {
201
 
      if ((st_serial[i] = (struct stats_serial *) malloc(STATS_SERIAL_SIZE * nr_serial)) == NULL) {
202
 
         perror("malloc");
203
 
         exit(4);
204
 
      }
205
 
 
206
 
      memset(st_serial[i], 0, STATS_SERIAL_SIZE * nr_serial);
207
 
   }
208
 
}
209
 
 
210
 
 
211
 
/*
212
 
 ***************************************************************************
213
 
 * Allocate stats_irq_cpu structures
214
 
 ***************************************************************************
215
 
 */
216
 
void salloc_irqcpu(unsigned int nr_cpus, unsigned int nr_irqcpu)
217
 
{
218
 
   int i;
219
 
 
220
 
   for (i = 0; i < DIM; i++) {
221
 
      if ((st_irq_cpu[i] = (struct stats_irq_cpu *) malloc(STATS_IRQ_CPU_SIZE * nr_cpus * nr_irqcpu)) == NULL) {
222
 
         perror("malloc");
223
 
         exit(4);
224
 
      }
225
 
 
226
 
      memset(st_irq_cpu[i], 0, STATS_IRQ_CPU_SIZE * nr_cpus * nr_irqcpu);
227
 
   }
228
 
}
229
 
 
230
 
 
231
 
/*
232
 
 ***************************************************************************
233
 
 * Allocate stats_net_dev structures
234
 
 ***************************************************************************
235
 
 */
236
 
void salloc_net_dev(unsigned int nr_iface)
237
 
{
238
 
   int i;
239
 
 
240
 
   for (i = 0; i < DIM; i++) {
241
 
      if ((st_net_dev[i] = (struct stats_net_dev *) malloc(STATS_NET_DEV_SIZE * nr_iface)) == NULL) {
242
 
         perror("malloc");
243
 
         exit(4);
244
 
      }
245
 
 
246
 
      memset(st_net_dev[i], 0, STATS_NET_DEV_SIZE * nr_iface);
247
 
   }
248
 
}
249
 
 
250
 
 
251
 
/*
252
 
 ***************************************************************************
253
 
 * Allocate disk_stats structures
254
 
 ***************************************************************************
255
 
 */
256
 
void salloc_disk(int nr_disk)
257
 
{
258
 
   int i;
259
 
 
260
 
   for (i = 0; i < DIM; i++) {
261
 
      if ((st_disk[i] = (struct disk_stats *) malloc(DISK_STATS_SIZE * nr_disk)) == NULL) {
262
 
         perror("malloc");
263
 
         exit(4);
264
 
      }
265
 
 
266
 
      memset(st_disk[i], 0, DISK_STATS_SIZE * nr_disk);
267
 
   }
268
 
}
269
 
 
270
 
 
271
 
/*
272
 
 ***************************************************************************
273
129
 * Allocate pid_stats structures
274
130
 ***************************************************************************
275
131
 */
278
134
   int i, pid;
279
135
 
280
136
   for (i = 0; i < DIM; i++) {
 
137
      if (pid_stats[i][0])
 
138
         free(pid_stats[i][0]);
281
139
      if ((pid_stats[i][0] = (struct pid_stats *) malloc(PID_STATS_SIZE * nr_pid)) == NULL) {
282
140
         perror("malloc");
283
141
         exit(4);
291
149
   }
292
150
}
293
151
 
294
 
/*
295
 
 ***************************************************************************
296
 
 * Use time stamp to fill tstamp structure
297
 
 ***************************************************************************
298
 
 */
299
 
int decode_time_stamp(char time_stamp[], struct tstamp *tse)
300
 
{
301
 
   time_stamp[2] = time_stamp[5] = '\0';
302
 
   tse->tm_sec  = atoi(&(time_stamp[6]));
303
 
   tse->tm_min  = atoi(&(time_stamp[3]));
304
 
   tse->tm_hour = atoi(time_stamp);
305
 
 
306
 
   if ((tse->tm_sec < 0) || (tse->tm_sec > 59) ||
307
 
       (tse->tm_min < 0) || (tse->tm_min > 59) ||
308
 
       (tse->tm_hour < 0) || (tse->tm_hour > 23))
309
 
      return 1;
310
 
 
311
 
   tse->use = TRUE;
312
 
 
313
 
   return 0;
314
 
}
315
 
 
316
 
 
317
 
/*
318
 
 ***************************************************************************
319
 
 * Compare two time stamps
320
 
 ***************************************************************************
321
 
 */
322
 
int datecmp(struct tm *loc_time, struct tstamp *tse)
323
 
{
324
 
   if (loc_time->tm_hour == tse->tm_hour) {
325
 
      if (loc_time->tm_min == tse->tm_min)
326
 
        return (loc_time->tm_sec - tse->tm_sec);
327
 
      else
328
 
        return (loc_time->tm_min - tse->tm_min);
 
152
 
 
153
/*
 
154
 ***************************************************************************
 
155
 * Allocate structures
 
156
 ***************************************************************************
 
157
 */
 
158
void allocate_structures(int stype)
 
159
{
 
160
   if (file_hdr.sa_proc > 0)
 
161
      salloc_cpu_array(st_cpu, file_hdr.sa_proc + 1);
 
162
   if ((stype == USE_SADC) &&
 
163
       (GET_PID(sar_actflag) || GET_CPID(sar_actflag))) {
 
164
      pid_nr = file_hdr.sa_nr_pid;
 
165
      salloc_pid(pid_nr);
329
166
   }
330
 
   else
331
 
     return (loc_time->tm_hour - tse->tm_hour);
 
167
   if (file_hdr.sa_serial)
 
168
      salloc_serial_array(st_serial, file_hdr.sa_serial);
 
169
   if (file_hdr.sa_irqcpu)
 
170
      salloc_irqcpu_array(st_irq_cpu, file_hdr.sa_proc + 1, file_hdr.sa_irqcpu);
 
171
   if (file_hdr.sa_iface)
 
172
      salloc_net_dev_array(st_net_dev, file_hdr.sa_iface);
 
173
   if (file_hdr.sa_nr_disk)
 
174
      salloc_disk_array(st_disk, file_hdr.sa_nr_disk);
332
175
}
333
176
 
334
177
 
384
227
 
385
228
/*
386
229
 ***************************************************************************
387
 
 * Check if we are close enough to desired interval
 
230
 * Fill loc_time structure according to time data saved in current
 
231
 * structure.
388
232
 ***************************************************************************
389
233
*/
390
 
int next_slice(int curr, int reset)
391
 
{
392
 
   unsigned long file_interval;
393
 
   static unsigned long last_uptime = 0;
394
 
   int min, max, pt1, pt2;
395
 
 
396
 
   if (!last_uptime || reset)
397
 
      last_uptime = file_stats[2].uptime;
398
 
 
399
 
   file_interval =
400
 
      ((file_stats[curr].uptime - last_uptime) / (file_hdr.sa_proc + 1)) / HZ;
401
 
   last_uptime = file_stats[curr].uptime;
402
 
 
403
 
   /*
404
 
    * A few notes about the "algorithm" used here to display selected entries
405
 
    * from the system activity file (option -f with -i flag):
406
 
    * Let 'Iu' be the interval value given by the user on the command line,
407
 
    *     'If' the interval between current and previous line in the system
408
 
    * activity file,
409
 
    * and 'En' the nth entry (identified by its time stamp) of the file.
410
 
    * We choose In = [ En - If/2, En + If/2 [ if If is even,
411
 
    *        or In = [ En - If/2, En + If/2 ] if not.
412
 
    * En will be displayed if
413
 
    *       (Pn * Iu) or (P'n * Iu) belongs to In
414
 
    * with  Pn = En / Iu and P'n = En / Iu + 1
415
 
    */
416
 
   min =
417
 
      (((file_stats[curr].uptime - file_stats[2].uptime) / (file_hdr.sa_proc + 1)) / HZ)
418
 
      - (file_interval / 2);
419
 
   max =
420
 
      (((file_stats[curr].uptime - file_stats[2].uptime) / (file_hdr.sa_proc + 1)) / HZ)
421
 
      + (file_interval / 2) + (file_interval & 0x1);
422
 
 
423
 
   pt1 =
424
 
      ((((file_stats[curr].uptime - file_stats[2].uptime) / (file_hdr.sa_proc + 1)) / HZ) / interval) * interval;
425
 
   pt2 =
426
 
      (((((file_stats[curr].uptime - file_stats[2].uptime) / (file_hdr.sa_proc + 1)) / HZ) / interval) + 1) * interval;
427
 
 
428
 
   return (((pt1 >= min) && (pt1 < max)) || ((pt2 >= min) && (pt2 < max)));
429
 
}
430
 
 
431
 
 
432
 
/*
433
 
 ***************************************************************************
434
 
 * Print report header
435
 
 ***************************************************************************
436
 
 */
437
 
void print_report_hdr(void)
 
234
void set_loc_time(short curr)
438
235
{
439
236
   struct tm *ltm;
440
237
 
441
 
   if (PRINT_ORG_TIME(flags)) {
442
 
      /* Get local time */
443
 
      get_localtime(&loc_time);
 
238
   /* NOTE: loc_time structure must have been init'ed before! */
444
239
 
445
 
      loc_time.tm_mday = file_hdr.sa_day;
446
 
      loc_time.tm_mon  = file_hdr.sa_month;
447
 
      loc_time.tm_year = file_hdr.sa_year;
448
 
      /*
449
 
       * Call mktime() to set DST (Daylight Saving Time) flag.
450
 
       * Has anyone a better way to do it?
451
 
       */
452
 
      loc_time.tm_hour = loc_time.tm_min = loc_time.tm_sec = 0;
453
 
      mktime(&loc_time);
 
240
   /* Check if option -t was specified on the command line */
 
241
   if (PRINT_TRUE_TIME(flags)) {
 
242
      /* -t */
 
243
      loc_time.tm_hour = file_stats[curr].hour;
 
244
      loc_time.tm_min  = file_stats[curr].minute;
 
245
      loc_time.tm_sec  = file_stats[curr].second;
454
246
   }
455
247
   else {
456
 
      ltm = localtime(&file_hdr.sa_ust_time);
 
248
      ltm = localtime(&file_stats[curr].ust_time);
457
249
      loc_time = *ltm;
458
250
   }
459
 
 
460
 
   if (!USE_H_OPTION(flags) && !USE_DB_OPTION(flags))
461
 
      print_gal_header(&loc_time, file_hdr.sa_sysname, file_hdr.sa_release, file_hdr.sa_nodename);
462
 
}
463
 
 
464
 
 
465
 
/*
466
 
 ***************************************************************************
467
 
 * Check time and get interval value
468
 
 ***************************************************************************
469
 
 */
470
 
int prep_time(int use_tm_start, short curr, unsigned long *itv, unsigned long *g_itv)
471
 
{
472
 
   if (use_tm_start && (datecmp(&loc_time, &tm_start) < 0))
473
 
      return 1;
474
 
 
475
 
   /* Interval value in jiffies */
476
 
   *g_itv = file_stats[curr].uptime - file_stats[!curr].uptime;
477
 
   if (!(*g_itv))       /* Paranoia checking */
478
 
      *g_itv = 1;
479
 
 
480
 
   if (file_hdr.sa_proc){
481
 
      *itv = file_stats[curr].uptime0 - file_stats[!curr].uptime0;
482
 
      if (!(*itv))
483
 
         *itv = 1;
484
 
   }
485
 
   else
486
 
      *itv = *g_itv;
487
 
 
488
 
   return 0;
489
251
}
490
252
 
491
253
 
494
256
 * Set timestamp string
495
257
 ***************************************************************************
496
258
*/
497
 
void init_timestamp(short curr, char *cur_time, int len)
 
259
void set_timestamp(short curr, char *cur_time, int len)
498
260
{
499
 
   struct tm *ltm;
500
 
 
501
 
   /* NOTE: loc_time structure must have been init'ed before! */
502
 
   if (!USE_H_OPTION(flags) && !USE_DB_OPTION(flags)) {
503
 
 
504
 
      /* Check if option -t was specified on the command line */
505
 
      if (PRINT_ORG_TIME(flags)) {
506
 
         /* -t */
507
 
         loc_time.tm_hour = file_stats[curr].hour;
508
 
         loc_time.tm_min  = file_stats[curr].minute;
509
 
         loc_time.tm_sec  = file_stats[curr].second;
510
 
      }
511
 
      else {
512
 
         ltm = localtime(&file_stats[curr].ust_time);
513
 
         loc_time = *ltm;
514
 
      }
515
 
   }
516
 
   else {
517
 
      /* Option '-h' or '-H' used */
518
 
      if (PRINT_ORG_TIME(flags) && USE_DB_OPTION(flags))
519
 
         /* -H -t */
520
 
         ltm = localtime(&file_stats[curr].ust_time);
521
 
      else
522
 
         /* '-h' or '-h -t' or '-H' */
523
 
         ltm = gmtime(&file_stats[curr].ust_time);
524
 
 
525
 
      loc_time = *ltm;
526
 
      /*
527
 
       * NB: Option -t is ignored when option -h is used, since option -h
528
 
       * displays its timestamp as a long integer. This is type 'time_t',
529
 
       * which is the number of seconds since 1970 _always_ expressed in UTC.
530
 
       */
531
 
   }
532
 
        
533
 
   if (!cur_time)
534
 
      /* Stop if cur_time is NULL */
535
 
      return;
 
261
   set_loc_time(curr);
536
262
 
537
263
   /* Set cur_time date value */
538
 
   if (USE_DB_OPTION(flags)) {
539
 
      if (PRINT_ORG_TIME(flags))
540
 
         strftime(cur_time, len, "%Y-%m-%d %H:%M:%S", &loc_time);
541
 
      else
542
 
         strftime(cur_time, len, "%Y-%m-%d %H:%M:%S UTC", &loc_time);
543
 
   }
544
 
   else if (!USE_H_OPTION(flags))
545
 
      strftime(cur_time, len, "%X", &loc_time);
546
 
}
547
 
 
548
 
 
549
 
/*
550
 
 ***************************************************************************
551
 
 * Network interfaces may now be registered (and unregistered) dynamically.
552
 
 * This is what we try to guess here.
553
 
 ***************************************************************************
554
 
 */
555
 
unsigned int check_iface_reg(struct stats_net_dev *st_net_dev[], short curr, short ref,
556
 
                             unsigned int pos)
557
 
{
558
 
   struct stats_net_dev *st_net_dev_i, *st_net_dev_j;
559
 
   unsigned int index = 0;
560
 
 
561
 
   st_net_dev_i = st_net_dev[curr] + pos;
562
 
 
563
 
   while (index < file_hdr.sa_iface) {
564
 
      st_net_dev_j = st_net_dev[ref] + index;
565
 
      if (!strcmp(st_net_dev_i->interface, st_net_dev_j->interface)) {
566
 
         /*
567
 
          * Network interface found.
568
 
          * If a counter has decreased, then we may assume that the
569
 
          * corresponding interface was unregistered, then registered again.
570
 
          */
571
 
         if ((st_net_dev_i->rx_packets < st_net_dev_j->rx_packets) ||
572
 
             (st_net_dev_i->tx_packets < st_net_dev_j->tx_packets) ||
573
 
             (st_net_dev_i->rx_bytes < st_net_dev_j->rx_bytes) ||
574
 
             (st_net_dev_i->tx_bytes < st_net_dev_j->tx_bytes) ||
575
 
             (st_net_dev_i->rx_compressed < st_net_dev_j->rx_compressed) ||
576
 
             (st_net_dev_i->tx_compressed < st_net_dev_j->tx_compressed) ||
577
 
             (st_net_dev_i->multicast < st_net_dev_j->multicast) ||
578
 
             (st_net_dev_i->rx_errors < st_net_dev_j->rx_errors) ||
579
 
             (st_net_dev_i->tx_errors < st_net_dev_j->tx_errors) ||
580
 
             (st_net_dev_i->collisions < st_net_dev_j->collisions) ||
581
 
             (st_net_dev_i->rx_dropped < st_net_dev_j->rx_dropped) ||
582
 
             (st_net_dev_i->tx_dropped < st_net_dev_j->tx_dropped) ||
583
 
             (st_net_dev_i->tx_carrier_errors < st_net_dev_j->tx_carrier_errors) ||
584
 
             (st_net_dev_i->rx_frame_errors < st_net_dev_j->rx_frame_errors) ||
585
 
             (st_net_dev_i->rx_fifo_errors < st_net_dev_j->rx_fifo_errors) ||
586
 
             (st_net_dev_i->tx_fifo_errors < st_net_dev_j->tx_fifo_errors)) {
587
 
 
588
 
            /*
589
 
             * Special processing for rx_bytes (_packets) and tx_bytes (_packets)
590
 
             * counters: If the number of bytes (packets) has decreased, whereas
591
 
             * the number of packets (bytes) has increased, then assume that the
592
 
             * relevant counter has met an overflow condition, and that the
593
 
             * interface was not unregistered, which is all the more plausible
594
 
             * that the previous value for the counter was > ULONG_MAX/2.
595
 
             * NB: the average value displayed will be wrong in this case...
596
 
             *
597
 
             * If such an overflow is detected, just set the flag. There is no
598
 
             * need to handle this in a special way: the difference is still
599
 
             * properly calculated if the result is of the same type (i.e.
600
 
             * unsigned long) as the two values.
601
 
             */
602
 
            int ovfw = FALSE;
603
 
        
604
 
            if ((st_net_dev_i->rx_bytes < st_net_dev_j->rx_bytes) &&
605
 
                (st_net_dev_i->rx_packets > st_net_dev_j->rx_packets) &&
606
 
                (st_net_dev_j->rx_bytes > (~0UL >> 1)))
607
 
               ovfw = TRUE;
608
 
            if ((st_net_dev_i->tx_bytes < st_net_dev_j->tx_bytes) &&
609
 
                (st_net_dev_i->tx_packets > st_net_dev_j->tx_packets) &&
610
 
                (st_net_dev_j->tx_bytes > (~0UL >> 1)))
611
 
               ovfw = TRUE;
612
 
            if ((st_net_dev_i->rx_packets < st_net_dev_j->rx_packets) &&
613
 
                (st_net_dev_i->rx_bytes > st_net_dev_j->rx_bytes) &&
614
 
                (st_net_dev_j->rx_packets > (~0UL >> 1)))
615
 
               ovfw = TRUE;
616
 
            if ((st_net_dev_i->tx_packets < st_net_dev_j->tx_packets) &&
617
 
                (st_net_dev_i->tx_bytes > st_net_dev_j->tx_bytes) &&
618
 
                (st_net_dev_j->tx_packets > (~0UL >> 1)))
619
 
               ovfw = TRUE;
620
 
 
621
 
            if (!ovfw) {
622
 
               /* OK: assume here that the device was actually unregistered */
623
 
               memset(st_net_dev_j, 0, STATS_NET_DEV_SIZE);
624
 
               strcpy(st_net_dev_j->interface, st_net_dev_i->interface);
625
 
            }
626
 
         }
627
 
         return index;
628
 
      }
629
 
      index++;
630
 
   }
631
 
 
632
 
   /* Network interface not found: Look for the first free structure */
633
 
   for (index = 0; index < file_hdr.sa_iface; index++) {
634
 
      st_net_dev_j = st_net_dev[ref] + index;
635
 
      if (!strcmp(st_net_dev_j->interface, "?")) {
636
 
         memset(st_net_dev_j, 0, STATS_NET_DEV_SIZE);
637
 
         strcpy(st_net_dev_j->interface, st_net_dev_i->interface);
638
 
         break;
639
 
      }
640
 
   }
641
 
   if (index >= file_hdr.sa_iface)
642
 
      /* No free structure: Default is structure of same rank */
643
 
      index = pos;
644
 
 
645
 
   st_net_dev_j = st_net_dev[ref] + index;
646
 
   /* Since the name is not the same, reset all the structure */
647
 
   memset(st_net_dev_j, 0, STATS_NET_DEV_SIZE);
648
 
   strcpy(st_net_dev_j->interface, st_net_dev_i->interface);
649
 
 
650
 
   return  index;
651
 
}
652
 
 
653
 
 
654
 
/*
655
 
 ***************************************************************************
656
 
 * Disks in /proc/stat may be registered dynamically.
657
 
 * This is what we try to guess here.
658
 
 ***************************************************************************
659
 
 */
660
 
int check_disk_reg(struct disk_stats *st_disk[], short curr, short ref, int pos)
661
 
{
662
 
   struct disk_stats *st_disk_i, *st_disk_j;
663
 
   int index = 0;
664
 
 
665
 
   st_disk_i = st_disk[curr] + pos;
666
 
 
667
 
   while (index < file_hdr.sa_nr_disk) {
668
 
      st_disk_j = st_disk[ref] + index;
669
 
      if ((st_disk_i->major == st_disk_j->major) &&
670
 
          (st_disk_i->index == st_disk_j->index)) {
671
 
         /*
672
 
          * Disk found.
673
 
          * If a counter has decreased, then we may assume that the
674
 
          * corresponding device was unregistered, then registered again.
675
 
          * NB: AFAIK, such a device cannot be unregistered with current
676
 
          * kernels.
677
 
          */
678
 
         if ((st_disk_i->nr_ios < st_disk_j->nr_ios) ||
679
 
             (st_disk_i->rd_sect < st_disk_j->rd_sect) ||
680
 
             (st_disk_i->wr_sect < st_disk_j->wr_sect)) {
681
 
 
682
 
            memset(st_disk_j, 0, DISK_STATS_SIZE);
683
 
            st_disk_j->major = st_disk_i->major;
684
 
            st_disk_j->index = st_disk_i->index;
685
 
         }
686
 
         return index;
687
 
      }
688
 
      index++;
689
 
   }
690
 
 
691
 
   /* Disk not found: Look for the first free structure */
692
 
   for (index = 0; index < file_hdr.sa_nr_disk; index++) {
693
 
      st_disk_j = st_disk[ref] + index;
694
 
      if (!(st_disk_j->major + st_disk_j->index)) {
695
 
         memset(st_disk_j, 0, DISK_STATS_SIZE);
696
 
         st_disk_j->major = st_disk_i->major;
697
 
         st_disk_j->index = st_disk_i->index;
698
 
         break;
699
 
      }
700
 
   }
701
 
   if (index >= file_hdr.sa_nr_disk)
702
 
      /* No free structure found: Default is structure of same rank */
703
 
      index = pos;
704
 
 
705
 
   st_disk_j = st_disk[ref] + index;
706
 
   /* Since the device is not the same, reset all the structure */
707
 
   memset(st_disk_j, 0, DISK_STATS_SIZE);
708
 
   st_disk_j->major = st_disk_i->major;
709
 
   st_disk_j->index = st_disk_i->index;
710
 
 
711
 
   return index;
712
 
}
713
 
 
714
 
 
715
 
/*
716
 
 ***************************************************************************
717
 
 * Since ticks may vary slightly from cpu to cpu, we'll want
718
 
 * to recalculate itv based on this cpu's tick count, rather
719
 
 * than that reported by the "cpu" line.  Otherwise we
720
 
 * occasionally end up with slightly skewed figures, with
721
 
 * the skew being greater as the time interval grows shorter.
722
 
 ***************************************************************************
723
 
 */
724
 
unsigned long get_per_cpu_interval(struct stats_one_cpu *st_cpu_i,
725
 
                                   struct stats_one_cpu *st_cpu_j)
726
 
{
727
 
 
728
 
   return ((st_cpu_i->per_cpu_user + st_cpu_i->per_cpu_nice +
729
 
            st_cpu_i->per_cpu_system + st_cpu_i->per_cpu_iowait +
730
 
            st_cpu_i->per_cpu_idle) -
731
 
           (st_cpu_j->per_cpu_user + st_cpu_j->per_cpu_nice +
732
 
            st_cpu_j->per_cpu_system + st_cpu_j->per_cpu_iowait +
733
 
            st_cpu_j->per_cpu_idle));
 
264
   strftime(cur_time, len, "%X", &loc_time);
734
265
}
735
266
 
736
267
 
740
271
 ***************************************************************************
741
272
 */
742
273
void write_stats_core(short prev, short curr, short dis, char *prev_string,
743
 
                      char *curr_string, unsigned int act, unsigned long itv,
744
 
                      unsigned long g_itv, int disp_avg, int want_since_boot)
 
274
                      char *curr_string, unsigned int act,
 
275
                      unsigned long long itv, unsigned long long g_itv,
 
276
                      int disp_avg, int want_since_boot)
745
277
{
746
278
   int i, j = 0, k;
747
 
   struct stats_irq_cpu *p, *q, *p0, *q0;
748
 
   struct stats_serial *st_serial_i, *st_serial_j;
749
 
   struct stats_net_dev *st_net_dev_i, *st_net_dev_j;
750
 
   struct stats_one_cpu *st_cpu_i, *st_cpu_j;
751
 
   struct disk_stats *st_disk_i, *st_disk_j;
752
 
   char stemp[16];
 
279
   struct file_stats
 
280
      *fsi = &file_stats[curr],
 
281
      *fsj = &file_stats[prev];
753
282
 
754
283
   /*
755
284
    * Under very special circumstances, STDOUT may become unavailable,
763
292
   /* Print number of processes created per second */
764
293
   if (GET_PROC(act)) {
765
294
      if (dis)
766
 
         printf(_("\n%-11s    proc/s\n"), prev_string);
 
295
         printf("\n%-11s    proc/s\n", prev_string);
767
296
 
768
297
      printf("%-11s %9.2f\n", curr_string,
769
 
             S_VALUE(file_stats[prev].processes, file_stats[curr].processes, itv));
 
298
             S_VALUE(fsj->processes, fsi->processes, itv));
770
299
   }
771
300
 
772
301
   /* Print number of context switches per second */
773
302
   if (GET_CTXSW(act)) {
774
303
      if (dis)
775
 
         printf(_("\n%-11s   cswch/s\n"), prev_string);
 
304
         printf("\n%-11s   cswch/s\n", prev_string);
776
305
 
777
306
      printf("%-11s %9.2f\n", curr_string,
778
 
             S_VALUE(file_stats[prev].context_swtch, file_stats[curr].context_swtch, itv));
 
307
             ll_s_value(fsj->context_swtch, fsi->context_swtch, itv));
779
308
   }
780
309
 
781
310
   /* Print CPU usage */
782
311
   if (GET_CPU(act)) {
783
312
      if (dis)
784
 
         printf(_("\n%-11s       CPU     %%user     %%nice   %%system   %%iowait     %%idle\n"),
 
313
         printf("\n%-11s       CPU     %%user     %%nice   %%system   "
 
314
                "%%iowait     %%idle\n",
785
315
                prev_string);
786
316
 
787
317
      if (!WANT_PER_PROC(flags) ||
788
318
          (WANT_PER_PROC(flags) && WANT_ALL_PROC(flags))) {
789
319
 
790
 
         printf(_("%-11s       all"), curr_string);
 
320
         printf("%-11s       all", curr_string);
791
321
 
792
322
         printf("    %6.2f    %6.2f    %6.2f    %6.2f",
793
 
                SP_VALUE(file_stats[prev].cpu_user,   file_stats[curr].cpu_user,   g_itv),
794
 
                SP_VALUE(file_stats[prev].cpu_nice,   file_stats[curr].cpu_nice,   g_itv),
795
 
                SP_VALUE(file_stats[prev].cpu_system, file_stats[curr].cpu_system, g_itv),
796
 
                SP_VALUE(file_stats[prev].cpu_iowait, file_stats[curr].cpu_iowait, g_itv));
 
323
                ll_sp_value(fsj->cpu_user, fsi->cpu_user, g_itv),
 
324
                ll_sp_value(fsj->cpu_nice, fsi->cpu_nice, g_itv),
 
325
                ll_sp_value(fsj->cpu_system, fsi->cpu_system, g_itv),
 
326
                ll_sp_value(fsj->cpu_iowait, fsi->cpu_iowait, g_itv));
797
327
 
798
 
         if (file_stats[curr].cpu_idle < file_stats[prev].cpu_idle)
799
 
            printf("      %.2f\n", 0.0);  /* Handle buggy RTC (or kernels?) */
800
 
         else
801
 
            printf("    %6.2f\n",
802
 
                   SP_VALUE(file_stats[prev].cpu_idle, file_stats[curr].cpu_idle, g_itv));
 
328
         printf("    %6.2f\n",
 
329
                fsi->cpu_idle < fsj->cpu_idle ? /* Handle buggy kernels */
 
330
                0.0 : ll_sp_value(fsj->cpu_idle, fsi->cpu_idle, g_itv));
803
331
      }
804
332
 
805
333
      if (WANT_PER_PROC(flags) && file_hdr.sa_proc) {
806
 
         unsigned long pc_itv;
 
334
         unsigned long long pc_itv;
 
335
         struct stats_one_cpu
 
336
            *sci = st_cpu[curr],
 
337
            *scj = st_cpu[prev];
807
338
        
808
 
         for (i = 0; i <= file_hdr.sa_proc; i++) {
 
339
         for (i = 0; i <= file_hdr.sa_proc; i++, sci++, scj++) {
809
340
            if (cpu_bitmap[i >> 3] & (1 << (i & 0x07))) {
810
341
 
811
342
               printf("%-11s       %3d", curr_string, i);
812
 
               st_cpu_i = st_cpu[curr] + i;
813
 
               st_cpu_j = st_cpu[prev] + i;
814
343
        
815
344
               /* Recalculate itv for current proc */
816
 
               pc_itv = get_per_cpu_interval(st_cpu_i, st_cpu_j);
 
345
               pc_itv = get_per_cpu_interval(sci, scj);
817
346
        
818
347
               printf("    %6.2f    %6.2f    %6.2f    %6.2f",
819
 
                      SP_VALUE(st_cpu_j->per_cpu_user,   st_cpu_i->per_cpu_user,   pc_itv),
820
 
                      SP_VALUE(st_cpu_j->per_cpu_nice,   st_cpu_i->per_cpu_nice,   pc_itv),
821
 
                      SP_VALUE(st_cpu_j->per_cpu_system, st_cpu_i->per_cpu_system, pc_itv),
822
 
                      SP_VALUE(st_cpu_j->per_cpu_iowait, st_cpu_i->per_cpu_iowait, pc_itv));
 
348
                      ll_sp_value(scj->per_cpu_user, sci->per_cpu_user, pc_itv),
 
349
                      ll_sp_value(scj->per_cpu_nice, sci->per_cpu_nice, pc_itv),
 
350
                      ll_sp_value(scj->per_cpu_system, sci->per_cpu_system, pc_itv),
 
351
                      ll_sp_value(scj->per_cpu_iowait, sci->per_cpu_iowait, pc_itv));
823
352
 
824
 
               if (st_cpu_i->per_cpu_idle < st_cpu_j->per_cpu_idle)
825
 
                  printf("      %.2f\n", 0.0);
826
 
               else
827
 
                  printf("    %6.2f\n",
828
 
                         SP_VALUE(st_cpu_j->per_cpu_idle, st_cpu_i->per_cpu_idle, pc_itv));
 
353
               printf("    %6.2f\n",
 
354
                      sci->per_cpu_idle < scj->per_cpu_idle ?
 
355
                      0.0 : ll_sp_value(scj->per_cpu_idle, sci->per_cpu_idle, pc_itv));
829
356
            }
830
357
         }
831
358
      }
836
363
        (WANT_PER_PROC(flags) && WANT_ALL_PROC(flags)))) {
837
364
 
838
365
         if (dis)
839
 
            printf(_("\n%-11s      INTR    intr/s\n"), prev_string);
 
366
            printf("\n%-11s      INTR    intr/s\n", prev_string);
840
367
 
841
368
         /* Print number of interrupts per second */
842
 
         printf(_("%-11s       sum"), curr_string);
 
369
         printf("%-11s       sum", curr_string);
843
370
 
844
371
         printf(" %9.2f\n",
845
 
                S_VALUE(file_stats[prev].irq_sum, file_stats[curr].irq_sum, itv));
 
372
                ll_s_value(fsj->irq_sum, fsi->irq_sum, itv));
846
373
   }
847
374
 
848
375
   if (GET_ONE_IRQ(act)) {
849
376
      if (dis)
850
 
         printf(_("\n%-11s      INTR    intr/s\n"), prev_string);
 
377
         printf("\n%-11s      INTR    intr/s\n", prev_string);
851
378
 
852
379
      /* Print number of interrupts per second */
853
380
      for (i = 0; i < NR_IRQS; i++) {
864
391
   /* Print paging statistics */
865
392
   if (GET_PAGE(act)) {
866
393
      if (dis)
867
 
         printf(_("\n%-11s  pgpgin/s pgpgout/s   fault/s  majflt/s\n"),
 
394
         printf("\n%-11s  pgpgin/s pgpgout/s   fault/s  majflt/s\n",
868
395
                prev_string);
869
396
 
870
397
      printf("%-11s %9.2f %9.2f %9.2f %9.2f\n", curr_string,
871
 
             S_VALUE(file_stats[prev].pgpgin,     file_stats[curr].pgpgin,  itv),
872
 
             S_VALUE(file_stats[prev].pgpgout,    file_stats[curr].pgpgout, itv),
873
 
             S_VALUE(file_stats[prev].pgfault,    file_stats[curr].pgfault, itv),
874
 
             S_VALUE(file_stats[prev].pgmajfault, file_stats[curr].pgmajfault, itv));
 
398
             S_VALUE(fsj->pgpgin, fsi->pgpgin, itv),
 
399
             S_VALUE(fsj->pgpgout, fsi->pgpgout, itv),
 
400
             S_VALUE(fsj->pgfault, fsi->pgfault, itv),
 
401
             S_VALUE(fsj->pgmajfault, fsi->pgmajfault, itv));
875
402
   }
876
403
 
877
404
   /* Print number of swap pages brought in and out */
878
405
   if (GET_SWAP(act)) {
879
406
      if (dis)
880
 
         printf(_("\n%-11s  pswpin/s pswpout/s\n"), prev_string);
 
407
         printf("\n%-11s  pswpin/s pswpout/s\n", prev_string);
881
408
 
882
409
      printf("%-11s %9.2f %9.2f\n", curr_string,
883
 
             S_VALUE(file_stats[prev].pswpin,  file_stats[curr].pswpin,  itv),
884
 
             S_VALUE(file_stats[prev].pswpout, file_stats[curr].pswpout, itv));
 
410
             S_VALUE(fsj->pswpin, fsi->pswpin, itv),
 
411
             S_VALUE(fsj->pswpout, fsi->pswpout, itv));
885
412
   }
886
413
 
887
414
   /* Print I/O stats (no distinction made between disks) */
888
415
   if (GET_IO(act)) {
889
416
      if (dis)
890
 
         printf(_("\n%-11s       tps      rtps      wtps   bread/s   bwrtn/s\n"),
 
417
         printf("\n%-11s       tps      rtps      wtps   bread/s   bwrtn/s\n",
891
418
                prev_string);
892
419
 
893
420
      printf("%-11s %9.2f %9.2f %9.2f %9.2f %9.2f\n", curr_string,
894
 
             S_VALUE(file_stats[prev].dk_drive,      file_stats[curr].dk_drive,      itv),
895
 
             S_VALUE(file_stats[prev].dk_drive_rio,  file_stats[curr].dk_drive_rio,  itv),
896
 
             S_VALUE(file_stats[prev].dk_drive_wio,  file_stats[curr].dk_drive_wio,  itv),
897
 
             S_VALUE(file_stats[prev].dk_drive_rblk, file_stats[curr].dk_drive_rblk, itv),
898
 
             S_VALUE(file_stats[prev].dk_drive_wblk, file_stats[curr].dk_drive_wblk, itv));
 
421
             S_VALUE(fsj->dk_drive, fsi->dk_drive, itv),
 
422
             S_VALUE(fsj->dk_drive_rio, fsi->dk_drive_rio, itv),
 
423
             S_VALUE(fsj->dk_drive_wio, fsi->dk_drive_wio, itv),
 
424
             S_VALUE(fsj->dk_drive_rblk, fsi->dk_drive_rblk, itv),
 
425
             S_VALUE(fsj->dk_drive_wblk, fsi->dk_drive_wblk, itv));
899
426
   }
900
427
 
901
428
   /* Print memory stats */
902
429
   if (GET_MEMORY(act)) {
903
430
      if (dis)
904
 
         printf(_("\n%-11s   frmpg/s   bufpg/s   campg/s\n"), prev_string);
 
431
         printf("\n%-11s   frmpg/s   bufpg/s   campg/s\n", prev_string);
905
432
 
906
433
      printf("%-11s %9.2f %9.2f %9.2f\n", curr_string,
907
 
             ((double) PG(file_stats[curr].frmkb) - (double) PG(file_stats[prev].frmkb))
908
 
             / itv * HZ,
909
 
             ((double) PG(file_stats[curr].bufkb) - (double) PG(file_stats[prev].bufkb))
910
 
             / itv * HZ,
911
 
             ((double) PG(file_stats[curr].camkb) - (double) PG(file_stats[prev].camkb))
912
 
             / itv * HZ);
 
434
             S_VALUE((double) PG(fsj->frmkb), (double) PG(fsi->frmkb), itv),
 
435
             S_VALUE((double) PG(fsj->bufkb), (double) PG(fsi->bufkb), itv),
 
436
             S_VALUE((double) PG(fsj->camkb), (double) PG(fsi->camkb), itv));
913
437
   }
914
438
 
915
439
   /* Print per-process statistics */
916
440
   if (GET_PID(act)) {
917
441
      if (dis) {
918
 
         printf(_("\n%-11s       PID  minflt/s  majflt/s     %%user   %%system   nswap/s"),
 
442
         printf("\n%-11s       PID  minflt/s  majflt/s     %%user   %%system   nswap/s",
919
443
                prev_string);
920
444
         if (!disp_avg)
921
 
            printf(_("   CPU\n"));
 
445
            printf("   CPU\n");
922
446
         else
923
447
            printf("\n");
924
448
      }
925
449
 
926
450
      for (i = 0; i < pid_nr; i++) {
927
 
         if (!pid_stats[curr][i]->pid || !(pid_stats[curr][i]->flag & 0x01))
 
451
         if (!pid_stats[curr][i]->pid || !(pid_stats[curr][i]->flag & X_PID_SET))
928
452
            continue;
929
453
 
930
454
         printf("%-11s %9ld", curr_string, pid_stats[curr][i]->pid);
932
456
         printf(" %9.2f %9.2f    %6.2f    %6.2f %9.2f",
933
457
                S_VALUE(pid_stats[prev][i]->minflt, pid_stats[curr][i]->minflt, itv),
934
458
                S_VALUE(pid_stats[prev][i]->majflt, pid_stats[curr][i]->majflt, itv),
935
 
                SP_VALUE(pid_stats[prev][i]->utime,  pid_stats[curr][i]->utime,  itv),
936
 
                SP_VALUE(pid_stats[prev][i]->stime,  pid_stats[curr][i]->stime,  itv),
937
 
                ((double) ((long) pid_stats[curr][i]->nswap - (long) pid_stats[prev][i]->nswap))
938
 
                / itv * HZ);
 
459
                SP_VALUE(pid_stats[prev][i]->utime, pid_stats[curr][i]->utime, itv),
 
460
                SP_VALUE(pid_stats[prev][i]->stime, pid_stats[curr][i]->stime, itv),
 
461
                S_VALUE((long) pid_stats[prev][i]->nswap,
 
462
                        (long) pid_stats[curr][i]->nswap, itv));
 
463
 
939
464
         if (!disp_avg)
940
465
            printf("   %3d\n", pid_stats[curr][i]->processor);
941
466
         else
946
471
   /* Print statistics about children of a given process */
947
472
   if (GET_CPID(act)) {
948
473
      if (dis)
949
 
         printf(_("\n%-11s      PPID cminflt/s cmajflt/s    %%cuser  %%csystem  cnswap/s\n"),
 
474
         printf("\n%-11s      PPID cminflt/s cmajflt/s    %%cuser  %%csystem  cnswap/s\n",
950
475
                prev_string);
951
476
 
952
477
      for (i = 0; i < pid_nr; i++) {
953
 
         if (!pid_stats[curr][i]->pid || !(pid_stats[curr][i]->flag & 0x02))
 
478
         if (!pid_stats[curr][i]->pid || !(pid_stats[curr][i]->flag & X_PPID_SET))
954
479
            continue;
955
480
         printf("%-11s %9ld", curr_string, pid_stats[curr][i]->pid);
956
481
 
959
484
                S_VALUE(pid_stats[prev][i]->cmajflt, pid_stats[curr][i]->cmajflt, itv),
960
485
                SP_VALUE(pid_stats[prev][i]->cutime,  pid_stats[curr][i]->cutime,  itv),
961
486
                SP_VALUE(pid_stats[prev][i]->cstime,  pid_stats[curr][i]->cstime,  itv),
962
 
                ((double) ((long) pid_stats[curr][i]->cnswap - (long) pid_stats[prev][i]->cnswap))
963
 
                / itv * HZ);
 
487
                S_VALUE((long) pid_stats[prev][i]->cnswap,
 
488
                        (long) pid_stats[curr][i]->cnswap, itv));
964
489
      }
965
490
   }
966
491
 
967
492
   /* Print TTY statistics (serial lines) */
968
493
   if (GET_SERIAL(act)) {
 
494
      struct stats_serial
 
495
         *ssi = st_serial[curr],
 
496
         *ssj = st_serial[prev];
 
497
 
969
498
      if (dis)
970
 
         printf(_("\n%-11s       TTY   rcvin/s   xmtin/s\n"), prev_string);
971
 
 
972
 
      for (i = 0; i < file_hdr.sa_serial; i++) {
973
 
 
974
 
         st_serial_i = st_serial[curr] + i;
975
 
         st_serial_j = st_serial[prev] + i;
976
 
         if (st_serial_i->line == ~0)
 
499
         printf("\n%-11s       TTY   rcvin/s   xmtin/s framerr/s prtyerr/s     "
 
500
                "brk/s   ovrun/s\n", prev_string);
 
501
 
 
502
      for (i = 0; i < file_hdr.sa_serial; i++, ssi++, ssj++) {
 
503
 
 
504
         if (ssi->line == ~0)
977
505
            continue;
978
506
        
979
 
         printf("%-11s       %3d", curr_string, st_serial_i->line);
 
507
         printf("%-11s       %3d", curr_string, ssi->line);
980
508
 
981
 
         if ((st_serial_i->line == st_serial_j->line) || want_since_boot) {
982
 
            printf(" %9.2f %9.2f\n",
983
 
                   S_VALUE(st_serial_j->rx, st_serial_i->rx, itv),
984
 
                   S_VALUE(st_serial_j->tx, st_serial_i->tx, itv));
 
509
         if ((ssi->line == ssj->line) || want_since_boot) {
 
510
            printf(" %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f\n",
 
511
                   S_VALUE(ssj->rx, ssi->rx, itv),
 
512
                   S_VALUE(ssj->tx, ssi->tx, itv),
 
513
                   S_VALUE(ssj->frame, ssi->frame, itv),
 
514
                   S_VALUE(ssj->parity, ssi->parity, itv),
 
515
                   S_VALUE(ssj->brk, ssi->brk, itv),
 
516
                   S_VALUE(ssj->overrun, ssi->overrun, itv));
985
517
         }
986
518
         else
987
 
            printf("       N/A       N/A\n");
 
519
            printf("       N/A       N/A       N/A       N/A       N/A       N/A\n");
988
520
      }
989
521
   }
990
522
 
991
523
   if (GET_IRQ(act) && WANT_PER_PROC(flags) && file_hdr.sa_irqcpu) {
992
524
      int offset;
 
525
      struct stats_irq_cpu *p, *q, *p0, *q0;
993
526
 
994
527
      j = 0;
995
528
      /* Check if number of interrupts has changed */
1008
541
 
1009
542
      if (dis || (j < 0)) {
1010
543
         /* Print header */
1011
 
         printf(_("\n%-11s  CPU"), prev_string);
 
544
         printf("\n%-11s  CPU", prev_string);
1012
545
         for (j = 0; j < file_hdr.sa_irqcpu; j++) {
1013
546
            p0 = st_irq_cpu[curr] + j;
1014
547
            if (p0->irq != ~0)  /* Nb of irq per proc may have varied... */
1015
 
               printf(_("  i%03d/s"), p0->irq);
 
548
               printf("  i%03d/s", p0->irq);
1016
549
         }
1017
550
         printf("\n");
1018
551
      }
1065
598
 
1066
599
   /* Print network interface statistics */
1067
600
   if (GET_NET_DEV(act)) {
 
601
      struct stats_net_dev
 
602
         *sndi = st_net_dev[curr],
 
603
         *sndj;
 
604
 
1068
605
      if (dis)
1069
 
         printf(_("\n%-11s     IFACE   rxpck/s   txpck/s   rxbyt/s   txbyt/s   rxcmp/s   txcmp/s  rxmcst/s\n"),
 
606
         printf("\n%-11s     IFACE   rxpck/s   txpck/s   rxbyt/s   txbyt/s   "
 
607
                "rxcmp/s   txcmp/s  rxmcst/s\n",
1070
608
                prev_string);
1071
609
 
1072
 
      for (i = 0; i < file_hdr.sa_iface; i++) {
 
610
      for (i = 0; i < file_hdr.sa_iface; i++, sndi++) {
1073
611
 
1074
 
         st_net_dev_i = st_net_dev[curr] + i;
1075
 
         if (!strcmp(st_net_dev_i->interface, "?"))
 
612
         if (!strcmp(sndi->interface, "?"))
1076
613
            continue;
1077
 
         j = check_iface_reg(st_net_dev, curr, prev, i);
1078
 
         st_net_dev_j = st_net_dev[prev] + j;
 
614
         j = check_iface_reg(&file_hdr, st_net_dev, curr, prev, i);
 
615
         sndj = st_net_dev[prev] + j;
1079
616
        
1080
 
         printf("%-11s %9s", curr_string, st_net_dev_i->interface);
 
617
         printf("%-11s %9s", curr_string, sndi->interface);
1081
618
        
1082
619
         printf(" %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f\n",
1083
 
                S_VALUE(st_net_dev_j->rx_packets,    st_net_dev_i->rx_packets,    itv),
1084
 
                S_VALUE(st_net_dev_j->tx_packets,    st_net_dev_i->tx_packets,    itv),
1085
 
                S_VALUE(st_net_dev_j->rx_bytes,      st_net_dev_i->rx_bytes,      itv),
1086
 
                S_VALUE(st_net_dev_j->tx_bytes,      st_net_dev_i->tx_bytes,      itv),
1087
 
                S_VALUE(st_net_dev_j->rx_compressed, st_net_dev_i->rx_compressed, itv),
1088
 
                S_VALUE(st_net_dev_j->tx_compressed, st_net_dev_i->tx_compressed, itv),
1089
 
                S_VALUE(st_net_dev_j->multicast,     st_net_dev_i->multicast,     itv));
 
620
                S_VALUE(sndj->rx_packets, sndi->rx_packets, itv),
 
621
                S_VALUE(sndj->tx_packets, sndi->tx_packets, itv),
 
622
                S_VALUE(sndj->rx_bytes, sndi->rx_bytes, itv),
 
623
                S_VALUE(sndj->tx_bytes, sndi->tx_bytes, itv),
 
624
                S_VALUE(sndj->rx_compressed, sndi->rx_compressed, itv),
 
625
                S_VALUE(sndj->tx_compressed, sndi->tx_compressed, itv),
 
626
                S_VALUE(sndj->multicast, sndi->multicast, itv));
1090
627
      }
1091
628
   }
1092
629
 
1093
630
   /* Print network interface statistics (errors) */
1094
631
   if (GET_NET_EDEV(act)) {
 
632
      struct stats_net_dev
 
633
         *sndi = st_net_dev[curr],
 
634
         *sndj;
 
635
 
1095
636
      if (dis)
1096
 
         printf(_("\n%-11s     IFACE   rxerr/s   txerr/s    coll/s  rxdrop/s  txdrop/s  txcarr/s  rxfram/s  rxfifo/s  txfifo/s\n"),
 
637
         printf("\n%-11s     IFACE   rxerr/s   txerr/s    coll/s  rxdrop/s  "
 
638
                "txdrop/s  txcarr/s  rxfram/s  rxfifo/s  txfifo/s\n",
1097
639
                prev_string);
1098
640
 
1099
 
      for (i = 0; i < file_hdr.sa_iface; i++) {
 
641
      for (i = 0; i < file_hdr.sa_iface; i++, sndi++) {
1100
642
 
1101
 
         st_net_dev_i = st_net_dev[curr] + i;
1102
 
         if (!strcmp(st_net_dev_i->interface, "?"))
 
643
         if (!strcmp(sndi->interface, "?"))
1103
644
            continue;
1104
 
         j = check_iface_reg(st_net_dev, curr, prev, i);
1105
 
         st_net_dev_j = st_net_dev[prev] + j;
 
645
         j = check_iface_reg(&file_hdr, st_net_dev, curr, prev, i);
 
646
         sndj = st_net_dev[prev] + j;
1106
647
        
1107
 
         printf("%-11s %9s", curr_string, st_net_dev_i->interface);
 
648
         printf("%-11s %9s", curr_string, sndi->interface);
1108
649
 
1109
650
         printf(" %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f\n",
1110
 
                S_VALUE(st_net_dev_j->rx_errors,         st_net_dev_i->rx_errors,         itv),
1111
 
                S_VALUE(st_net_dev_j->tx_errors,         st_net_dev_i->tx_errors,         itv),
1112
 
                S_VALUE(st_net_dev_j->collisions,        st_net_dev_i->collisions,        itv),
1113
 
                S_VALUE(st_net_dev_j->rx_dropped,        st_net_dev_i->rx_dropped,        itv),
1114
 
                S_VALUE(st_net_dev_j->tx_dropped,        st_net_dev_i->tx_dropped,        itv),
1115
 
                S_VALUE(st_net_dev_j->tx_carrier_errors, st_net_dev_i->tx_carrier_errors, itv),
1116
 
                S_VALUE(st_net_dev_j->rx_frame_errors,   st_net_dev_i->rx_frame_errors,   itv),
1117
 
                S_VALUE(st_net_dev_j->rx_fifo_errors,    st_net_dev_i->rx_fifo_errors,    itv),
1118
 
                S_VALUE(st_net_dev_j->tx_fifo_errors,    st_net_dev_i->tx_fifo_errors,    itv));
 
651
                S_VALUE(sndj->rx_errors, sndi->rx_errors, itv),
 
652
                S_VALUE(sndj->tx_errors, sndi->tx_errors, itv),
 
653
                S_VALUE(sndj->collisions, sndi->collisions, itv),
 
654
                S_VALUE(sndj->rx_dropped, sndi->rx_dropped, itv),
 
655
                S_VALUE(sndj->tx_dropped, sndi->tx_dropped, itv),
 
656
                S_VALUE(sndj->tx_carrier_errors, sndi->tx_carrier_errors, itv),
 
657
                S_VALUE(sndj->rx_frame_errors, sndi->rx_frame_errors, itv),
 
658
                S_VALUE(sndj->rx_fifo_errors, sndi->rx_fifo_errors, itv),
 
659
                S_VALUE(sndj->tx_fifo_errors, sndi->tx_fifo_errors, itv));
1119
660
      }
1120
661
   }
1121
662
 
1122
663
   /* Print disk statistics */
1123
664
   if (GET_DISK(act)) {
 
665
      double tput, util, await, svctm, arqsz;
 
666
      struct disk_stats
 
667
         *sdi = st_disk[curr],
 
668
         *sdj;
 
669
 
1124
670
      if (dis)
1125
 
         printf(_("\n%-11s       DEV       tps  rd_sec/s  wr_sec/s\n"), prev_string);
 
671
         printf("\n%-11s       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  "
 
672
                "avgqu-sz     await     svctm     %%util\n",
 
673
                prev_string);
1126
674
 
1127
 
      for (i = 0; i < file_hdr.sa_nr_disk; i++) {
1128
 
        
1129
 
         st_disk_i = st_disk[curr]  + i;
1130
 
        
1131
 
         if (!(st_disk_i->major + st_disk_i->index))
 
675
      for (i = 0; i < file_hdr.sa_nr_disk; i++, ++sdi) {
 
676
        
 
677
         if (!(sdi->major + sdi->minor))
1132
678
            continue;
1133
 
         j = check_disk_reg(st_disk, curr, prev, i);
1134
 
         st_disk_j = st_disk[prev] + j;
1135
 
 
1136
 
         sprintf(stemp, "dev%d-%d", st_disk_i->major, st_disk_i->index);
1137
 
         printf("%-11s %9.9s %9.2f %9.2f %9.2f\n", curr_string, stemp,
1138
 
                S_VALUE(st_disk_j->nr_ios,  st_disk_i->nr_ios,  itv),
1139
 
                S_VALUE(st_disk_j->rd_sect, st_disk_i->rd_sect, itv),
1140
 
                S_VALUE(st_disk_j->wr_sect, st_disk_i->wr_sect, itv));
 
679
 
 
680
         j = check_disk_reg(&file_hdr, st_disk, curr, prev, i);
 
681
         sdj = st_disk[prev] + j;
 
682
 
 
683
         tput = ((double) (sdi->nr_ios - sdj->nr_ios)) * HZ / itv;
 
684
         util = S_VALUE(sdj->tot_ticks, sdi->tot_ticks, itv);
 
685
         svctm = tput ? util / tput : 0.0;
 
686
         await = (sdi->nr_ios - sdj->nr_ios) ?
 
687
            ((sdi->rd_ticks - sdj->rd_ticks) + (sdi->wr_ticks - sdj->wr_ticks)) /
 
688
            ((double) (sdi->nr_ios - sdj->nr_ios)) : 0.0;
 
689
         arqsz  = (sdi->nr_ios - sdj->nr_ios) ?
 
690
            ((sdi->rd_sect - sdj->rd_sect) + (sdi->wr_sect - sdj->wr_sect)) /
 
691
            ((double) (sdi->nr_ios - sdj->nr_ios)) : 0.0;
 
692
 
 
693
         printf("%-11s %9s %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f\n",
 
694
                curr_string,
 
695
                /* Confusion possible here between index and minor numbers */
 
696
                get_devname(sdi->major, sdi->minor, USE_PRETTY_OPTION(flags)),
 
697
                S_VALUE(sdj->nr_ios, sdi->nr_ios,  itv),
 
698
                ll_s_value(sdj->rd_sect, sdi->rd_sect, itv),
 
699
                ll_s_value(sdj->wr_sect, sdi->wr_sect, itv),
 
700
                /* See iostat for explanations */
 
701
                arqsz,
 
702
                S_VALUE(sdj->rq_ticks, sdi->rq_ticks, itv) / 1000.0,
 
703
                await,
 
704
                svctm,
 
705
                util / 10.0);
1141
706
      }
1142
707
   }
 
708
 
 
709
   /* Print NFS client stats */
 
710
   if (GET_NET_NFS(act)) {
 
711
      if (dis)
 
712
         printf("\n%-11s    call/s retrans/s    read/s   write/s  access/s  getatt/s\n",
 
713
                prev_string);
 
714
 
 
715
      printf("%-11s %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f\n", curr_string,
 
716
             S_VALUE(fsj->nfs_rpccnt, fsi->nfs_rpccnt, itv),
 
717
             S_VALUE(fsj->nfs_rpcretrans, fsi->nfs_rpcretrans, itv),
 
718
             S_VALUE(fsj->nfs_readcnt, fsi->nfs_readcnt, itv),
 
719
             S_VALUE(fsj->nfs_writecnt, fsi->nfs_writecnt, itv),
 
720
             S_VALUE(fsj->nfs_accesscnt, fsi->nfs_accesscnt, itv),
 
721
             S_VALUE(fsj->nfs_getattcnt, fsi->nfs_getattcnt, itv));
 
722
   }
 
723
 
 
724
   /* Print NFS server stats */
 
725
   if (GET_NET_NFSD(act)) {
 
726
      if (dis)
 
727
         printf("\n%-11s   scall/s badcall/s  packet/s     udp/s     tcp/s     "
 
728
                "hit/s    miss/s   sread/s  swrite/s saccess/s sgetatt/s\n",
 
729
                prev_string);
 
730
 
 
731
      printf("%-11s %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f\n",
 
732
             curr_string,
 
733
             S_VALUE(fsj->nfsd_rpccnt, fsi->nfsd_rpccnt, itv),
 
734
             S_VALUE(fsj->nfsd_rpcbad, fsi->nfsd_rpcbad, itv),
 
735
             S_VALUE(fsj->nfsd_netcnt, fsi->nfsd_netcnt, itv),
 
736
             S_VALUE(fsj->nfsd_netudpcnt, fsi->nfsd_netudpcnt, itv),
 
737
             S_VALUE(fsj->nfsd_nettcpcnt, fsi->nfsd_nettcpcnt, itv),
 
738
             S_VALUE(fsj->nfsd_rchits, fsi->nfsd_rchits, itv),
 
739
             S_VALUE(fsj->nfsd_rcmisses, fsi->nfsd_rcmisses, itv),
 
740
             S_VALUE(fsj->nfsd_readcnt, fsi->nfsd_readcnt, itv),
 
741
             S_VALUE(fsj->nfsd_writecnt, fsi->nfsd_writecnt, itv),
 
742
             S_VALUE(fsj->nfsd_accesscnt, fsi->nfsd_accesscnt, itv),
 
743
             S_VALUE(fsj->nfsd_getattcnt, fsi->nfsd_getattcnt, itv));
 
744
   }
1143
745
}
1144
746
 
1145
747
 
1150
752
 */
1151
753
void write_stats_avg(int curr, short dis, unsigned int act, int read_from_file)
1152
754
{
1153
 
   unsigned long itv, g_itv;
 
755
   unsigned long long itv, g_itv;
1154
756
   char string[16];
 
757
   struct file_stats
 
758
     *fsi = &file_stats[curr];
1155
759
 
1156
760
   /* Interval value in jiffies */
1157
 
   g_itv = file_stats[curr].uptime - file_stats[2].uptime;
 
761
   g_itv = (file_stats[curr].uptime - file_stats[2].uptime) & 0xffffffff;
1158
762
   if (file_hdr.sa_proc)
1159
 
      itv = file_stats[curr].uptime0 - file_stats[2].uptime0;
 
763
      itv = (file_stats[curr].uptime0 - file_stats[2].uptime0) & 0xffffffff;
1160
764
   else
1161
765
      itv = g_itv;
1162
766
 
1174
778
 
1175
779
   if (GET_MEM_AMT(act)) {
1176
780
      if (dis)
1177
 
         printf(_("\n%-11s kbmemfree kbmemused  %%memused kbbuffers  kbcached kbswpfree kbswpused  %%swpused  kbswpcad\n"),
 
781
         printf("\n%-11s kbmemfree kbmemused  %%memused kbbuffers  kbcached kbswpfree "
 
782
                "kbswpused  %%swpused  kbswpcad\n",
1178
783
                string);
1179
784
 
1180
 
      printf("%-11s %9.0f %9.0f", string,
 
785
      printf("%-11s %9.0f %9.0f    %6.2f %9.0f %9.0f %9.0f %9.0f    %6.2f %9.0f\n",
 
786
             string,
1181
787
             (double) asum.frmkb / asum.count,
1182
 
             (double) file_stats[curr].tlmkb - ((double) asum.frmkb / asum.count));
1183
 
      if (file_stats[curr].tlmkb)
1184
 
         printf("    %6.2f",
1185
 
                SP_VALUE(asum.frmkb / asum.count, file_stats[curr].tlmkb, file_stats[curr].tlmkb));
1186
 
      else
1187
 
         printf("      %.2f", 0.0);
1188
 
 
1189
 
      printf(" %9.0f %9.0f %9.0f %9.0f",
 
788
             (double) fsi->tlmkb - ((double) asum.frmkb / asum.count),
 
789
             fsi->tlmkb ?
 
790
             SP_VALUE(asum.frmkb / asum.count, fsi->tlmkb, fsi->tlmkb) : 0.0,
1190
791
             (double) asum.bufkb / asum.count,
1191
792
             (double) asum.camkb / asum.count,
1192
793
             (double) asum.frskb / asum.count,
1193
 
             ((double) asum.tlskb / asum.count) - ((double) asum.frskb / asum.count));
1194
 
      if (asum.tlskb / asum.count)
1195
 
         printf("    %6.2f",
1196
 
                SP_VALUE(asum.frskb / asum.count, asum.tlskb / asum.count, asum.tlskb / asum.count));
1197
 
      else
1198
 
         printf("      %.2f", 0.0);
1199
 
 
1200
 
      printf(" %9.0f\n", (double) asum.caskb / asum.count);
 
794
             ((double) asum.tlskb / asum.count) - ((double) asum.frskb / asum.count),
 
795
             (asum.tlskb / asum.count) ?
 
796
             SP_VALUE(asum.frskb / asum.count,
 
797
                      asum.tlskb / asum.count, asum.tlskb / asum.count)
 
798
             : 0.0,
 
799
             (double) asum.caskb / asum.count);
1201
800
   }
1202
801
 
1203
802
   if (GET_KTABLES(act)) {
1204
803
      if (dis)
1205
 
         printf(_("\n%-11s dentunusd   file-sz  inode-sz  super-sz %%super-sz  dquot-sz %%dquot-sz  rtsig-sz %%rtsig-sz\n"),
 
804
         printf("\n%-11s dentunusd   file-sz  inode-sz  super-sz %%super-sz  "
 
805
                "dquot-sz %%dquot-sz  rtsig-sz %%rtsig-sz\n",
1206
806
                string);
1207
807
 
1208
 
      printf("%-11s %9.0f", string, (double) asum.dentry_stat / asum.count);
1209
 
      printf(" %9.0f", (double) asum.file_used / asum.count);
1210
 
      printf(" %9.0f", (double) asum.inode_used / asum.count);
1211
 
 
1212
 
      printf(" %9.0f", (double) asum.super_used / asum.count);
1213
 
      if (file_stats[curr].super_max)
1214
 
         printf("    %6.2f",
1215
 
                ((double) ((asum.super_used / asum.count) * 100))
1216
 
                / file_stats[curr].super_max);
1217
 
      else
1218
 
         printf("      %.2f", 0.0);
1219
 
 
1220
 
      printf(" %9.0f", (double) asum.dquot_used / asum.count);
1221
 
      if (file_stats[curr].dquot_max)
1222
 
         printf("    %6.2f",
1223
 
                ((double) ((asum.dquot_used / asum.count) * 100))
1224
 
                / file_stats[curr].dquot_max);
1225
 
      else
1226
 
         printf("      %.2f", 0.0);
1227
 
 
1228
 
      printf(" %9.0f", (double) asum.rtsig_queued / asum.count);
1229
 
      if (file_stats[curr].rtsig_max)
1230
 
         printf("    %6.2f\n",
1231
 
                ((double) ((asum.rtsig_queued / asum.count) * 100))
1232
 
                / file_stats[curr].rtsig_max);
1233
 
      else
1234
 
         printf("      %.2f\n", 0.0);
 
808
      printf("%-11s %9.0f %9.0f %9.0f %9.0f    %6.2f %9.0f    %6.2f %9.0f    %6.2f\n",
 
809
             string,
 
810
             (double) asum.dentry_stat / asum.count,
 
811
             (double) asum.file_used / asum.count,
 
812
             (double) asum.inode_used / asum.count,
 
813
             (double) asum.super_used / asum.count,
 
814
             fsi->super_max ?
 
815
             ((double) ((asum.super_used / asum.count) * 100)) / fsi->super_max
 
816
             : 0.0,
 
817
             (double) asum.dquot_used / asum.count,
 
818
             fsi->dquot_max ?
 
819
             ((double) ((asum.dquot_used / asum.count) * 100)) / fsi->dquot_max
 
820
             : 0.0,
 
821
             (double) asum.rtsig_queued / asum.count,
 
822
             fsi->rtsig_max ?
 
823
             ((double) ((asum.rtsig_queued / asum.count) * 100)) / fsi->rtsig_max
 
824
             : 0.0);
1235
825
   }
1236
826
 
1237
827
   if (GET_NET_SOCK(act)) {
1238
828
      if (dis)
1239
 
         printf(_("\n%-11s    totsck    tcpsck    udpsck    rawsck   ip-frag\n"),
 
829
         printf("\n%-11s    totsck    tcpsck    udpsck    rawsck   ip-frag\n",
1240
830
                string);
1241
831
 
1242
832
      printf("%-11s %9.0f %9.0f %9.0f %9.0f %9.0f\n", string,
1243
833
             (double) asum.sock_inuse / asum.count,
1244
 
             (double) asum.tcp_inuse  / asum.count,
1245
 
             (double) asum.udp_inuse  / asum.count,
1246
 
             (double) asum.raw_inuse  / asum.count,
 
834
             (double) asum.tcp_inuse / asum.count,
 
835
             (double) asum.udp_inuse / asum.count,
 
836
             (double) asum.raw_inuse / asum.count,
1247
837
             (double) asum.frag_inuse / asum.count);
1248
838
   }
1249
839
 
1250
840
   if (GET_QUEUE(act)) {
1251
841
      if (dis)
1252
 
         printf(_("\n%-11s   runq-sz  plist-sz   ldavg-1   ldavg-5  ldavg-15\n"),
 
842
         printf("\n%-11s   runq-sz  plist-sz   ldavg-1   ldavg-5  ldavg-15\n",
1253
843
                string);
1254
844
 
1255
845
      printf("%-11s %9.0f %9.0f %9.2f %9.2f %9.2f\n", string,
1256
 
             (double) asum.nr_running  / asum.count,
1257
 
             (double) asum.nr_threads  / asum.count,
1258
 
             (double) asum.load_avg_1  / (asum.count * 100),
1259
 
             (double) asum.load_avg_5  / (asum.count * 100),
 
846
             (double) asum.nr_running / asum.count,
 
847
             (double) asum.nr_threads / asum.count,
 
848
             (double) asum.load_avg_1 / (asum.count * 100),
 
849
             (double) asum.load_avg_5 / (asum.count * 100),
1260
850
             (double) asum.load_avg_15 / (asum.count * 100));
1261
851
   }
1262
852
 
1263
853
   if (read_from_file)
1264
854
      /* Reset counters only if we read stats from a system activity file */
1265
 
      init_stats_sum();
 
855
      memset(&asum, 0, STATS_SUM_SIZE);
1266
856
}
1267
857
 
1268
858
 
1271
861
 * Print system statistics
1272
862
 ***************************************************************************
1273
863
 */
1274
 
int write_stats(short curr, short dis, unsigned int act, int read_from_file, long *cnt,
1275
 
                int use_tm_start, int use_tm_end, int reset, int want_since_boot)
 
864
int write_stats(short curr, short dis, unsigned int act, int read_from_file,
 
865
                long *cnt, int use_tm_start, int use_tm_end, int reset,
 
866
                int want_since_boot)
1276
867
{
1277
868
   char cur_time[2][16];
1278
 
   unsigned long itv, g_itv;
 
869
   unsigned long long itv, g_itv;
 
870
   struct file_stats
 
871
      *fsi = &file_stats[curr];
1279
872
 
1280
873
   /* Check time (1) */
1281
874
   if (read_from_file) {
1282
 
      if (!next_slice(curr, reset))
 
875
      if (!next_slice(file_stats[2].uptime, file_stats[curr].uptime,
 
876
                      &file_hdr, reset, interval))
1283
877
         /* Not close enough to desired interval */
1284
878
         return 0;
1285
879
   }
1286
880
 
1287
 
   /* Get previous timestamp */
1288
 
   init_timestamp(!curr, cur_time[!curr], 16);
1289
 
   /* Get current timestamp */
1290
 
   init_timestamp(curr, cur_time[curr], 16);
1291
 
 
1292
 
   /* Check time */
1293
 
   if (prep_time(use_tm_start, curr, &itv, &g_itv))
1294
 
      /* It's too soon... */
1295
 
      return 0;
 
881
   /* Set previous timestamp */
 
882
   set_timestamp(!curr, cur_time[!curr], 16);
 
883
   /* Set current timestamp */
 
884
   set_timestamp(curr, cur_time[curr], 16);
 
885
 
 
886
   /* Check time (2) */
 
887
   if (use_tm_start && (datecmp(&loc_time, &tm_start) < 0))
 
888
     /* it's too soon... */
 
889
     return 0;
 
890
 
 
891
   /* Get interval values */
 
892
   get_itv_value(&file_stats[curr], &file_stats[!curr],
 
893
                 file_hdr.sa_proc, &itv, &g_itv);
 
894
 
 
895
   /* Check time (3) */
1296
896
   if (use_tm_end && (datecmp(&loc_time, &tm_end) > 0)) {
1297
897
      /* It's too late... */
1298
898
      *cnt = 0;
1307
907
   /* Print amount and usage of memory */
1308
908
   if (GET_MEM_AMT(act)) {
1309
909
      if (dis)
1310
 
         printf(_("\n%-11s kbmemfree kbmemused  %%memused kbbuffers  kbcached kbswpfree kbswpused  %%swpused  kbswpcad\n"),
 
910
         printf("\n%-11s kbmemfree kbmemused  %%memused kbbuffers  kbcached "
 
911
                "kbswpfree kbswpused  %%swpused  kbswpcad\n",
1311
912
                cur_time[!curr]);
1312
913
 
1313
 
      printf("%-11s %9lu %9lu", cur_time[curr],
1314
 
             file_stats[curr].frmkb,
1315
 
             file_stats[curr].tlmkb - file_stats[curr].frmkb);
1316
 
      if (file_stats[curr].tlmkb)
1317
 
         printf("    %6.2f",
1318
 
                SP_VALUE(file_stats[curr].frmkb, file_stats[curr].tlmkb, file_stats[curr].tlmkb));
1319
 
      else
1320
 
         printf("      %.2f", 0.0);
1321
 
 
1322
 
      printf(" %9lu %9lu %9lu %9lu",
1323
 
             file_stats[curr].bufkb,
1324
 
             file_stats[curr].camkb,
1325
 
             file_stats[curr].frskb,
1326
 
             file_stats[curr].tlskb - file_stats[curr].frskb);
1327
 
      if (file_stats[curr].tlskb)
1328
 
         printf("    %6.2f",
1329
 
                SP_VALUE(file_stats[curr].frskb, file_stats[curr].tlskb, file_stats[curr].tlskb));
1330
 
      else
1331
 
         printf("      %.2f", 0.0);
1332
 
 
1333
 
      printf(" %9lu\n", file_stats[curr].caskb);
 
914
      printf("%-11s %9lu %9lu    %6.2f %9lu %9lu %9lu %9lu    %6.2f %9lu\n",
 
915
             cur_time[curr],
 
916
             fsi->frmkb,
 
917
             fsi->tlmkb - fsi->frmkb,
 
918
             fsi->tlmkb ?
 
919
             SP_VALUE(fsi->frmkb, fsi->tlmkb, fsi->tlmkb) : 0.0,
 
920
             fsi->bufkb,
 
921
             fsi->camkb,
 
922
             fsi->frskb,
 
923
             fsi->tlskb - fsi->frskb,
 
924
             fsi->tlskb ?
 
925
             SP_VALUE(fsi->frskb, fsi->tlskb, fsi->tlskb) : 0.0,
 
926
             fsi->caskb);
1334
927
 
1335
928
      /*
1336
929
       * Will be used to compute the average.
1339
932
       * during the interval given on the command line, whereas the total
1340
933
       * amount of swap space may.
1341
934
       */
1342
 
      asum.frmkb += file_stats[curr].frmkb;
1343
 
      asum.bufkb += file_stats[curr].bufkb;
1344
 
      asum.camkb += file_stats[curr].camkb;
1345
 
      asum.frskb += file_stats[curr].frskb;
1346
 
      asum.tlskb += file_stats[curr].tlskb;
1347
 
      asum.caskb += file_stats[curr].caskb;
 
935
      asum.frmkb += fsi->frmkb;
 
936
      asum.bufkb += fsi->bufkb;
 
937
      asum.camkb += fsi->camkb;
 
938
      asum.frskb += fsi->frskb;
 
939
      asum.tlskb += fsi->tlskb;
 
940
      asum.caskb += fsi->caskb;
1348
941
   }
1349
942
 
1350
943
   /* Print values of some kernel tables */
1351
944
   if (GET_KTABLES(act)) {
1352
945
      if (dis)
1353
 
         printf(_("\n%-11s dentunusd   file-sz  inode-sz  super-sz %%super-sz  dquot-sz %%dquot-sz  rtsig-sz %%rtsig-sz\n"),
 
946
         printf("\n%-11s dentunusd   file-sz  inode-sz  super-sz %%super-sz  "
 
947
                "dquot-sz %%dquot-sz  rtsig-sz %%rtsig-sz\n",
1354
948
                cur_time[!curr]);
1355
949
 
1356
 
      printf("%-11s %9u", cur_time[curr], file_stats[curr].dentry_stat);
1357
 
      printf(" %9u", file_stats[curr].file_used);
1358
 
      printf(" %9u", file_stats[curr].inode_used);
1359
 
 
1360
 
      printf(" %9u", file_stats[curr].super_used);
1361
 
      if (file_stats[curr].super_max)
1362
 
         printf("    %6.2f",
1363
 
                ((double) (file_stats[curr].super_used * 100))
1364
 
                / file_stats[curr].super_max);
1365
 
      else
1366
 
         printf("      %.2f", 0.0);
1367
 
 
1368
 
      printf(" %9u", file_stats[curr].dquot_used);
1369
 
      if (file_stats[curr].dquot_max)
1370
 
         printf("    %6.2f",
1371
 
                ((double) (file_stats[curr].dquot_used * 100))
1372
 
                / file_stats[curr].dquot_max);
1373
 
      else
1374
 
         printf("      %.2f", 0.0);
1375
 
 
1376
 
      printf(" %9u", file_stats[curr].rtsig_queued);
1377
 
      if (file_stats[curr].rtsig_max)
1378
 
         printf("    %6.2f\n",
1379
 
                ((double) (file_stats[curr].rtsig_queued * 100))
1380
 
                / file_stats[curr].rtsig_max);
1381
 
      else
1382
 
         printf("      %.2f\n", 0.0);
 
950
      printf("%-11s %9u %9u %9u %9u    %6.2f %9u    %6.2f %9u    %6.2f\n",
 
951
             cur_time[curr],
 
952
             fsi->dentry_stat,
 
953
             fsi->file_used,
 
954
             fsi->inode_used,
 
955
             fsi->super_used,
 
956
             fsi->super_max ?
 
957
             ((double) (fsi->super_used * 100)) / fsi->super_max : 0.0,
 
958
             fsi->dquot_used,
 
959
             fsi->dquot_max ?
 
960
             ((double) (fsi->dquot_used * 100)) / fsi->dquot_max : 0.0,
 
961
             fsi->rtsig_queued,
 
962
             fsi->rtsig_max ?
 
963
             ((double) (fsi->rtsig_queued * 100)) / fsi->rtsig_max : 0.0);
1383
964
 
1384
965
      /*
1385
966
       * Will be used to compute the average.
1386
967
       * Note: overflow unlikely to happen but not impossible...
1387
968
       * We assume that *_max values can not vary during the interval.
1388
969
       */
1389
 
      asum.dentry_stat  += file_stats[curr].dentry_stat;
1390
 
      asum.file_used    += file_stats[curr].file_used;
1391
 
      asum.inode_used   += file_stats[curr].inode_used;
1392
 
      asum.super_used   += file_stats[curr].super_used;
1393
 
      asum.dquot_used   += file_stats[curr].dquot_used;
1394
 
      asum.rtsig_queued += file_stats[curr].rtsig_queued;
 
970
      asum.dentry_stat += fsi->dentry_stat;
 
971
      asum.file_used += fsi->file_used;
 
972
      asum.inode_used += fsi->inode_used;
 
973
      asum.super_used += fsi->super_used;
 
974
      asum.dquot_used += fsi->dquot_used;
 
975
      asum.rtsig_queued += fsi->rtsig_queued;
1395
976
   }
1396
977
 
1397
978
   /* Print number of sockets in use */
1398
979
   if (GET_NET_SOCK(act)) {
1399
980
      if (dis)
1400
 
         printf(_("\n%-11s    totsck    tcpsck    udpsck    rawsck   ip-frag\n"),
 
981
         printf("\n%-11s    totsck    tcpsck    udpsck    rawsck   ip-frag\n",
1401
982
                cur_time[!curr]);
1402
983
 
1403
984
      printf("%-11s %9u %9u %9u %9u %9u\n", cur_time[curr],
1404
 
             file_stats[curr].sock_inuse,
1405
 
             file_stats[curr].tcp_inuse,
1406
 
             file_stats[curr].udp_inuse,
1407
 
             file_stats[curr].raw_inuse,
1408
 
             file_stats[curr].frag_inuse);
 
985
             fsi->sock_inuse, fsi->tcp_inuse, fsi->udp_inuse,
 
986
             fsi->raw_inuse, fsi->frag_inuse);
1409
987
 
1410
988
      /* Will be used to compute the average */
1411
 
      asum.sock_inuse += file_stats[curr].sock_inuse;
1412
 
      asum.tcp_inuse  += file_stats[curr].tcp_inuse;
1413
 
      asum.udp_inuse  += file_stats[curr].udp_inuse;
1414
 
      asum.raw_inuse  += file_stats[curr].raw_inuse;
1415
 
      asum.frag_inuse += file_stats[curr].frag_inuse;
 
989
      asum.sock_inuse += fsi->sock_inuse;
 
990
      asum.tcp_inuse += fsi->tcp_inuse;
 
991
      asum.udp_inuse += fsi->udp_inuse;
 
992
      asum.raw_inuse += fsi->raw_inuse;
 
993
      asum.frag_inuse += fsi->frag_inuse;
1416
994
   }
1417
995
 
1418
996
   /* Print load averages and queue length */
1419
997
   if (GET_QUEUE(act)) {
1420
998
      if (dis)
1421
 
         printf(_("\n%-11s   runq-sz  plist-sz   ldavg-1   ldavg-5  ldavg-15\n"),
 
999
         printf("\n%-11s   runq-sz  plist-sz   ldavg-1   ldavg-5  ldavg-15\n",
1422
1000
                cur_time[!curr]);
1423
1001
 
1424
 
      printf("%-11s %9u %9u %9.2f %9.2f %9.2f\n", cur_time[curr],
1425
 
             file_stats[curr].nr_running,
1426
 
             file_stats[curr].nr_threads,
1427
 
             (double) file_stats[curr].load_avg_1  / 100,
1428
 
             (double) file_stats[curr].load_avg_5  / 100,
1429
 
             (double) file_stats[curr].load_avg_15 / 100);
 
1002
      printf("%-11s %9lu %9u %9.2f %9.2f %9.2f\n", cur_time[curr],
 
1003
             fsi->nr_running, fsi->nr_threads,
 
1004
             (double) fsi->load_avg_1 / 100,
 
1005
             (double) fsi->load_avg_5 / 100,
 
1006
             (double) fsi->load_avg_15 / 100);
1430
1007
 
1431
1008
      /* Will be used to compute the average */
1432
 
      asum.nr_running  += file_stats[curr].nr_running;
1433
 
      asum.nr_threads  += file_stats[curr].nr_threads;
1434
 
      asum.load_avg_1  += file_stats[curr].load_avg_1;
1435
 
      asum.load_avg_5  += file_stats[curr].load_avg_5;
1436
 
      asum.load_avg_15 += file_stats[curr].load_avg_15;
 
1009
      asum.nr_running += fsi->nr_running;
 
1010
      asum.nr_threads += fsi->nr_threads;
 
1011
      asum.load_avg_1 += fsi->load_avg_1;
 
1012
      asum.load_avg_5 += fsi->load_avg_5;
 
1013
      asum.load_avg_15 += fsi->load_avg_15;
1437
1014
   }
1438
1015
 
1439
1016
   return 1;
1442
1019
 
1443
1020
/*
1444
1021
 ***************************************************************************
1445
 
 * Print system statistics to be used by pattern processing commands
1446
 
 ***************************************************************************
1447
 
 */
1448
 
void write_stats_for_ppc(short curr, unsigned int act, unsigned long dt,
1449
 
                        unsigned long itv, unsigned long g_itv, char *cur_time)
1450
 
{
1451
 
   int i, j, k;
1452
 
   struct stats_one_cpu *st_cpu_i, *st_cpu_j;
1453
 
   struct stats_serial *st_serial_i, *st_serial_j;
1454
 
   struct stats_irq_cpu *p, *q, *p0, *q0;
1455
 
   struct stats_net_dev *st_net_dev_i, *st_net_dev_j;
1456
 
   struct disk_stats *st_disk_i, *st_disk_j;
1457
 
 
1458
 
   if (GET_PROC(act))
1459
 
      printf("%s\t%ld\t%s\t-\tproc/s\t%.2f\n",
1460
 
             file_hdr.sa_nodename, dt, cur_time,
1461
 
             S_VALUE(file_stats[!curr].processes, file_stats[curr].processes, itv));
1462
 
 
1463
 
   /* Print number of context switches per second */
1464
 
   if (GET_CTXSW(act))
1465
 
      printf("%s\t%ld\t%s\t-\tcswch/s\t%.2f\n",
1466
 
             file_hdr.sa_nodename, dt, cur_time,
1467
 
             S_VALUE(file_stats[!curr].context_swtch, file_stats[curr].context_swtch, itv));
1468
 
 
1469
 
   /* Print CPU usage */
1470
 
   if (GET_CPU(act) &&
1471
 
       (!WANT_PER_PROC(flags) ||
1472
 
        (WANT_PER_PROC(flags) && WANT_ALL_PROC(flags)))) {
1473
 
      printf("%s\t%ld\t%s\tall\t%%user\t%.2f\n",
1474
 
             file_hdr.sa_nodename, dt, cur_time,
1475
 
             SP_VALUE(file_stats[!curr].cpu_user, file_stats[curr].cpu_user, g_itv));
1476
 
      printf("%s\t%ld\t%s\tall\t%%nice\t%.2f\n",
1477
 
             file_hdr.sa_nodename, dt, cur_time,
1478
 
             SP_VALUE(file_stats[!curr].cpu_nice, file_stats[curr].cpu_nice, g_itv));
1479
 
      printf("%s\t%ld\t%s\tall\t%%system\t%.2f\n",
1480
 
             file_hdr.sa_nodename, dt, cur_time,
1481
 
             SP_VALUE(file_stats[!curr].cpu_system, file_stats[curr].cpu_system, g_itv));
1482
 
      printf("%s\t%ld\t%s\tall\t%%iowait\t%.2f\n",
1483
 
             file_hdr.sa_nodename, dt, cur_time,
1484
 
             SP_VALUE(file_stats[!curr].cpu_iowait, file_stats[curr].cpu_iowait, g_itv));
1485
 
      printf("%s\t%ld\t%s\tall\t%%idle\t",
1486
 
             file_hdr.sa_nodename, dt, cur_time);
1487
 
      if (file_stats[curr].cpu_idle < file_stats[!curr].cpu_idle)
1488
 
         printf("%.2f\n", 0.0); /* Handle buggy RTC (or kernels?) */
1489
 
      else
1490
 
         printf("%.2f\n",
1491
 
                SP_VALUE(file_stats[!curr].cpu_idle, file_stats[curr].cpu_idle, g_itv));
1492
 
   }
1493
 
 
1494
 
   if (GET_CPU(act) && WANT_PER_PROC(flags) && file_hdr.sa_proc) {
1495
 
      unsigned long pc_itv;
1496
 
 
1497
 
      for (i = 0; i <= file_hdr.sa_proc; i++) {
1498
 
         if (cpu_bitmap[i >> 3] & (1 << (i & 0x07))) {
1499
 
 
1500
 
            st_cpu_i = st_cpu[curr]  + i;
1501
 
            st_cpu_j = st_cpu[!curr] + i;
1502
 
 
1503
 
            /* Recalculate itv for current proc */
1504
 
            pc_itv = get_per_cpu_interval(st_cpu_i, st_cpu_j);
1505
 
        
1506
 
            printf("%s\t%ld\t%s\tcpu%d\t%%user\t%.2f\n",
1507
 
                   file_hdr.sa_nodename, dt, cur_time, i,
1508
 
                   SP_VALUE(st_cpu_j->per_cpu_user, st_cpu_i->per_cpu_user, pc_itv));
1509
 
            printf("%s\t%ld\t%s\tcpu%d\t%%nice\t%.2f\n",
1510
 
                   file_hdr.sa_nodename, dt, cur_time, i,
1511
 
                   SP_VALUE(st_cpu_j->per_cpu_nice, st_cpu_i->per_cpu_nice, pc_itv));
1512
 
            printf("%s\t%ld\t%s\tcpu%d\t%%system\t%.2f\n",
1513
 
                   file_hdr.sa_nodename, dt, cur_time, i,
1514
 
                   SP_VALUE(st_cpu_j->per_cpu_system, st_cpu_i->per_cpu_system, pc_itv));
1515
 
            printf("%s\t%ld\t%s\tcpu%d\t%%iowait\t%.2f\n",
1516
 
                   file_hdr.sa_nodename, dt, cur_time, i,
1517
 
                   SP_VALUE(st_cpu_j->per_cpu_iowait, st_cpu_i->per_cpu_iowait, pc_itv));
1518
 
 
1519
 
            if (st_cpu_i->per_cpu_idle < st_cpu_j->per_cpu_idle)
1520
 
               printf("%s\t%ld\t%s\tcpu%d\t%%idle\t%.2f\n",
1521
 
                      file_hdr.sa_nodename, dt, cur_time, i, 0.0);
1522
 
            else
1523
 
               printf("%s\t%ld\t%s\tcpu%d\t%%idle\t%.2f\n",
1524
 
                      file_hdr.sa_nodename, dt, cur_time, i,
1525
 
                      SP_VALUE(st_cpu_j->per_cpu_idle, st_cpu_i->per_cpu_idle, pc_itv));
1526
 
         }
1527
 
      }
1528
 
   }
1529
 
 
1530
 
   /* Print number of interrupts per second */
1531
 
   if (GET_IRQ(act) &&
1532
 
       (!WANT_PER_PROC(flags) ||
1533
 
        (WANT_PER_PROC(flags) && WANT_ALL_PROC(flags)))) {
1534
 
      printf("%s\t%ld\t%s\tsum\tintr/s\t%.2f\n",
1535
 
             file_hdr.sa_nodename, dt, cur_time,
1536
 
             S_VALUE(file_stats[!curr].irq_sum, file_stats[curr].irq_sum, itv));
1537
 
   }
1538
 
 
1539
 
   if (GET_ONE_IRQ(act)) {
1540
 
      for (i = 0; i < NR_IRQS; i++) {
1541
 
         if (irq_bitmap[i >> 3] & (1 << (i & 0x07))) {
1542
 
 
1543
 
            printf("%s\t%ld\t%s\ti%03d\tintr/s\t%.2f\n",
1544
 
                   file_hdr.sa_nodename, dt, cur_time, i,
1545
 
                   S_VALUE(interrupts[!curr][i], interrupts[curr][i], itv));
1546
 
         }
1547
 
      }
1548
 
   }
1549
 
 
1550
 
   /* Print paging statistics */
1551
 
   if (GET_PAGE(act)) {
1552
 
      printf("%s\t%ld\t%s\t-\tpgpgin/s\t%.2f\n",
1553
 
             file_hdr.sa_nodename, dt, cur_time,
1554
 
             S_VALUE(file_stats[!curr].pgpgin, file_stats[curr].pgpgin, itv));
1555
 
      printf("%s\t%ld\t%s\t-\tpgpgout/s\t%.2f\n",
1556
 
             file_hdr.sa_nodename, dt, cur_time,
1557
 
             S_VALUE(file_stats[!curr].pgpgout, file_stats[curr].pgpgout, itv));
1558
 
      printf("%s\t%ld\t%s\t-\tfault/s\t%.2f\n",
1559
 
             file_hdr.sa_nodename, dt, cur_time,
1560
 
             S_VALUE(file_stats[!curr].pgfault, file_stats[curr].pgfault, itv));
1561
 
      printf("%s\t%ld\t%s\t-\tmajflt/s\t%.2f\n",
1562
 
             file_hdr.sa_nodename, dt, cur_time,
1563
 
             S_VALUE(file_stats[!curr].pgmajfault, file_stats[curr].pgmajfault, itv));
1564
 
   }
1565
 
 
1566
 
   /* Print number of swap pages brought in and out */
1567
 
   if (GET_SWAP(act)) {
1568
 
      printf("%s\t%ld\t%s\t-\tpswpin/s\t%.2f\n",
1569
 
             file_hdr.sa_nodename, dt, cur_time,
1570
 
             S_VALUE(file_stats[!curr].pswpin, file_stats[curr].pswpin, itv));
1571
 
      printf("%s\t%ld\t%s\t-\tpswpout/s\t%.2f\n",
1572
 
             file_hdr.sa_nodename, dt, cur_time,
1573
 
             S_VALUE(file_stats[!curr].pswpout, file_stats[curr].pswpout, itv));
1574
 
   }
1575
 
 
1576
 
   /* Print I/O stats (no distinction made between disks) */
1577
 
   if (GET_IO(act)) {
1578
 
      printf("%s\t%ld\t%s\t-\ttps\t%.2f\n",
1579
 
             file_hdr.sa_nodename, dt, cur_time,
1580
 
             S_VALUE(file_stats[!curr].dk_drive, file_stats[curr].dk_drive, itv));
1581
 
      printf("%s\t%ld\t%s\t-\trtps\t%.2f\n",
1582
 
             file_hdr.sa_nodename, dt, cur_time,
1583
 
             S_VALUE(file_stats[!curr].dk_drive_rio, file_stats[curr].dk_drive_rio, itv));
1584
 
      printf("%s\t%ld\t%s\t-\twtps\t%.2f\n",
1585
 
             file_hdr.sa_nodename, dt, cur_time,
1586
 
             S_VALUE(file_stats[!curr].dk_drive_wio, file_stats[curr].dk_drive_wio, itv));
1587
 
      printf("%s\t%ld\t%s\t-\tbread/s\t%.2f\n",
1588
 
             file_hdr.sa_nodename, dt, cur_time,
1589
 
             S_VALUE(file_stats[!curr].dk_drive_rblk, file_stats[curr].dk_drive_rblk, itv));
1590
 
      printf("%s\t%ld\t%s\t-\tbwrtn/s\t%.2f\n",
1591
 
             file_hdr.sa_nodename, dt, cur_time,
1592
 
             S_VALUE(file_stats[!curr].dk_drive_wblk, file_stats[curr].dk_drive_wblk, itv));
1593
 
   }
1594
 
 
1595
 
   /* Print memory stats */
1596
 
   if (GET_MEMORY(act)) {
1597
 
      printf("%s\t%ld\t%s\t-\tfrmpg/s\t%.2f\n",
1598
 
             file_hdr.sa_nodename, dt, cur_time,
1599
 
             ((double) PG(file_stats[curr].frmkb) - (double) PG(file_stats[!curr].frmkb))
1600
 
             / itv * HZ);
1601
 
      printf("%s\t%ld\t%s\t-\tbufpg/s\t%.2f\n",
1602
 
             file_hdr.sa_nodename, dt, cur_time,
1603
 
             ((double) PG(file_stats[curr].bufkb) - (double) PG(file_stats[!curr].bufkb))
1604
 
             / itv * HZ);
1605
 
      printf("%s\t%ld\t%s\t-\tcampg/s\t%.2f\n",
1606
 
             file_hdr.sa_nodename, dt, cur_time,
1607
 
             ((double) PG(file_stats[curr].camkb) - (double) PG(file_stats[!curr].camkb))
1608
 
             / itv * HZ);
1609
 
   }
1610
 
 
1611
 
   /* Print TTY statistics (serial lines) */
1612
 
   if (GET_SERIAL(act)) {
1613
 
 
1614
 
      for (i = 0; i < file_hdr.sa_serial; i++) {
1615
 
 
1616
 
         st_serial_i = st_serial[curr]  + i;
1617
 
         st_serial_j = st_serial[!curr] + i;
1618
 
         if (st_serial_i->line == ~0)
1619
 
            continue;
1620
 
        
1621
 
         if (st_serial_i->line == st_serial_j->line) {
1622
 
            printf("%s\t%ld\t%s\tttyS%d\trcvin/s\t%.2f\n",
1623
 
                   file_hdr.sa_nodename, dt, cur_time, st_serial_i->line,
1624
 
                   S_VALUE(st_serial_j->rx, st_serial_i->rx, itv));
1625
 
            printf("%s\t%ld\t%s\tttyS%d\txmtin/s\t%.2f\n",
1626
 
                   file_hdr.sa_nodename, dt, cur_time, st_serial_i->line,
1627
 
                   S_VALUE(st_serial_j->tx, st_serial_i->tx, itv));
1628
 
         }
1629
 
      }
1630
 
   }
1631
 
 
1632
 
   /* Print amount and usage of memory */
1633
 
   if (GET_MEM_AMT(act)) {
1634
 
      printf("%s\t%ld\t%s\t-\tkbmemfree\t%lu\n",
1635
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].frmkb);
1636
 
      printf("%s\t%ld\t%s\t-\tkbmemused\t%lu\n",
1637
 
             file_hdr.sa_nodename, dt, cur_time,
1638
 
             file_stats[curr].tlmkb - file_stats[curr].frmkb);
1639
 
      printf("%s\t%ld\t%s\t-\t%%memused\t",
1640
 
             file_hdr.sa_nodename, dt, cur_time);
1641
 
      if (file_stats[curr].tlmkb)
1642
 
         printf("%.2f\n",
1643
 
                SP_VALUE(file_stats[curr].frmkb, file_stats[curr].tlmkb, file_stats[curr].tlmkb));
1644
 
      else
1645
 
         printf("%.2f\n", 0.0);
1646
 
 
1647
 
      printf("%s\t%ld\t%s\t-\tkbbuffers\t%lu\n",
1648
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].bufkb);
1649
 
      printf("%s\t%ld\t%s\t-\tkbcached\t%lu\n",
1650
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].camkb);
1651
 
      printf("%s\t%ld\t%s\t-\tkbswpfree\t%lu\n",
1652
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].frskb);
1653
 
      printf("%s\t%ld\t%s\t-\tkbswpused\t%lu\n",
1654
 
             file_hdr.sa_nodename, dt, cur_time,
1655
 
             file_stats[curr].tlskb - file_stats[curr].frskb);
1656
 
      printf("%s\t%ld\t%s\t-\t%%swpused\t",
1657
 
             file_hdr.sa_nodename, dt, cur_time);
1658
 
      if (file_stats[curr].tlskb)
1659
 
         printf("%.2f\n",
1660
 
                SP_VALUE(file_stats[curr].frskb, file_stats[curr].tlskb, file_stats[curr].tlskb));
1661
 
      else
1662
 
         printf("%.2f\n", 0.0);
1663
 
      printf("%s\t%ld\t%s\t-\tkbswpcad\t%lu\n",
1664
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].caskb);
1665
 
   }
1666
 
 
1667
 
   if (GET_IRQ(act) && WANT_PER_PROC(flags) && file_hdr.sa_irqcpu) {
1668
 
      int offset;
1669
 
 
1670
 
      for (k = 0; k <= file_hdr.sa_proc; k++) {
1671
 
         if (cpu_bitmap[k >> 3] & (1 << (k & 0x07))) {
1672
 
 
1673
 
            for (j = 0; j < file_hdr.sa_irqcpu; j++) {
1674
 
               p0 = st_irq_cpu[curr] + j;       /* irq field set only for proc #0 */
1675
 
               /*
1676
 
                * A value of ~0 means it is a remaining interrupt
1677
 
                * which is no longer used, for example because the
1678
 
                * number of interrupts has decreased in /proc/interrupts
1679
 
                * or because we are appending data to an old sa file
1680
 
                * with more interrupts than are actually available now.
1681
 
                */
1682
 
               if (p0->irq != ~0) {
1683
 
                  q0 = st_irq_cpu[!curr] + j;
1684
 
                  offset = j;
1685
 
 
1686
 
                  if (p0->irq != q0->irq) {
1687
 
                     if (j)
1688
 
                        offset = j - 1;
1689
 
                     q0 = st_irq_cpu[!curr] + offset;
1690
 
                     if ((p0->irq != q0->irq) && (j + 1 < file_hdr.sa_irqcpu))
1691
 
                        offset = j + 1;
1692
 
                     q0 = st_irq_cpu[!curr] + offset;
1693
 
                  }
1694
 
                  if (p0->irq == q0->irq) {
1695
 
                     p = st_irq_cpu[curr]  + k * file_hdr.sa_irqcpu + j;
1696
 
                     q = st_irq_cpu[!curr] + k * file_hdr.sa_irqcpu + offset;
1697
 
                     printf("%s\t%ld\t%s\tcpu%d\ti%03d/s\t%.2f\n",
1698
 
                            file_hdr.sa_nodename, dt, cur_time, k, p0->irq,
1699
 
                            S_VALUE(q->interrupt, p->interrupt, itv));
1700
 
                  }
1701
 
               }
1702
 
            }
1703
 
         }
1704
 
      }
1705
 
   }
1706
 
 
1707
 
   /* Print values of some kernel tables */
1708
 
   if (GET_KTABLES(act)) {
1709
 
      printf("%s\t%ld\t%s\t-\tdentunusd\t%u\n",
1710
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].dentry_stat);
1711
 
      printf("%s\t%ld\t%s\t-\tfile-sz\t%u\n",
1712
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].file_used);
1713
 
      printf("%s\t%ld\t%s\t-\tinode-sz\t%u\n",
1714
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].inode_used);
1715
 
 
1716
 
      printf("%s\t%ld\t%s\t-\tsuper-sz\t%u\n",
1717
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].super_used);
1718
 
      printf("%s\t%ld\t%s\t-\t%%super-sz\t",
1719
 
             file_hdr.sa_nodename, dt, cur_time);
1720
 
      if (file_stats[curr].super_max)
1721
 
         printf("%.2f\n",
1722
 
                ((double) (file_stats[curr].super_used * 100)) / file_stats[curr].super_max);
1723
 
      else
1724
 
         printf("%.2f\n", 0.0);
1725
 
 
1726
 
      printf("%s\t%ld\t%s\t-\tdquot-sz\t%u\n",
1727
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].dquot_used);
1728
 
      printf("%s\t%ld\t%s\t-\t%%dquot-sz\t",
1729
 
             file_hdr.sa_nodename, dt, cur_time);
1730
 
      if (file_stats[curr].dquot_max)
1731
 
         printf("%.2f\n",
1732
 
                ((double) (file_stats[curr].dquot_used * 100)) / file_stats[curr].dquot_max);
1733
 
      else
1734
 
         printf("%.2f\n", 0.0);
1735
 
 
1736
 
      printf("%s\t%ld\t%s\t-\trtsig-sz\t%u\n",
1737
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].rtsig_queued);
1738
 
      printf("%s\t%ld\t%s\t-\t%%rtsig-sz\t",
1739
 
             file_hdr.sa_nodename, dt, cur_time);
1740
 
      if (file_stats[curr].rtsig_max)
1741
 
         printf("%.2f\n",
1742
 
                ((double) (file_stats[curr].rtsig_queued * 100)) / file_stats[curr].rtsig_max);
1743
 
      else
1744
 
         printf("%.2f\n", 0.0);
1745
 
   }
1746
 
 
1747
 
   /* Print network interface statistics */
1748
 
   if (GET_NET_DEV(act)) {
1749
 
 
1750
 
      for (i = 0; i < file_hdr.sa_iface; i++) {
1751
 
 
1752
 
         st_net_dev_i = st_net_dev[curr] + i;
1753
 
         if (!strcmp(st_net_dev_i->interface, "?"))
1754
 
            continue;
1755
 
         j = check_iface_reg(st_net_dev, curr, !curr, i);
1756
 
         st_net_dev_j = st_net_dev[!curr] + j;
1757
 
 
1758
 
         printf("%s\t%ld\t%s\t%s\trxpck/s\t%.2f\n",
1759
 
                file_hdr.sa_nodename, dt, cur_time, st_net_dev_i->interface,
1760
 
                S_VALUE(st_net_dev_j->rx_packets, st_net_dev_i->rx_packets, itv));
1761
 
         printf("%s\t%ld\t%s\t%s\ttxpck/s\t%.2f\n",
1762
 
                file_hdr.sa_nodename, dt, cur_time, st_net_dev_i->interface,
1763
 
                S_VALUE(st_net_dev_j->tx_packets, st_net_dev_i->tx_packets, itv));
1764
 
         printf("%s\t%ld\t%s\t%s\trxbyt/s\t%.2f\n",
1765
 
                file_hdr.sa_nodename, dt, cur_time, st_net_dev_i->interface,
1766
 
                S_VALUE(st_net_dev_j->rx_bytes, st_net_dev_i->rx_bytes, itv));
1767
 
         printf("%s\t%ld\t%s\t%s\ttxbyt/s\t%.2f\n",
1768
 
                file_hdr.sa_nodename, dt, cur_time, st_net_dev_i->interface,
1769
 
                S_VALUE(st_net_dev_j->tx_bytes, st_net_dev_i->tx_bytes, itv));
1770
 
         printf("%s\t%ld\t%s\t%s\trxcmp/s\t%.2f\n",
1771
 
                file_hdr.sa_nodename, dt, cur_time, st_net_dev_i->interface,
1772
 
                S_VALUE(st_net_dev_j->rx_compressed, st_net_dev_i->rx_compressed, itv));
1773
 
         printf("%s\t%ld\t%s\t%s\ttxcmp/s\t%.2f\n",
1774
 
                file_hdr.sa_nodename, dt, cur_time, st_net_dev_i->interface,
1775
 
                S_VALUE(st_net_dev_j->tx_compressed, st_net_dev_i->tx_compressed, itv));
1776
 
         printf("%s\t%ld\t%s\t%s\trxmcst/s\t%.2f\n",
1777
 
                file_hdr.sa_nodename, dt, cur_time, st_net_dev_i->interface,
1778
 
                S_VALUE(st_net_dev_j->multicast, st_net_dev_i->multicast, itv));
1779
 
      }
1780
 
   }
1781
 
 
1782
 
   /* Print network interface statistics (errors) */
1783
 
   if (GET_NET_EDEV(act)) {
1784
 
 
1785
 
      for (i = 0; i < file_hdr.sa_iface; i++) {
1786
 
 
1787
 
         st_net_dev_i = st_net_dev[curr] + i;
1788
 
         if (!strcmp(st_net_dev_i->interface, "?"))
1789
 
            continue;
1790
 
         j = check_iface_reg(st_net_dev, curr, !curr, i);
1791
 
         st_net_dev_j = st_net_dev[!curr] + j;
1792
 
        
1793
 
         printf("%s\t%ld\t%s\t%s\trxerr/s\t%.2f\n",
1794
 
                file_hdr.sa_nodename, dt, cur_time, st_net_dev_i->interface,
1795
 
                S_VALUE(st_net_dev_j->rx_errors, st_net_dev_i->rx_errors, itv));
1796
 
         printf("%s\t%ld\t%s\t%s\ttxerr/s\t%.2f\n",
1797
 
                file_hdr.sa_nodename, dt, cur_time, st_net_dev_i->interface,
1798
 
                S_VALUE(st_net_dev_j->tx_errors, st_net_dev_i->tx_errors, itv));
1799
 
         printf("%s\t%ld\t%s\t%s\tcoll/s\t%.2f\n",
1800
 
                file_hdr.sa_nodename, dt, cur_time, st_net_dev_i->interface,
1801
 
                S_VALUE(st_net_dev_j->collisions, st_net_dev_i->collisions, itv));
1802
 
         printf("%s\t%ld\t%s\t%s\trxdrop/s\t%.2f\n",
1803
 
                file_hdr.sa_nodename, dt, cur_time, st_net_dev_i->interface,
1804
 
                S_VALUE(st_net_dev_j->rx_dropped, st_net_dev_i->rx_dropped, itv));
1805
 
         printf("%s\t%ld\t%s\t%s\ttxdrop/s\t%.2f\n",
1806
 
                file_hdr.sa_nodename, dt, cur_time, st_net_dev_i->interface,
1807
 
                S_VALUE(st_net_dev_j->tx_dropped, st_net_dev_i->tx_dropped, itv));
1808
 
         printf("%s\t%ld\t%s\t%s\ttxcarr/s\t%.2f\n",
1809
 
                file_hdr.sa_nodename, dt, cur_time, st_net_dev_i->interface,
1810
 
                S_VALUE(st_net_dev_j->tx_carrier_errors, st_net_dev_i->tx_carrier_errors, itv));
1811
 
         printf("%s\t%ld\t%s\t%s\trxfram/s\t%.2f\n",
1812
 
                file_hdr.sa_nodename, dt, cur_time, st_net_dev_i->interface,
1813
 
                S_VALUE(st_net_dev_j->rx_frame_errors, st_net_dev_i->rx_frame_errors, itv));
1814
 
         printf("%s\t%ld\t%s\t%s\trxfifo/s\t%.2f\n",
1815
 
                file_hdr.sa_nodename, dt, cur_time, st_net_dev_i->interface,
1816
 
                S_VALUE(st_net_dev_j->rx_fifo_errors, st_net_dev_i->rx_fifo_errors, itv));
1817
 
         printf("%s\t%ld\t%s\t%s\ttxfifo/s\t%.2f\n",
1818
 
                file_hdr.sa_nodename, dt, cur_time, st_net_dev_i->interface,
1819
 
                S_VALUE(st_net_dev_j->tx_fifo_errors, st_net_dev_i->tx_fifo_errors, itv));
1820
 
      }
1821
 
   }
1822
 
 
1823
 
   /* Print number of sockets in use */
1824
 
   if (GET_NET_SOCK(act)) {
1825
 
      printf("%s\t%ld\t%s\t-\ttotsck\t%u\n",
1826
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].sock_inuse);
1827
 
      printf("%s\t%ld\t%s\t-\ttcpsck\t%u\n",
1828
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].tcp_inuse);
1829
 
      printf("%s\t%ld\t%s\t-\tudpsck\t%u\n",
1830
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].udp_inuse);
1831
 
      printf("%s\t%ld\t%s\t-\trawsck\t%u\n",
1832
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].raw_inuse);
1833
 
      printf("%s\t%ld\t%s\t-\tip-frag\t%u\n",
1834
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].frag_inuse);
1835
 
   }
1836
 
 
1837
 
   /* Print load averages and queue length */
1838
 
   if (GET_QUEUE(act)) {
1839
 
      printf("%s\t%ld\t%s\t-\trunq-sz\t%u\n",
1840
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].nr_running);
1841
 
      printf("%s\t%ld\t%s\t-\tplist-sz\t%u\n",
1842
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].nr_threads);
1843
 
      printf("%s\t%ld\t%s\t-\tldavg-1\t%.2f\n",
1844
 
             file_hdr.sa_nodename, dt, cur_time,
1845
 
             (double) file_stats[curr].load_avg_1 / 100);
1846
 
      printf("%s\t%ld\t%s\t-\tldavg-5\t%.2f\n",
1847
 
             file_hdr.sa_nodename, dt, cur_time,
1848
 
             (double) file_stats[curr].load_avg_5 / 100);
1849
 
      printf("%s\t%ld\t%s\t-\tldavg-15\t%.2f\n",
1850
 
             file_hdr.sa_nodename, dt, cur_time,
1851
 
             (double) file_stats[curr].load_avg_15 / 100);
1852
 
   }
1853
 
 
1854
 
   /* Print disk statistics */
1855
 
   if (GET_DISK(act)) {
1856
 
 
1857
 
      for (i = 0; i < file_hdr.sa_nr_disk; i++) {
1858
 
 
1859
 
         st_disk_i = st_disk[curr]  + i;
1860
 
         if (!(st_disk_i->major + st_disk_i->index))
1861
 
            continue;
1862
 
         j = check_disk_reg(st_disk, curr, !curr, i);
1863
 
         st_disk_j = st_disk[!curr] + j;
1864
 
        
1865
 
         printf("%s\t%ld\t%s\tdev%d-%d\ttps\t%.2f\n",
1866
 
                file_hdr.sa_nodename, dt, cur_time,
1867
 
                st_disk_i->major, st_disk_i->index,
1868
 
                S_VALUE(st_disk_j->nr_ios, st_disk_i->nr_ios, itv));
1869
 
         printf("%s\t%ld\t%s\tdev%d-%d\trd_sec/s\t%.2f\n",
1870
 
                file_hdr.sa_nodename, dt, cur_time,
1871
 
                st_disk_i->major, st_disk_i->index,
1872
 
                S_VALUE(st_disk_j->rd_sect, st_disk_i->rd_sect, itv));
1873
 
         printf("%s\t%ld\t%s\tdev%d-%d\twr_sec/s\t%.2f\n",
1874
 
                file_hdr.sa_nodename, dt, cur_time,
1875
 
                st_disk_i->major, st_disk_i->index,
1876
 
                S_VALUE(st_disk_j->wr_sect, st_disk_i->wr_sect, itv));
1877
 
      }
1878
 
   }
1879
 
}
1880
 
 
1881
 
 
1882
 
/*
1883
 
 ***************************************************************************
1884
 
 * Print system statistics to be used for loading into a database
1885
 
 ***************************************************************************
1886
 
 */
1887
 
void write_stats_for_db(short curr, unsigned int act, unsigned long dt,
1888
 
                       unsigned long itv, unsigned long g_itv, char *cur_time)
1889
 
{
1890
 
   int i, j, k;
1891
 
   struct stats_one_cpu *st_cpu_i, *st_cpu_j;
1892
 
   struct stats_serial *st_serial_i, *st_serial_j;
1893
 
   struct stats_irq_cpu *p, *q, *p0, *q0;
1894
 
   struct stats_net_dev *st_net_dev_i, *st_net_dev_j;
1895
 
   struct disk_stats *st_disk_i, *st_disk_j;
1896
 
 
1897
 
   /* Print number of processes created per second */
1898
 
   if (GET_PROC(act))
1899
 
      printf("%s;%ld;%s;%.2f\n", file_hdr.sa_nodename, dt, cur_time,
1900
 
             S_VALUE(file_stats[!curr].processes, file_stats[curr].processes, itv));
1901
 
 
1902
 
   /* Print number of context switches per second */
1903
 
   if (GET_CTXSW(act))
1904
 
      printf("%s;%ld;%s;%.2f\n", file_hdr.sa_nodename, dt, cur_time,
1905
 
             S_VALUE(file_stats[!curr].context_swtch, file_stats[curr].context_swtch, itv));
1906
 
 
1907
 
   /* Print CPU usage */
1908
 
   if (GET_CPU(act) &&
1909
 
       (!WANT_PER_PROC(flags) ||
1910
 
        (WANT_PER_PROC(flags) && WANT_ALL_PROC(flags)))) {
1911
 
      printf("%s;%ld;%s;-1;%.2f;%.2f;%.2f;%.2f;",
1912
 
             file_hdr.sa_nodename, dt, cur_time,
1913
 
             SP_VALUE(file_stats[!curr].cpu_user, file_stats[curr].cpu_user, g_itv),
1914
 
             SP_VALUE(file_stats[!curr].cpu_nice, file_stats[curr].cpu_nice, g_itv),
1915
 
             SP_VALUE(file_stats[!curr].cpu_system, file_stats[curr].cpu_system, g_itv),
1916
 
             SP_VALUE(file_stats[!curr].cpu_iowait, file_stats[curr].cpu_iowait, g_itv));
1917
 
      if (file_stats[curr].cpu_idle < file_stats[!curr].cpu_idle)
1918
 
         printf("%.2f\n", 0.0); /* Handle buggy RTC (or kernels?) */
1919
 
      else
1920
 
         printf("%.2f\n",
1921
 
                SP_VALUE(file_stats[!curr].cpu_idle, file_stats[curr].cpu_idle, g_itv));
1922
 
   }
1923
 
 
1924
 
   if (GET_CPU(act) && WANT_PER_PROC(flags) && file_hdr.sa_proc) {
1925
 
      unsigned long pc_itv;
1926
 
 
1927
 
      for (i = 0; i <= file_hdr.sa_proc; i++) {
1928
 
         if (cpu_bitmap[i >> 3] & (1 << (i & 0x07))) {
1929
 
 
1930
 
            st_cpu_i = st_cpu[curr]  + i;
1931
 
            st_cpu_j = st_cpu[!curr] + i;
1932
 
 
1933
 
            /* Recalculate itv for current proc */
1934
 
            pc_itv = get_per_cpu_interval(st_cpu_i, st_cpu_j);
1935
 
        
1936
 
            printf("%s;%ld;%s;%d;%.2f;%.2f;%.2f;%.2f;",
1937
 
                   file_hdr.sa_nodename, dt, cur_time, i,
1938
 
                   SP_VALUE(st_cpu_j->per_cpu_user, st_cpu_i->per_cpu_user, pc_itv),
1939
 
                   SP_VALUE(st_cpu_j->per_cpu_nice, st_cpu_i->per_cpu_nice, pc_itv),
1940
 
                   SP_VALUE(st_cpu_j->per_cpu_system, st_cpu_i->per_cpu_system, pc_itv),
1941
 
                   SP_VALUE(st_cpu_j->per_cpu_iowait, st_cpu_i->per_cpu_iowait, pc_itv));
1942
 
 
1943
 
            if (st_cpu_i->per_cpu_idle < st_cpu_j->per_cpu_idle)
1944
 
               printf("%.2f\n", 0.0);
1945
 
            else
1946
 
               printf("%.2f\n",
1947
 
                      SP_VALUE(st_cpu_j->per_cpu_idle, st_cpu_i->per_cpu_idle, pc_itv));
1948
 
         }
1949
 
      }
1950
 
   }
1951
 
 
1952
 
   /* Print number of interrupts per second */
1953
 
   if (GET_IRQ(act) &&
1954
 
       (!WANT_PER_PROC(flags) ||
1955
 
        (WANT_PER_PROC(flags) && WANT_ALL_PROC(flags)))) {
1956
 
      printf("%s;%ld;%s;-1;%.2f\n", file_hdr.sa_nodename, dt, cur_time,
1957
 
             S_VALUE(file_stats[!curr].irq_sum, file_stats[curr].irq_sum, itv));
1958
 
   }
1959
 
 
1960
 
   if (GET_ONE_IRQ(act)) {
1961
 
      for (i = 0; i < NR_IRQS; i++) {
1962
 
         if (irq_bitmap[i >> 3] & (1 << (i & 0x07))) {
1963
 
 
1964
 
            printf("%s;%ld;%s;%d;%.2f\n",
1965
 
                   file_hdr.sa_nodename, dt, cur_time, i,
1966
 
                   S_VALUE(interrupts[!curr][i], interrupts[curr][i], itv));
1967
 
         }
1968
 
      }
1969
 
   }
1970
 
 
1971
 
   /* Print paging statistics */
1972
 
   if (GET_PAGE(act))
1973
 
      printf("%s;%ld;%s;%.2f;%.2f;%.2f;%.2f\n",
1974
 
             file_hdr.sa_nodename, dt, cur_time,
1975
 
             S_VALUE(file_stats[!curr].pgpgin, file_stats[curr].pgpgin, itv),
1976
 
             S_VALUE(file_stats[!curr].pgpgout, file_stats[curr].pgpgout, itv),
1977
 
             S_VALUE(file_stats[!curr].pgfault, file_stats[curr].pgfault, itv),
1978
 
             S_VALUE(file_stats[!curr].pgmajfault, file_stats[curr].pgmajfault, itv));
1979
 
 
1980
 
   /* Print number of swap pages brought in and out */
1981
 
   if (GET_SWAP(act))
1982
 
      printf("%s;%ld;%s;%.2f;%.2f\n", file_hdr.sa_nodename, dt, cur_time,
1983
 
             S_VALUE(file_stats[!curr].pswpin, file_stats[curr].pswpin, itv),
1984
 
             S_VALUE(file_stats[!curr].pswpout, file_stats[curr].pswpout, itv));
1985
 
 
1986
 
   /* Print I/O stats (no distinction made between disks) */
1987
 
   if (GET_IO(act))
1988
 
      printf("%s;%ld;%s;%.2f;%.2f;%.2f;%.2f;%.2f\n",
1989
 
             file_hdr.sa_nodename, dt, cur_time,
1990
 
             S_VALUE(file_stats[!curr].dk_drive, file_stats[curr].dk_drive, itv),
1991
 
             S_VALUE(file_stats[!curr].dk_drive_rio, file_stats[curr].dk_drive_rio, itv),
1992
 
             S_VALUE(file_stats[!curr].dk_drive_wio, file_stats[curr].dk_drive_wio, itv),
1993
 
             S_VALUE(file_stats[!curr].dk_drive_rblk, file_stats[curr].dk_drive_rblk, itv),
1994
 
             S_VALUE(file_stats[!curr].dk_drive_wblk, file_stats[curr].dk_drive_wblk, itv));
1995
 
 
1996
 
   /* Print memory stats */
1997
 
   if (GET_MEMORY(act))
1998
 
      printf("%s;%ld;%s;%.2f;%.2f;%.2f\n",
1999
 
             file_hdr.sa_nodename, dt, cur_time,
2000
 
             ((double) PG(file_stats[curr].frmkb) - (double) PG(file_stats[!curr].frmkb))
2001
 
             / itv * HZ,
2002
 
             ((double) PG(file_stats[curr].bufkb) - (double) PG(file_stats[!curr].bufkb))
2003
 
             / itv * HZ,
2004
 
             ((double) PG(file_stats[curr].camkb) - (double) PG(file_stats[!curr].camkb))
2005
 
             / itv * HZ);
2006
 
 
2007
 
   /* Print TTY statistics (serial lines) */
2008
 
   if (GET_SERIAL(act)) {
2009
 
 
2010
 
      for (i = 0; i < file_hdr.sa_serial; i++) {
2011
 
 
2012
 
         st_serial_i = st_serial[curr]  + i;
2013
 
         st_serial_j = st_serial[!curr] + i;
2014
 
         if (st_serial_i->line == ~0)
2015
 
            continue;
2016
 
        
2017
 
         if (st_serial_i->line == st_serial_j->line) {
2018
 
            printf("%s;%ld;%s;%d;%.2f;%.2f\n",
2019
 
                   file_hdr.sa_nodename, dt, cur_time, st_serial_i->line,
2020
 
                   S_VALUE(st_serial_j->rx, st_serial_i->rx, itv),
2021
 
                   S_VALUE(st_serial_j->tx, st_serial_i->tx, itv));
2022
 
         }
2023
 
      }
2024
 
   }
2025
 
 
2026
 
   /* Print amount and usage of memory */
2027
 
   if (GET_MEM_AMT(act)) {
2028
 
      printf("%s;%ld;%s;%lu;%lu;",
2029
 
             file_hdr.sa_nodename, dt, cur_time, file_stats[curr].frmkb,
2030
 
             file_stats[curr].tlmkb - file_stats[curr].frmkb);
2031
 
      if (file_stats[curr].tlmkb)
2032
 
         printf("%.2f",
2033
 
                SP_VALUE(file_stats[curr].frmkb, file_stats[curr].tlmkb, file_stats[curr].tlmkb));
2034
 
      else
2035
 
         printf("%.2f", 0.0);
2036
 
      printf(";%lu;%lu;%lu;%lu;",
2037
 
             file_stats[curr].bufkb, file_stats[curr].camkb,
2038
 
             file_stats[curr].frskb,
2039
 
             file_stats[curr].tlskb - file_stats[curr].frskb);
2040
 
      if (file_stats[curr].tlskb)
2041
 
         printf("%.2f",
2042
 
                SP_VALUE(file_stats[curr].frskb, file_stats[curr].tlskb, file_stats[curr].tlskb));
2043
 
      else
2044
 
         printf("%.2f", 0.0);
2045
 
      printf(";%lu\n", file_stats[curr].caskb);
2046
 
   }
2047
 
 
2048
 
   if (GET_IRQ(act) && WANT_PER_PROC(flags) && file_hdr.sa_irqcpu) {
2049
 
      int offset;
2050
 
 
2051
 
      for (k = 0; k <= file_hdr.sa_proc; k++) {
2052
 
         if (cpu_bitmap[k >> 3] & (1 << (k & 0x07))) {
2053
 
 
2054
 
            for (j = 0; j < file_hdr.sa_irqcpu; j++) {
2055
 
               p0 = st_irq_cpu[curr] + j;       /* irq field set only for proc #0 */
2056
 
               /*
2057
 
                * A value of ~0 means it is a remaining interrupt
2058
 
                * which is no longer used, for example because the
2059
 
                * number of interrupts has decreased in /proc/interrupts
2060
 
                * or because we are appending data to an old sa file
2061
 
                * with more interrupts than are actually available now.
2062
 
                */
2063
 
               if (p0->irq != ~0) {
2064
 
                  q0 = st_irq_cpu[!curr] + j;
2065
 
                  offset = j;
2066
 
 
2067
 
                  if (p0->irq != q0->irq) {
2068
 
                     if (j)
2069
 
                        offset = j - 1;
2070
 
                     q0 = st_irq_cpu[!curr] + offset;
2071
 
                     if ((p0->irq != q0->irq) && (j + 1 < file_hdr.sa_irqcpu))
2072
 
                        offset = j + 1;
2073
 
                     q0 = st_irq_cpu[!curr] + offset;
2074
 
                  }
2075
 
                  if (p0->irq == q0->irq) {
2076
 
                     p = st_irq_cpu[curr]  + k * file_hdr.sa_irqcpu + j;
2077
 
                     q = st_irq_cpu[!curr] + k * file_hdr.sa_irqcpu + offset;
2078
 
                     printf("%s;%ld;%s;%d;%d;%.2f\n",
2079
 
                            file_hdr.sa_nodename, dt, cur_time, k, p0->irq,
2080
 
                            S_VALUE(q->interrupt, p->interrupt, itv));
2081
 
                  }
2082
 
               }
2083
 
            }
2084
 
         }
2085
 
      }
2086
 
   }
2087
 
 
2088
 
   /* Print values of some kernel tables */
2089
 
   if (GET_KTABLES(act)) {
2090
 
      printf("%s;%ld;%s;%u;%u;%u;%u;", file_hdr.sa_nodename, dt, cur_time,
2091
 
             file_stats[curr].dentry_stat, file_stats[curr].file_used,
2092
 
             file_stats[curr].inode_used, file_stats[curr].super_used);
2093
 
      if (file_stats[curr].super_max)
2094
 
         printf("%.2f",
2095
 
                ((double) (file_stats[curr].super_used * 100))
2096
 
                / file_stats[curr].super_max);
2097
 
      else
2098
 
         printf("%.2f", 0.0);
2099
 
      printf(";%u;", file_stats[curr].dquot_used);
2100
 
      if (file_stats[curr].dquot_max)
2101
 
         printf("%.2f",
2102
 
                ((double) (file_stats[curr].dquot_used * 100))
2103
 
                / file_stats[curr].dquot_max);
2104
 
      else
2105
 
         printf("%.2f", 0.0);
2106
 
      printf(";%u;", file_stats[curr].rtsig_queued);
2107
 
      if (file_stats[curr].rtsig_max)
2108
 
         printf("%.2f\n",
2109
 
                ((double) (file_stats[curr].rtsig_queued * 100))
2110
 
                / file_stats[curr].rtsig_max);
2111
 
      else
2112
 
         printf("%.2f\n", 0.0);
2113
 
   }
2114
 
 
2115
 
   /* Print network interface statistics */
2116
 
   if (GET_NET_DEV(act)) {
2117
 
 
2118
 
      for (i = 0; i < file_hdr.sa_iface; i++) {
2119
 
 
2120
 
         st_net_dev_i = st_net_dev[curr] + i;
2121
 
         if (!strcmp(st_net_dev_i->interface, "?"))
2122
 
            continue;
2123
 
         j = check_iface_reg(st_net_dev, curr, !curr, i);
2124
 
         st_net_dev_j = st_net_dev[!curr] + j;
2125
 
 
2126
 
         printf("%s;%ld;%s;%s;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f\n",
2127
 
                file_hdr.sa_nodename, dt, cur_time,
2128
 
                st_net_dev_i->interface,
2129
 
                S_VALUE(st_net_dev_j->rx_packets, st_net_dev_i->rx_packets, itv),
2130
 
                S_VALUE(st_net_dev_j->tx_packets, st_net_dev_i->tx_packets, itv),
2131
 
                S_VALUE(st_net_dev_j->rx_bytes, st_net_dev_i->rx_bytes, itv),
2132
 
                S_VALUE(st_net_dev_j->tx_bytes, st_net_dev_i->tx_bytes, itv),
2133
 
                S_VALUE(st_net_dev_j->rx_compressed, st_net_dev_i->rx_compressed, itv),
2134
 
                S_VALUE(st_net_dev_j->tx_compressed, st_net_dev_i->tx_compressed, itv),
2135
 
                S_VALUE(st_net_dev_j->multicast, st_net_dev_i->multicast, itv));
2136
 
      }
2137
 
   }
2138
 
 
2139
 
   /* Print network interface statistics (errors) */
2140
 
   if (GET_NET_EDEV(act)) {
2141
 
 
2142
 
      for (i = 0; i < file_hdr.sa_iface; i++) {
2143
 
 
2144
 
         st_net_dev_i = st_net_dev[curr] + i;
2145
 
         if (!strcmp(st_net_dev_i->interface, "?"))
2146
 
            continue;
2147
 
         j = check_iface_reg(st_net_dev, curr, !curr, i);
2148
 
         st_net_dev_j = st_net_dev[!curr] + j;
2149
 
 
2150
 
         printf("%s;%ld;%s;%s;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f\n",
2151
 
                file_hdr.sa_nodename, dt, cur_time,
2152
 
                st_net_dev_i->interface,
2153
 
                S_VALUE(st_net_dev_j->rx_errors, st_net_dev_i->rx_errors, itv),
2154
 
                S_VALUE(st_net_dev_j->tx_errors, st_net_dev_i->tx_errors, itv),
2155
 
                S_VALUE(st_net_dev_j->collisions, st_net_dev_i->collisions, itv),
2156
 
                S_VALUE(st_net_dev_j->rx_dropped, st_net_dev_i->rx_dropped, itv),
2157
 
                S_VALUE(st_net_dev_j->tx_dropped, st_net_dev_i->tx_dropped, itv),
2158
 
                S_VALUE(st_net_dev_j->tx_carrier_errors, st_net_dev_i->tx_carrier_errors, itv),
2159
 
                S_VALUE(st_net_dev_j->rx_frame_errors, st_net_dev_i->rx_frame_errors, itv),
2160
 
                S_VALUE(st_net_dev_j->rx_fifo_errors, st_net_dev_i->rx_fifo_errors, itv),
2161
 
                S_VALUE(st_net_dev_j->tx_fifo_errors, st_net_dev_i->tx_fifo_errors, itv));
2162
 
      }
2163
 
   }
2164
 
 
2165
 
   /* Print number of sockets in use */
2166
 
   if (GET_NET_SOCK(act))
2167
 
      printf("%s;%ld;%s;%u;%u;%u;%u;%u\n",
2168
 
             file_hdr.sa_nodename, dt, cur_time,
2169
 
             file_stats[curr].sock_inuse, file_stats[curr].tcp_inuse,
2170
 
             file_stats[curr].udp_inuse, file_stats[curr].raw_inuse,
2171
 
             file_stats[curr].frag_inuse);
2172
 
 
2173
 
   /* Print load averages and queue length */
2174
 
   if (GET_QUEUE(act))
2175
 
      printf("%s;%ld;%s;%u;%u;%.2f;%.2f;%.2f\n",
2176
 
             file_hdr.sa_nodename, dt, cur_time,
2177
 
             file_stats[curr].nr_running, file_stats[curr].nr_threads,
2178
 
             (double) file_stats[curr].load_avg_1  / 100,
2179
 
             (double) file_stats[curr].load_avg_5  / 100,
2180
 
             (double) file_stats[curr].load_avg_15 / 100);
2181
 
 
2182
 
   /* Print disk statistics */
2183
 
   if (GET_DISK(act)) {
2184
 
 
2185
 
      for (i = 0; i < file_hdr.sa_nr_disk; i++) {
2186
 
 
2187
 
         st_disk_i = st_disk[curr]  + i;
2188
 
         if (!(st_disk_i->major + st_disk_i->index))
2189
 
            continue;
2190
 
         j = check_disk_reg(st_disk, curr, !curr, i);
2191
 
         st_disk_j = st_disk[!curr] + j;
2192
 
        
2193
 
         printf("%s;%ld;%s;dev%d-%d;%.2f;%.2f;%.2f\n",
2194
 
                file_hdr.sa_nodename, dt, cur_time,
2195
 
                st_disk_i->major, st_disk_i->index,
2196
 
                S_VALUE(st_disk_j->nr_ios, st_disk_i->nr_ios, itv),
2197
 
                S_VALUE(st_disk_j->rd_sect, st_disk_i->rd_sect, itv),
2198
 
                S_VALUE(st_disk_j->wr_sect, st_disk_i->wr_sect, itv));
2199
 
      }
2200
 
   }
2201
 
}
 
1022
 * Display stats since system startup
 
1023
 ***************************************************************************
 
1024
 */
 
1025
void write_stats_startup(short curr)
 
1026
{
 
1027
   /* Set to 0 previous structures corresponding to boot time */
 
1028
   memset(&file_stats[!curr], 0, FILE_STATS_SIZE);
 
1029
   file_stats[!curr].record_type = R_STATS;
 
1030
   file_stats[!curr].hour        = file_stats[curr].hour;
 
1031
   file_stats[!curr].minute      = file_stats[curr].minute;
 
1032
   file_stats[!curr].second      = file_stats[curr].second;
 
1033
   file_stats[!curr].ust_time    = file_stats[curr].ust_time;
 
1034
   if (file_hdr.sa_proc > 0)
 
1035
      memset(st_cpu[!curr], 0, STATS_ONE_CPU_SIZE * (file_hdr.sa_proc + 1));
 
1036
   memset(interrupts[!curr], 0, STATS_ONE_IRQ_SIZE);
 
1037
   if (pid_nr)
 
1038
      memset (pid_stats[!curr][0], 0, PID_STATS_SIZE * pid_nr);
 
1039
   if (file_hdr.sa_serial)
 
1040
      memset(st_serial[!curr], 0, STATS_SERIAL_SIZE * file_hdr.sa_serial);
 
1041
   if (file_hdr.sa_irqcpu)
 
1042
      memset(st_irq_cpu[!curr], 0, STATS_IRQ_CPU_SIZE * (file_hdr.sa_proc + 1) * file_hdr.sa_irqcpu);
 
1043
   if (file_hdr.sa_iface)
 
1044
      memset(st_net_dev[!curr], 0, STATS_NET_DEV_SIZE * file_hdr.sa_iface);
 
1045
   if (file_hdr.sa_nr_disk)
 
1046
      memset(st_disk[!curr], 0, DISK_STATS_SIZE * file_hdr.sa_nr_disk);
 
1047
        
 
1048
   /* Display stats since boot time */
 
1049
   write_stats(curr, DISP_HDR, sar_actflag, USE_SADC, &count,
 
1050
               NO_TM_START, NO_TM_END, NO_RESET, ST_SINCE_BOOT);
 
1051
   exit(0);
 
1052
   }
2202
1053
 
2203
1054
 
2204
1055
/*
2221
1072
         return 1;      /* EOF */
2222
1073
 
2223
1074
      size -= n;
2224
 
      (char *) buffer += n;
2225
 
   }
2226
 
 
2227
 
   return 0;
2228
 
}
2229
 
 
2230
 
 
2231
 
/*
2232
 
 ***************************************************************************
2233
 
 * Read data from a sa data file
2234
 
 ***************************************************************************
2235
 
 */
2236
 
int sa_fread(int ifd, void *buffer, int size, int mode)
2237
 
{
2238
 
   int n;
2239
 
 
2240
 
   if ((n = read(ifd, buffer, size)) < 0) {
2241
 
      fprintf(stderr, _("Error while reading system activity file: %s\n"), strerror(errno));
2242
 
      exit(2);
2243
 
   }
2244
 
 
2245
 
   if (!n && (mode == SOFT_SIZE))
2246
 
      return 1; /* EOF */
2247
 
 
2248
 
   if (n < size) {
2249
 
      fprintf(stderr, _("End of system activity file unexpected\n"));
2250
 
      exit(2);
2251
 
   }
2252
 
 
2253
 
   return 0;
2254
 
}
2255
 
 
2256
 
 
2257
 
/*
2258
 
 ***************************************************************************
2259
 
 * Write system statistics for options -h/-H
2260
 
 ***************************************************************************
2261
 
 */
2262
 
int write_parsable_stats(short curr, unsigned int act, int reset, long *cnt,
2263
 
                         int use_tm_start, int use_tm_end)
2264
 
{
2265
 
   unsigned long dt, itv, g_itv;
2266
 
   char cur_time[26];
2267
 
 
2268
 
   /* Check time (1) */
2269
 
   if (!next_slice(curr, reset))
2270
 
      /* Not close enough to desired interval */
2271
 
      return 0;
2272
 
 
2273
 
   /* Get current timestamp */
2274
 
   init_timestamp(curr, cur_time, 26);
2275
 
   if (USE_H_OPTION(flags))
2276
 
      sprintf(cur_time, "%ld", file_stats[curr].ust_time);
2277
 
 
2278
 
   /* Check time */
2279
 
   if (prep_time(use_tm_start, curr, &itv, &g_itv))
2280
 
      /* It's too soon... */
2281
 
      return 0;
2282
 
   if (use_tm_end && (datecmp(&loc_time, &tm_end) > 0)) {
2283
 
      /* It's too late... */
2284
 
      *cnt = 0;
2285
 
      return 0;
2286
 
   }
2287
 
 
2288
 
   dt = itv / HZ;
2289
 
   /* Correct rounding error for dt */
2290
 
   if ((itv % HZ) >= (HZ / 2))
2291
 
      dt++;
2292
 
 
2293
 
   if (USE_H_OPTION(flags))
2294
 
      /* Write stats to be used by pattern processing commands */
2295
 
      write_stats_for_ppc(curr, act, dt, itv, g_itv, cur_time);
2296
 
   else if (USE_DB_OPTION(flags))
2297
 
      /* Write stats to be used for loading into a database */
2298
 
      write_stats_for_db(curr, act, dt, itv, g_itv, cur_time);
2299
 
 
2300
 
   return 1;
 
1075
      buffer = (char *) buffer + n;
 
1076
   }
 
1077
 
 
1078
   return 0;
2301
1079
}
2302
1080
 
2303
1081
 
2310
1088
{
2311
1089
   char cur_time[26];
2312
1090
 
2313
 
   init_timestamp(curr, cur_time, 26);
 
1091
   set_timestamp(curr, cur_time, 26);
2314
1092
 
2315
1093
   /* The RESTART message must be in the interval specified by -s/-e options */
2316
1094
   if ((use_tm_start && (datecmp(&loc_time, &tm_start) < 0)) ||
2317
1095
       (use_tm_end && (datecmp(&loc_time, &tm_end) > 0)))
2318
1096
      return;
2319
1097
 
2320
 
   if (USE_H_OPTION(flags))
2321
 
      printf("%s\t-1\t%ld\tLINUX-RESTART\n",
2322
 
             file_hdr.sa_nodename, file_stats[curr].ust_time);
2323
 
   else if (USE_DB_OPTION(flags))
2324
 
      printf("%s;-1;%s;LINUX-RESTART\n",
2325
 
             file_hdr.sa_nodename, cur_time);
2326
 
   else
2327
 
      printf(_("\n%-11s       LINUX RESTART\n"), cur_time);
2328
 
}
2329
 
 
2330
 
 
2331
 
/*
2332
 
 ***************************************************************************
2333
 
 * Allocate structures
2334
 
 ***************************************************************************
2335
 
 */
2336
 
void allocate_structures(int stype)
2337
 
{
2338
 
   if (file_hdr.sa_proc > 0)
2339
 
      salloc_cpu(file_hdr.sa_proc + 1);
2340
 
   if ((stype == USE_SADC) &&
2341
 
       (GET_PID(sar_actflag) || GET_CPID(sar_actflag))) {
2342
 
      pid_nr = file_hdr.sa_nr_pid;
2343
 
      salloc_pid(pid_nr);
2344
 
   }
2345
 
   if (file_hdr.sa_serial)
2346
 
      salloc_serial(file_hdr.sa_serial);
2347
 
   if (file_hdr.sa_irqcpu)
2348
 
      salloc_irqcpu(file_hdr.sa_proc + 1, file_hdr.sa_irqcpu);
2349
 
   if (file_hdr.sa_iface)
2350
 
      salloc_net_dev(file_hdr.sa_iface);
2351
 
   if (file_hdr.sa_nr_disk)
2352
 
      salloc_disk(file_hdr.sa_nr_disk);
2353
 
 
2354
 
   /* Print report header */
2355
 
   print_report_hdr();
 
1098
   printf("\n%-11s       LINUX RESTART\n", cur_time);
2356
1099
}
2357
1100
 
2358
1101
 
2452
1195
 
2453
1196
/*
2454
1197
 ***************************************************************************
2455
 
 * Read stats for current activity from file
 
1198
 * Read stats for current activity from file and display them.
2456
1199
 ***************************************************************************
2457
1200
 */
2458
 
void read_curr_act_stats(int ifd, off_t fpos, short *curr, long *cnt, int *eosaf,
 
1201
void handle_curr_act_stats(int ifd, off_t fpos, short *curr, long *cnt, int *eosaf,
2459
1202
                         int rows, unsigned int act, int *reset)
2460
1203
{
2461
1204
   short dis = 1;
2462
1205
   unsigned long lines;
2463
1206
   unsigned char rtype;
2464
1207
   int davg, next;
2465
 
   off_t fps;
2466
1208
 
2467
 
   if ((fps = lseek(ifd, fpos, SEEK_SET)) < fpos) {
 
1209
   if (lseek(ifd, fpos, SEEK_SET) < fpos) {
2468
1210
      perror("lseek");
2469
1211
      exit(2);
2470
1212
   }
2494
1236
      if (!(*eosaf) && (rtype != R_DUMMY)) {
2495
1237
 
2496
1238
         /* next is set to 1 when we were close enough to desired interval */
2497
 
         if (USE_H_OPTION(flags) || USE_DB_OPTION(flags))
2498
 
            next = write_parsable_stats(*curr, act, *reset, cnt,
2499
 
                                        tm_start.use, tm_end.use);
2500
 
         else
2501
 
            next = write_stats(*curr, dis, act, USE_SA_FILE, cnt,
2502
 
                               tm_start.use, tm_end.use, *reset, ST_IMMEDIATE);
 
1239
         next = write_stats(*curr, dis, act, USE_SA_FILE, cnt,
 
1240
                            tm_start.use, tm_end.use, *reset, ST_IMMEDIATE);
2503
1241
         if (next && ((*cnt) > 0))
2504
1242
            (*cnt)--;
2505
1243
         if (next) {
2513
1251
   }
2514
1252
   while ((*cnt) && !(*eosaf) && (rtype != R_DUMMY));
2515
1253
 
2516
 
   if (davg && !USE_H_OPTION(flags) && !USE_DB_OPTION(flags))
 
1254
   if (davg)
2517
1255
      write_stats_avg(!(*curr), dis, act, USE_SA_FILE);
2518
1256
 
2519
1257
   *reset = TRUE;
2522
1260
 
2523
1261
/*
2524
1262
 ***************************************************************************
 
1263
 * Read header data sent by sadc
 
1264
 ***************************************************************************
 
1265
 */
 
1266
void read_header_data(void)
 
1267
{
 
1268
   /* Read stats header */
 
1269
   if (sa_read(&file_hdr, FILE_HDR_SIZE))
 
1270
      exit(0);
 
1271
   if (file_hdr.sa_magic != SA_MAGIC) {
 
1272
      /* sar and sadc commands are not consistent */
 
1273
      fprintf(stderr, _("Invalid data format\n"));
 
1274
      exit(3);
 
1275
   }
 
1276
 
 
1277
}
 
1278
 
 
1279
 
 
1280
/*
 
1281
 ***************************************************************************
2525
1282
 * Read statistics from a system activity data file
2526
1283
 ***************************************************************************
2527
1284
 */
2529
1286
{
2530
1287
   short curr = 1;
2531
1288
   unsigned int act;
2532
 
   int ifd, nb;
 
1289
   int ifd;
2533
1290
   int rows = 23, eosaf = TRUE, reset = FALSE;
2534
1291
   long cnt = 1;
2535
1292
   off_t fpos;
2538
1295
      /* Get window size */
2539
1296
      rows = get_win_height();
2540
1297
 
2541
 
   /* Open sa data file */
2542
 
   if ((ifd = open(from_file, O_RDONLY)) < 0) {
2543
 
      fprintf(stderr, _("Cannot open %s: %s\n"), from_file, strerror(errno));
2544
 
      exit(2);
2545
 
   }
2546
 
 
2547
 
   /* Read sa data file header */
2548
 
   nb = read(ifd, &file_hdr, FILE_HDR_SIZE);
2549
 
   if ((nb != FILE_HDR_SIZE) || (file_hdr.sa_magic != SA_MAGIC)) {
2550
 
      fprintf(stderr, _("Invalid system activity file: %s\n"), from_file);
2551
 
      exit(3);
2552
 
   }
 
1298
   /* Prepare file for reading */
 
1299
   prep_file_for_reading(&ifd, from_file, &file_hdr, &sar_actflag, flags);
2553
1300
 
2554
1301
   if ((GET_SERIAL(sar_actflag) && (file_hdr.sa_serial > 1)) ||
2555
1302
       ((GET_NET_DEV(sar_actflag) || GET_NET_EDEV(sar_actflag)) && (file_hdr.sa_iface  > 1)) ||
2556
1303
       (GET_DISK(sar_actflag) && (file_hdr.sa_nr_disk > 1)))
2557
1304
      dis_hdr = 9;
2558
1305
 
2559
 
   sar_actflag &= file_hdr.sa_actflag;
2560
 
   if (!sar_actflag ||
2561
 
       (WANT_PER_PROC(flags) && !WANT_ALL_PROC(flags) && !file_hdr.sa_proc && !(sar_actflag & ~(A_CPU + A_IRQ)))) {
2562
 
      /*
2563
 
       * We want stats that are not available,
2564
 
       * maybe because this is an old version of the sa data file.
2565
 
       * Error message is displayed if:
2566
 
       * -> no activities remain in sar_actflag
2567
 
       * -> or if the user entered eg 'sar -u -P 0 -f file' or
2568
 
       * 'sar -I SUM -P 0 -f file', with file created on a UP machine.
2569
 
       * NOTE1: If A_ONE_IRQ stats are available, stats
2570
 
       * concerning _all_ the IRQs are available.
2571
 
       * NOTE2: If file_hdr.sa_proc > 0, stats
2572
 
       * concerning _all_ the CPUs are available.
2573
 
       * NOTE3: If file_hdr.sa_irqcpu != 0, stats
2574
 
       * concerning the IRQs per processor are available.
2575
 
       */
2576
 
      fprintf(stderr, _("Requested activities not available in file\n"));
2577
 
      close(ifd);
2578
 
      exit(1);
2579
 
   }
2580
 
 
2581
1306
   /* Perform required allocations */
2582
1307
   allocate_structures(USE_SA_FILE);
2583
1308
 
 
1309
   /* Print report header */
 
1310
   print_report_hdr(S_O_NONE, flags, &loc_time, &file_hdr);
 
1311
 
2584
1312
   /* Read system statistics from file */
2585
1313
   do {
2586
1314
      /*
2591
1319
         if (sa_fread(ifd, &file_stats[0], file_hdr.sa_st_size, SOFT_SIZE))
2592
1320
            /* End of sa data file */
2593
1321
            return;
2594
 
 
 
1322
        
2595
1323
         if (file_stats[0].record_type == R_DUMMY)
2596
1324
            write_dummy(0, tm_start.use, tm_end.use);
2597
1325
         else {
2600
1328
             * So read now the extra fields.
2601
1329
             */
2602
1330
            read_extra_stats(0, ifd);
2603
 
 
2604
 
            init_timestamp(0, NULL, 0);
 
1331
            set_loc_time(0);
2605
1332
         }
2606
1333
      }
2607
1334
      while ((file_stats[0].record_type == R_DUMMY) ||
2627
1354
         if (sar_actflag & act) {
2628
1355
            if ((act == A_IRQ) && WANT_PER_PROC(flags) && WANT_ALL_PROC(flags)) {
2629
1356
               /* Distinguish -I SUM activity from IRQs per processor activity */
2630
 
               flags &= ~F_PER_PROC;
2631
 
               read_curr_act_stats(ifd, fpos, &curr, &cnt, &eosaf, rows, act, &reset);
2632
 
               flags |= F_PER_PROC;
2633
 
               flags &= ~F_ALL_PROC;
2634
 
               read_curr_act_stats(ifd, fpos, &curr, &cnt, &eosaf, rows, act, &reset);
2635
 
               flags |= F_ALL_PROC;
 
1357
               flags &= ~S_F_PER_PROC;
 
1358
               handle_curr_act_stats(ifd, fpos, &curr, &cnt, &eosaf, rows, act, &reset);
 
1359
               flags |= S_F_PER_PROC;
 
1360
               flags &= ~S_F_ALL_PROC;
 
1361
               handle_curr_act_stats(ifd, fpos, &curr, &cnt, &eosaf, rows, act, &reset);
 
1362
               flags |= S_F_ALL_PROC;
2636
1363
            }
2637
1364
            else
2638
 
               read_curr_act_stats(ifd, fpos, &curr, &cnt, &eosaf, rows, act, &reset);
 
1365
               handle_curr_act_stats(ifd, fpos, &curr, &cnt, &eosaf, rows, act, &reset);
2639
1366
         }
2640
1367
      }
2641
1368
 
2672
1399
   unsigned int rows = 23, more = 1;
2673
1400
 
2674
1401
   /* Read stats header */
2675
 
   if (sa_read(&file_hdr, FILE_HDR_SIZE))
2676
 
      exit(0);
2677
 
   if (file_hdr.sa_magic != SA_MAGIC) {
2678
 
      /* sar and sadc commands are not consistent */
2679
 
      fprintf(stderr, _("Invalid data format\n"));
2680
 
      exit(3);
2681
 
   }
 
1402
   read_header_data();
2682
1403
 
2683
1404
   /* Force '-P ALL' flag if -A option is used on SMP machines */
2684
1405
   if (USE_A_OPTION(flags) && file_hdr.sa_proc) {
2685
 
      init_cpu_bitmap(~0);
2686
 
      flags |= F_ALL_PROC + F_PER_PROC;
 
1406
      init_bitmap(cpu_bitmap, ~0, NR_CPUS);
 
1407
      flags |= S_F_ALL_PROC + S_F_PER_PROC;
2687
1408
   }
2688
1409
 
2689
1410
   /*
2731
1452
   /* Perform required allocations */
2732
1453
   allocate_structures(USE_SADC);
2733
1454
 
 
1455
   /* Print report header */
 
1456
   print_report_hdr(S_O_NONE, flags, &loc_time, &file_hdr);
 
1457
 
2734
1458
   /* Read system statistics sent by the data collector */
2735
1459
   read_stat_bunch(0);
2736
1460
 
2741
1465
         more = pid_nr;
2742
1466
   }
2743
1467
 
2744
 
   if (!interval) {
2745
 
      /* Update structures corresponding to boot time */
2746
 
      memset(&file_stats[1], 0, FILE_STATS_SIZE);
2747
 
      file_stats[1].record_type = R_STATS;
2748
 
      file_stats[1].hour        = file_stats[0].hour;
2749
 
      file_stats[1].minute      = file_stats[0].minute;
2750
 
      file_stats[1].second      = file_stats[0].second;
2751
 
      file_stats[1].ust_time    = file_stats[0].ust_time;
2752
 
      if (file_hdr.sa_proc > 0)
2753
 
         memset(st_cpu[1], 0, STATS_ONE_CPU_SIZE * (file_hdr.sa_proc + 1));
2754
 
      memset(interrupts[1], 0, STATS_ONE_IRQ_SIZE);
2755
 
      if (pid_nr)
2756
 
         memset (pid_stats[1][0], 0, PID_STATS_SIZE * pid_nr);
2757
 
      if (file_hdr.sa_serial)
2758
 
         memset(st_serial[1], 0, STATS_SERIAL_SIZE * file_hdr.sa_serial);
2759
 
      if (file_hdr.sa_irqcpu)
2760
 
         memset(st_irq_cpu[1], 0, STATS_IRQ_CPU_SIZE * (file_hdr.sa_proc + 1) * file_hdr.sa_irqcpu);
2761
 
      if (file_hdr.sa_iface)
2762
 
         memset(st_net_dev[1], 0, STATS_NET_DEV_SIZE * file_hdr.sa_iface);
2763
 
      if (file_hdr.sa_nr_disk)
2764
 
         memset(st_disk[1], 0, DISK_STATS_SIZE * file_hdr.sa_nr_disk);
2765
 
        
2766
 
      /* Display stats since boot time (First arg: !curr) */
2767
 
      write_stats(0, DISP_HDR, sar_actflag, USE_SADC, &count,
2768
 
                  NO_TM_START, NO_TM_END, NO_RESET, ST_SINCE_BOOT);
2769
 
      exit(0);
2770
 
   }
 
1468
   if (!interval)
 
1469
      /* Display stats since boot time and exit */
 
1470
      write_stats_startup(0);
2771
1471
 
2772
1472
   /* Save the first stats collected. Will be used to compute the average */
2773
1473
   copy_structures(2, 0, USE_SADC);
2789
1489
                  tm_end.use, NO_RESET, ST_IMMEDIATE);
2790
1490
      fflush(stdout);   /* Don't buffer data if redirected to a pipe... */
2791
1491
 
 
1492
      if (file_stats[curr].record_type == R_LAST_STATS) {
 
1493
         /* File rotation is happening: re-read header data sent by sadc */
 
1494
         read_header_data();
 
1495
         allocate_structures(USE_SADC);
 
1496
      }
 
1497
 
2792
1498
      if (count > 0)
2793
1499
         count--;
2794
1500
      if (count)
2809
1515
int main(int argc, char **argv)
2810
1516
{
2811
1517
   int opt = 1, args_idx = 2;
2812
 
   int i;
2813
1518
   int fd[2];
2814
1519
   unsigned long pid = 0;
2815
1520
   char from_file[MAX_FILE_LEN], to_file[MAX_FILE_LEN];
2816
1521
   char ltemp[20];
2817
 
   char time_stamp[9];
2818
1522
 
2819
1523
   /* Compute page shift in kB */
2820
1524
   kb_shift = get_kb_shift();
2827
1531
#endif
2828
1532
 
2829
1533
   tm_start.use = tm_end.use = FALSE;
2830
 
   init_irq_bitmap(0);
2831
 
   init_cpu_bitmap(0);
2832
 
   init_stats();
 
1534
   init_bitmap(irq_bitmap, 0, NR_IRQS);
 
1535
   init_bitmap(cpu_bitmap, 0, NR_CPUS);
 
1536
   init_all_stats();
2833
1537
 
2834
1538
   /* Process options */
2835
1539
   while (opt < argc) {
2837
1541
      if (!strcmp(argv[opt], "-I")) {
2838
1542
         if (argv[++opt]) {
2839
1543
            dis_hdr++;
2840
 
            if (!strcmp(argv[opt], K_SUM))
2841
 
               sar_actflag |= A_IRQ;
2842
 
            else {
2843
 
               sar_actflag |= A_ONE_IRQ;
2844
 
               if (!strcmp(argv[opt], K_ALL)) {
2845
 
                  dis_hdr = 9;
2846
 
                  /* Set bit for the first 16 irq */
2847
 
                  irq_bitmap[0] = 0xff;
2848
 
                  irq_bitmap[1] = 0xff;
2849
 
               }
2850
 
               else if (!strcmp(argv[opt], K_XALL)) {
2851
 
                  dis_hdr = 9;
2852
 
                  /* Set every bit */
2853
 
                  init_irq_bitmap(~0);
2854
 
               }
2855
 
               else {
2856
 
                  /*
2857
 
                   * Get irq number.
2858
 
                   */
2859
 
                  if (strspn(argv[opt], DIGITS) != strlen(argv[opt]))
2860
 
                     usage(argv[0]);
2861
 
                  i = atoi(argv[opt]);
2862
 
                  if ((i < 0) || (i >= NR_IRQS))
2863
 
                     usage(argv[0]);
2864
 
                  irq_bitmap[i >> 3] |= 1 << (i & 0x07);
2865
 
               }
2866
 
            }
2867
 
            opt++;
 
1544
            /* Parse -I option */
 
1545
            if (parse_sar_I_opt(argv, &opt, &sar_actflag, &dis_hdr,
 
1546
                                irq_bitmap))
 
1547
               usage(argv[0]);
2868
1548
         }
2869
1549
         else
2870
1550
            usage(argv[0]);
2871
1551
      }
2872
1552
 
2873
1553
      else if (!strcmp(argv[opt], "-P")) {
2874
 
         if (argv[++opt]) {
2875
 
            flags |= F_PER_PROC;
2876
 
            dis_hdr++;
2877
 
            if (!strcmp(argv[opt], K_ALL)) {
2878
 
               dis_hdr = 9;
2879
 
               /*
2880
 
                * Set bit for every processor.
2881
 
                * We still don't know if we are going to read stats
2882
 
                * from a file or not...
2883
 
                */
2884
 
               init_cpu_bitmap(~0);
2885
 
               flags |= F_ALL_PROC;
2886
 
            }
2887
 
            else {
2888
 
               if (strspn(argv[opt], DIGITS) != strlen(argv[opt]))
2889
 
                  usage(argv[0]);
2890
 
               i = atoi(argv[opt]);     /* Get cpu number */
2891
 
               if ((i < 0) || (i >= NR_CPUS))
2892
 
                  usage(argv[0]);
2893
 
               cpu_bitmap[i >> 3] |= 1 << (i & 0x07);
2894
 
            }
2895
 
            opt++;
2896
 
         }
2897
 
         else
 
1554
         /* Parse -P option */
 
1555
         if (parse_sa_P_opt(argv, &opt, &flags, &dis_hdr, cpu_bitmap))
2898
1556
            usage(argv[0]);
2899
1557
      }
2900
1558
 
2926
1584
 
2927
1585
      else if (!strcmp(argv[opt], "-s")) {
2928
1586
         /* Get time start */
2929
 
         if ((argv[++opt]) && (strlen(argv[opt]) == 8))
2930
 
            strcpy(time_stamp, argv[opt++]);
2931
 
         else
2932
 
            strcpy(time_stamp, DEF_TMSTART);
2933
 
         if (decode_time_stamp(time_stamp, &tm_start))
 
1587
         if (parse_timestamp(argv, &opt, &tm_start, DEF_TMSTART))
2934
1588
            usage(argv[0]);
2935
1589
      }
2936
1590
 
2937
1591
      else if (!strcmp(argv[opt], "-e")) {
2938
1592
         /* Get time end */
2939
 
         if ((argv[++opt]) && (strlen(argv[opt]) == 8))
2940
 
            strcpy(time_stamp, argv[opt++]);
2941
 
         else
2942
 
            strcpy(time_stamp, DEF_TMEND);
2943
 
         if (decode_time_stamp(time_stamp, &tm_end))
 
1593
         if (parse_timestamp(argv, &opt, &tm_end, DEF_TMEND))
2944
1594
            usage(argv[0]);
2945
1595
      }
2946
1596
 
2950
1600
         interval = atol(argv[opt++]);
2951
1601
         if (interval < 1)
2952
1602
           usage(argv[0]);
2953
 
         flags |= F_I_OPTION;
2954
 
         flags |= F_DEFAULT_COUNT;
 
1603
         flags |= S_F_I_OPTION;
2955
1604
      }
2956
1605
 
2957
1606
      else if (!strcmp(argv[opt], "-x") || !strcmp(argv[opt], "-X")) {
2994
1643
                  sar_actflag |= A_PID;
2995
1644
               else
2996
1645
                  sar_actflag |= A_CPID;
2997
 
               salloc(args_idx++, argv[opt -2]);        /* "-x" or "-X" */
 
1646
               salloc(args_idx++, argv[opt - 2]);       /* "-x" or "-X" */
2998
1647
               salloc(args_idx++, ltemp);
2999
1648
            }
3000
1649
         }
 
1650
         else
 
1651
            usage(argv[0]);
3001
1652
      }
3002
1653
 
3003
1654
      else if (!strcmp(argv[opt], "-n")) {
3004
1655
         if (argv[++opt]) {
3005
1656
            dis_hdr++;
3006
 
            if (!strcmp(argv[opt], K_DEV))
3007
 
               sar_actflag |= A_NET_DEV;
3008
 
            else if (!strcmp(argv[opt], K_EDEV))
3009
 
               sar_actflag |= A_NET_EDEV;
3010
 
            else if (!strcmp(argv[opt], K_SOCK))
3011
 
               sar_actflag |= A_NET_SOCK;
3012
 
            else if (!strcmp(argv[opt], K_FULL)) {
3013
 
               sar_actflag |= A_NET_DEV + A_NET_EDEV + A_NET_SOCK;
3014
 
               dis_hdr = 9;
3015
 
            }
3016
 
            else
 
1657
            /* Parse option -n */
 
1658
            if (parse_sar_n_opt(argv, &opt, &sar_actflag, &dis_hdr))
3017
1659
               usage(argv[0]);
3018
 
            opt++;
3019
1660
         }
3020
1661
         else
3021
1662
            usage(argv[0]);
3023
1664
 
3024
1665
      else if (!strncmp(argv[opt], "-", 1)) {
3025
1666
         /* Other options not previously tested */
3026
 
         for (i = 1; *(argv[opt] + i); i++) {
3027
 
 
3028
 
            switch (*(argv[opt] + i)) {
3029
 
 
3030
 
             case 'A':
3031
 
               sar_actflag |= A_PROC + A_PAGE + A_IRQ + A_IO + A_CPU +
3032
 
                              A_CTXSW + A_SWAP + A_MEMORY + A_SERIAL +
3033
 
                              A_MEM_AMT + A_KTABLES + A_NET_DEV +
3034
 
                              A_NET_EDEV + A_NET_SOCK + A_QUEUE + A_DISK;
3035
 
               flags |= F_A_OPTION;
3036
 
               break;
3037
 
             case 'B':
3038
 
               sar_actflag |= A_PAGE;
3039
 
               dis_hdr++;
3040
 
               break;
3041
 
             case 'b':
3042
 
               sar_actflag |= A_IO;
3043
 
               dis_hdr++;
3044
 
               break;
3045
 
             case 'c':
3046
 
               sar_actflag |= A_PROC;
3047
 
               dis_hdr++;
3048
 
               break;
3049
 
             case 'd':
3050
 
               sar_actflag |= A_DISK;
3051
 
               dis_hdr++;
3052
 
               break;
3053
 
             case 'H':
3054
 
               flags |= F_DB_OPTION;
3055
 
               break;
3056
 
             case 'h':
3057
 
               flags |= F_H_OPTION;
3058
 
               break;
3059
 
             case 'q':
3060
 
               sar_actflag |= A_QUEUE;
3061
 
               dis_hdr++;
3062
 
               break;
3063
 
             case 'r':
3064
 
               sar_actflag |= A_MEM_AMT;
3065
 
               dis_hdr++;
3066
 
               break;
3067
 
             case 'R':
3068
 
               sar_actflag |= A_MEMORY;
3069
 
               dis_hdr++;
3070
 
               break;
3071
 
             case 't':
3072
 
               flags |= F_ORG_TIME;
3073
 
               break;
3074
 
             case 'u':
3075
 
               sar_actflag |= A_CPU;
3076
 
               dis_hdr++;
3077
 
               break;
3078
 
             case 'v':
3079
 
               sar_actflag |= A_KTABLES;
3080
 
               dis_hdr++;
3081
 
               break;
3082
 
             case 'w':
3083
 
               sar_actflag |= A_CTXSW;
3084
 
               dis_hdr++;
3085
 
               break;
3086
 
             case 'W':
3087
 
               sar_actflag |= A_SWAP;
3088
 
               dis_hdr++;
3089
 
               break;
3090
 
             case 'y':
3091
 
               sar_actflag |= A_SERIAL;
3092
 
               dis_hdr++;
3093
 
               break;
3094
 
             case 'V':
3095
 
             default:
3096
 
               usage(argv[0]);
3097
 
            }
3098
 
         }
 
1667
         if (parse_sar_opt(argv, opt, &sar_actflag, &flags, &dis_hdr, C_SAR,
 
1668
                           irq_bitmap, cpu_bitmap))
 
1669
            usage(argv[0]);
3099
1670
         opt++;
3100
1671
      }
3101
1672
 
3102
 
      else if (!interval) {                             /* Get interval */
 
1673
      else if (interval < 0) {                          /* Get interval */
 
1674
         if (strspn(argv[opt], DIGITS) != strlen(argv[opt]))
 
1675
            usage(argv[0]);
 
1676
         interval = atol(argv[opt++]);
 
1677
         if (interval < 0)
 
1678
           usage(argv[0]);
 
1679
      }
 
1680
 
 
1681
      else {                                    /* Get count value */
3103
1682
         if ((strspn(argv[opt], DIGITS) != strlen(argv[opt])) ||
3104
 
             WANT_BOOT_STATS(flags))
3105
 
            usage(argv[0]);
3106
 
         interval = atol(argv[opt++]);
3107
 
         if (!interval)
3108
 
            flags |= F_BOOT_STATS;
3109
 
         else if (interval < 0)
3110
 
           usage(argv[0]);
3111
 
         count = 1;     /* Default value for the count parameter is 1 */
3112
 
         flags |= F_DEFAULT_COUNT;
3113
 
      }
3114
 
 
3115
 
      else {                                    /* Get count value */
3116
 
         if (strspn(argv[opt], DIGITS) != strlen(argv[opt]))
3117
 
            usage(argv[0]);
3118
 
         if (count && !USE_DEFAULT_COUNT(flags))
 
1683
             !interval)
 
1684
            usage(argv[0]);
 
1685
         if (count)
3119
1686
            /* Count parameter already set */
3120
1687
            usage(argv[0]);
3121
1688
         count = atol(argv[opt++]);
3123
1690
           usage(argv[0]);
3124
1691
         else if (!count)
3125
1692
            count = -1; /* To generate a report continuously */
3126
 
         flags &= ~F_DEFAULT_COUNT;
3127
1693
      }
3128
1694
   }
3129
1695
 
3130
1696
   /* 'sar' is equivalent to 'sar -f' */
3131
1697
   if ((argc == 1) ||
3132
 
       (!interval && !WANT_BOOT_STATS(flags) &&
3133
 
        !from_file[0] && !to_file[0])) {
 
1698
       ((interval < 0) && !from_file[0] && !to_file[0])) {
3134
1699
      get_localtime(&loc_time);
3135
1700
      snprintf(from_file, MAX_FILE_LEN,
3136
1701
               "%s/sa%02d", SA_DIR, loc_time.tm_mday);
3145
1710
      fprintf(stderr, _("-f and -o options are mutually exclusive\n"));
3146
1711
      exit(1);
3147
1712
   }
3148
 
   /* Use time start or options -i/-h/-H only when reading stats from a file */
3149
 
   if ((tm_start.use || (USE_I_OPTION(flags)) ||
3150
 
        USE_H_OPTION(flags) || USE_DB_OPTION(flags))
3151
 
       && !from_file[0]) {
3152
 
      fprintf(stderr, _("Not reading from a system activity file (use -f option)\n"));
 
1713
   /* Use time start or option -i only when reading stats from a file */
 
1714
   if ((tm_start.use || USE_I_OPTION(flags)) && !from_file[0]) {
 
1715
      fprintf(stderr,
 
1716
              _("Not reading from a system activity file (use -f option)\n"));
3153
1717
      exit(1);
3154
1718
   }
3155
 
   /* Don't print stats since boot time if -o or -f flags are used */
3156
 
   if (WANT_BOOT_STATS(flags) && (from_file[0] || to_file[0]))
 
1719
   /* Don't print stats since boot time if -o or -f options are used */
 
1720
   if (!interval && (from_file[0] || to_file[0]))
3157
1721
      usage(argv[0]);
3158
 
   /*
3159
 
    * Display all the contents of the daily data file if the count parameter
3160
 
    * was not set on the command line.
3161
 
    */
3162
 
   if (USE_DEFAULT_COUNT(flags) && from_file[0])
3163
 
      count = -1;
 
1722
 
 
1723
   if (!count) {
 
1724
      /* count parameter not set */
 
1725
      if (from_file[0])
 
1726
         /* Display all the contents of the daily data file */
 
1727
         count = -1;
 
1728
      else
 
1729
         /* Default value for the count parameter is 1 */
 
1730
         count = 1;
 
1731
   }
3164
1732
 
3165
1733
   /* -x and -X options ignored when writing to a file */
3166
1734
   if (to_file[0]) {
3180
1748
 
3181
1749
   /* ---Reading stats from file */
3182
1750
   if (from_file[0]) {
3183
 
      if (!count)
3184
 
         count = -1;
3185
 
      if (!interval)
 
1751
      if (interval < 0)
3186
1752
         interval = 1;
3187
1753
 
3188
 
      /* If -A option is used, force '-P ALL' */
3189
 
      if (USE_A_OPTION(flags)) {
3190
 
         init_cpu_bitmap(~0);
3191
 
         flags |= F_ALL_PROC + F_PER_PROC;
3192
 
      }
3193
 
 
3194
1754
      /* Read stats from file */
3195
1755
      read_stats_from_file(from_file);
3196
1756
 
3223
1783
      salloc(0, SADC);
3224
1784
 
3225
1785
      /* Interval value */
3226
 
      if (!interval) {
3227
 
         if (WANT_BOOT_STATS(flags))
3228
 
            strcpy(ltemp, "1");
3229
 
         else
3230
 
            usage(argv[0]);
3231
 
      }
 
1786
      if (interval < 0)
 
1787
         usage(argv[0]);
 
1788
      else if (!interval)
 
1789
         strcpy(ltemp, "1");
3232
1790
      else
3233
1791
         sprintf(ltemp, "%ld", interval);
3234
1792
      salloc(1, ltemp);
3239
1797
         salloc(args_idx++, ltemp);
3240
1798
      }
3241
1799
 
3242
 
      /* -I flag */
 
1800
      /* Flags to be passed to sadc */
 
1801
      salloc(args_idx++, "-z");
3243
1802
      if (GET_ONE_IRQ(sar_actflag))
3244
1803
         salloc(args_idx++, "-I");
 
1804
      if (GET_DISK(sar_actflag))
 
1805
         salloc(args_idx++, "-d");
3245
1806
 
3246
1807
      /* Outfile arg */
3247
1808
      if (to_file[0])
3252
1813
 
3253
1814
      /* Call now the data collector */
3254
1815
      execv(SADC_PATH, args);
3255
 
      execv(SADC_LOCAL_PATH, args);
3256
1816
      execvp(SADC, args);
3257
 
      execv(SADC_ALT_PATH, args);
3258
1817
      /*
3259
1818
       * Note: don't use execl/execlp since we don't have a fixed number of
3260
1819
       * args to give to sadc.