~ubuntu-branches/ubuntu/precise/sysstat/precise

« back to all changes in this revision

Viewing changes to sadf.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Luberda
  • Date: 2009-11-21 21:34:09 UTC
  • mfrom: (1.1.17 upstream) (2.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20091121213409-r1doxsuhuhj1gvsm
Tags: 9.0.6-1
* New upstream release:
  + sadf improved (closes: #546259).
* Install a new sargraph script into examples.

Show diffs side-by-side

added added

removed removed

Lines of Context:
86
86
                progname);
87
87
 
88
88
        fprintf(stderr, _("Options are:\n"
89
 
                          "[ -d | -D | -H | -p | -x ] [ -h ] [ -t ] [ -V ]\n"
 
89
                          "[ -d | -D | -H | -p | -x ] [ -C ] [ -h ] [ -t ] [ -V ]\n"
90
90
                          "[ -P { <cpu> [,...] | ALL } ] [ -s [ <hh:mm:ss> ] ] [ -e [ <hh:mm:ss> ] ]\n"
91
91
                          "[ -- <sar_options> ]\n"));
92
92
        exit(1);
296
296
{
297
297
        unsigned long long dt, itv, g_itv;
298
298
        char cur_time[26];
299
 
        static int cross_day = 0;
 
299
        static int cross_day = FALSE;
300
300
        static __nr_t cpu_nr = -1;
301
301
        
302
302
        if (cpu_nr < 0) {
322
322
        if (use_tm_start && record_hdr[!curr].ust_time &&
323
323
            (record_hdr[curr].ust_time > record_hdr[!curr].ust_time) &&
324
324
            (record_hdr[curr].hour < record_hdr[!curr].hour)) {
325
 
                cross_day = 1;
 
325
                cross_day = TRUE;
326
326
        }
327
327
 
328
328
        if (cross_day) {
366
366
 * Display XML activity records
367
367
 *
368
368
 * IN:
369
 
 * @curr        Index in array for current sample statistics.
370
 
 * @tab         Number of tabulations to print.
371
 
 * @cpu_nr      Number of processors.
 
369
 * @curr                Index in array for current sample statistics.
 
370
 * @use_tm_start        Set to TRUE if option -s has been used.
 
371
 * @use_tm_end          Set to TRUE if option -e has been used.
 
372
 * @reset               Set to TRUE if last_uptime should be reinitialized
 
373
 *                      (used in next_slice() function).
 
374
 * @tab                 Number of tabulations to print.
 
375
 * @cpu_nr              Number of processors.
 
376
 *
 
377
 * OUT:
 
378
 * @cnt                 Set to 0 to indicate that no other lines of stats
 
379
 *                      should be displayed.
 
380
 *
 
381
 * RETURNS:
 
382
 * 1 if stats have been successfully displayed.
372
383
 ***************************************************************************
373
384
 */
374
 
void write_xml_stats(int curr, int tab, __nr_t cpu_nr)
 
385
int write_xml_stats(int curr, int use_tm_start, int use_tm_end, int reset,
 
386
                    long *cnt, int tab, __nr_t cpu_nr)
375
387
{
376
388
        int i;
377
389
        unsigned long long dt, itv, g_itv;
378
390
        char cur_time[XML_TIMESTAMP_LEN];
 
391
        static int cross_day = FALSE;
379
392
 
380
393
        /* Fill timestamp structure (rectime) for current record */
381
394
        sadf_get_record_timestamp_struct(curr);
382
395
 
 
396
        /*
 
397
         * Check time (1).
 
398
         * For this first check, we use the time interval entered on
 
399
         * the command line. This is equivalent to sar's option -i which
 
400
         * selects records at seconds as close as possible to the number
 
401
         * specified by the interval parameter.
 
402
         */
 
403
        if (!next_slice(record_hdr[2].uptime0, record_hdr[curr].uptime0,
 
404
                        reset, interval))
 
405
                /* Not close enough to desired interval */
 
406
                return 0;
 
407
 
 
408
        /* Check if we are beginning a new day */
 
409
        if (use_tm_start && record_hdr[!curr].ust_time &&
 
410
            (record_hdr[curr].ust_time > record_hdr[!curr].ust_time) &&
 
411
            (record_hdr[curr].hour < record_hdr[!curr].hour)) {
 
412
                cross_day = TRUE;
 
413
        }
 
414
 
 
415
        if (cross_day) {
 
416
                /*
 
417
                 * This is necessary if we want to properly handle something like:
 
418
                 * sar -s time_start -e time_end with
 
419
                 * time_start(day D) > time_end(day D+1)
 
420
                 */
 
421
                loctime.tm_hour += 24;
 
422
        }
 
423
 
 
424
        /* Check time (2) */
 
425
        if (use_tm_start && (datecmp(&loctime, &tm_start) < 0))
 
426
                /* it's too soon... */
 
427
                return 0;
 
428
 
383
429
        /* Get interval values */
384
430
        get_itv_value(&record_hdr[curr], &record_hdr[!curr],
385
431
                      cpu_nr, &itv, &g_itv);
386
432
 
 
433
        /* Check time (3) */
 
434
        if (use_tm_end && (datecmp(&loctime, &tm_end) > 0)) {
 
435
                /* It's too late... */
 
436
                *cnt = 0;
 
437
                return 0;
 
438
        }
 
439
 
387
440
        dt = itv / HZ;
388
441
        /* Correct rounding error for dt */
389
442
        if ((itv % HZ) >= (HZ / 2)) {
396
449
        xprintf(tab, "<timestamp %s interval=\"%llu\">", cur_time, dt);
397
450
        tab++;
398
451
 
399
 
 
400
452
        /* Display XML statistics */
401
453
        for (i = 0; i < NR_ACT; i++) {
402
454
                
413
465
        }
414
466
 
415
467
        xprintf(--tab, "</timestamp>");
 
468
 
 
469
        return 1;
416
470
}
417
471
 
418
472
/*
420
474
 * Display XML restart records
421
475
 *
422
476
 * IN:
423
 
 * @curr        Index in array for current sample statistics.
424
 
 * @tab         Number of tabulations to print.
 
477
 * @curr                Index in array for current sample statistics.
 
478
 * @use_tm_start        Set to TRUE if option -s has been used.
 
479
 * @use_tm_end          Set to TRUE if option -e has been used.
 
480
 * @tab                 Number of tabulations to print.
425
481
 ***************************************************************************
426
482
 */
427
 
void write_xml_restarts(int curr, int tab)
 
483
void write_xml_restarts(int curr, int use_tm_start, int use_tm_end, int tab)
428
484
{
429
485
        char cur_time[64];
430
486
 
431
487
        /* Fill timestamp structure for current record */
432
488
        sadf_get_record_timestamp_struct(curr);
 
489
        
 
490
        /* The record must be in the interval specified by -s/-e options */
 
491
        if ((use_tm_start && (datecmp(&loctime, &tm_start) < 0)) ||
 
492
            (use_tm_end && (datecmp(&loctime, &tm_end) > 0)))
 
493
                return;
433
494
 
434
495
        strftime(cur_time, 64, "date=\"%Y-%m-%d\" time=\"%H:%M:%S\"", &rectime);
435
496
        xprintf(tab, "<boot %s/>", cur_time);
440
501
 * Display XML COMMENT records
441
502
 *
442
503
 * IN:
443
 
 * @curr        Index in array for current sample statistics.
444
 
 * @tab         Number of tabulations to print.
445
 
 * @ifd         Input file descriptor.
 
504
 * @curr                Index in array for current sample statistics.
 
505
 * @use_tm_start        Set to TRUE if option -s has been used.
 
506
 * @use_tm_end          Set to TRUE if option -e has been used.
 
507
 * @tab                 Number of tabulations to print.
 
508
 * @ifd                 Input file descriptor.
446
509
 ***************************************************************************
447
510
 */
448
 
void write_xml_comments(int curr, int tab, int ifd)
 
511
void write_xml_comments(int curr, int use_tm_start, int use_tm_end, int tab, int ifd)
449
512
{
450
513
        char cur_time[64];
451
514
        char file_comment[MAX_COMMENT_LEN];
456
519
        /* Fill timestamp structure for current record */
457
520
        sadf_get_record_timestamp_struct(curr);
458
521
 
 
522
        /* The record must be in the interval specified by -s/-e options */
 
523
        if ((use_tm_start && (datecmp(&loctime, &tm_start) < 0)) ||
 
524
            (use_tm_end && (datecmp(&loctime, &tm_end) > 0)))
 
525
                return;
 
526
 
459
527
        strftime(cur_time, 64, "date=\"%Y-%m-%d\" time=\"%H:%M:%S\"", &rectime);
460
528
        xprintf(tab, "<comment %s com=\"%s\"/>", cur_time, file_comment);
461
529
}
681
749
                                        (*cnt)--;
682
750
                                }
683
751
                        }
684
 
 
685
752
                        *reset = FALSE;
686
753
                }
687
754
        }
702
769
void xml_display_loop(int ifd, struct file_activity *file_actlst)
703
770
{
704
771
        int curr, tab = 0, rtype;
705
 
        int eosaf = TRUE;
 
772
        int eosaf = TRUE, next, reset = FALSE;
 
773
        long cnt = 1;
706
774
        off_t fpos;
707
775
        static __nr_t cpu_nr = -1;
708
776
        
737
805
                                 */
738
806
                                read_file_stat_bunch(act, 0, ifd, file_hdr.sa_nr_act,
739
807
                                                     file_actlst);
 
808
                                sadf_get_record_timestamp_struct(0);
740
809
                        }
741
810
 
742
811
                        if (!eosaf && (rtype == R_COMMENT)) {
750
819
                                }
751
820
                        }
752
821
                }
