]> granicus.if.org Git - sysstat/commitdiff
sar: Allow user to select interfaces to display
authorSebastien GODARD <sysstat@users.noreply.github.com>
Sat, 12 May 2018 08:31:50 +0000 (10:31 +0200)
committerSebastien GODARD <sysstat@users.noreply.github.com>
Sat, 12 May 2018 08:31:50 +0000 (10:31 +0200)
Add new option "--iface=<iface_list>" to allow the user to specify which
network interfaces to display. This option is to be used with options
"-n DEV" and "-n EDEV".
Sample output:

$ sar -n DEV
Linux 4.4.14-200.fc22.x86_64 (home) 05/12/18 _x86_64_ (8 CPU)

10:35:29        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s [...]
10:35:31           lo      0.00      0.00      0.00      0.00
10:35:31       virbr0      0.00      0.00      0.00      0.00
10:35:31       wlp5s0      0.00      0.00      0.00      0.00
10:35:31    virbr0-nic      0.00      0.00      0.00      0.00
10:35:31       enp6s0     49.00     41.00     29.17      6.47
10:35:33           lo      0.00      0.00      0.00      0.00
10:35:33       virbr0      0.00      0.00      0.00      0.00
10:35:33       wlp5s0      0.00      0.00      0.00      0.00
10:35:33    virbr0-nic      0.00      0.00      0.00      0.00
10:35:33       enp6s0   1033.50    608.50    993.34    116.88
[...]

$ sar -n DEV --iface=virbr0,enp6s0
Linux 4.4.14-200.fc22.x86_64 (home) 05/12/18 _x86_64_ (8 CPU)

10:35:29        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s [...]
10:35:31       virbr0      0.00      0.00      0.00      0.00
10:35:31       enp6s0     49.00     41.00     29.17      6.47
10:35:33       virbr0      0.00      0.00      0.00      0.00
10:35:33       enp6s0   1033.50    608.50    993.34    116.88
[...]

Signed-off-by: Sebastien GODARD <sysstat@users.noreply.github.com>
pr_stats.c
sa.h
sa_common.c
sar.c

index 40b3da8db1bfff024e9a0a5ffee248811eb84286..a0f106d77f789ec72724f346a63ed9c0af6834b5 100644 (file)
@@ -41,7 +41,8 @@ extern unsigned int dm_major;
 extern int  dis;
 extern char timestamp[][TIMESTAMP_LEN];
 extern unsigned long avg_count;
