diff options
author | Alexander Bersenev <bay@hackerdom.ru> | 2011-07-02 16:28:32 +0000 |
---|---|---|
committer | Alexander Bersenev <bay@hackerdom.ru> | 2011-07-02 16:28:32 +0000 |
commit | 12b34e7369e0c0561da1af0a81ca588f5a026e0d (patch) | |
tree | 9bd59cfd88293f981335a846ae784ef8e88760ef | |
parent | more reliable logging logic with ld_preload approach (diff) | |
download | autodep-12b34e7369e0c0561da1af0a81ca588f5a026e0d.tar.gz autodep-12b34e7369e0c0561da1af0a81ca588f5a026e0d.tar.bz2 autodep-12b34e7369e0c0561da1af0a81ca588f5a026e0d.zip |
ctrl-c handling
-rw-r--r-- | logger/src/autodep/logfs/fstracer.py | 219 | ||||
-rw-r--r-- | logger/src/autodep/logfs/logger_fusefs.py | 15 | ||||
-rw-r--r-- | logger/src/autodep/logfs/logger_hooklib.py | 1 | ||||
-rwxr-xr-x | logger/src/autodep/showfsevents.py | 8 |
4 files changed, 127 insertions, 116 deletions
diff --git a/logger/src/autodep/logfs/fstracer.py b/logger/src/autodep/logfs/fstracer.py index 1b99f8e..80666e6 100644 --- a/logger/src/autodep/logfs/fstracer.py +++ b/logger/src/autodep/logfs/fstracer.py @@ -11,12 +11,16 @@ import tempfile import socket import select import re +import signal import proc_helpers import logger_hooklib import logger_fusefs +stop=False; +stoptime=0; + def parse_message(message): ret=message.split("\0") return ret @@ -92,27 +96,6 @@ def checkparent(parent,child): print "External actions with filesystem detected pid of external prog is %d" % child return False -# check pid, returns stage of building -def get_stage_by_pid(pid,toppid): - #return "unknown" - - currpid=proc_helpers.getparentpid(pid) - try: - while currpid>1 and currpid!=toppid: - cmdlinefile=open("/proc/%d/cmdline" % currpid,"r") - cmdline=cmdlinefile.read() - cmdlinefile.close() - arguments=cmdline.split("\0") - #print arguments - if len(arguments)>=3 and arguments[1][-9:]=="ebuild.sh": - return arguments[2] - currpid=proc_helpers.getparentpid(currpid) - - - except IOError,e: - return "unknown" - - return "unknown" # default access filter. Allow acess to all files def defaultfilter(eventname, filename, pid): @@ -127,7 +110,6 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter) socketname = os.path.join(tmpdir, 'socket') try: - #sock_listen=socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock_listen=socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) sock_listen.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) @@ -142,7 +124,6 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter) return [] else: #print socketname - pid=os.fork() if pid==0: logger=None @@ -160,100 +141,116 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter) print "Launch likely was unsuccessful" sys.exit(1) else: + def signal_handler(sig, frame): + print "You pressed Ctrl+C!" + global stoptime + if(time.time()-stoptime>5): + print "Sending SIGINT to child" + print "Press again in 5 seconds to force exit" + stoptime=time.time() + else: + print "Sending SIGKILL to child" + os.kill(pid,signal.SIGKILL) + os._exit(1) + global signal + signal.signal(signal.SIGINT, signal_handler) + epoll=select.epoll() epoll.register(sock_listen.fileno(), select.EPOLLIN) connects = 0; clients={} - stop=0 was_first_connect=False - - #print "fileno listen: %d",sock_listen.fileno() - - while stop==0: - sock_events = epoll.poll(3) - for fileno, sock_event in sock_events: - if fileno == sock_listen.fileno(): - #print "\n\nEVENT\n\n" - ret = sock_listen.accept() - #print ret - if ret is None: - # print "\n\nPASS\n\n" - pass - else: - (client,addr)=ret - # print client - connects+=1; # client accepted - was_first_connect=True - epoll.register(client.fileno(), select.EPOLLIN) - clients[client.fileno()]=client - #print "opened %d" % client.fileno() - #elif sock_event & select.EPOLLHUP: - #epoll.unregister(fileno) - #clients[fileno].close() - #del clients[fileno] - #connects-=1 - - elif sock_event & select.EPOLLIN: - s=clients[fileno] - record=s.recv(8192) - - if not record: # if connection was closed - epoll.unregister(fileno) - clients[fileno].close() - del clients[fileno] - connects-=1 - #print "closed %d"%fileno - continue - - message=record.split("\0") - #print message - - try: - if message[4]=="ASKING": - if filterproc(message[1],message[2],message[3]): - #print "Allowing an access to %s" % message[2] - s.sendall("ALLOW\0"); # TODO: think about flush here - - else: - print "Blocking an access to %s" % message[2] - s.sendall("DENY\0"); # TODO: think about flush here - + + while True: + try: + sock_events = epoll.poll(3) + + for fileno, sock_event in sock_events: + if fileno == sock_listen.fileno(): + #print "\n\nEVENT\n\n" + ret = sock_listen.accept() + #print ret + if ret is None: + # print "\n\nPASS\n\n" + pass else: - eventname,filename,stage,result=message[1:5] + (client,addr)=ret + # print client + connects+=1; # client accepted + was_first_connect=True + epoll.register(client.fileno(), select.EPOLLIN) + clients[client.fileno()]=client + #print "opened %d" % client.fileno() + #elif sock_event & select.EPOLLHUP: + #epoll.unregister(fileno) + #clients[fileno].close() + #del clients[fileno] + #connects-=1 + + elif sock_event & select.EPOLLIN: + s=clients[fileno] + record=s.recv(8192) + + if not record: # if connection was closed + epoll.unregister(fileno) + clients[fileno].close() + del clients[fileno] + connects-=1 + #print "closed %d"%fileno + continue + + message=record.split("\0") + #print message + + try: + if message[4]=="ASKING": + if filterproc(message[1],message[2],message[3]): + #print "Allowing an access to %s" % message[2] + s.sendall("ALLOW\0"); # TODO: think about flush here + + else: + print "Blocking an access to %s" % message[2] + s.sendall("DENY\0"); # TODO: think about flush here + + else: + eventname,filename,stage,result=message[1:5] - if not stage in events: - events[stage]=[{},{}] - - hashofsucesses=events[stage][0] - hashoffailures=events[stage][1] - - if result=="OK": - if not filename in hashofsucesses: - hashofsucesses[filename]=[False,False] + if not stage in events: + events[stage]=[{},{}] - readed_or_writed=hashofsucesses[filename] + hashofsucesses=events[stage][0] + hashoffailures=events[stage][1] - if eventname=="read": - readed_or_writed[0]=True - elif eventname=="write": - readed_or_writed[1]=True + if result=="OK": + if not filename in hashofsucesses: + hashofsucesses[filename]=[False,False] - elif result[0:3]=="ERR" or result=="DENIED": - if not filename in hashoffailures: - hashoffailures[filename]=[False,False] - notfound_or_blocked=hashoffailures[filename] - - if result=="ERR/2": - notfound_or_blocked[0]=True - elif result=="DENIED": - notfound_or_blocked[1]=True + readed_or_writed=hashofsucesses[filename] + + if eventname=="read": + readed_or_writed[0]=True + elif eventname=="write": + readed_or_writed[1]=True + + elif result[0:3]=="ERR" or result=="DENIED": + if not filename in hashoffailures: + hashoffailures[filename]=[False,False] + notfound_or_blocked=hashoffailures[filename] + + if result=="ERR/2": + notfound_or_blocked[0]=True + elif result=="DENIED": + notfound_or_blocked[1]=True - else: - print "Error in logger module<->analyser protocol" - - except IndexError: - print "IndexError while parsing %s"%record + else: + print "Error in logger module<->analyser protocol" + + except IndexError: + print "IndexError while parsing %s"%record + except IOError, e: + if e.errno!=4: # handling "Interrupted system call" errors + raise if was_first_connect and connects==0: break @@ -264,15 +261,17 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter) "Check that you are not launching a suid program under non-root user." return [] if len(clients)==0 and iszombie(pid): - break - - #print "\n\nRETURNING!!!!\n\n" - + break - os.wait() + #print "\n\nRETURNING!!!!\n\n" epoll.unregister(sock_listen.fileno()) epoll.close() sock_listen.close() + + _, exit_status=os.waitpid(pid,0) + signal,exit_status=exit_status%256,exit_status/256 + print "Signal: %s Exit status: %s" % (signal,exit_status) + return events diff --git a/logger/src/autodep/logfs/logger_fusefs.py b/logger/src/autodep/logfs/logger_fusefs.py index 9990ef9..6c135e8 100644 --- a/logger/src/autodep/logfs/logger_fusefs.py +++ b/logger/src/autodep/logfs/logger_fusefs.py @@ -4,6 +4,8 @@ import subprocess import time import os import sys +import signal + class logger: @@ -47,6 +49,7 @@ class logger: os.environ["LOG_SOCKET"]=self.socketname os.environ["PARENT_PID"]=str(self.currpid) + # TODO: change ret=subprocess.call(['/home/bay/gsoc/logger/src/hook_fusefs/hookfs',self.rootmountpath, '-o','allow_other,suid']) if ret!=0: @@ -102,7 +105,12 @@ class logger: sys.exit(1) else: - exitcode=os.wait()[1]; + exitcode=2; # if ctrl-c pressed then returning this value + needtokillself=False + try: + exitcode=os.wait()[1]/256; + except KeyboardInterrupt: + needtokillself=True try: print "Unmounting partitions" self.mountlist.reverse() @@ -118,4 +126,7 @@ class logger: print "Error while unmounting fuse filesystem: %s" % e sys.exit(1) - sys.exit(int(exitcode/256)) + if needtokillself: # we kill self for report the status correct + signal.signal(signal.SIGINT,signal.SIG_DFL) + os.kill(os.getpid(),signal.SIGINT) + os._exit(exitcode) diff --git a/logger/src/autodep/logfs/logger_hooklib.py b/logger/src/autodep/logfs/logger_hooklib.py index cda22b6..008fc56 100644 --- a/logger/src/autodep/logfs/logger_hooklib.py +++ b/logger/src/autodep/logfs/logger_hooklib.py @@ -20,3 +20,4 @@ class logger: except OSError, e: print "Failed to launch the programm: %s" % e sys.exit(1) + diff --git a/logger/src/autodep/showfsevents.py b/logger/src/autodep/showfsevents.py index 3af07d0..aa03d9f 100755 --- a/logger/src/autodep/showfsevents.py +++ b/logger/src/autodep/showfsevents.py @@ -12,9 +12,9 @@ if len(sys.argv)<2: print "Usage: showfsevents.py <command>" exit(1) -events=logfs.fstracer.getfsevents(sys.argv[1], sys.argv[1:],approach="hooklib") +events=logfs.fstracer.getfsevents(sys.argv[1], sys.argv[1:],approach="fusefs") print "Program finished, analyzing dependencies" -#exit(0); +exit(0); # get unique filenames filenames={} for stage in events: @@ -27,8 +27,8 @@ for stage in events: filenames=filenames.keys(); # temporary disabled -file_to_package=logfs.portage_utils.getpackagesbyfiles(filenames) -#file_to_package={} +#file_to_package=logfs.portage_utils.getpackagesbyfiles(filenames) +file_to_package={} #print events stagesorder={"clean":1,"setup":2,"unpack":3,"prepare":4,"configure":5,"compile":6,"test":7, |