753
 
                while (!eosaf && ((rtype == R_RESTART) || (rtype == R_COMMENT)));
 
822
                while (!eosaf && ((rtype == R_RESTART) || (rtype == R_COMMENT) ||
 
823
                        (tm_start.use && (datecmp(&loctime, &tm_start) < 0)) ||
 
824
                        (tm_end.use && (datecmp(&loctime, &tm_end) >=0))));
 
825
 
 
826
                /* Save the first stats collected. Used for example in next_slice() function */
 
827
                copy_structures(act, id_seq, record_hdr, 2, 0);
754
828
 
755
829
                curr = 1;
 
830
                cnt = count;
 
831
                reset = TRUE;
756
832
 
757
833
                if (!eosaf) {
758
834
                        do {
765
841
                                        read_file_stat_bunch(act, curr, ifd, file_hdr.sa_nr_act,
766
842
                                                             file_actlst);
767
843
 
768
 
                                        write_xml_stats(curr, tab, cpu_nr);
769
 
                                        curr ^= 1;
 
844
                                        /* next is set to 1 when we were close enough to desired interval */
 
845
                                        next = write_xml_stats(curr, tm_start.use, tm_end.use, reset,
 
846
                                                        &cnt, tab, cpu_nr);
 
847
 
 
848
                                        if (next) {
 
849
                                                curr ^= 1;
 
850
                                                if (cnt > 0) {
 
851
                                                        cnt--;
 
852
                                                }
 
853
                                        }
 
854
                                        reset = FALSE;
770
855
                                }
771
856
 
772
857
                                if (!eosaf && (rtype == R_COMMENT)) {
776
861
                                        }
777
862
                                }
