diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2012-11-18 16:16:39 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2012-11-18 16:16:39 -0500 |
commit | d038966ddb918872700f9f21affbc84d6bc2c029 (patch) | |
tree | 0f5ab531fe6eaee4ffb3a0f8039ff3909db81a54 /src | |
parent | 14ddff44c22cb358775d5aad6953f0ce0fdb64cf (diff) | |
download | postgresql-d038966ddb918872700f9f21affbc84d6bc2c029.tar.gz postgresql-d038966ddb918872700f9f21affbc84d6bc2c029.zip |
Fix syslogger to not fail when log_rotation_age exceeds 2^31 milliseconds.
We need to avoid calling WaitLatch with timeouts exceeding INT_MAX.
Fortunately a simple clamp will do the trick, since no harm is done if
the wait times out before it's really time to rotate the log file.
Per bug #7670 (probably bug #7545 is the same thing, too).
In passing, fix bogus definition of log_rotation_age's maximum value in
guc.c --- it was numerically right, but only because MINS_PER_HOUR and
SECS_PER_MINUTE have the same value.
Back-patch to 9.2. Before that, syslogger wasn't using WaitLatch.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/postmaster/syslogger.c | 17 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 2 |
2 files changed, 16 insertions, 3 deletions
diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c index cccec743b0d..bb36633ee52 100644 --- a/src/backend/postmaster/syslogger.c +++ b/src/backend/postmaster/syslogger.c @@ -24,6 +24,7 @@ #include "postgres.h" #include <fcntl.h> +#include <limits.h> #include <signal.h> #include <time.h> #include <unistd.h> @@ -416,11 +417,23 @@ SysLoggerMain(int argc, char *argv[]) * above is still close enough. Note we can't make this calculation * until after calling logfile_rotate(), since it will advance * next_rotation_time. + * + * Also note that we need to beware of overflow in calculation of the + * timeout: with large settings of Log_RotationAge, next_rotation_time + * could be more than INT_MAX msec in the future. In that case we'll + * wait no more than INT_MAX msec, and try again. */ if (Log_RotationAge > 0 && !rotation_disabled) { - if (now < next_rotation_time) - cur_timeout = (next_rotation_time - now) * 1000L; /* msec */ + pg_time_t delay; + + delay = next_rotation_time - now; + if (delay > 0) + { + if (delay > INT_MAX / 1000) + delay = INT_MAX / 1000; + cur_timeout = delay * 1000L; /* msec */ + } else cur_timeout = 0; cur_flags = WL_TIMEOUT; diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 745e7be68e4..54461c830fe 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -2147,7 +2147,7 @@ static struct config_int ConfigureNamesInt[] = GUC_UNIT_MIN }, &Log_RotationAge, - HOURS_PER_DAY * MINS_PER_HOUR, 0, INT_MAX / MINS_PER_HOUR, + HOURS_PER_DAY * MINS_PER_HOUR, 0, INT_MAX / SECS_PER_MINUTE, NULL, NULL, NULL }, |