]> granicus.if.org Git - sysstat/blobdiff - cifsiostat.c
sar/sadc: Add stable identifier support for disks statistics
[sysstat] / cifsiostat.c
index 7e369201ed7305011885b58d5efac251a161cca6..936f95c83ead90e68a571cdbd9a1c6209dc8f059 100644 (file)
@@ -30,7 +30,8 @@
 
 #include "version.h"
 #include "cifsiostat.h"
-#include "common.h"
+#include "rd_stats.h"
+#include "count.h"
 
 #ifdef USE_NLS
 #include <locale.h>
 #define _(string) (string)
 #endif
 
+#ifdef USE_SCCSID
 #define SCCSID "@(#)sysstat-" VERSION ": " __FILE__ " compiled " __DATE__ " " __TIME__
 char *sccsid(void) { return (SCCSID); }
+#endif
+
+#ifdef TEST
+void int_handler(int n) { return; }
+#endif
 
-unsigned long long uptime[2]  = {0, 0};
-unsigned long long uptime0[2] = {0, 0};
+unsigned long long uptime_cs[2] = {0, 0};
 struct cifs_stats *st_cifs[2];
 struct io_hdr_stats *st_hdr_cifs;
 
 int cifs_nr = 0;       /* Nb of CIFS mounted directories found */
 int cpu_nr = 0;                /* Nb of processors on the machine */
 int flags = 0;         /* Flag for common options and system state */
+int dplaces_nr = -1;   /* Number of decimal places */
 
 long interval = 0;
-char timestamp[64];
+char timestamp[TIMESTAMP_LEN];
 
+struct sigaction alrm_act;
 
 /*
  ***************************************************************************
@@ -71,10 +79,10 @@ void usage(char *progname)
 
 #ifdef DEBUG
        fprintf(stderr, _("Options are:\n"
-                         "[ --debuginfo ] [ -h ] [ -k | -m ] [ -t ] [ -V ]\n"));
+                         "[ --dec={ 0 | 1 | 2 } ] [ --human ] [ -h ] [ -k | -m ] [ -t ] [ -V ] [ --debuginfo ]\n"));
 #else
        fprintf(stderr, _("Options are:\n"
-                         "[ -h ] [ -k | -m ] [ -t ] [ -V ]\n"));
+                         "[ --dec={ 0 | 1 | 2 } ] [ --human ] [ -h ] [ -k | -m ] [ -t ] [ -V ]\n"));
 #endif
        exit(1);
 }
@@ -84,12 +92,11 @@ void usage(char *progname)
  * SIGALRM signal handler.
  *
  * IN:
- * @sig        Signal number. Set to 0 for the first time, then to SIGALRM.
+ * @sig        Signal number.
  ***************************************************************************
  */
 void alarm_handler(int sig)
 {
-       signal(SIGALRM, alarm_handler);
        alarm(interval);
 }
 
@@ -112,8 +119,8 @@ int get_cifs_nr(void)
                /* File non-existent */
                return 0;
 