778
863
                        }
779
 
                        while (!eosaf && (rtype != R_RESTART));
 
864
                        while (cnt && !eosaf && (rtype != R_RESTART));
 
865
 
 
866
                        if (!cnt) {
 
867
                                /* Go to next Linux restart, if possible */
 
868
                                do {
 
869
                                        eosaf = sa_fread(ifd, &record_hdr[curr], RECORD_HEADER_SIZE,
 
870
                                                         SOFT_SIZE);
 
871
                                        rtype = record_hdr[curr].record_type;
 
872
                                        if (!eosaf && (rtype != R_RESTART) && (rtype != R_COMMENT)) {
 
873
                                                read_file_stat_bunch(act, curr, ifd, file_hdr.sa_nr_act,
 
874
                                                                     file_actlst);
 
875
                                        }
 
876
                                        else if (!eosaf && (rtype == R_COMMENT)) {
 
877
                                                /* Ignore COMMENT record */
 
878
                                                if (lseek(ifd, MAX_COMMENT_LEN, SEEK_CUR) < MAX_COMMENT_LEN) {
 
879
                                                        perror("lseek");
 
880
                                                }
 
881
                                        }
 
882
                                }
 
883
                                while (!eosaf && (rtype != R_RESTART));
 
884
                        }
 
885
                        reset = TRUE;
