public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Александр Берсенев" <bay@hackerdom.ru>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/autodep:master commit in: logger/src/autodep/logfs/, logger/src/hook_fusefs/
Date: Fri, 24 Jun 2011 20:17:09 +0000 (UTC)	[thread overview]
Message-ID: <d01cf77441dc9560b1b90b73d7df89e9423b4ef5.bay@gentoo> (raw)

commit:     d01cf77441dc9560b1b90b73d7df89e9423b4ef5
Author:     Alexander Bersenev <bay <AT> hackerdom <DOT> ru>
AuthorDate: Sat Jun 25 02:16:42 2011 +0000
Commit:     Александр Берсенев <bay <AT> hackerdom <DOT> ru>
CommitDate: Sat Jun 25 02:16:42 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/autodep.git;a=commit;h=d01cf774

better algorythm to log stage

---
 logger/src/autodep/logfs/fstracer.py      |    6 +-
 logger/src/autodep/logfs/logger_fusefs.py |    5 +-
 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) {



             reply	other threads:[~2011-06-24 20:17 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-06-24 20:17 Александр Берсенев [this message]
  -- strict thread matches above, loose matches on Subject: below --
2011-06-18 10:00 [gentoo-commits] proj/autodep:master commit in: logger/src/autodep/logfs/, logger/src/hook_fusefs/ Александр Берсенев
2011-06-18  8:27 Александр Берсенев
2011-06-08 16:48 Александр Берсенев

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d01cf77441dc9560b1b90b73d7df89e9423b4ef5.bay@gentoo \
    --to=bay@hackerdom.ru \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox