diff options
author | Alexander Bersenev <bay@hackerdom.ru> | 2011-06-25 02:16:42 +0000 |
---|---|---|
committer | Alexander Bersenev <bay@hackerdom.ru> | 2011-06-25 02:16:42 +0000 |
commit | d01cf77441dc9560b1b90b73d7df89e9423b4ef5 (patch) | |
tree | 7d61961abd1455cf0ea4fc562ca1a62d49ee2140 | |
parent | reporting a possible dependency packages (diff) | |
download | autodep-d01cf77441dc9560b1b90b73d7df89e9423b4ef5.tar.gz autodep-d01cf77441dc9560b1b90b73d7df89e9423b4ef5.tar.bz2 autodep-d01cf77441dc9560b1b90b73d7df89e9423b4ef5.zip |
better algorythm to log stage
-rw-r--r-- | logger/src/autodep/logfs/fstracer.py | 6 | ||||
-rw-r--r-- | logger/src/autodep/logfs/logger_fusefs.py | 5 | ||||
-rw-r--r-- | logger/src/hook_fusefs/hookfs.c | 148 |
3 files changed, 102 insertions, 57 deletions
diff --git a/logger/src/autodep/logfs/fstracer.py b/logger/src/autodep/logfs/fstracer.py index 95d64f5..5842372 100644 --- a/logger/src/autodep/logfs/fstracer.py +++ b/logger/src/autodep/logfs/fstracer.py @@ -199,11 +199,12 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter) #print "!"+"%d"%len(record)+"?" #print "datalen: %d" % len(data) 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\n"); # TODO: think about flush here else: @@ -212,7 +213,8 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter) else: eventname,filename,stage,result=message[1:5] - #print message; + #if stage != "unknown": + if not stage in events: events[stage]=[{},{}] diff --git a/logger/src/autodep/logfs/logger_fusefs.py b/logger/src/autodep/logfs/logger_fusefs.py index c8d417d..9990ef9 100644 --- a/logger/src/autodep/logfs/logger_fusefs.py +++ b/logger/src/autodep/logfs/logger_fusefs.py @@ -21,7 +21,7 @@ class logger: self.socketname=socketname self.currpid=os.getpid() - + if accuracy==False: self.mountlist=self.mountlist+["/lib64/", "/lib32/","/var/tmp/portage/"] @@ -84,7 +84,7 @@ class logger: if self.currpid!=os.getpid(): print "Detected an attempt to execute execproc in other thread" sys.exit(1) - + pid=os.fork() if pid==0: try: @@ -93,6 +93,7 @@ class logger: os.chdir(cwd) env=os.environ.copy() + env["LOGGER_PROCESS_IS_INTERNAL"]="YES" os.execvpe(prog_name, arguments, env) sys.exit(1) diff --git a/logger/src/hook_fusefs/hookfs.c b/logger/src/hook_fusefs/hookfs.c index 6456bef..89c899a 100644 --- a/logger/src/hook_fusefs/hookfs.c +++ b/logger/src/hook_fusefs/hookfs.c @@ -46,6 +46,8 @@ #define MAXSOCKETPATHLEN 108 #define MAXFILEBUFFLEN 2048 +#define MAXSTAGELEN 20 + #define IOBUFSIZE 65536 @@ -72,6 +74,8 @@ char *stagenames[]={ }; int stagenameslength=sizeof(stagenames)/sizeof(char *); +static void log_event(const char*, const char*, char *,int , char* ); + /* * Get a pid of the parent proccess * Parse the /proc/pid/stat @@ -115,54 +119,91 @@ pid_t getparentpid(pid_t pid){ } /* - * Get a stage of building + * Get an environment variable of remote process + * result is an output arg(can be NULL) */ -static char * getstagebypid(pid_t pid, pid_t toppid) { - pid_t currpid; - for(currpid=getparentpid(pid); currpid!=0 && currpid!=1 && currpid!=toppid;currpid=getparentpid(currpid)) { - char filename[MAXPATHLEN]; - snprintf(filename,MAXPATHLEN, "/proc/%d/cmdline",pid); - FILE *cmdline_file_handle=fopen(filename,"r"); - - if(cmdline_file_handle==NULL) - return "unknown"; - - char read_buffer[MAXFILEBUFFLEN]; - int readed; - readed=fread(read_buffer,sizeof(char),MAXFILEBUFFLEN,cmdline_file_handle); +static int getenv_by_pid(pid_t pid, char *envname,char *result,int result_len) { + char filename[MAXPATHLEN]; + snprintf(filename,MAXPATHLEN, "/proc/%d/environ",pid); + FILE *environ_file_handle=fopen(filename,"r"); + + if(environ_file_handle==NULL) + return 0; + + char filebuff[IOBUFSIZE]; + + int automata_state=0; + int offset; + int envname_len=strlen(envname); + + for(;;) { + int readed=fread(filebuff,1,IOBUFSIZE,environ_file_handle); - fclose(cmdline_file_handle); - - int off; - int null_bytes_num=0; - char *stage_name; - // small automata here. For readabilyity it is not in classic form - for(off=0;off<readed;off++) { - if(read_buffer[off]==0){ - null_bytes_num++; - if(null_bytes_num==2) { - if(read_buffer+off-9<read_buffer) // 9 is a "ebuild.sh" string length - break; - if(strcmp(read_buffer+off-9,"ebuild.sh")!=0) - break; - stage_name=read_buffer+off+1; - } else if(null_bytes_num==3) { - // ugly, but memory allocation is not better - // there is better way to write this - int i; - for(i=0; i<stagenameslength;i++) { - if(strcmp(stage_name,stagenames[i])==0) - return stagenames[i]; - } + for(offset=0; offset<readed; offset++) { + char c=filebuff[offset]; + + if(automata_state<envname_len) { + if(c==0) { automata_state=0;} + else if(automata_state==-1) continue; + else if(c==envname[automata_state]) automata_state++; + else automata_state=-1; + } else if(automata_state==envname_len) { + if(result==NULL) { + fclose(environ_file_handle); + return 1; + } + if(c=='=') automata_state++; + else automata_state=-1; + } else if(automata_state>envname_len){ + int result_off=automata_state-1-envname_len; + if(result_off>=result_len) { + result[result_len-1]=0; // force last byte to be 0 + fclose(environ_file_handle); + return 1; + } else { + result[result_off]=c; + if(c==0) { + fclose(environ_file_handle); + return 1; } + automata_state++; } + } } + if(feof(environ_file_handle)) + break; + } + fclose(environ_file_handle); + return 0; +} + +/* + * Get a stage of building +*/ +static char * getstagebypid(pid_t pid) { + char stage[MAXSTAGELEN]; + if(!getenv_by_pid(getparentpid(pid),"EBUILD_PHASE",stage,MAXSTAGELEN)) + return "unknown"; + + // ugly, but memory allocation is not better + // there is better way to write this, but this is fast + int i; + for(i=0; i<stagenameslength;i++) { + if(strcmp(stage,stagenames[i])==0) + return stagenames[i]; } return "unknown"; } /* + * Check environment variable for process +*/ +static int is_process_has_env(pid_t pid, char *envname) { + return getenv_by_pid(pid,envname,NULL,0); +} + +/* * This is here because launching of a task is very slow without it */ static int is_file_excluded(const char *filename) { @@ -180,11 +221,18 @@ static int is_file_excluded(const char *filename) { return 0; } + /* * Check external access - for example user's access to mount */ static int is_process_external(pid_t pid) { - if(pid==1 || getparentpid(pid)==1) + pid_t ppid=getparentpid(pid); + if(pid==1 || ppid==1 || ppid==parent_pid) + return 0; + + // ppid is here to bypass a deadlock on several kernels + // while trying to see environ but process is not executed yet + if( is_process_has_env(ppid,"LOGGER_PROCESS_IS_INTERNAL")) return 0; for(;pid!=0;pid=getparentpid(pid)) @@ -270,7 +318,7 @@ static void give_to_creator_path(const char *path) { static int hookfs_getattr(const char *path, struct stat *stbuf) { struct fuse_context * context = fuse_get_context(); - char *stage=getstagebypid(context->pid,parent_pid); + char *stage=getstagebypid(context->pid); if(! is_event_allowed("stat",path,context->pid,stage)) { errno=2; // not found @@ -303,7 +351,7 @@ static int hookfs_fgetattr(const char *path, struct stat *stbuf, int res; struct fuse_context * context = fuse_get_context(); - char *stage=getstagebypid(context->pid,parent_pid); + char *stage=getstagebypid(context->pid); if(! is_event_allowed("stat",path,context->pid,stage)) { errno=2; // not found @@ -599,7 +647,7 @@ static int hookfs_chown(const char *path, uid_t uid, gid_t gid) static int hookfs_truncate(const char *path, off_t size) { struct fuse_context * context = fuse_get_context(); - char *stage=getstagebypid(context->pid,parent_pid); + char *stage=getstagebypid(context->pid); char * rel_path = malloc_relative_path(path); if (! rel_path) { @@ -624,7 +672,7 @@ static int hookfs_ftruncate(const char *path, off_t size, int res; struct fuse_context * context = fuse_get_context(); - char *stage=getstagebypid(context->pid,parent_pid); + char *stage=getstagebypid(context->pid); res = ftruncate(fi->fh, size); @@ -640,20 +688,14 @@ static int hookfs_ftruncate(const char *path, off_t size, static int hookfs_utimens(const char *path, const struct timespec ts[2]) { int res; - struct timeval tv[2]; char * rel_path = NULL; - tv[0].tv_sec = ts[0].tv_sec; - tv[0].tv_usec = ts[0].tv_nsec / 1000; - tv[1].tv_sec = ts[1].tv_sec; - tv[1].tv_usec = ts[1].tv_nsec / 1000; - rel_path = malloc_relative_path(path); if (! rel_path) { return -errno; } - res = utimes(rel_path, tv); + res = utimensat(AT_FDCWD,rel_path, ts, AT_SYMLINK_NOFOLLOW); free(rel_path); if (res == -1) return -errno; @@ -689,7 +731,7 @@ static int open_safely(const char *rel_path, int flags, mode_t mode) { static int hookfs_create(const char *path, mode_t mode, struct fuse_file_info *fi) { struct fuse_context * context = fuse_get_context(); - char *stage=getstagebypid(context->pid,parent_pid); + char *stage=getstagebypid(context->pid); if(! is_event_allowed("create",path,context->pid,stage)) { errno=2; // not found @@ -723,7 +765,7 @@ static int hookfs_open(const char *path, struct fuse_file_info *fi) char * rel_path = NULL; struct fuse_context * context = fuse_get_context(); - char *stage=getstagebypid(context->pid,parent_pid); + char *stage=getstagebypid(context->pid); if(! is_event_allowed("open",path,context->pid,stage)) { errno=2; // not found @@ -756,7 +798,7 @@ static int hookfs_read(const char *path, char *buf, size_t size, off_t offset, int res; struct fuse_context * context = fuse_get_context(); - char *stage=getstagebypid(context->pid,parent_pid); + char *stage=getstagebypid(context->pid); res = pread(fi->fh, buf, size, offset); if (res == -1) { @@ -774,7 +816,7 @@ static int hookfs_write(const char *path, const char *buf, size_t size, int res; struct fuse_context * context = fuse_get_context(); - char *stage=getstagebypid(context->pid,parent_pid); + char *stage=getstagebypid(context->pid); res = pwrite(fi->fh, buf, size, offset); if (res == -1) { |