From: Sebastien GODARD Date: Sun, 19 Apr 2020 06:11:33 +0000 (+0200) Subject: sadc: Check that PSI statistics can be collected X-Git-Tag: v12.3.3~22 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0f6e03145c99d1cafec11f24a69de722c2e29f4f;p=sysstat sadc: Check that PSI statistics can be collected Check that /proc/pressure directory exists for PSI statistics to be collected. Add all the necessary code that will be reusable to check if an activity can be collected by sadc. Signed-off-by: Sebastien GODARD --- diff --git a/activity.c b/activity.c index 8f41ce6..088ff30 100644 --- a/activity.c +++ b/activity.c @@ -1876,11 +1876,11 @@ struct activity softnet_act = { /* Pressure-stall CPU activity */ struct activity psi_cpu_act = { .id = A_PSI_CPU, - .options = AO_COLLECTED, + .options = AO_COLLECTED + AO_DETECTED, .magic = ACTIVITY_MAGIC_BASE, .group = G_DEFAULT, #ifdef SOURCE_SADC - .f_count_index = -1, + .f_count_index = 11, .f_count2 = NULL, .f_read = wrap_read_psicpu, #endif @@ -1922,11 +1922,11 @@ struct activity psi_cpu_act = { /* Pressure-stall I/O activity */ struct activity psi_io_act = { .id = A_PSI_IO, - .options = AO_COLLECTED, + .options = AO_COLLECTED + AO_DETECTED, .magic = ACTIVITY_MAGIC_BASE, .group = G_DEFAULT, #ifdef SOURCE_SADC - .f_count_index = -1, + .f_count_index = 11, .f_count2 = NULL, .f_read = wrap_read_psiio, #endif @@ -1968,11 +1968,11 @@ struct activity psi_io_act = { /* Pressure-stall memory activity */ struct activity psi_mem_act = { .id = A_PSI_MEM, - .options = AO_COLLECTED + AO_CLOSE_MARKUP, + .options = AO_COLLECTED + AO_DETECTED + AO_CLOSE_MARKUP, .magic = ACTIVITY_MAGIC_BASE, .group = G_DEFAULT, #ifdef SOURCE_SADC - .f_count_index = -1, + .f_count_index = 11, .f_count2 = NULL, .f_read = wrap_read_psimem, #endif @@ -2026,7 +2026,8 @@ __nr_t (*f_count[NR_F_COUNT]) (struct activity *) = { wrap_get_in_nr, wrap_get_usb_nr, wrap_get_filesystem_nr, - wrap_get_fchost_nr + wrap_get_fchost_nr, + wrap_detect_psi }; #endif diff --git a/common.c b/common.c index ddfe75d..e8aef69 100644 --- a/common.c +++ b/common.c @@ -410,6 +410,28 @@ int get_wwnid_from_pretty(char *pretty, unsigned long long *wwn, unsigned int *p return rc; } +/* + *************************************************************************** + * Check if a directory exists. + * + * IN: + * @dirname Name of the directory. + * + * RETURNS: + * TRUE if @dirname is actually an existing directory. + *************************************************************************** + */ +int check_dir(char *dirname) +{ + struct stat sb; + + if (!stat(dirname, &sb) && S_ISDIR(sb.st_mode)) + return 1; + + return 0; +} + + #ifndef SOURCE_SADC /* *************************************************************************** diff --git a/common.h b/common.h index 86905ba..adbb774 100644 --- a/common.h +++ b/common.h @@ -247,6 +247,8 @@ int extract_wwnid (char *, unsigned long long *, unsigned int *); int get_wwnid_from_pretty (char *, unsigned long long *, unsigned int *); +int check_dir + (char *); #ifndef SOURCE_SADC int count_bits diff --git a/rd_stats.h b/rd_stats.h index f89c3ef..d982074 100644 --- a/rd_stats.h +++ b/rd_stats.h @@ -65,9 +65,10 @@ #define NET_RPC_NFSD PRE "/proc/net/rpc/nfsd" #define NET_SOFTNET PRE "/proc/net/softnet_stat" #define LOADAVG PRE "/proc/loadavg" -#define PSI_CPU PRE "/proc/pressure/cpu" -#define PSI_IO PRE "/proc/pressure/io" -#define PSI_MEM PRE "/proc/pressure/memory" +#define PRESSURE PRE "/proc/pressure" +#define PSI_CPU PRESSURE "/cpu" +#define PSI_IO PRESSURE "/io" +#define PSI_MEM PRESSURE "/memory" #define VMSTAT PRE "/proc/vmstat" #define NET_SNMP PRE "/proc/net/snmp" #define NET_SNMP6 PRE "/proc/net/snmp6" diff --git a/sa.h b/sa.h index b1abff4..804e0c9 100644 --- a/sa.h +++ b/sa.h @@ -25,7 +25,7 @@ #define MAX_NR_ACT 256 /* Number of functions used to count items */ -#define NR_F_COUNT 11 +#define NR_F_COUNT 12 /* Activities */ #define A_CPU 1 @@ -821,10 +821,22 @@ struct record_header { * be counted, even if the activity is not collected. */ #define AO_ALWAYS_COUNTED 0x200 +/* + * Indicate that corresponding activity should be collected only + * if a test has been successfully passed before. + * The test corresponds to the count() function (see @f_count_index). + * This is intended for activities with a fixed number of items but + * whose {/proc|/sys} files are not necessarily available, e.g. depending + * on the kernel version used. Unlike activities with AO_COUNTED flag, + * those having AO_DETECTED flag won't have a @has_nr number preceding + * their statistics structures in datafile. + */ +#define AO_DETECTED 0x400 #define IS_COLLECTED(m) (((m) & AO_COLLECTED) == AO_COLLECTED) #define IS_SELECTED(m) (((m) & AO_SELECTED) == AO_SELECTED) #define HAS_COUNT_FUNCTION(m) (((m) & AO_COUNTED) == AO_COUNTED) +#define HAS_DETECT_FUNCTION(m) (((m) & AO_DETECTED) == AO_DETECTED) #define HAS_PERSISTENT_VALUES(m) (((m) & AO_PERSISTENT) == AO_PERSISTENT) #define CLOSE_MARKUP(m) (((m) & AO_CLOSE_MARKUP) == AO_CLOSE_MARKUP) #define HAS_MULTIPLE_OUTPUTS(m) (((m) & AO_MULTIPLE_OUTPUTS) == AO_MULTIPLE_OUTPUTS) @@ -876,7 +888,8 @@ struct activity { unsigned int group; /* * Index in f_count[] array to determine function used to count - * the number of items (serial lines, network interfaces, etc.) -> @nr + * the number of items (serial lines, network interfaces, etc.) for + * activities with AO_COUNTED flag. Determine @nr value. * Such a function should _always_ return a value greater than * or equal to 0. * @@ -886,6 +899,10 @@ struct activity { * These functions are called even if corresponding activities have not * been selected, to make sure that all items have been calculated * (including #CPU, etc.) + * + * The count() function may also be used to know if an activity (with + * AO_DETECTED flag) can actually be collected based on the presence of + * {/proc|/sys} files. */ int f_count_index; /* @@ -1342,6 +1359,8 @@ __nr_t wrap_get_filesystem_nr (struct activity *); __nr_t wrap_get_fchost_nr (struct activity *); +__nr_t wrap_detect_psi + (struct activity *); /* Functions used to read activities statistics */ __read_funct_t wrap_read_stat_cpu diff --git a/sa_common.c b/sa_common.c index c37fde1..a38dfd6 100644 --- a/sa_common.c +++ b/sa_common.c @@ -276,17 +276,13 @@ int set_default_file(char *datafile, int d_off, int sa_name) */ int check_alt_sa_dir(char *datafile, int d_off, int sa_name) { - struct stat sb; - - if (stat(datafile, &sb) == 0) { - if (S_ISDIR(sb.st_mode)) { - /* - * This is a directory: So append - * the default file name to it. - */ - set_default_file(datafile, d_off, sa_name); - return 1; - } + if (check_dir(datafile)) { + /* + * This is a directory: So append + * the default file name to it. + */ + set_default_file(datafile, d_off, sa_name); + return 1; } return 0; diff --git a/sa_wrap.c b/sa_wrap.c index df12b97..5f02970 100644 --- a/sa_wrap.c +++ b/sa_wrap.c @@ -1509,3 +1509,19 @@ __nr_t wrap_get_fchost_nr(struct activity *a) return 0; } + +/* + *************************************************************************** + * Check that /proc/pressure directory exists. + * + * IN: + * @a Activity structure. + * + * RETURNS: + * TRUE if directory exists. + *************************************************************************** + */ +__nr_t wrap_detect_psi(struct activity *a) +{ + return (check_dir(PRESSURE)); +} diff --git a/sadc.c b/sadc.c index 5516a81..a020fba 100644 --- a/sadc.c +++ b/sadc.c @@ -363,6 +363,19 @@ void sa_sys_init(void) act[i]->options &= ~AO_COLLECTED; } + if (HAS_DETECT_FUNCTION(act[i]->options) && IS_COLLECTED(act[i]->options)) { + idx = act[i]->f_count_index; + + /* Detect if files needed by activity exist */ + if (f_count_results[idx] < 0) { + f_count_results[idx] = (f_count[idx])(act[i]); + } + if (f_count_results[idx] == 0) { + /* Files not present */ + act[i]->options &= ~AO_COLLECTED; + } + } + /* Set default activity list */ id_seq[i] = act[i]->id; } @@ -674,7 +687,7 @@ void write_stats(int ofd) continue; if (IS_COLLECTED(act[p]->options)) { - if (act[p]->f_count_index >= 0) { + if (HAS_COUNT_FUNCTION(act[p]->options) && (act[p]->f_count_index >= 0)) { if (write_all(ofd, &(act[p]->_nr0), sizeof(__nr_t)) != sizeof(__nr_t)) { p_write_error(); } @@ -937,7 +950,7 @@ void open_ofile(int *ofd, char ofile[], int restart_mark) } if ((file_act[i].has_nr && (act[p]->f_count_index < 0)) || - (!file_act[i].has_nr && (act[p]->f_count_index >= 0))) { + (!file_act[i].has_nr && (act[p]->f_count_index >= 0) && HAS_COUNT_FUNCTION(act[p]->options))) { #ifdef DEBUG fprintf(stderr, "%s: %s: has_nr=%d count_index=%d\n", __FUNCTION__, act[p]->name, file_act[i].has_nr, act[p]->f_count_index);