Permalink
Browse files

If you have an incredibly large log file.. kerneloops takes too long.

Just parse the last 32Mb instead, should be plenty.
  • Loading branch information...
1 parent 47cd292 commit 4aad027635f8d8faf211a824cc502efa3ea41d16 @fenrus75 fenrus75 committed Jun 22, 2008
Showing with 14 additions and 4 deletions.
  1. +14 −4 dmesg.c
View
18 dmesg.c
@@ -40,6 +40,8 @@ static char **linepointer;
static char *linelevel;
static int linecount;
+#define MAX(A,B) ((A) > (B) ? (A) : (B))
+
/*
* This function splits the dmesg buffer data into lines
@@ -352,6 +354,7 @@ void scan_filename(char *filename, int issyslog)
struct stat statb;
FILE *file;
int ret;
+ size_t buflen;
memset(&statb, 0, sizeof(statb));
@@ -364,21 +367,28 @@ void scan_filename(char *filename, int issyslog)
* in theory there's a race here, since someone could spew
* to /var/log/messages before we read it in... we try to
* deal with it by reading at most 1023 bytes extra. If there's
- * more than that.. any oops will be in dmesg anyway
+ * more than that.. any oops will be in dmesg anyway.
+ * Do not try to allocate an absurt amount of memory; ignore
+ * older log messages because they are unlikely to have
+ * sufficiently recent data to be useful. 32MB is more
+ * than enough; it's not worth looping through more log
+ * if the log is larger than that.
*/
- buffer = calloc(statb.st_size+1024, 1);
+ buflen = MAX(statb.st_size+1024, 32*1024*1024);
+ buffer = calloc(buflen, 1);
assert(buffer != NULL);
file = fopen(filename, "rm");
if (!file) {
free(buffer);
return;
}
- ret = fread(buffer, 1, statb.st_size+1023, file);
+ fseek(file, -buflen, SEEK_END);
+ ret = fread(buffer, 1, buflen-1, file);
fclose(file);
if (ret > 0)
- extract_oops(buffer, statb.st_size+1023, issyslog);
+ extract_oops(buffer, buflen-1, issyslog);
free(buffer);
if (opted_in >= 2)
submit_queue();

0 comments on commit 4aad027

Please sign in to comment.