780
886
                }
781
887
        }
782
888
        while (!eosaf);
800
906
                                                     file_actlst);
801
907
                        }
802
908
                        if (rtype == R_RESTART) {
803
 
                                write_xml_restarts(0, tab);
 
909
                                write_xml_restarts(0, tm_start.use, tm_end.use, tab);
804
910
                        }
805
911
                        else if (rtype == R_COMMENT) {
806
912
                                /* Ignore COMMENT record */
820
926
        }
821
927
 
822
928
        /* Last, process COMMENT entries to display comments */
823
 
        xprintf(tab++, "<comments>");
824
 
        do {
825
 
                if ((eosaf = sa_fread(ifd, &record_hdr[0], RECORD_HEADER_SIZE,
826
 
                                      SOFT_SIZE)) == 0) {
 
929
        if (DISPLAY_COMMENT(flags)) {
 
930
                xprintf(tab++, "<comments>");
 
931
                do {
 
932
                        if ((eosaf = sa_fread(ifd, &record_hdr[0], RECORD_HEADER_SIZE,
 
933
                                              SOFT_SIZE)) == 0) {
827
934
 
828
 
                        rtype = record_hdr[0].record_type;
829
 
                        if ((rtype != R_RESTART) && (rtype != R_COMMENT)) {
830
 
                                read_file_stat_bunch(act, 0, ifd, file_hdr.sa_nr_act,
831
 
                                                     file_actlst);
832
 
                        }
833
 
                        if (rtype == R_COMMENT) {
834
 
                                write_xml_comments(0, tab, ifd);
 
935
                                rtype = record_hdr[0].record_type;
 
936
                                if ((rtype != R_RESTART) && (rtype != R_COMMENT)) {
 
937
                                        read_file_stat_bunch(act, 0, ifd, file_hdr.sa_nr_act,
 
938
                                                             file_actlst);
 
939
                                }
 
940
                                if (rtype == R_COMMENT) {
 
941
                                        write_xml_comments(0, tm_start.use, tm_end.use,
 
942
                                                           tab, ifd);
 
943
                                }
835
944
                        }
836
945
                }
 
946
                while (!eosaf);
 
947
                xprintf(--tab, "</comments>");
837
948
        }
838
 
        while (!eosaf);
839
 
        xprintf(--tab, "</comments>");
840
 
 
 
949
        
841
950
        xprintf(--tab, "</host>");
842
951
        xprintf(--tab, "</sysstat>");
843
952
}
891
1000
                /* Save the first stats collected. Will be used to compute the average */
892
1001
                copy_structures(act, id_seq, record_hdr, 2, 0);
893
1002
 
894
 
                reset = TRUE;   /* Set flag to reset last_uptime variable */
 
1003
                /* Set flag to reset last_uptime variable. Should be done after a LINUX RESTART record */
 
1004
                reset = TRUE;
895
1005
 
896
1006
                /* Save current file position */
897
1007
                if ((fpos = lseek(ifd, 0, SEEK_CUR)) < 0) {
955
1065
                                        read_file_stat_bunch(act, curr, ifd, file_hdr.sa_nr_act,
956
1066
                                                             file_actlst);
957
1067
                                }
 
1068
                                else if (!eosaf && (rtype == R_COMMENT)) {
 
1069
                                        /* This was a COMMENT record: print it */
 
1070
                                        sadf_print_special(curr, tm_start.use, tm_end.use, R_COMMENT, ifd);
 
1071
                                }
958
1072
                        }
959
1073
                        while (!eosaf && (rtype != R_RESTART));
960
1074
                }
1105
1219
 
1106
1220
                                        switch (*(argv[opt] + i)) {
1107
1221
 
 
1222
                                        case 'C':
 
1223
                                                flags |= S_F_COMMENT;
 
1224
                                                break;
 
1225
                                                        
1108
1226
                                        case 'd':
1109
1227
                                                if (format && (format != S_O_DB_OPTION)) {
1110
1228
                                                        usage(argv[0]);