aboutsummaryrefslogtreecommitdiff
path: root/sysklogd
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-01-04 18:02:32 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-01-04 18:02:32 +0000
commitb8934971516d69086cf693a1a51acf649930ee64 (patch)
tree381a3c9269bcc43b752b228dbe89532df6e6277e /sysklogd
parenta9b60e93eeb4d2706ebc95bafb18bd4267a03d6f (diff)
downloadbusybox-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.c117
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 */
31static const char *logFilePath = "/var/log/messages"; 31static const char *logFilePath = "/var/log/messages";
32static int logFD = -1;
32 33
33/* interval between marks in seconds */ 34/* interval between marks in seconds */
34static int markInterval = 20 * 60; 35static 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 */
44static int logFileSize = 200 * 1024; 45static unsigned logFileSize = 200 * 1024;
45/* number of rotated message files */ 46/* number of rotated message files */
46static int logFileRotate = 1; 47static unsigned logFileRotate = 1;
48static unsigned curFileSize;
49static 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. */
257static void log_locally(char *msg) 260static 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
325static void parse_fac_prio_20(int pri, char *res20) 338static void parse_fac_prio_20(int pri, char *res20)