Gentoo Archives: gentoo-commits

From: "Александр Берсенев" <bay@×××××××××.ru>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/autodep:master commit in: logger/src/autodep/logfs/, logger/src/autodep/
Date: Sat, 02 Jul 2011 10:29:04
Message-Id: 12b34e7369e0c0561da1af0a81ca588f5a026e0d.bay@gentoo
1 commit: 12b34e7369e0c0561da1af0a81ca588f5a026e0d
2 Author: Alexander Bersenev <bay <AT> hackerdom <DOT> ru>
3 AuthorDate: Sat Jul 2 16:28:32 2011 +0000
4 Commit: Александр Берсенев <bay <AT> hackerdom <DOT> ru>
5 CommitDate: Sat Jul 2 16:28:32 2011 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/autodep.git;a=commit;h=12b34e73
7
8 ctrl-c handling
9
10 ---
11 logger/src/autodep/logfs/fstracer.py | 219 ++++++++++++++--------------
12 logger/src/autodep/logfs/logger_fusefs.py | 15 ++-
13 logger/src/autodep/logfs/logger_hooklib.py | 1 +
14 logger/src/autodep/showfsevents.py | 8 +-
15 4 files changed, 127 insertions(+), 116 deletions(-)
16
17 diff --git a/logger/src/autodep/logfs/fstracer.py b/logger/src/autodep/logfs/fstracer.py
18 index 1b99f8e..80666e6 100644
19 --- a/logger/src/autodep/logfs/fstracer.py
20 +++ b/logger/src/autodep/logfs/fstracer.py
21 @@ -11,12 +11,16 @@ import tempfile
22 import socket
23 import select
24 import re
25 +import signal
26
27 import proc_helpers
28
29 import logger_hooklib
30 import logger_fusefs
31
32 +stop=False;
33 +stoptime=0;
34 +
35 def parse_message(message):
36 ret=message.split("\0")
37 return ret
38 @@ -92,27 +96,6 @@ def checkparent(parent,child):
39 print "External actions with filesystem detected pid of external prog is %d" % child
40 return False
41
42 -# check pid, returns stage of building
43 -def get_stage_by_pid(pid,toppid):
44 - #return "unknown"
45 -
46 - currpid=proc_helpers.getparentpid(pid)
47 - try:
48 - while currpid>1 and currpid!=toppid:
49 - cmdlinefile=open("/proc/%d/cmdline" % currpid,"r")
50 - cmdline=cmdlinefile.read()
51 - cmdlinefile.close()
52 - arguments=cmdline.split("\0")
53 - #print arguments
54 - if len(arguments)>=3 and arguments[1][-9:]=="ebuild.sh":
55 - return arguments[2]
56 - currpid=proc_helpers.getparentpid(currpid)
57 -
58 -
59 - except IOError,e:
60 - return "unknown"
61 -
62 - return "unknown"
63
64 # default access filter. Allow acess to all files
65 def defaultfilter(eventname, filename, pid):
66 @@ -127,7 +110,6 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter)
67 socketname = os.path.join(tmpdir, 'socket')
68
69 try:
70 - #sock_listen=socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
71 sock_listen=socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
72
73 sock_listen.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
74 @@ -142,7 +124,6 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter)
75 return []
76 else:
77 #print socketname
78 -
79 pid=os.fork()
80 if pid==0:
81 logger=None
82 @@ -160,100 +141,116 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter)
83 print "Launch likely was unsuccessful"
84 sys.exit(1)
85 else:
86 + def signal_handler(sig, frame):
87 + print "You pressed Ctrl+C!"
88 + global stoptime
89 + if(time.time()-stoptime>5):
90 + print "Sending SIGINT to child"
91 + print "Press again in 5 seconds to force exit"
92 + stoptime=time.time()
93 + else:
94 + print "Sending SIGKILL to child"
95 + os.kill(pid,signal.SIGKILL)
96 + os._exit(1)
97 + global signal
98 + signal.signal(signal.SIGINT, signal_handler)
99 +
100 epoll=select.epoll()
101 epoll.register(sock_listen.fileno(), select.EPOLLIN)
102
103 connects = 0;
104 clients={}
105 - stop=0
106 was_first_connect=False
107 -
108 - #print "fileno listen: %d",sock_listen.fileno()
109 -
110 - while stop==0:
111 - sock_events = epoll.poll(3)
112 - for fileno, sock_event in sock_events:
113 - if fileno == sock_listen.fileno():
114 - #print "\n\nEVENT\n\n"
115 - ret = sock_listen.accept()
116 - #print ret
117 - if ret is None:
118 - # print "\n\nPASS\n\n"
119 - pass
120 - else:
121 - (client,addr)=ret
122 - # print client
123 - connects+=1; # client accepted
124 - was_first_connect=True
125 - epoll.register(client.fileno(), select.EPOLLIN)
126 - clients[client.fileno()]=client
127 - #print "opened %d" % client.fileno()
128 - #elif sock_event & select.EPOLLHUP:
129 - #epoll.unregister(fileno)
130 - #clients[fileno].close()
131 - #del clients[fileno]
132 - #connects-=1
133 -
134 - elif sock_event & select.EPOLLIN:
135 - s=clients[fileno]
136 - record=s.recv(8192)
137 -
138 - if not record: # if connection was closed
139 - epoll.unregister(fileno)
140 - clients[fileno].close()
141 - del clients[fileno]
142 - connects-=1
143 - #print "closed %d"%fileno
144 - continue
145 -
146 - message=record.split("\0")
147 - #print message
148 -
149 - try:
150 - if message[4]=="ASKING":
151 - if filterproc(message[1],message[2],message[3]):
152 - #print "Allowing an access to %s" % message[2]
153 - s.sendall("ALLOW\0"); # TODO: think about flush here
154 -
155 - else:
156 - print "Blocking an access to %s" % message[2]
157 - s.sendall("DENY\0"); # TODO: think about flush here
158 -
159 +
160 + while True:
161 + try:
162 + sock_events = epoll.poll(3)
163 +
164 + for fileno, sock_event in sock_events:
165 + if fileno == sock_listen.fileno():
166 + #print "\n\nEVENT\n\n"
167 + ret = sock_listen.accept()
168 + #print ret
169 + if ret is None:
170 + # print "\n\nPASS\n\n"
171 + pass
172 else:
173 - eventname,filename,stage,result=message[1:5]
174 + (client,addr)=ret
175 + # print client
176 + connects+=1; # client accepted
177 + was_first_connect=True
178 + epoll.register(client.fileno(), select.EPOLLIN)
179 + clients[client.fileno()]=client
180 + #print "opened %d" % client.fileno()
181 + #elif sock_event & select.EPOLLHUP:
182 + #epoll.unregister(fileno)
183 + #clients[fileno].close()
184 + #del clients[fileno]
185 + #connects-=1
186 +
187 + elif sock_event & select.EPOLLIN:
188 + s=clients[fileno]
189 + record=s.recv(8192)
190 +
191 + if not record: # if connection was closed
192 + epoll.unregister(fileno)
193 + clients[fileno].close()
194 + del clients[fileno]
195 + connects-=1
196 + #print "closed %d"%fileno
197 + continue
198 +
199 + message=record.split("\0")
200 + #print message
201 +
202 + try:
203 + if message[4]=="ASKING":
204 + if filterproc(message[1],message[2],message[3]):
205 + #print "Allowing an access to %s" % message[2]
206 + s.sendall("ALLOW\0"); # TODO: think about flush here
207 +
208 + else:
209 + print "Blocking an access to %s" % message[2]
210 + s.sendall("DENY\0"); # TODO: think about flush here
211 +
212 + else:
213 + eventname,filename,stage,result=message[1:5]
214
215 - if not stage in events:
216 - events[stage]=[{},{}]
217 -
218 - hashofsucesses=events[stage][0]
219 - hashoffailures=events[stage][1]
220 -
221 - if result=="OK":
222 - if not filename in hashofsucesses:
223 - hashofsucesses[filename]=[False,False]
224 + if not stage in events:
225 + events[stage]=[{},{}]
226
227 - readed_or_writed=hashofsucesses[filename]
228 + hashofsucesses=events[stage][0]
229 + hashoffailures=events[stage][1]
230
231 - if eventname=="read":
232 - readed_or_writed[0]=True
233 - elif eventname=="write":
234 - readed_or_writed[1]=True
235 + if result=="OK":
236 + if not filename in hashofsucesses:
237 + hashofsucesses[filename]=[False,False]
238
239 - elif result[0:3]=="ERR" or result=="DENIED":
240 - if not filename in hashoffailures:
241 - hashoffailures[filename]=[False,False]
242 - notfound_or_blocked=hashoffailures[filename]
243 -
244 - if result=="ERR/2":
245 - notfound_or_blocked[0]=True
246 - elif result=="DENIED":
247 - notfound_or_blocked[1]=True
248 + readed_or_writed=hashofsucesses[filename]
249 +
250 + if eventname=="read":
251 + readed_or_writed[0]=True
252 + elif eventname=="write":
253 + readed_or_writed[1]=True
254 +
255 + elif result[0:3]=="ERR" or result=="DENIED":
256 + if not filename in hashoffailures:
257 + hashoffailures[filename]=[False,False]
258 + notfound_or_blocked=hashoffailures[filename]
259 +
260 + if result=="ERR/2":
261 + notfound_or_blocked[0]=True
262 + elif result=="DENIED":
263 + notfound_or_blocked[1]=True
264
265 - else:
266 - print "Error in logger module<->analyser protocol"
267 -
268 - except IndexError:
269 - print "IndexError while parsing %s"%record
270 + else:
271 + print "Error in logger module<->analyser protocol"
272 +
273 + except IndexError:
274 + print "IndexError while parsing %s"%record
275 + except IOError, e:
276 + if e.errno!=4: # handling "Interrupted system call" errors
277 + raise
278
279 if was_first_connect and connects==0:
280 break
281 @@ -264,15 +261,17 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter)
282 "Check that you are not launching a suid program under non-root user."
283 return []
284 if len(clients)==0 and iszombie(pid):
285 - break
286 -
287 - #print "\n\nRETURNING!!!!\n\n"
288 -
289 + break
290
291 - os.wait()
292 + #print "\n\nRETURNING!!!!\n\n"
293
294 epoll.unregister(sock_listen.fileno())
295 epoll.close()
296 sock_listen.close()
297 +
298 + _, exit_status=os.waitpid(pid,0)
299 + signal,exit_status=exit_status%256,exit_status/256
300 + print "Signal: %s Exit status: %s" % (signal,exit_status)
301 +
302 return events
303
304
305 diff --git a/logger/src/autodep/logfs/logger_fusefs.py b/logger/src/autodep/logfs/logger_fusefs.py
306 index 9990ef9..6c135e8 100644
307 --- a/logger/src/autodep/logfs/logger_fusefs.py
308 +++ b/logger/src/autodep/logfs/logger_fusefs.py
309 @@ -4,6 +4,8 @@ import subprocess
310 import time
311 import os
312 import sys
313 +import signal
314 +
315
316
317 class logger:
318 @@ -47,6 +49,7 @@ class logger:
319 os.environ["LOG_SOCKET"]=self.socketname
320 os.environ["PARENT_PID"]=str(self.currpid)
321
322 + # TODO: change
323 ret=subprocess.call(['/home/bay/gsoc/logger/src/hook_fusefs/hookfs',self.rootmountpath,
324 '-o','allow_other,suid'])
325 if ret!=0:
326 @@ -102,7 +105,12 @@ class logger:
327 sys.exit(1)
328
329 else:
330 - exitcode=os.wait()[1];
331 + exitcode=2; # if ctrl-c pressed then returning this value
332 + needtokillself=False
333 + try:
334 + exitcode=os.wait()[1]/256;
335 + except KeyboardInterrupt:
336 + needtokillself=True
337 try:
338 print "Unmounting partitions"
339 self.mountlist.reverse()
340 @@ -118,4 +126,7 @@ class logger:
341 print "Error while unmounting fuse filesystem: %s" % e
342 sys.exit(1)
343
344 - sys.exit(int(exitcode/256))
345 + if needtokillself: # we kill self for report the status correct
346 + signal.signal(signal.SIGINT,signal.SIG_DFL)
347 + os.kill(os.getpid(),signal.SIGINT)
348 + os._exit(exitcode)
349
350 diff --git a/logger/src/autodep/logfs/logger_hooklib.py b/logger/src/autodep/logfs/logger_hooklib.py
351 index cda22b6..008fc56 100644
352 --- a/logger/src/autodep/logfs/logger_hooklib.py
353 +++ b/logger/src/autodep/logfs/logger_hooklib.py
354 @@ -20,3 +20,4 @@ class logger:
355 except OSError, e:
356 print "Failed to launch the programm: %s" % e
357 sys.exit(1)
358 +
359
360 diff --git a/logger/src/autodep/showfsevents.py b/logger/src/autodep/showfsevents.py
361 index 3af07d0..aa03d9f 100755
362 --- a/logger/src/autodep/showfsevents.py
363 +++ b/logger/src/autodep/showfsevents.py
364 @@ -12,9 +12,9 @@ if len(sys.argv)<2:
365 print "Usage: showfsevents.py <command>"
366 exit(1)
367
368 -events=logfs.fstracer.getfsevents(sys.argv[1], sys.argv[1:],approach="hooklib")
369 +events=logfs.fstracer.getfsevents(sys.argv[1], sys.argv[1:],approach="fusefs")
370 print "Program finished, analyzing dependencies"
371 -#exit(0);
372 +exit(0);
373 # get unique filenames
374 filenames={}
375 for stage in events:
376 @@ -27,8 +27,8 @@ for stage in events:
377 filenames=filenames.keys();
378
379 # temporary disabled
380 -file_to_package=logfs.portage_utils.getpackagesbyfiles(filenames)
381 -#file_to_package={}
382 +#file_to_package=logfs.portage_utils.getpackagesbyfiles(filenames)
383 +file_to_package={}
384 #print events
385
386 stagesorder={"clean":1,"setup":2,"unpack":3,"prepare":4,"configure":5,"compile":6,"test":7,