Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP5:Update
logrotate.5563
logrotate-3.8.7-recover-from-corrupted-state-fi...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File logrotate-3.8.7-recover-from-corrupted-state-file.patch of Package logrotate.5563
From b9d82003002c98370e4131a7e43c76afcd23306a Mon Sep 17 00:00:00 2001 From: Kamil Dudka <kdudka@redhat.com> Date: Wed, 8 Feb 2017 15:39:47 +0100 Subject: [PATCH] do not treat failure of readState() as fatal This also prevents an empty state file from being written when running with the --debug option. Closes #45 --- logrotate.c | 68 +++++++++++++++++++++++++++++++++++-------------------------- test/test | 5 ++--- 2 files changed, 41 insertions(+), 32 deletions(-) Index: logrotate-3.8.7/logrotate.c =================================================================== --- logrotate-3.8.7.orig/logrotate.c +++ logrotate-3.8.7/logrotate.c @@ -181,23 +181,17 @@ static void unescape(char *arg) } #define HASH_SIZE_MIN 64 -static int allocateHash(void) +static int allocateHash(unsigned int hs) { - struct logInfo *log; - unsigned int hs; int i; - hs = 0; - - for (log = logs.tqh_first; log != NULL; log = log->list.tqe_next) - hs += log->numFiles; - - hs *= 2; - /* Enforce some reasonable minimum hash size */ if (hs < HASH_SIZE_MIN) hs = HASH_SIZE_MIN; + message(MESS_DEBUG, "Allocating hash table for state file, size %d entries\n", + hs); + states = calloc(hs, sizeof(struct logStates *)); if (states == NULL) { message(MESS_ERROR, "could not allocate memory for " @@ -2009,7 +2003,7 @@ static int readState(char *stateFilename { FILE *f; char buf[STATEFILE_BUFFER_SIZE]; - char *filename; + char *filename; const char **argv; int argc; int year, month, day, hour, minute, second; @@ -2019,27 +2013,50 @@ static int readState(char *stateFilename struct logState *st; time_t lr_time; struct stat f_stat; + int rc = 0; + + message(MESS_DEBUG, "Reading state from file: %s\n", stateFilename); error = stat(stateFilename, &f_stat); + if (error) { + /* treat non-statable file as an empty file */ + f_stat.st_size = 0; + if (errno != ENOENT) { + message(MESS_ERROR, "error stat()ing state file %s: %s\n", + stateFilename, strerror(errno)); + + /* do not return until the hash table is allocated */ + rc = 1; + } + } - if ((error && errno == ENOENT) || (!error && f_stat.st_size == 0)) { - /* create the file before continuing to ensure we have write - access to the file */ - f = fopen(stateFilename, "w"); - if (!f) { - message(MESS_ERROR, "error creating state file %s: %s\n", - stateFilename, strerror(errno)); - return 1; - } - fprintf(f, "logrotate state -- version 2\n"); - fclose(f); - return 0; - } else if (error) { - message(MESS_ERROR, "error stat()ing state file %s: %s\n", - stateFilename, strerror(errno)); - return 1; + if (!debug && (f_stat.st_size == 0)) { + /* create the file before continuing to ensure we have write + access to the file */ + f = fopen(stateFilename, "w"); + if (f) { + fprintf(f, "logrotate state -- version 2\n"); + fclose(f); + } else { + message(MESS_ERROR, "error creating state file %s: %s\n", + stateFilename, strerror(errno)); + + /* do not return until the hash table is allocated */ + rc = 1; + } } + /* Try to estimate how many state entries we have in the state file. + * We expect single entry to have around 80 characters (Of course this is + * just an estimation). During the testing I've found out that 200 entries + * per single hash entry gives good mem/performance ratio. */ + if (allocateHash(f_stat.st_size / 80 / 200)) + return 1; + + if (rc || (f_stat.st_size == 0)) + /* error already occurred, or we have no state file to read from */ + return rc; + f = fopen(stateFilename, "r"); if (!f) { message(MESS_ERROR, "error opening state file %s: %s\n", @@ -2091,7 +2108,7 @@ static int readState(char *stateFilename } /* Hack to hide earlier bug */ - if ((year != 1900) && (year < 1996 || year > 2100)) { + if ((year != 1900) && (year < 1970 || year > 2100)) { message(MESS_ERROR, "bad year %d for file %s in state file %s\n", year, argv[0], stateFilename); @@ -2256,11 +2273,8 @@ int main(int argc, const char **argv) poptFreeContext(optCon); nowSecs = time(NULL); - if (allocateHash() != 0) - return 1; - - if (readState(stateFile)) - exit(1); + if (readState(stateFile)) + rc = 1; message(MESS_DEBUG, "\nHandling %d logs\n", numLogs); Index: logrotate-3.8.7/test/test =================================================================== --- logrotate-3.8.7.orig/test/test +++ logrotate-3.8.7/test/test @@ -1147,7 +1147,7 @@ fi rm -f error.log checkoutput <<EOF -test.log 0 zero +test.log 0 EOF
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor