]> granicus.if.org Git - sysstat/commitdiff
A_IRQ: Add new "--int=" option to sar and sadf
authorSebastien GODARD <sysstat@users.noreply.github.com>
Fri, 28 Jan 2022 16:04:31 +0000 (17:04 +0100)
committerSebastien GODARD <sysstat@users.noreply.github.com>
Fri, 28 Jan 2022 16:04:31 +0000 (17:04 +0100)
The option "--int=" can be used with sar and sadf to enter a list of
comma-separated interrupts values, ranges of interrupts values, or even
interrupts names.
These interrupts will then be displayed using option -I.

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

index 7097e17e24c21948c87be2a1b437079da7e4fcce..a322db533ca4285572428346106b6fedba21189d 100644 (file)
--- a/common.c
+++ b/common.c
@@ -1553,6 +1553,59 @@ int parse_valstr(char *s, int max_val, int *val)
        return 0;
 }
 
+/*
+ ***************************************************************************
+ * Parse string containing a single value or a range of values
+ * (e.g. "0,2-5,10-").
+ *
+ * IN:
+ * @t          String to parse.
+ * @max_val    Upper limit that value should not reach.
+ *
+ * OUT:
+ * @val_low    Low value in range
+ * @val                High value in range. @val_low and @val are the same if it's
+ *             a single value.
+ *
+ * RETURNS:
+ * 0 on success, 1 otherwise.
+ ***************************************************************************
+ */
+int parse_range_values(char *t, int max_val, int *val_low, int *val)
+{
+       char *s, *valstr, range[16];
+
+       /* Parse value or range of values */
+       strncpy(range, t, 16);
+       range[15] = '\0';
+       valstr = t;
+
+       if ((s = strchr(range, '-')) != NULL) {
+               /* Possible range of values */
+               *s = '\0';
+               if (parse_valstr(range, max_val, val_low) || (*val_low < 0))
+                       return 1;
+               valstr = s + 1;
+       }
+       if (parse_valstr(valstr, max_val, val))
+               return 1;
+       if (s && *val < 0) {
+               /* Range of values with no upper limit (e.g. "3-") */
+               *val = max_val - 1;
+       }
+       if ((!s && (*val < 0)) || (s && (*val < *val_low)))
+               /*
+                * Individual value: string cannot be empty.
+                * Range of values: n-m: m can be empty (e.g. "3-") but
+                * cannot be lower than n.
+                */
+               return 1;
+       if (!s) {
+               *val_low = *val;
+       }
+       return 0;
+}
+
 /*
  ***************************************************************************
  * Parse string containing a set of coma-separated values or ranges of
@@ -1577,7 +1630,7 @@ int parse_valstr(char *s, int max_val, int *val)
 int parse_values(char *strargv, unsigned char bitmap[], int max_val, const char *__K_VALUE0)
 {
        int i, val_low, val;
-       char *t, *s, *valstr, range[16];
+       char *t;
 
        if (!strcmp(strargv, K_ALL)) {
                /* Set bit for every possible values (CPU, IRQ, etc.) */
