diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-04 18:02:32 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-04 18:02:32 +0000 |
commit | b8934971516d69086cf693a1a51acf649930ee64 (patch) | |
tree | 381a3c9269bcc43b752b228dbe89532df6e6277e /sysklogd | |
parent | a9b60e93eeb4d2706ebc95bafb18bd4267a03d6f (diff) | |
download | busybox-w32-b8934971516d69086cf693a1a51acf649930ee64.tar.gz busybox-w32-b8934971516d69086cf693a1a51acf649930ee64.tar.bz2 busybox-w32-b8934971516d69086cf693a1a51acf649930ee64.zip |
syslogd: stop doing open/fstat/lseek/close on _every_ write
(still doing it if more than a second passed in between).
Costs ~40 bytes.
Diffstat (limited to 'sysklogd')
-rw-r--r-- | sysklogd/syslogd.c | 117 |
1 files changed, 65 insertions, 52 deletions
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index f4644f218..7edce7a0a 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c | |||
@@ -29,6 +29,7 @@ static char *dev_log_name; | |||
29 | 29 | ||
30 | /* Path for the file where all log messages are written */ | 30 | /* Path for the file where all log messages are written */ |
31 | static const char *logFilePath = "/var/log/messages"; | 31 | static const char *logFilePath = "/var/log/messages"; |
32 | static int logFD = -1; | ||
32 | 33 | ||
33 | /* interval between marks in seconds */ | 34 | /* interval between marks in seconds */ |
34 | static int markInterval = 20 * 60; | 35 | static int markInterval = 20 * 60; |
@@ -41,9 +42,11 @@ static char localHostName[64]; | |||
41 | 42 | ||
42 | #if ENABLE_FEATURE_ROTATE_LOGFILE | 43 | #if ENABLE_FEATURE_ROTATE_LOGFILE |
43 | /* max size of message file before being rotated */ | 44 | /* max size of message file before being rotated */ |
44 | static int logFileSize = 200 * 1024; | 45 | static unsigned logFileSize = 200 * 1024; |
45 | /* number of rotated message files */ | 46 | /* number of rotated message files */ |
46 | static int logFileRotate = 1; | 47 | static unsigned logFileRotate = 1; |
48 | static unsigned curFileSize; | ||
49 | static smallint isRegular; | ||
47 | #endif | 50 | #endif |
48 | 51 | ||
49 | #if ENABLE_FEATURE_REMOTE_LOG | 52 | #if ENABLE_FEATURE_REMOTE_LOG |
@@ -256,7 +259,10 @@ void log_to_shmem(const char *msg); | |||
256 | /* Print a message to the log file. */ | 259 | /* Print a message to the log file. */ |
257 | static void log_locally(char *msg) | 260 | static void log_locally(char *msg) |
258 | { | 261 | { |
259 | int fd, len = strlen(msg); | 262 | static time_t last; |
263 | |||
264 | struct flock fl; | ||
265 | int len = strlen(msg); | ||
260 | 266 | ||
261 | #if ENABLE_FEATURE_IPC_SYSLOG | 267 | #if ENABLE_FEATURE_IPC_SYSLOG |
262 | if ((option_mask32 & OPT_circularlog) && shbuf) { | 268 | if ((option_mask32 & OPT_circularlog) && shbuf) { |
@@ -264,62 +270,69 @@ static void log_locally(char *msg) | |||
264 | return; | 270 | return; |
265 | } | 271 | } |
266 | #endif | 272 | #endif |
267 | 273 | if (logFD >= 0) { | |
268 | again: | 274 | time_t cur; |
269 | fd = device_open(logFilePath, O_WRONLY | O_CREAT | 275 | time(&cur); |
276 | if (last != cur) { | ||
277 | last = cur; /* reopen log file every second */ | ||
278 | close(logFD); | ||
279 | goto reopen; | ||
280 | } | ||
281 | } else { | ||
282 | struct stat statf; | ||
283 | reopen: | ||
284 | logFD = device_open(logFilePath, O_WRONLY | O_CREAT | ||
270 | | O_NOCTTY | O_APPEND | O_NONBLOCK); | 285 | | O_NOCTTY | O_APPEND | O_NONBLOCK); |
271 | if (fd >= 0) { | 286 | if (logFD < 0) { |
272 | struct flock fl; | 287 | /* cannot open logfile? - print to /dev/console then */ |
288 | int fd = device_open(_PATH_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK); | ||
289 | if (fd < 0) | ||
290 | fd = 2; /* then stderr, dammit */ | ||
291 | full_write(fd, msg, len); | ||
292 | if (fd != 2) | ||
293 | close(fd); | ||
294 | return; | ||
295 | } | ||
296 | #if ENABLE_FEATURE_ROTATE_LOGFILE | ||
297 | isRegular = (fstat(logFD, &statf) == 0 && (statf.st_mode & S_IFREG)); | ||
298 | /* bug (mostly harmless): can wrap around if file > 4gb */ | ||
299 | curFileSize = statf.st_size; | ||
300 | #endif | ||
301 | } | ||
273 | 302 | ||
274 | fl.l_whence = SEEK_SET; | 303 | fl.l_whence = SEEK_SET; |
275 | fl.l_start = 0; | 304 | fl.l_start = 0; |
276 | fl.l_len = 1; | 305 | fl.l_len = 1; |
277 | fl.l_type = F_WRLCK; | 306 | fl.l_type = F_WRLCK; |
278 | fcntl(fd, F_SETLKW, &fl); | 307 | fcntl(logFD, F_SETLKW, &fl); |
279 | 308 | ||
280 | #if ENABLE_FEATURE_ROTATE_LOGFILE | 309 | #if ENABLE_FEATURE_ROTATE_LOGFILE |
281 | if (logFileSize) { | 310 | if (logFileSize && isRegular && curFileSize > logFileSize) { |
282 | struct stat statf; | 311 | if (logFileRotate) { /* always 0..99 */ |
283 | int r = fstat(fd, &statf); | 312 | int i = strlen(logFilePath) + 3 + 1; |
284 | if (!r && (statf.st_mode & S_IFREG) | 313 | char oldFile[i]; |
285 | && (lseek(fd, 0, SEEK_END) > logFileSize) | 314 | char newFile[i]; |
286 | ) { | 315 | i = logFileRotate - 1; |
287 | if (logFileRotate) { /* always 0..99 */ | 316 | /* rename: f.8 -> f.9; f.7 -> f.8; ... */ |
288 | int i = strlen(logFilePath) + 3 + 1; | 317 | while (1) { |
289 | char oldFile[i]; | 318 | sprintf(newFile, "%s.%d", logFilePath, i); |
290 | char newFile[i]; | 319 | if (i == 0) break; |
291 | i = logFileRotate - 1; | 320 | sprintf(oldFile, "%s.%d", logFilePath, --i); |
292 | /* rename: f.8 -> f.9; f.7 -> f.8; ... */ | 321 | rename(oldFile, newFile); |
293 | while (1) { | ||
294 | sprintf(newFile, "%s.%d", logFilePath, i); | ||
295 | if (i == 0) break; | ||
296 | sprintf(oldFile, "%s.%d", logFilePath, --i); | ||
297 | rename(oldFile, newFile); | ||
298 | } | ||
299 | /* newFile == "f.0" now */ | ||
300 | rename(logFilePath, newFile); | ||
301 | fl.l_type = F_UNLCK; | ||
302 | fcntl(fd, F_SETLKW, &fl); | ||
303 | close(fd); | ||
304 | goto again; | ||
305 | } | ||
306 | ftruncate(fd, 0); | ||
307 | } | 322 | } |
323 | /* newFile == "f.0" now */ | ||
324 | rename(logFilePath, newFile); | ||
325 | fl.l_type = F_UNLCK; | ||
326 | fcntl(logFD, F_SETLKW, &fl); | ||
327 | close(logFD); | ||
328 | goto reopen; | ||
308 | } | 329 | } |
309 | #endif | 330 | ftruncate(logFD, 0); |
310 | full_write(fd, msg, len); | ||
311 | fl.l_type = F_UNLCK; | ||
312 | fcntl(fd, F_SETLKW, &fl); | ||
313 | close(fd); | ||
314 | } else { | ||
315 | /* cannot open logfile? - print to /dev/console then */ | ||
316 | fd = device_open(_PATH_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK); | ||
317 | if (fd < 0) | ||
318 | fd = 2; /* then stderr, dammit */ | ||
319 | full_write(fd, msg, len); | ||
320 | if (fd != 2) | ||
321 | close(fd); | ||
322 | } | 331 | } |
332 | #endif | ||
333 | curFileSize += full_write(logFD, msg, len); | ||
334 | fl.l_type = F_UNLCK; | ||
335 | fcntl(logFD, F_SETLKW, &fl); | ||
323 | } | 336 | } |
324 | 337 | ||
325 | static void parse_fac_prio_20(int pri, char *res20) | 338 | static void parse_fac_prio_20(int pri, char *res20) |