From a7ef273e1cebb913cd4a524fcf3b42caa41bd431 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 2 Jan 2014 21:45:47 -0500 Subject: [PATCH] Fix calculation of maximum statistics-message size. The PGSTAT_NUM_TABENTRIES macro should have been updated when new fields were added to struct PgStat_MsgTabstat in commit 644828908, but it wasn't. Fix that. Also, add a static assertion that we didn't overrun the intended size limit on stats messages. This will not necessarily catch every mistake in computing the maximum array size for stats messages, but it will catch ones that have practical consequences. (The assertion in fact doesn't complain about the aforementioned error in PGSTAT_NUM_TABENTRIES, because that was not big enough to cause the array length to increase.) No back-patch, as there's no actual bug in existing releases; this is just in the nature of future-proofing. Mark Dilger and Tom Lane --- src/backend/postmaster/pgstat.c | 10 ++++++++++ src/include/pgstat.h | 10 ++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index b5ce2f6cc7..d251fddc0b 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -329,6 +329,16 @@ pgstat_init(void) #define TESTBYTEVAL ((char) 199) + /* + * This static assertion verifies that we didn't mess up the calculations + * involved in selecting maximum payload sizes for our UDP messages. + * Because the only consequence of overrunning PGSTAT_MAX_MSG_SIZE would + * be silent performance loss from fragmentation, it seems worth having a + * compile-time cross-check that we didn't. + */ + StaticAssertStmt(sizeof(PgStat_Msg) <= PGSTAT_MAX_MSG_SIZE, + 'maximum stats message size exceeds PGSTAT_MAX_MSG_SIZE'); + /* * Create the UDP socket for sending and receiving statistic messages */ diff --git a/src/include/pgstat.h b/src/include/pgstat.h index fb242e4b91..b79a0ebcc3 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -177,11 +177,13 @@ typedef struct PgStat_MsgHdr /* ---------- * Space available in a message. This will keep the UDP packets below 1K, - * which should fit unfragmented into the MTU of the lo interface on most - * platforms. Does anybody care for platforms where it doesn't? + * which should fit unfragmented into the MTU of the loopback interface. + * (Larger values of PGSTAT_MAX_MSG_SIZE would work for that on most + * platforms, but we're being conservative here.) * ---------- */ -#define PGSTAT_MSG_PAYLOAD (1000 - sizeof(PgStat_MsgHdr)) +#define PGSTAT_MAX_MSG_SIZE 1000 +#define PGSTAT_MSG_PAYLOAD (PGSTAT_MAX_MSG_SIZE - sizeof(PgStat_MsgHdr)) /* ---------- @@ -225,7 +227,7 @@ typedef struct PgStat_TableEntry * ---------- */ #define PGSTAT_NUM_TABENTRIES \ - ((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - 3 * sizeof(int)) \ + ((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - 3 * sizeof(int) - 2 * sizeof(PgStat_Counter)) \ / sizeof(PgStat_TableEntry)) typedef struct PgStat_MsgTabstat -- 2.40.0