-       while (fgets(line, 128, fp) != NULL) {
-               
+       while (fgets(line, sizeof(line), fp) != NULL) {
+
                if (!strncmp(line, "Share (unique mount targets): ", 30)) {
                        sscanf(line + 30, "%d", &cifs);
                        break;
@@ -166,26 +173,36 @@ void free_inactive_entries(void)
 void io_sys_init(void)
 {
        int i;
-       
+
        /* How many processors on this machine? */
-       cpu_nr = get_cpu_nr(~0);
+       cpu_nr = get_cpu_nr(~0, FALSE);
 
        /* Get number of CIFS directories in /proc/fs/cifs/Stats */
        if ((cifs_nr = get_cifs_nr()) > 0) {
                cifs_nr += NR_CIFS_PREALLOC;
        }
-       if ((st_hdr_cifs = (struct io_hdr_stats *) calloc(cifs_nr, IO_HDR_STATS_SIZE)) == NULL) {
-               perror("malloc");
-               exit(4);
-       }
-       
-       /* Allocate structures for number of CIFS directories found */
-       for (i = 0; i < 2; i++) {
-               if ((st_cifs[i] =
-                   (struct cifs_stats *) calloc(cifs_nr, CIFS_STATS_SIZE)) == NULL) {
+
+       if (cifs_nr > 0) {
+               if ((st_hdr_cifs = (struct io_hdr_stats *) calloc(cifs_nr, IO_HDR_STATS_SIZE)) == NULL) {
                        perror("malloc");
                        exit(4);
                }
+
+               /* Allocate structures for number of CIFS directories found */
+               for (i = 0; i < 2; i++) {
+                       if ((st_cifs[i] =
+                       (struct cifs_stats *) calloc(cifs_nr, CIFS_STATS_SIZE)) == NULL) {
+                               perror("malloc");
+                               exit(4);
+                       }
+               }
+       }
+       else {
+               /*
+                * cifs_nr value is probably zero, but it can also be negative
+                * (possible overflow when adding NR_CIFS_PREALLOC above).
+                */
+               cifs_nr = 0;
        }
 }
 
@@ -200,15 +217,10 @@ void io_sys_free(void)
 
        /* Free CIFS directories structures */
        for (i = 0; i < 2; i++) {
-
-               if (st_cifs[i]) {
-                       free(st_cifs[i]);
-               }
-       }
-       
-       if (st_hdr_cifs) {
-               free(st_hdr_cifs);
+               free(st_cifs[i]);
        }
+
+       free(st_hdr_cifs);
 }
 
 /*
@@ -246,7 +258,8 @@ void save_stats(char *name, int curr, struct cifs_stats *st_io)
                                /* Unused entry found... */
                                st_hdr_cifs_i->used = TRUE; /* Indicate it is now used */
                                st_hdr_cifs_i->active = TRUE;
-                               strcpy(st_hdr_cifs_i->name, name);
+                               strncpy(st_hdr_cifs_i->name, name, MAX_NAME_LEN - 1);
+                               st_hdr_cifs_i->name[MAX_NAME_LEN - 1] = '\0';
                                st_cifs_i = st_cifs[curr] + i;
                                *st_cifs_i = *((struct cifs_stats *) st_io);
                                break;
@@ -288,7 +301,8 @@ void save_stats(char *name, int curr, struct cifs_stats *st_io)
                        st_hdr_cifs_i = st_hdr_cifs + i;
                        st_hdr_cifs_i->used = TRUE; /* Indicate it is now used */
                        st_hdr_cifs_i->active = TRUE;
-                       strcpy(st_hdr_cifs_i->name, name);
+                       strncpy(st_hdr_cifs_i->name, name, MAX_NAME_LEN - 1);
+                       st_hdr_cifs_i->name[MAX_NAME_LEN - 1] = '\0';
                        st_cifs_i = st_cifs[curr] + i;
                        *st_cifs_i = *st_io;
                }
@@ -323,7 +337,7 @@ void read_cifs_stat(int curr)
        long long unsigned all_open = 0;
        char cifs_name[MAX_NAME_LEN];
        char name_tmp[MAX_NAME_LEN];
-       struct cifs_stats scifs;
+       struct cifs_stats scifs = {0, 0, 0, 0, 0, 0, 0};
 
        /* Every CIFS entry is potentially unregistered */
        set_entries_inactive();
@@ -334,7 +348,7 @@ void read_cifs_stat(int curr)
        sprintf(aux, "%%*d) %%%ds",
                MAX_NAME_LEN < 200 ? MAX_NAME_LEN - 1 : 200);
 
-       while (fgets(line, 256, fp) != NULL) {
+       while (fgets(line, sizeof(line), fp) != NULL) {
 
                /* Read CIFS directory name */
                if (isdigit((unsigned char) line[0]) && sscanf(line, aux , name_tmp) == 1) {
@@ -346,7 +360,8 @@ void read_cifs_stat(int curr)
                        else {
                                start = 1;
                        }
-                       strcpy(cifs_name, name_tmp);
+                       strncpy(cifs_name, name_tmp, MAX_NAME_LEN);
+                       cifs_name[MAX_NAME_LEN - 1] = '\0';
                }
                else {
                        if (!strncmp(line, "Reads:", 6)) {
@@ -366,7 +381,7 @@ void read_cifs_stat(int curr)
                        }
                }
        }
-       
+
        if (start) {
                scifs.fopens = all_open;
                save_stats(cifs_name, curr, &scifs);
@@ -388,7 +403,9 @@ void read_cifs_stat(int curr)
  */
 void write_cifs_stat_header(int *fctr)
 {
-       printf("Filesystem:           ");
+       if (!DISPLAY_HUMAN_READ(flags)) {
+               printf("Filesystem            ");
+       }
        if (DISPLAY_KILOBYTES(flags)) {
                printf("        rkB/s        wkB/s");
                *fctr = 1024;
@@ -401,7 +418,11 @@ void write_cifs_stat_header(int *fctr)
                printf("         rB/s         wB/s");
                *fctr = 1;
        }
-       printf("    rops/s    wops/s         fo/s         fc/s         fd/s\n");
+       printf("    rops/s    wops/s         fo/s         fc/s         fd/s");
+       if (DISPLAY_HUMAN_READ(flags)) {
+               printf(" Filesystem");
+       }
+       printf("\n");
 }
 
 /*
@@ -410,7 +431,7 @@ void write_cifs_stat_header(int *fctr)
  *
  * IN:
  * @curr       Index in array for current sample statistics.
- * @itv                Interval of time.
+ * @itv                Interval of time (in 1/100th of a second).
  * @fctr       Conversion factor.
  * @shi                Structures describing the CIFS filesystems.
  * @ioi                Current sample statistics.
@@ -421,22 +442,32 @@ void write_cifs_stat(int curr, unsigned long long itv, int fctr,
                     struct io_hdr_stats *shi, struct cifs_stats *ioni,
                     struct cifs_stats *ionj)
 {
-       if (DISPLAY_HUMAN_READ(flags)) {
-               printf("%-22s\n%23s", shi->name, "");
-       }
-       else {
-               printf("%-22s ", shi->name);
+       double rbytes, wbytes;
+
+       if (!DISPLAY_HUMAN_READ(flags)) {
+               cprintf_in(IS_STR, "%-22s", shi->name, 0);
        }
 
        /*       rB/s   wB/s   fo/s   fc/s   fd/s*/
-       printf("%12.2f %12.2f %9.2f %9.2f %12.2f %12.2f %12.2f \n",
-              S_VALUE(ionj->rd_bytes, ioni->rd_bytes, itv) / fctr,
-              S_VALUE(ionj->wr_bytes, ioni->wr_bytes, itv) / fctr,
-              S_VALUE(ionj->rd_ops, ioni->rd_ops, itv),
-              S_VALUE(ionj->wr_ops, ioni->wr_ops, itv),
-              S_VALUE(ionj->fopens, ioni->fopens, itv),
-              S_VALUE(ionj->fcloses, ioni->fcloses, itv),
-              S_VALUE(ionj->fdeletes, ioni->fdeletes, itv));
+       rbytes = S_VALUE(ionj->rd_bytes, ioni->rd_bytes, itv);
+       wbytes = S_VALUE(ionj->wr_bytes, ioni->wr_bytes, itv);
+       if (!DISPLAY_UNIT(flags)) {
+               rbytes /= fctr;
+               wbytes /= fctr;
+       }
+       cprintf_f(DISPLAY_UNIT(flags) ? UNIT_BYTE : NO_UNIT, 2, 12, 2,
+                 rbytes, wbytes);
+       cprintf_f(NO_UNIT, 2, 9, 2,
+                 S_VALUE(ionj->rd_ops, ioni->rd_ops, itv),
+                 S_VALUE(ionj->wr_ops, ioni->wr_ops, itv));
+       cprintf_f(NO_UNIT, 3, 12, 2,
+                 S_VALUE(ionj->fopens, ioni->fopens, itv),
+                 S_VALUE(ionj->fcloses, ioni->fcloses, itv),
+                 S_VALUE(ionj->fdeletes, ioni->fdeletes, itv));
+       if (DISPLAY_HUMAN_READ(flags)) {
+               cprintf_in(IS_STR, " %s", shi->name, 0);
+       }
+       printf("\n");
 }
 
 /*
@@ -474,13 +505,8 @@ void write_stats(int curr, struct tm *rectime)
 #endif
        }
 
-       /* Interval is multiplied by the number of processors */
-       itv = get_interval(uptime[!curr], uptime[curr]);
-
-       if (cpu_nr > 1) {
-               /* On SMP machines, reduce itv to one processor (see note above) */
-               itv = get_interval(uptime0[!curr], uptime0[curr]);
-       }
+       /* Interval of time, reduced to one processor */
+       itv = get_interval(uptime_cs[!curr], uptime_cs[curr]);
 
        shi = st_hdr_cifs;
 
@@ -525,17 +551,10 @@ void rw_io_stat_loop(long int count, struct tm *rectime)
 
        /* Don't buffer data if redirected to a pipe */
        setbuf(stdout, NULL);
-       
+
        do {
-               if (cpu_nr > 1) {
-                       /*
-                        * Read system uptime (only for SMP machines).
-                        * Init uptime0. So if /proc/uptime cannot fill it,
-                        * this will be done by /proc/stat.
-                        */
-                       uptime0[curr] = 0;
-                       read_uptime(&(uptime0[curr]));
-               }
+               /* Read system uptime in 1/100th of a second */
+               read_uptime(&(uptime_cs[curr]));
 
                /* Read CIFS stats */
                read_cifs_stat(curr);
@@ -577,8 +596,8 @@ int main(int argc, char **argv)
        init_nls();
 #endif
 
-       /* Get HZ */
-       get_HZ();
+       /* Init color strings */
+       init_colors();
 
        /* Process args... */
        while (opt < argc) {
@@ -589,16 +608,31 @@ int main(int argc, char **argv)
                        opt++;
                } else
 #endif
-               if (!strncmp(argv[opt], "-", 1)) {
+
+               if (!strcmp(argv[opt], "--human")) {
+                       flags |= I_D_UNIT;
+                       opt++;
+               }
+
+               else if (!strncmp(argv[opt], "--dec=", 6) && (strlen(argv[opt]) == 7)) {
+                       /* Get number of decimal places */
+                       dplaces_nr = atoi(argv[opt] + 6);
+                       if ((dplaces_nr < 0) || (dplaces_nr > 2)) {
+                               usage(argv[0]);
+                       }
+                       opt++;
+               }
+
+               else if (!strncmp(argv[opt], "-", 1)) {
                        for (i = 1; *(argv[opt] + i); i++) {
 
                                switch (*(argv[opt] + i)) {
 
                                case 'h':
-                                       /* Display an easy-to-read CIFS report */
-                                       flags |= I_D_HUMAN_READ;
+                                       /* Display an easy-to-read CIFS report. Also imply --human */
+                                       flags |= I_D_HUMAN_READ + I_D_UNIT;
                                        break;
-       
+
                                case 'k':
                                        if (DISPLAY_MEGABYTES(flags)) {
                                                usage(argv[0]);
@@ -624,7 +658,7 @@ int main(int argc, char **argv)
                                        /* Print version number and exit */
                                        print_version();
                                        break;
-       
+
                                default:
                                        usage(argv[0]);
                                }
@@ -663,15 +697,19 @@ int main(int argc, char **argv)
        get_localtime(&rectime, 0);
 
        /* Get system name, release number and hostname */
-       uname(&header);
+       __uname(&header);
        if (print_gal_header(&rectime, header.sysname, header.release,
-                            header.nodename, header.machine, cpu_nr)) {
+                            header.nodename, header.machine, cpu_nr,
+                            PLAIN_OUTPUT)) {
                flags |= I_D_ISO;
        }
        printf("\n");
 
        /* Set a handler for SIGALRM */
-       alarm_handler(0);
+       memset(&alrm_act, 0, sizeof(alrm_act));
+       alrm_act.sa_handler = alarm_handler;
+       sigaction(SIGALRM, &alrm_act, NULL);
+       alarm(interval);
 
        /* Main loop */
        rw_io_stat_loop(count, &rectime);