diff --git a/genutils.c b/genutils.c index 94009fe..14a9bf6 100644 --- a/genutils.c +++ b/genutils.c @@ -845,7 +845,7 @@ Datum pgnodemx_stat_file(PG_FUNCTION_ARGS) groupname = pstrdup(grp->gr_name); /* get mode string */ - snprintf(buf, INTEGER_LEN, "%jo", (uintmax_t) st_mode); + snprintf(buf, INTEGER_LEN, "%o", st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)); modestr = pstrdup(buf); values[0] = (char **) palloc(ncol * sizeof(char *)); diff --git a/pg_proctab--0.0.9-compat.sql b/pg_proctab--0.0.9-compat.sql index 52a09b5..248e277 100644 --- a/pg_proctab--0.0.9-compat.sql +++ b/pg_proctab--0.0.9-compat.sql @@ -169,23 +169,36 @@ CREATE OR REPLACE FUNCTION pg_diskusage ( OUT writetime bigint, OUT current_io bigint, OUT iotime bigint, - OUT totaliotime bigint) + OUT totaliotime bigint, + OUT discards_completed bigint, + OUT discards_merged bigint, + OUT sectors_discarded bigint, + OUT discardtime bigint, + OUT flushes_completed bigint, + OUT flushtime bigint +) RETURNS SETOF record AS $$ SELECT major_number::smallint AS major, minor_number::smallint AS minor, device_name AS devname, - reads_completed_successfully AS reads_completed, - reads_merged AS reads_merged, - sectors_read AS sectors_read, + reads_completed_successfully::bigint AS reads_completed, + reads_merged::bigint AS reads_merged, + sectors_read::bigint AS sectors_read, time_spent_reading_ms AS readtime, - writes_completed AS writes_completed, - writes_merged AS writes_merged, - sectors_written AS sectors_written, + writes_completed::bigint AS writes_completed, + writes_merged::bigint AS writes_merged, + sectors_written::bigint AS sectors_written, time_spent_writing_ms AS writetime, ios_currently_in_progress AS current_io, time_spent_doing_ios_ms AS iotime, - weighted_time_spent_doing_ios_ms AS totaliotime + weighted_time_spent_doing_ios_ms AS totaliotime, + COALESCE(discards_completed_successfully, 0)::bigint AS discards_completed, + COALESCE(discards_merged, 0)::bigint AS discards_merged, + COALESCE(sectors_discarded, 0)::bigint AS sectors_discarded, + COALESCE(time_spent_discarding, 0) AS discardtime, + COALESCE(flush_requests_completed_successfully, 0)::bigint AS flushes_completed, + COALESCE(time_spent_flushing, 0) AS flushtime FROM proc_diskstats() $$ LANGUAGE sql; diff --git a/pgnodemx--1.2--1.3.sql b/pgnodemx--1.2--1.3.sql index f3c864b..3c60c81 100644 --- a/pgnodemx--1.2--1.3.sql +++ b/pgnodemx--1.2--1.3.sql @@ -128,3 +128,31 @@ CREATE OR REPLACE FUNCTION openssl_version() RETURNS TEXT AS 'MODULE_PATHNAME', 'pgnodemx_openssl_version' LANGUAGE C IMMUTABLE STRICT; + +DROP FUNCTION proc_diskstats(); +CREATE FUNCTION proc_diskstats +( + OUT major_number BIGINT, + OUT minor_number BIGINT, + OUT device_name TEXT, + OUT reads_completed_successfully NUMERIC, + OUT reads_merged NUMERIC, + OUT sectors_read NUMERIC, + OUT time_spent_reading_ms BIGINT, + OUT writes_completed NUMERIC, + OUT writes_merged NUMERIC, + OUT sectors_written NUMERIC, + OUT time_spent_writing_ms BIGINT, + OUT ios_currently_in_progress BIGINT, + OUT time_spent_doing_ios_ms BIGINT, + OUT weighted_time_spent_doing_ios_ms BIGINT, + OUT discards_completed_successfully NUMERIC, + OUT discards_merged NUMERIC, + OUT sectors_discarded NUMERIC, + OUT time_spent_discarding BIGINT, + OUT flush_requests_completed_successfully NUMERIC, + OUT time_spent_flushing BIGINT +) +RETURNS SETOF record +AS 'MODULE_PATHNAME', 'pgnodemx_proc_diskstats' +LANGUAGE C STABLE STRICT; diff --git a/pgnodemx--1.3.sql b/pgnodemx--1.3.sql index 9ed640a..6f51f1c 100644 --- a/pgnodemx--1.3.sql +++ b/pgnodemx--1.3.sql @@ -134,17 +134,23 @@ CREATE FUNCTION proc_diskstats OUT major_number BIGINT, OUT minor_number BIGINT, OUT device_name TEXT, - OUT reads_completed_successfully BIGINT, - OUT reads_merged BIGINT, - OUT sectors_read BIGINT, + OUT reads_completed_successfully NUMERIC, + OUT reads_merged NUMERIC, + OUT sectors_read NUMERIC, OUT time_spent_reading_ms BIGINT, - OUT writes_completed BIGINT, - OUT writes_merged BIGINT, - OUT sectors_written BIGINT, + OUT writes_completed NUMERIC, + OUT writes_merged NUMERIC, + OUT sectors_written NUMERIC, OUT time_spent_writing_ms BIGINT, OUT ios_currently_in_progress BIGINT, OUT time_spent_doing_ios_ms BIGINT, - OUT weighted_time_spent_doing_ios_ms BIGINT + OUT weighted_time_spent_doing_ios_ms BIGINT, + OUT discards_completed_successfully NUMERIC, + OUT discards_merged NUMERIC, + OUT sectors_discarded NUMERIC, + OUT time_spent_discarding BIGINT, + OUT flush_requests_completed_successfully NUMERIC, + OUT time_spent_flushing BIGINT ) RETURNS SETOF record AS 'MODULE_PATHNAME', 'pgnodemx_proc_diskstats' diff --git a/pgnodemx.c b/pgnodemx.c index 2b90360..4dc560c 100644 --- a/pgnodemx.c +++ b/pgnodemx.c @@ -75,17 +75,12 @@ Oid _2_numeric_text_9_numeric_text_sig[] = {NUMERICOID, NUMERICOID, TEXTOID, NUM NUMERICOID, NUMERICOID, NUMERICOID, TEXTOID}; Oid _4_bigint_6_text_sig[] = {INT8OID, INT8OID, INT8OID, INT8OID, TEXTOID, TEXTOID, TEXTOID, TEXTOID, TEXTOID, TEXTOID}; -Oid bigint_bigint_text_11_bigint_sig[] = {INT8OID, INT8OID, TEXTOID, - INT8OID, INT8OID, INT8OID, INT8OID, - INT8OID, INT8OID, INT8OID, INT8OID, - INT8OID, INT8OID, INT8OID}; Oid text_16_bigint_sig[] = {TEXTOID, INT8OID, INT8OID, INT8OID, INT8OID, INT8OID, INT8OID, INT8OID, INT8OID, INT8OID, INT8OID, INT8OID, INT8OID, INT8OID, INT8OID, INT8OID, INT8OID}; - Oid _5_bigint_sig[] = { INT8OID, INT8OID, INT8OID, INT8OID, INT8OID }; Oid int_7_numeric_sig[] = { INT4OID, NUMERICOID, NUMERICOID, NUMERICOID, @@ -93,6 +88,14 @@ Oid int_7_numeric_sig[] = { INT4OID, NUMERICOID, NUMERICOID, NUMERICOID, Oid int_text_int_text_sig[] = { INT4OID, TEXTOID, INT4OID, TEXTOID }; Oid load_avg_sig[] = { FLOAT8OID, FLOAT8OID, FLOAT8OID, INT4OID }; +/* proc_diskstats is unique enough to have its own sig */ +Oid proc_diskstats_sig[] = {INT8OID, INT8OID, TEXTOID, + NUMERICOID, NUMERICOID, NUMERICOID, INT8OID, + NUMERICOID, NUMERICOID, NUMERICOID, INT8OID, + INT8OID, INT8OID, INT8OID, + NUMERICOID, NUMERICOID, NUMERICOID, INT8OID, + NUMERICOID, INT8OID}; + /* proc_pid_stat is unique enough to have its own sig */ Oid proc_pid_stat_sig[] = {INT4OID, TEXTOID, TEXTOID, INT4OID, INT4OID, INT4OID, INT4OID, @@ -193,7 +196,7 @@ _PG_init(void) } /* force kdapi disabled if path does not exist */ - if (access(kdapi_path, F_OK) != 0) + if (kdapi_enabled && access(kdapi_path, F_OK) != 0) { /* * If kdapi_path does not exist, there is not diff --git a/procfunc.c b/procfunc.c index b78620a..2db641c 100644 --- a/procfunc.c +++ b/procfunc.c @@ -138,32 +138,30 @@ check_procfs(void) * 19 - flush requests completed successfully * 20 - time spent flushing * - * For now, validate either 14,18, or 20 fields found when - * parsing the lines, but only return the first 14. If there - * is demand for the other fields at some point, possibly - * add them then. + * Validate either 14,18, or 20 fields found when + * parsing the lines. Unused fields passed as NULL. */ PG_FUNCTION_INFO_V1(pgnodemx_proc_diskstats); Datum pgnodemx_proc_diskstats(PG_FUNCTION_ARGS) { int nrow = 0; - int ncol = 14; + int ncol = 20; char ***values = (char ***) palloc(0); char **lines; int nlines; if (!proc_enabled) - return form_srf(fcinfo, NULL, 0, ncol, bigint_bigint_text_11_bigint_sig); + return form_srf(fcinfo, NULL, 0, ncol, proc_diskstats_sig); /* read /proc/diskstats file */ lines = read_nlsv(diskstats, &nlines); /* * These files have either 14,18, or 20 fields per line. - * We will validate one of those lengths, but only use 14 of the - * space separated columns. The third column is the device name. - * Rest of the columns are bigints. + * Validate one of those lengths. The third column is the device name. + * Rest of the columns are unsigned long or unsigned int, which + * are mapped to postgres numeric or bigints respectively. */ if (nlines > 0) { @@ -187,7 +185,12 @@ pgnodemx_proc_diskstats(PG_FUNCTION_ARGS) ntok, diskstats, j + 1))); for (k = 0; k < ncol; ++k) - values[j][k] = pstrdup(toks[k]); + { + if (k < ntok) + values[j][k] = pstrdup(toks[k]); + else + values[j][k] = NULL; + } } } else @@ -195,7 +198,7 @@ pgnodemx_proc_diskstats(PG_FUNCTION_ARGS) (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("pgnodemx: no data in file: %s ", diskstats))); - return form_srf(fcinfo, values, nrow, ncol, bigint_bigint_text_11_bigint_sig); + return form_srf(fcinfo, values, nrow, ncol, proc_diskstats_sig); } /* diff --git a/srfsigs.h b/srfsigs.h index dde40b2..0471f88 100644 --- a/srfsigs.h +++ b/srfsigs.h @@ -37,13 +37,14 @@ extern Oid text_text_bigint_sig[]; extern Oid text_text_float8_sig[]; extern Oid _2_numeric_text_9_numeric_text_sig[]; extern Oid _4_bigint_6_text_sig[]; -extern Oid bigint_bigint_text_11_bigint_sig[]; extern Oid text_16_bigint_sig[]; extern Oid _5_bigint_sig[]; extern Oid int_7_numeric_sig[]; extern Oid int_text_int_text_sig[]; +extern Oid num_text_num_2_text_sig[]; + extern Oid load_avg_sig[]; +extern Oid proc_diskstats_sig[]; extern Oid proc_pid_stat_sig[]; -extern Oid num_text_num_2_text_sig[]; #endif /* _SRFSIGS_H_ */