-
+extern struct sa_dlist *st_dev_list;
+extern int dlist_idx;
 
 /*
  ***************************************************************************
@@ -1153,6 +1154,14 @@ __print_funct_t print_net_dev_stats(struct activity *a, int prev, int curr,
                if (DISPLAY_ZERO_OMIT(flags) && !memcmp(sndp, sndc, STATS_NET_DEV_SIZE2CMP))
                        continue;
 
+               if (dlist_idx) {
+                       /* A list of devices has been entered on the command line */
+                       if (!search_sa_dlist(st_dev_list, dlist_idx, sndc->interface,
+                                            A_NET_DEV))
+                               /* Device not found */
+                               continue;
+               }
+
                printf("%-11s", timestamp[curr]);
 
                if (!DISPLAY_HUMAN_READ(flags)) {
@@ -1226,6 +1235,14 @@ __print_funct_t print_net_edev_stats(struct activity *a, int prev, int curr,
                if (DISPLAY_ZERO_OMIT(flags) && !memcmp(snedp, snedc, STATS_NET_EDEV_SIZE2CMP))
                        continue;
 
+               if (dlist_idx) {
+                       /* A list of devices has been entered on the command line */
+                       if (!search_sa_dlist(st_dev_list, dlist_idx, snedc->interface,
+                                            A_NET_DEV))
+                               /* Device not found */
+                               continue;
+               }
+
                printf("%-11s", timestamp[curr]);
 
                if (!DISPLAY_HUMAN_READ(flags)) {
diff --git a/sa.h b/sa.h
index dbb48e6555b92808c451648b7491318e32f1b759..ca157517e7dd4d714f4718755a671a8d0057fbc4 100644 (file)
--- a/sa.h
+++ b/sa.h
@@ -1097,6 +1097,16 @@ struct tstamp {
        int use;
 };
 
+/* List of devices entered on the command line */
+struct sa_dlist {
+       /* Device type */
+       int dev_id              __attribute__ ((aligned (4)));
+       /* Device name */
+       char dev_name[MAX_NAME_LEN];
+};
+
+#define SA_DLIST_SIZE  (sizeof(struct sa_dlist))
+
 
 /*
  ***************************************************************************
@@ -1264,6 +1274,8 @@ void get_itv_value
        (struct record_header *, struct record_header *, unsigned long long *);
 int next_slice
        (unsigned long long, unsigned long long, int, long);
+void parse_sa_devices
+       (int, char *[], struct sa_dlist **, int *, int *, int, int);
 int parse_sar_opt
        (char * [], int *, struct activity * [], unsigned int *, int);
 int parse_sar_I_opt
@@ -1305,6 +1317,10 @@ int sa_get_record_timestamp_struct
        (unsigned int, struct record_header *, struct tm *, struct tm *);
 int sa_open_read_magic
        (int *, char *, struct file_magic *, int, int *, int);
+void salloc_sa_dlist
+       (struct sa_dlist **, int);
+int search_sa_dlist
+       (struct sa_dlist *, int, char *, int);
 void select_all_activities
        (struct activity * []);
 void select_default_activity
index ea659e471014095e4317cc658a73e40359d00562..434fd12b12089d3b4759599ca5effcb9b9389c2e 100644 (file)
@@ -123,6 +123,55 @@ int get_activity_nr(struct activity *act[], unsigned int option, int count_outpu
        return n;
 }
 
+/*
+ ***************************************************************************
+ * Allocate structures for devices entered on the command line.
+ *
+ * IN:
+ * @list_len   Number of arguments on the command line.
+ *
+ * OUT:
+ * @st_dev_list        Address of allocated structures.
+ ***************************************************************************
+ */
+void salloc_sa_dlist(struct sa_dlist **st_dev_list, int list_len)
+{
+       if ((*st_dev_list = (struct sa_dlist *) malloc(SA_DLIST_SIZE * list_len)) == NULL) {
+               perror("malloc");
+               exit(4);
+       }
+       memset(*st_dev_list, 0, SA_DLIST_SIZE * list_len);
+}
+
+/*
+ ***************************************************************************
+ * Look for device in list.
+ *
+ * IN:
+ * @st_dev_list        Structure where devices are saved.
+ * @dlist_idx  Number of devices in the list.
+ * @d_name     Device name to look for.
+ * @d_id       Device type.
+ *
+ * RETURNS:
+ * 1 if device found in list, 0 otherwise.
+ ***************************************************************************
+ */
+int search_sa_dlist(struct sa_dlist *st_dev_list, int dlist_idx, char *d_name, int d_id)
+{
+       int i;
+       struct sa_dlist *st_dev_list_i;
+
+       for (i = 0; i < dlist_idx; i++) {
+               st_dev_list_i = st_dev_list + i;
+               if ((st_dev_list_i->dev_id == d_id) &&
+                   !strcmp(st_dev_list_i->dev_name, d_name))
+                       return 1;
+       }
+
+       return 0;
+}
+
 /*
  ***************************************************************************
  * Look for the most recent of saDD and saYYYYMMDD to decide which one to
@@ -2379,6 +2428,43 @@ int parse_sa_P_opt(char *argv[], int *opt, unsigned int *flags, struct activity
        return 1;
 }
 
+/*
+ ***************************************************************************
+ * Parse devices entered on the command line.
+ *
+ * IN:
+ * @argc       Number of arguments in the list.
+ * @argv       Arguments list.
+ * @st_dev_list        Structure where devices will be saved.
+ * @dlist_idx  Number of devices previously saved in the list.
+ * @opt                Index in list of arguments.
+ * @d_id       Type of device.
+ * @pos                Position is string where is located the first device.
+ *
+ * OUT:
+ * @st_dev_list        Structure where devices have been saved.
+ * @dlist_idx  Total number of devices saved in the list.
+ * @opt                Index on next argument.
+ ***************************************************************************
+ */
+void parse_sa_devices(int argc, char *argv[], struct sa_dlist **st_dev_list,
+                     int *dlist_idx, int *opt, int d_id, int pos)
+{
+       char *t;
+       struct sa_dlist *st_dev_list_i;
+
+       if (*st_dev_list == NULL) {
+               /* Allocate device list */
+               salloc_sa_dlist(st_dev_list, argc - 1 + count_csvalues(argc, argv));
+       }
+       for (t = strtok(argv[*opt] + pos, ","); t; t = strtok(NULL, ",")) {
+               st_dev_list_i = *st_dev_list + (*dlist_idx)++;
+               st_dev_list_i->dev_id = d_id;
+               strncpy(st_dev_list_i->dev_name, t, MAX_NAME_LEN - 1);
+       }
+       (*opt)++;
+}
+
 /*
  ***************************************************************************
  * Compute network interface utilization.
diff --git a/sar.c b/sar.c
index 6bd9396146dd5db96477f28a68909004fcdfaf8a..85082ee1511b4b71c9ee42c37040038ad978c583 100644 (file)
--- a/sar.c
+++ b/sar.c
@@ -76,6 +76,10 @@ struct record_header record_hdr[3];
  */
 unsigned int id_seq[NR_ACT];
 
+/* Devices entered on the command line */
+struct sa_dlist *st_dev_list = NULL;
+int dlist_idx = 0;
+
 struct tm rectime;
 
 /* Contain the date specified by -s and -e options */
@@ -118,9 +122,10 @@ void usage(char *progname)
                          "[ -A ] [ -B ] [ -b ] [ -C ] [ -D ] [ -d ] [ -F [ MOUNT ] ] [ -H ] [ -h ]\n"
                          "[ -p ] [ -q ] [ -r [ ALL ] ] [ -S ] [ -t ] [ -u [ ALL ] ] [ -V ]\n"
                          "[ -v ] [ -W ] [ -w ] [ -y ] [ -z ]\n"
-                         "[ --dec={ 0 | 1 | 2 } ] [ --help ] [ --human ] [ --sadc ]\n"
                          "[ -I { <int_list> | SUM | ALL } ] [ -P { <cpu_list> | ALL } ]\n"
                          "[ -m { <keyword> [,...] | ALL } ] [ -n { <keyword> [,...] | ALL } ]\n"
+                         "[ --dec={ 0 | 1 | 2 } ] [ --iface=<iface_list> ]\n"
+                         "[ --help ] [ --human ] [ --sadc ]\n"
                          "[ -j { ID | LABEL | PATH | UUID | ... } ]\n"
                          "[ -f [ <filename> ] | -o [ <filename> ] | -[0-9]+ ]\n"
                          "[ -i <interval> ] [ -s [ <hh:mm[:ss]> ] ] [ -e [ <hh:mm[:ss]> ] ]\n"));
@@ -1271,6 +1276,12 @@ int main(int argc, char **argv)
                        which_sadc();
                }
 
+               else if (!strncmp(argv[opt], "--iface=", 8)) {
+                       /* Parse devices entered on the command line */
+                       parse_sa_devices(argc, argv, &st_dev_list,
+                                        &dlist_idx, &opt, A_NET_DEV, 8);
+               }
+
                else if (!strcmp(argv[opt], "--help")) {
                        /* Display help message */
                        display_help(argv[0]);
@@ -1501,6 +1512,9 @@ int main(int argc, char **argv)
                /* Free stuctures and activity bitmaps */
                free_bitmaps(act);
                free_structures(act);
+               if (st_dev_list) {
+                       free(st_dev_list);
+               }
 
                return 0;
        }
@@ -1625,6 +1639,9 @@ int main(int argc, char **argv)
        /* Free structures and activity bitmaps */
        free_bitmaps(act);
        free_structures(act);
+       if (st_dev_list) {
+               free(st_dev_list);
+       }
 
        return 0;
 }