@@ -1595,32 +1648,9 @@ int parse_values(char *strargv, unsigned char bitmap[], int max_val, const char
                }
                else {
                        /* Parse value or range of values */
-                       strncpy(range, t, 16);
-                       range[15] = '\0';
-                       valstr = t;
-                       if ((s = strchr(range, '-')) != NULL) {
-                               /* Possible range of values */
-                               *s = '\0';
-                               if (parse_valstr(range, max_val, &val_low) || (val_low < 0))
-                                       return 1;
-                               valstr = s + 1;
-                       }
-                       if (parse_valstr(valstr, max_val, &val))
+                       if (parse_range_values(t, max_val, &val_low, &val))
                                return 1;
-                       if (s && val < 0) {
-                               /* Range of values with no upper limit (e.g. "3-") */
-                               val = max_val - 1;
-                       }
-                       if ((!s && (val < 0)) || (s && (val < val_low)))
-                               /*
-                                * Individual value: string cannot be empty.
-                                * Range of values: n-m: m can be empty (e.g. "3-") but
-                                * cannot be lower than n.
-                                */
-                               return 1;
-                       if (!s) {
-                               val_low = val;
-                       }
+
                        for (i = val_low; i <= val; i++) {
                                bitmap[(i + 1) >> 3] |= 1 << ((i + 1) & 0x07);
                        }
index d25742daffdedbfb5cafc9f004a7c4cb15674590..0835ec7d0daf954509981d81d980d2995be0c5ba 100644 (file)
--- a/common.h
+++ b/common.h
 #define C_ALWAYS               "always"
 
 #define DIGITS                 "0123456789"
+#define XDIGITS                        "0123456789-"
 
 /*
  ***************************************************************************
@@ -297,6 +298,8 @@ double ll_sp_value
        (unsigned long long, unsigned long long, unsigned long long);
 int is_iso_time_fmt
        (void);
+int parse_range_values
+       (char *t, int, int *, int *);
 int parse_values
        (char *, unsigned char[], int, const char *);
 int print_gal_header
diff --git a/sa.h b/sa.h
index b8a70754e024c8b5b1ad1d4a206da56957e4b49e..dc5021f87c56f1f076c5fc0d2cc00f31dfdde51d 100644 (file)
--- a/sa.h
+++ b/sa.h
 #define NO_TM_START            0
 #define NO_TM_END              0
 #define NO_RESET               0
+#define NO_RANGE               0
 #define NON_FATAL              0
 #define FATAL                  1
 #define C_SAR                  0
@@ -1537,7 +1538,7 @@ void init_custom_color_palette
 int next_slice
        (unsigned long long, unsigned long long, int, long);
 void parse_sa_devices
-       (char *, struct activity *, int, int *, int);
+       (char *, struct activity *, int, int *, int, int);
 int parse_sar_opt
        (char * [], int *, struct activity * [], uint64_t *, int);
 int parse_sa_P_opt
index 529fbf51f4c6b968169f6b8f7be78f3ccbb20a53..b8d3dd6586f9e69afa810b11a675ccf0ec16e180 100644 (file)
@@ -2707,16 +2707,34 @@ int add_list_item(struct sa_item **list, char *item_name, int max_len)
  * @max_len    Max length of a device name.
  * @opt                Index in list of arguments.
  * @pos                Position is string where is located the first device.
+ * @max_val    If > 0 then ranges of values are allowed (e.g. 3-5,9-, etc.)
+ *             Values are in range [0..@max_val].
  *
  * OUT:
  * @opt                Index on next argument.
  ***************************************************************************
  */
-void parse_sa_devices(char *argv, struct activity *a, int max_len, int *opt, int pos)
+void parse_sa_devices(char *argv, struct activity *a, int max_len, int *opt, int pos,
+                     int max_val)
 {
+       int i, val_low, val;
        char *t;
+       char svalue[9];
 
        for (t = strtok(argv + pos, ","); t; t = strtok(NULL, ",")) {
+
+               /* Test ranges of values, if allowed */
+               if ((max_val > 0) && (strlen(t) <= 16) && (strspn(t, XDIGITS) == strlen(t))) {
+                       if (parse_range_values(t, max_val, &val_low, &val) == 0) {
+                               /* This is a real range of values: Save each if its values */
+                               for (i = val_low; i <= val; i++) {
+                                       snprintf(svalue, sizeof(svalue), "%d", i);
+                                       svalue[sizeof(svalue) - 1] = '\0';
+                                       a->item_list_sz += add_list_item(&(a->item_list), svalue, max_len);
+                               }
+                               continue;
+                       }
+               }
                a->item_list_sz += add_list_item(&(a->item_list), t, max_len);
        }
        if (a->item_list_sz) {
diff --git a/sadf.c b/sadf.c
index 0838f7d46990071c3b14bff65a7a4f8c95b86d79..da20a27fd1e3c5617a3edc4046860ec3845813e7 100644 (file)
--- a/sadf.c
+++ b/sadf.c
@@ -108,7 +108,7 @@ void usage(char *progname)
        fprintf(stderr, _("Options are:\n"
                          "[ -C ] [ -c | -d | -g | -j | -l | -p | -r | -x ] [ -H ] [ -h ] [ -T | -t | -U ] [ -V ]\n"
                          "[ -O <opts> [,...] ] [ -P { <cpu> [,...] | ALL } ]\n"
-                         "[ --dev=<dev_list> ] [ --fs=<fs_list> ] [ --iface=<iface_list> ]\n"
+                         "[ --dev=<dev_list> ] [ --fs=<fs_list> ] [ --iface=<iface_list> ] [ --int=<int_list> ]\n"
                          "[ -s [ <hh:mm[:ss]> ] ] [ -e [ <hh:mm[:ss]> ] ]\n"
                          "[ -- <sar_options> ]\n"));
        exit(1);
@@ -1536,25 +1536,31 @@ int main(int argc, char **argv)
                else if (!strncmp(argv[opt], "--dev=", 6)) {
                        /* Parse devices entered on the command line */
                        p = get_activity_position(act, A_DISK, EXIT_IF_NOT_FOUND);
-                       parse_sa_devices(argv[opt], act[p], MAX_DEV_LEN, &opt, 6);
+                       parse_sa_devices(argv[opt], act[p], MAX_DEV_LEN, &opt, 6, NO_RANGE);
                }
 
                else if (!strncmp(argv[opt], "--fs=", 5)) {
                        /* Parse devices entered on the command line */
                        p = get_activity_position(act, A_FS, EXIT_IF_NOT_FOUND);
-                       parse_sa_devices(argv[opt], act[p], MAX_FS_LEN, &opt, 5);
+                       parse_sa_devices(argv[opt], act[p], MAX_FS_LEN, &opt, 5, NO_RANGE);
                }
 
                else if (!strncmp(argv[opt], "--iface=", 8)) {
                        /* Parse devices entered on the command line */
                        p = get_activity_position(act, A_NET_DEV, EXIT_IF_NOT_FOUND);
-                       parse_sa_devices(argv[opt], act[p], MAX_IFACE_LEN, &opt, 8);
+                       parse_sa_devices(argv[opt], act[p], MAX_IFACE_LEN, &opt, 8, NO_RANGE);
                        q = get_activity_position(act, A_NET_EDEV, EXIT_IF_NOT_FOUND);
                        act[q]->item_list = act[p]->item_list;
                        act[q]->item_list_sz = act[p]->item_list_sz;
                        act[q]->options |= AO_LIST_ON_CMDLINE;
                }
 
+               else if (!strncmp(argv[opt], "--int=", 6)) {
+                       /* Parse interrupts names entered on the command line */
+                       p = get_activity_position(act, A_IRQ, EXIT_IF_NOT_FOUND);
+                       parse_sa_devices(argv[opt], act[p], MAX_SA_IRQ_LEN, &opt, 6, NR_IRQS);
+               }
+
                else if (!strcmp(argv[opt], "-s")) {
                        /* Get time start */
                        if (parse_timestamp(argv, &opt, &tm_start, DEF_TMSTART)) {
diff --git a/sar.c b/sar.c
index 99f1c7c446917340213109e09fc4192e673897af..0be24235d6b0c566f5442e073090e948f37fd008 100644 (file)
--- a/sar.c
+++ b/sar.c
@@ -126,7 +126,8 @@ void usage(char *progname)
                          "[ -I { <int_list> | SUM | ALL } ] [ -P { <cpu_list> | ALL } ]\n"
                          "[ -m { <keyword> [,...] | ALL } ] [ -n { <keyword> [,...] | ALL } ]\n"
                          "[ -q [ <keyword> [,...] | ALL ] ]\n"
-                         "[ --dev=<dev_list> ] [ --fs=<fs_list> ] [ --iface=<iface_list> ]\n"
+                         "[ --dev=<dev_list> ] [ --fs=<fs_list> ] [ --iface=<iface_list> ] "
+                         "[ --int=<int_list> ]\n"
                          "[ --dec={ 0 | 1 | 2 } ] [ --help ] [ --human ] [ --pretty ] [ --sadc ]\n"
                          "[ -j { SID | ID | LABEL | PATH | UUID | ... } ]\n"
                          "[ -f [ <filename> ] | -o [ <filename> ] | -[0-9]+ ]\n"
@@ -1315,25 +1316,31 @@ int main(int argc, char **argv)
                else if (!strncmp(argv[opt], "--dev=", 6)) {
                        /* Parse devices entered on the command line */
                        p = get_activity_position(act, A_DISK, EXIT_IF_NOT_FOUND);
-                       parse_sa_devices(argv[opt], act[p], MAX_DEV_LEN, &opt, 6);
+                       parse_sa_devices(argv[opt], act[p], MAX_DEV_LEN, &opt, 6, NO_RANGE);
                }
 
                else if (!strncmp(argv[opt], "--fs=", 5)) {
                        /* Parse devices entered on the command line */
                        p = get_activity_position(act, A_FS, EXIT_IF_NOT_FOUND);
-                       parse_sa_devices(argv[opt], act[p], MAX_FS_LEN, &opt, 5);
+                       parse_sa_devices(argv[opt], act[p], MAX_FS_LEN, &opt, 5, NO_RANGE);
                }
 
                else if (!strncmp(argv[opt], "--iface=", 8)) {
                        /* Parse devices entered on the command line */
                        p = get_activity_position(act, A_NET_DEV, EXIT_IF_NOT_FOUND);
-                       parse_sa_devices(argv[opt], act[p], MAX_IFACE_LEN, &opt, 8);
+                       parse_sa_devices(argv[opt], act[p], MAX_IFACE_LEN, &opt, 8, NO_RANGE);
                        q = get_activity_position(act, A_NET_EDEV, EXIT_IF_NOT_FOUND);
                        act[q]->item_list = act[p]->item_list;
                        act[q]->item_list_sz = act[p]->item_list_sz;
                        act[q]->options |= AO_LIST_ON_CMDLINE;
                }
 
+               else if (!strncmp(argv[opt], "--int=", 6)) {
+                       /* Parse interrupts names entered on the command line */
+                       p = get_activity_position(act, A_IRQ, EXIT_IF_NOT_FOUND);
+                       parse_sa_devices(argv[opt], act[p], MAX_SA_IRQ_LEN, &opt, 6, NR_IRQS);
+               }
+
                else if (!strcmp(argv[opt], "--help")) {
                        /* Display help message */
                        display_help(argv[0]);