forked from kernelslacker/trinity
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlog-files.c
172 lines (131 loc) · 3.23 KB
/
log-files.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "log.h"
#include "params.h" // logging, quiet_level
#include "pids.h"
#include "shm.h"
#define BUFSIZE 1024 // decoded syscall args are fprintf'd directly, this is for everything else.
FILE *mainlogfile;
static bool logfiles_opened = FALSE;
static FILE *open_logfile(const char *logfilename)
{
FILE *file;
unlink(logfilename);
file = fopen(logfilename, "w");
if (!file)
outputerr("## couldn't open logfile %s\n", logfilename);
return file;
}
void open_main_logfile(void)
{
if (logging == LOGGING_DISABLED)
return;
mainlogfile = open_logfile("trinity.log");
if (!mainlogfile)
exit(EXIT_FAILURE);
logfiles_opened = TRUE; //FIXME: This is a bit crap
}
void open_child_logfile(struct childdata *child)
{
char *logfilename;
if (logging == LOGGING_DISABLED)
return;
logfilename = zmalloc(64);
sprintf(logfilename, "trinity-child%u.log", child->num);
child->logfile = open_logfile(logfilename);
if (!child->logfile) {
shm->exit_reason = EXIT_LOGFILE_OPEN_ERROR;
exit(EXIT_FAILURE);
}
free(logfilename);
child->logdirty = FALSE;
}
void close_logfile(FILE **filehandle)
{
if (logging == LOGGING_DISABLED)
return;
if (*filehandle == NULL)
return;
fclose(*filehandle);
*filehandle = NULL;
}
static FILE * find_child_logfile_handle(pid_t pid)
{
int i;
unsigned int j;
FILE *log = NULL;
i = find_childno(pid);
if (i != CHILD_NOT_FOUND) {
log = shm->children[i]->logfile;
} else {
/* This is pretty ugly, and should never happen,
* but try again a second later, in case we're racing setup/teardown.
* FIXME: We may not even need this now that we have proper locking; test it.
*/
sleep(1);
i = find_childno(pid);
if (i == CHILD_NOT_FOUND) {
outputerr("Couldn't find child for pid %d\n", pid);
return mainlogfile;
}
log = shm->children[i]->logfile;
}
if (log != NULL)
return log;
/* if the logfile hadn't been set, log to main. */
shm->children[i]->logfile = mainlogfile;
outputerr("## child %d logfile handle was null logging to main!\n", i);
outputerr("## Couldn't find logfile for pid %d\n", pid);
dump_childnos();
outputerr("## Logfiles for pids: ");
for_each_child(j)
outputerr("%p ", shm->children[j]->logfile);
outputerr("\n");
(void)fflush(stdout);
sleep(5);
return mainlogfile;
}
FILE *find_logfile_handle(void)
{
FILE *handle = NULL;
pid_t pid;
if (logging == LOGGING_DISABLED)
return NULL;
if (!logfiles_opened)
return NULL;
pid = getpid();
if (pid == initpid)
return mainlogfile;
if (pid == shm->mainpid)
return mainlogfile;
if (pid == watchdog_pid)
return mainlogfile;
handle = find_child_logfile_handle(pid);
return handle;
}
/*
* Flush any pending log writes to disk.
* Only to be called from child context.
*/
void synclogs(void)
{
int fd;
if (logging == LOGGING_DISABLED)
return;
if (this_child->logdirty == FALSE)
return;
fflush(this_child->logfile);
fd = fileno(this_child->logfile);
if (fd != -1)
(void) fsync(fd);
this_child->logdirty = FALSE;
/* If we're flushing the child log, may as well flush
* any other logs while we're writing to disk.
*/
(void)fflush(mainlogfile);
fsync(fileno(mainlogfile));
}