1 |
commit: 275c33933ab8ef11ce965530013e47819dfde2fd |
2 |
Author: Alexander Bersenev <bay <AT> hackerdom <DOT> ru> |
3 |
AuthorDate: Sat Jul 2 13:36:15 2011 +0000 |
4 |
Commit: Александр Берсенев <bay <AT> hackerdom <DOT> ru> |
5 |
CommitDate: Sat Jul 2 13:36:15 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/autodep.git;a=commit;h=275c3393 |
7 |
|
8 |
more reliable logging logic with ld_preload approach |
9 |
|
10 |
--- |
11 |
logger/src/autodep/showfsevents.py | 4 +- |
12 |
logger/src/hook_lib/file_hook.c | 204 ++++++++++++++++++++---------------- |
13 |
2 files changed, 115 insertions(+), 93 deletions(-) |
14 |
|
15 |
diff --git a/logger/src/autodep/showfsevents.py b/logger/src/autodep/showfsevents.py |
16 |
index 20264e1..3af07d0 100755 |
17 |
--- a/logger/src/autodep/showfsevents.py |
18 |
+++ b/logger/src/autodep/showfsevents.py |
19 |
@@ -27,8 +27,8 @@ for stage in events: |
20 |
filenames=filenames.keys(); |
21 |
|
22 |
# temporary disabled |
23 |
-#file_to_package=logfs.portage_utils.getpackagesbyfiles(filenames) |
24 |
-file_to_package={} |
25 |
+file_to_package=logfs.portage_utils.getpackagesbyfiles(filenames) |
26 |
+#file_to_package={} |
27 |
#print events |
28 |
|
29 |
stagesorder={"clean":1,"setup":2,"unpack":3,"prepare":4,"configure":5,"compile":6,"test":7, |
30 |
|
31 |
diff --git a/logger/src/hook_lib/file_hook.c b/logger/src/hook_lib/file_hook.c |
32 |
index 2958cb7..8702a2c 100644 |
33 |
--- a/logger/src/hook_lib/file_hook.c |
34 |
+++ b/logger/src/hook_lib/file_hook.c |
35 |
@@ -52,9 +52,61 @@ int (*_close)(int fd); // we hooking this, because some programs closes our sock |
36 |
|
37 |
int log_socket=-1; |
38 |
|
39 |
-char log_socket_orig[MAXSOCKETPATHLEN]; |
40 |
+char log_socket_name[MAXSOCKETPATHLEN]; |
41 |
+ |
42 |
+void __doconnect(){ |
43 |
+ if(strlen(log_socket_name)>=MAXSOCKETPATHLEN) { |
44 |
+ fprintf(stderr,"Unable to create a unix-socket %s: socket name is too long,exiting\n", log_socket_name); |
45 |
+ exit(1); |
46 |
+ } |
47 |
+ |
48 |
+ log_socket=socket(AF_UNIX, SOCK_SEQPACKET, 0); |
49 |
+ if(log_socket==-1) { |
50 |
+ fprintf(stderr,"Unable to create a unix-socket %s: %s\n", log_socket_name, strerror(errno)); |
51 |
+ exit(1); |
52 |
+ } |
53 |
+ |
54 |
+ struct sockaddr_un serveraddr; |
55 |
+ memset(&serveraddr, 0, sizeof(serveraddr)); |
56 |
+ serveraddr.sun_family = AF_UNIX; |
57 |
+ strcpy(serveraddr.sun_path, log_socket_name); |
58 |
+ |
59 |
+ |
60 |
+ int ret=connect(log_socket, (struct sockaddr *)&serveraddr, SUN_LEN(&serveraddr)); |
61 |
+ if(ret==-1) { |
62 |
+ fprintf(stderr,"Unable to connect a unix-socket %s: %s\n",log_socket_name, strerror(errno)); |
63 |
+ fflush(stderr); |
64 |
+ //execlp("/bin/bash","/bin/bash",NULL); |
65 |
+ exit(1); |
66 |
+ } |
67 |
+} |
68 |
+ |
69 |
+void __dodisconnect() { |
70 |
+ close(log_socket); |
71 |
+} |
72 |
+ |
73 |
+void __doreconnect() { |
74 |
+ __doconnect(); |
75 |
+ __dodisconnect(); |
76 |
+} |
77 |
+ |
78 |
+// this fucnction executes when library is loaded |
79 |
+void _init() { |
80 |
+ char *log_socket_env=getenv("LOG_SOCKET"); |
81 |
+ |
82 |
+ if(log_socket_env==NULL) { |
83 |
+ fprintf(stderr,"LOG_SOCKET environment variable isn't defined." |
84 |
+ "Are this library launched by server?\n"); |
85 |
+ exit(1); |
86 |
+ } |
87 |
+ |
88 |
+ if(strlen(log_socket_env)>=MAXSOCKETPATHLEN) { |
89 |
+ fprintf(stderr,"Unable to create a unix-socket %s: socket name is too long,exiting\n", log_socket_name); |
90 |
+ exit(1); |
91 |
+ } |
92 |
+ strcpy(log_socket_name,log_socket_env); |
93 |
+ |
94 |
|
95 |
-void __doinit(){ |
96 |
_open = (int (*)(const char * pathname, int flags, ...)) dlsym(RTLD_NEXT, "open"); |
97 |
_open64 = (int (*)(const char * pathname, int flags, ...)) dlsym(RTLD_NEXT, "open64"); |
98 |
|
99 |
@@ -87,63 +139,17 @@ void __doinit(){ |
100 |
exit(1); |
101 |
} |
102 |
|
103 |
- |
104 |
- char *log_socket_name=getenv("LOG_SOCKET"); |
105 |
- |
106 |
- if(log_socket_name==NULL) { |
107 |
- fprintf(stderr,"LOG_SOCKET environment variable isn't defined." |
108 |
- "Are this library launched by server?\n"); |
109 |
- |
110 |
- exit(1); |
111 |
- } |
112 |
- strcpy(log_socket_orig,getenv("LOG_SOCKET")); |
113 |
- //fprintf(stderr,"%d %s\n",getpid(),log_socket_name); |
114 |
- |
115 |
- |
116 |
- if(strlen(log_socket_name)>=MAXSOCKETPATHLEN) { |
117 |
- fprintf(stderr,"Unable to create a unix-socket %s: socket name is too long,exiting\n", log_socket_name); |
118 |
- exit(1); |
119 |
- } |
120 |
- |
121 |
- log_socket=socket(AF_UNIX, SOCK_SEQPACKET, 0); |
122 |
- if(log_socket==-1) { |
123 |
- fprintf(stderr,"Unable to create a unix-socket %s: %s\n", log_socket_name, strerror(errno)); |
124 |
- exit(1); |
125 |
- } |
126 |
- |
127 |
- struct sockaddr_un serveraddr; |
128 |
- memset(&serveraddr, 0, sizeof(serveraddr)); |
129 |
- serveraddr.sun_family = AF_UNIX; |
130 |
- strcpy(serveraddr.sun_path, log_socket_name); |
131 |
- |
132 |
- |
133 |
- int ret=connect(log_socket, (struct sockaddr *)&serveraddr, SUN_LEN(&serveraddr)); |
134 |
- if(ret==-1) { |
135 |
- fprintf(stderr,"Unable to connect a unix-socket %d %s: %s\n", getpid(),log_socket_name, strerror(errno)); |
136 |
- fflush(stderr); |
137 |
- //execlp("/bin/bash","/bin/bash",NULL); |
138 |
- exit(1); |
139 |
- } |
140 |
-} |
141 |
- |
142 |
-void __dofini() { |
143 |
- close(log_socket); |
144 |
-} |
145 |
- |
146 |
-void _init() { |
147 |
- __doinit(); |
148 |
+ __doconnect(); |
149 |
} |
150 |
|
151 |
void _fini() { |
152 |
- __dofini(); |
153 |
+ __dodisconnect(); |
154 |
} |
155 |
|
156 |
/* |
157 |
* Format of log string: time event filename stage result/err |
158 |
*/ |
159 |
static int __raw_log_event(const char *event_type, const char *filename, char *result,int err, char* stage) { |
160 |
- //printf("lololo:%s %s %s\n",event_type,filename,stage); |
161 |
- |
162 |
char msg_buff[MAXSOCKETMSGLEN]; |
163 |
int bytes_to_send; |
164 |
if(strcmp(result,"ERR")==0) { |
165 |
@@ -157,8 +163,13 @@ static int __raw_log_event(const char *event_type, const char *filename, char *r |
166 |
if(bytes_to_send>=MAXSOCKETMSGLEN) |
167 |
return 0; |
168 |
|
169 |
- if(send(log_socket,msg_buff,bytes_to_send,0)==-1) |
170 |
- return 0; |
171 |
+ if(send(log_socket,msg_buff,bytes_to_send,0)==-1) { |
172 |
+ __doreconnect(); // looks like our socket has been destroyed by logged program |
173 |
+ // try to recreate it |
174 |
+ |
175 |
+ if(send(log_socket,msg_buff,bytes_to_send,0)==-1) |
176 |
+ return 0; |
177 |
+ } |
178 |
|
179 |
return 1; |
180 |
} |
181 |
@@ -167,7 +178,10 @@ static int __raw_log_event(const char *event_type, const char *filename, char *r |
182 |
* Log an event |
183 |
*/ |
184 |
static int __log_event(const char *event_type, const char *filename, char *result,int err, char* stage) { |
185 |
- return __raw_log_event(event_type,filename,result,err,stage); |
186 |
+ pthread_mutex_lock( &socketblock ); |
187 |
+ int ret=__raw_log_event(event_type,filename,result,err,stage); |
188 |
+ pthread_mutex_unlock( &socketblock ); |
189 |
+ return ret; |
190 |
} |
191 |
|
192 |
/* |
193 |
@@ -206,15 +220,21 @@ static int __is_event_allowed(const char *event_type,const char *filename, char* |
194 |
__raw_log_event(event_type,filename,"ASKING",0,stage); |
195 |
bytes_recieved=recv(log_socket,answer,8,0); |
196 |
|
197 |
+ if(bytes_recieved==-1) { |
198 |
+ __doreconnect(); // looks like our socket has been destroyed by logged program |
199 |
+ // try to recreate it |
200 |
+ bytes_recieved=recv(log_socket,answer,8,0); |
201 |
+ } |
202 |
+ |
203 |
pthread_mutex_unlock( &socketblock ); |
204 |
|
205 |
- if(strcmp(answer,"ALLOW")==0) |
206 |
+ if(strcmp(answer,"ALLOW")==0) { |
207 |
return 1; |
208 |
- else if(strcmp(answer,"DENY")==0) |
209 |
+ } else if(strcmp(answer,"DENY")==0) |
210 |
return 0; |
211 |
else { |
212 |
- fprintf(stderr,"Protocol error, text should be ALLOW or DENY, got: %s",answer); |
213 |
- |
214 |
+ fprintf(stderr,"Protocol error, text should be ALLOW or DENY, got: '%s' recv retcode=%d(%s)" |
215 |
+ " socket=%d",answer,bytes_recieved,strerror(errno),log_socket); |
216 |
exit(1); |
217 |
} |
218 |
return 0; |
219 |
@@ -231,18 +251,15 @@ int open(const char * path, int flags, mode_t mode) { |
220 |
__log_event("open",fullpath,"DENIED",errno,stage); |
221 |
return -1; |
222 |
} |
223 |
- |
224 |
|
225 |
- //if(flags & O_CREAT) |
226 |
- ret=_open(path, flags, mode); |
227 |
- //else |
228 |
- // ret=_open(path, flags, 0); |
229 |
+ ret=_open(path, flags, mode); |
230 |
+ int saved_errno=errno; |
231 |
|
232 |
if(ret==-1) |
233 |
__log_event("open",fullpath,"ERR",errno,stage); |
234 |
else |
235 |
- __log_event("open",fullpath,"OK",0,stage); |
236 |
- |
237 |
+ __log_event("open",fullpath,"OK",0,stage); |
238 |
+ errno=saved_errno; |
239 |
|
240 |
return ret; |
241 |
} |
242 |
@@ -258,15 +275,14 @@ int open64(const char * path, int flags, mode_t mode) { |
243 |
return -1; |
244 |
} |
245 |
|
246 |
- if(flags & O_CREAT) |
247 |
- ret=_open64(path, flags, mode); |
248 |
- else |
249 |
- ret=_open64(path, flags, 0); |
250 |
- |
251 |
+ ret=_open64(path, flags, mode); |
252 |
+ |
253 |
+ int saved_errno=errno; |
254 |
if(ret==-1) |
255 |
__log_event("open",fullpath,"ERR",errno,stage); |
256 |
else |
257 |
__log_event("open",fullpath,"OK",0,stage); |
258 |
+ errno=saved_errno; |
259 |
|
260 |
return ret; |
261 |
} |
262 |
@@ -284,10 +300,12 @@ FILE *fopen(const char *path, const char *mode) { |
263 |
} |
264 |
|
265 |
ret=_fopen(path,mode); |
266 |
+ int saved_errno=errno; |
267 |
if(ret==NULL) |
268 |
__log_event("open",fullpath,"ERR",errno,stage); |
269 |
else |
270 |
__log_event("open",fullpath,"OK",0,stage); |
271 |
+ errno=saved_errno; |
272 |
return ret; |
273 |
} |
274 |
|
275 |
@@ -304,45 +322,48 @@ FILE *fopen64(const char *path, const char *mode) { |
276 |
} |
277 |
|
278 |
ret=_fopen64(path,mode); |
279 |
+ int saved_errno=errno; |
280 |
|
281 |
if(ret==NULL) |
282 |
__log_event("open",fullpath,"ERR",errno,stage); |
283 |
else |
284 |
__log_event("open",fullpath,"OK",0,stage); |
285 |
|
286 |
+ errno=saved_errno; |
287 |
return ret; |
288 |
} |
289 |
|
290 |
ssize_t read(int fd, void *buf, size_t count){ |
291 |
ssize_t ret=_read(fd,buf,count); |
292 |
+ int saved_errno=errno; |
293 |
char *stage=__get_stage(); |
294 |
|
295 |
char fullpath[MAXPATHLEN]; |
296 |
ssize_t path_size=__get_path_by_fd(fd,fullpath,MAXPATHLEN); |
297 |
- if(path_size==-1) |
298 |
- return ret; |
299 |
- |
300 |
- if(ret==-1) |
301 |
- __log_event("read",fullpath,"ERR",errno,stage); |
302 |
- else |
303 |
- __log_event("read",fullpath,"OK",0,stage); |
304 |
- |
305 |
+ if(path_size!=-1) { |
306 |
+ if(ret==-1) |
307 |
+ __log_event("read",fullpath,"ERR",errno,stage); |
308 |
+ else |
309 |
+ __log_event("read",fullpath,"OK",0,stage); |
310 |
+ } |
311 |
+ errno=saved_errno; |
312 |
return ret; |
313 |
} |
314 |
|
315 |
ssize_t write(int fd,const void *buf, size_t count){ |
316 |
ssize_t ret=_write(fd,buf,count); |
317 |
+ int saved_errno=errno; |
318 |
char *stage=__get_stage(); |
319 |
char fullpath[MAXPATHLEN]; |
320 |
ssize_t path_size=__get_path_by_fd(fd,fullpath,MAXPATHLEN); |
321 |
- if(path_size==-1) |
322 |
- return ret; |
323 |
+ if(path_size!=-1){ |
324 |
+ if(ret==-1) |
325 |
+ __log_event("write",fullpath,"ERR",errno,stage); |
326 |
+ else |
327 |
+ __log_event("write",fullpath,"OK",0,stage); |
328 |
+ } |
329 |
|
330 |
- if(ret==-1) |
331 |
- __log_event("write",fullpath,"ERR",errno,stage); |
332 |
- else |
333 |
- __log_event("write",fullpath,"OK",0,stage); |
334 |
- |
335 |
+ errno=saved_errno; |
336 |
return ret; |
337 |
} |
338 |
|
339 |
@@ -350,21 +371,22 @@ pid_t fork(void) { |
340 |
//fprintf(stderr,"prefork %s %s\n",getenv("LOG_SOCKET"),log_socket_orig); |
341 |
|
342 |
//int succ= |
343 |
- setenv("LOG_SOCKET",log_socket_orig,1); |
344 |
+ _setenv("LOG_SOCKET",log_socket_name,1); |
345 |
|
346 |
//fprintf(stderr,"prefork %s%p%p%d %s\n",getenv("LOG_SOCKET"),_setenv,setenv,succ,log_socket_orig); |
347 |
|
348 |
int ret=_fork(); |
349 |
+ int saved_errno=errno; |
350 |
// we must to handle fork for reconnect a socket |
351 |
|
352 |
if(ret==0) { |
353 |
- |
354 |
- __dofini(); // reinit connection for clildren |
355 |
- __doinit(); // because now it is different processes |
356 |
+ __doreconnect(); // reinit connection for children |
357 |
+ // because now it is different processes |
358 |
} else { |
359 |
//fprintf(stderr,"fork new: %d LOG_SOCKET=%s\n", ret,getenv("LOG_SOCKET")); |
360 |
//sleep(3); |
361 |
} |
362 |
+ errno=saved_errno; |
363 |
return ret; |
364 |
} |
365 |
|
366 |
@@ -388,12 +410,12 @@ int execve(const char *filename, char *const argv[], |
367 |
if(strcmp(envp[i]+11,getenv("LD_PRELOAD"))==0) |
368 |
ld_preload_valid=1; |
369 |
if(strncmp(envp[i],"LOG_SOCKET=",11)==0) |
370 |
- if(strcmp(envp[i]+11,log_socket_orig)==0) |
371 |
+ if(strcmp(envp[i]+11,log_socket_name)==0) |
372 |
log_socket_valid=1; |
373 |
} |
374 |
if(!ld_preload_valid || !log_socket_valid) { |
375 |
snprintf(new_ld_preload,MAXENVITEMSIZE,"LD_PRELOAD=%s",getenv("LD_PRELOAD")); |
376 |
- snprintf(new_log_socket,MAXENVITEMSIZE,"LOG_SOCKET=%s",log_socket_orig); |
377 |
+ snprintf(new_log_socket,MAXENVITEMSIZE,"LOG_SOCKET=%s",log_socket_name); |
378 |
for(i=0; envp[i] && i<MAXENVSIZE-3; i++) { |
379 |
if(strncmp(envp[i],"LD_PRELOAD=",11)==0) { |
380 |
new_envp[i]=new_ld_preload; |
381 |
@@ -413,7 +435,7 @@ int execve(const char *filename, char *const argv[], |
382 |
if(!log_socket_valid) { |
383 |
new_envp[i]=new_log_socket; |
384 |
i++; |
385 |
- } |
386 |
+} |
387 |
new_envp[i]=NULL; |
388 |
envp=new_envp; |
389 |
// for(i=0;envp[i];i++){ |