1 |
commit: 1e08a6bccc05184a6f864263194b45066b8acea5 |
2 |
Author: Alexander Bersenev <bay <AT> hackerdom <DOT> ru> |
3 |
AuthorDate: Sun Jul 3 16:26:50 2011 +0000 |
4 |
Commit: Александр Берсенев <bay <AT> hackerdom <DOT> ru> |
5 |
CommitDate: Sun Jul 3 16:26:50 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/autodep.git;a=commit;h=1e08a6bc |
7 |
|
8 |
package files blocking feature, improved command line arguments |
9 |
|
10 |
--- |
11 |
logger/src/autodep/logfs/fstracer.py | 8 +-- |
12 |
logger/src/autodep/logfs/portage_utils.py | 22 +++++++- |
13 |
logger/src/autodep/showfsevents.py | 89 ++++++++++++++++++++++++----- |
14 |
logger/src/hook_fusefs/hookfs.c | 2 + |
15 |
logger/src/hook_lib/file_hook.c | 2 +- |
16 |
5 files changed, 101 insertions(+), 22 deletions(-) |
17 |
|
18 |
diff --git a/logger/src/autodep/logfs/fstracer.py b/logger/src/autodep/logfs/fstracer.py |
19 |
index 80666e6..66b1de3 100644 |
20 |
--- a/logger/src/autodep/logfs/fstracer.py |
21 |
+++ b/logger/src/autodep/logfs/fstracer.py |
22 |
@@ -98,8 +98,7 @@ def checkparent(parent,child): |
23 |
|
24 |
|
25 |
# default access filter. Allow acess to all files |
26 |
-def defaultfilter(eventname, filename, pid): |
27 |
- |
28 |
+def defaultfilter(eventname, filename, stage): |
29 |
return True |
30 |
|
31 |
# run the program and get file access events |
32 |
@@ -201,7 +200,8 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter) |
33 |
continue |
34 |
|
35 |
message=record.split("\0") |
36 |
- #print message |
37 |
+ #if message[3]!="unknown": |
38 |
+ #print message |
39 |
|
40 |
try: |
41 |
if message[4]=="ASKING": |
42 |
@@ -263,8 +263,6 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter) |
43 |
if len(clients)==0 and iszombie(pid): |
44 |
break |
45 |
|
46 |
- #print "\n\nRETURNING!!!!\n\n" |
47 |
- |
48 |
epoll.unregister(sock_listen.fileno()) |
49 |
epoll.close() |
50 |
sock_listen.close() |
51 |
|
52 |
diff --git a/logger/src/autodep/logfs/portage_utils.py b/logger/src/autodep/logfs/portage_utils.py |
53 |
index 6592d7a..a03f6af 100644 |
54 |
--- a/logger/src/autodep/logfs/portage_utils.py |
55 |
+++ b/logger/src/autodep/logfs/portage_utils.py |
56 |
@@ -38,4 +38,24 @@ def getpackagesbyfiles(files): |
57 |
print "Error while launching qfile: %s" % e |
58 |
|
59 |
|
60 |
- return ret |
61 |
\ No newline at end of file |
62 |
+ return ret |
63 |
+ |
64 |
+def getfilesbypackage(packagename): |
65 |
+ ret=[] |
66 |
+ try: |
67 |
+ proc=subprocess.Popen(['qlist']+['--nocolor',"--obj",packagename], |
68 |
+ stdout=subprocess.PIPE,stderr=subprocess.PIPE, |
69 |
+ bufsize=4096) |
70 |
+ |
71 |
+ out,err=proc.communicate() |
72 |
+ if err!=None and len(err)!=0 : |
73 |
+ print "Noncritical error while launch qlist: %s" % err; |
74 |
+ |
75 |
+ ret=out.split("\n") |
76 |
+ if ret==['']: |
77 |
+ ret=[] |
78 |
+ except OSError,e: |
79 |
+ print "Error while launching qfile: %s" % e |
80 |
+ |
81 |
+ return ret |
82 |
+ |
83 |
|
84 |
diff --git a/logger/src/autodep/showfsevents.py b/logger/src/autodep/showfsevents.py |
85 |
index 9d252c3..cc4bec6 100755 |
86 |
--- a/logger/src/autodep/showfsevents.py |
87 |
+++ b/logger/src/autodep/showfsevents.py |
88 |
@@ -8,19 +8,44 @@ import sys |
89 |
import logfs.fstracer |
90 |
import logfs.portage_utils |
91 |
|
92 |
-#logfs.fstracer.getfsevents("/bin/sh", ["sh" , "-c", "/usr/bin/tac bay_success; /usr/bin/tac bay_god bay_god2"]) |
93 |
-#events=logfs.fstracer.getfsevents("/bin/cat", ["cat" , "l l l"]) |
94 |
-#if len(sys.argv)<2: |
95 |
-# print "Usage: showfsevents.py <command>" |
96 |
-# exit(1) |
97 |
- |
98 |
args_parser=optparse.OptionParser("%prog [options] <command>") |
99 |
-args_parser.add_option("-v", action="store_true", dest="verbose", default=False, help="show accessed files") |
100 |
+args_parser.add_option("-v", action="store_true", dest="verbose", |
101 |
+ default=False, help="show accessed files") |
102 |
+args_parser.add_option("-u", "--unknown", action="store_true", dest="show_unknown_stage", |
103 |
+ default=False, help="show unknown stage") |
104 |
+args_parser.add_option("-b", "--block",action="store", type="string", |
105 |
+ dest="packages", default="", help="block an access to files from this packages") |
106 |
+args_parser.epilog="Example: %s -b lsof,cowsay emerge bash" % (os.path.basename(sys.argv[0])) |
107 |
+ |
108 |
+args_parser.disable_interspersed_args() |
109 |
|
110 |
(options, args) = args_parser.parse_args() |
111 |
-print args |
112 |
|
113 |
-events=logfs.fstracer.getfsevents(args[0], args,approach="hooklib") |
114 |
+if len(args)==0: |
115 |
+ args_parser.print_help() |
116 |
+ exit(1) |
117 |
+#print args |
118 |
+#print options |
119 |
+ |
120 |
+filter_function=lambda eventname,filename,stage: True |
121 |
+ |
122 |
+# handling --block |
123 |
+if options.packages: |
124 |
+ packages=options.packages.split(",") |
125 |
+ files_to_block=[] |
126 |
+ for package in packages: |
127 |
+ files_in_package=logfs.portage_utils.getfilesbypackage(package) |
128 |
+ if len(files_in_package)==0: |
129 |
+ print "Bad package name: %s. Exiting" % package |
130 |
+ exit(1) |
131 |
+ files_to_block+=files_in_package |
132 |
+ files_to_block={}.fromkeys(files_to_block) |
133 |
+ # new filter function |
134 |
+ def filter(eventname,filename,stage): |
135 |
+ return not filename in files_to_block |
136 |
+ filter_function=filter |
137 |
+ |
138 |
+events=logfs.fstracer.getfsevents(args[0], args,approach="fusefs",filterproc=filter_function) |
139 |
print "Program finished, analyzing dependencies" |
140 |
|
141 |
# get unique filenames |
142 |
@@ -29,9 +54,9 @@ for stage in events: |
143 |
succ_events=events[stage][0] |
144 |
fail_events=events[stage][1] |
145 |
for filename in succ_events: |
146 |
- filenames[filename]="" |
147 |
+ filenames[filename]=None |
148 |
for filename in fail_events: |
149 |
- filenames[filename]="" |
150 |
+ filenames[filename]=None |
151 |
filenames=filenames.keys(); |
152 |
|
153 |
# temporary disabled |
154 |
@@ -39,8 +64,8 @@ file_to_package=logfs.portage_utils.getpackagesbyfiles(filenames) |
155 |
#file_to_package={} |
156 |
#print events |
157 |
|
158 |
-# this part is completly unreadable. It converting one complex struct(returned with getfsevents) to |
159 |
-# another which good for user |
160 |
+# this part is completly unreadable. It converting one complex struct(returned by getfsevents) to |
161 |
+# another complex struct which good for generating output |
162 |
|
163 |
events_converted_for_output={} |
164 |
packagesinfo={} |
165 |
@@ -95,12 +120,46 @@ stagesorder={"clean":1,"setup":2,"unpack":3,"prepare":4,"configure":5,"compile": |
166 |
|
167 |
|
168 |
for package in sorted(packagesinfo): |
169 |
- print "%-40s: %s"%(package,packagesinfo[package].keys()) |
170 |
+ # not showing special directory package |
171 |
+ if package=="directory": |
172 |
+ continue |
173 |
+ |
174 |
+ stages=[] |
175 |
+ for stage in sorted(packagesinfo[package].keys(), key=stagesorder.get): |
176 |
+ if stage!="unknown" or options.show_unknown_stage: |
177 |
+ stages.append(stage) |
178 |
+ |
179 |
+ if len(stages)!=0: |
180 |
+ print "%-40s: %s"%(package,stages) |
181 |
+ # show information about accessed files |
182 |
+ if options.verbose: |
183 |
+ filenames={} |
184 |
+ for stage in stages: |
185 |
+ for filename in packagesinfo[package][stage]: |
186 |
+ if len(packagesinfo[package][stage][filename]["found"])!=0: |
187 |
+ was_readed,was_writed=packagesinfo[package][stage][filename]["found"] |
188 |
+ if not filename in filenames: |
189 |
+ filenames[filename]=[was_readed,was_writed] |
190 |
+ else: |
191 |
+ old_was_readed, old_was_writed=filenames[filename] |
192 |
+ filenames[filename]=[old_was_readed | was_readed, old_was_writed | was_writed ] |
193 |
+ |
194 |
+ for filename in filenames: |
195 |
+ if filenames[filename]==[False,False]: |
196 |
+ action="accessed" |
197 |
+ elif filenames[filename]==[True,False]: |
198 |
+ action="readed" |
199 |
+ elif filenames[filename]==[False,True]: |
200 |
+ action="writed" |
201 |
+ elif filenames[filename]==[True,True]: |
202 |
+ action="readed and writed" |
203 |
+ print " %-56s %-21s" % (filename,action) |
204 |
+ |
205 |
|
206 |
|
207 |
""" |
208 |
for stage in sorted(events, key=stagesorder.get): |
209 |
- succ_events=events[stage][0] |
210 |
+ succ_events=events[stage][0]- |
211 |
fail_events=events[stage][1] |
212 |
print "On stage %s:" % stage |
213 |
for filename in sorted(succ_events, key=file_to_package.get): |
214 |
|
215 |
diff --git a/logger/src/hook_fusefs/hookfs.c b/logger/src/hook_fusefs/hookfs.c |
216 |
index 24b6342..0d957dc 100644 |
217 |
--- a/logger/src/hook_fusefs/hookfs.c |
218 |
+++ b/logger/src/hook_fusefs/hookfs.c |
219 |
@@ -184,9 +184,11 @@ static int getenv_by_pid(pid_t pid, char *envname,char *result,int result_len) { |
220 |
*/ |
221 |
static char * getstagebypid(pid_t pid) { |
222 |
char stage[MAXSTAGELEN]; |
223 |
+ //log_event("",filename,result,err,stage); |
224 |
if(!getenv_by_pid(getparentpid(pid),"EBUILD_PHASE",stage,MAXSTAGELEN)) |
225 |
return "unknown"; |
226 |
|
227 |
+ |
228 |
// ugly, but memory allocation is not better |
229 |
// there is better way to write this, but this is fast |
230 |
int i; |
231 |
|
232 |
diff --git a/logger/src/hook_lib/file_hook.c b/logger/src/hook_lib/file_hook.c |
233 |
index 8702a2c..4ad6b97 100644 |
234 |
--- a/logger/src/hook_lib/file_hook.c |
235 |
+++ b/logger/src/hook_lib/file_hook.c |
236 |
@@ -393,7 +393,7 @@ pid_t fork(void) { |
237 |
int execve(const char *filename, char *const argv[], |
238 |
char *const envp[]) { |
239 |
if(access(filename, F_OK)!=-1) |
240 |
- __log_event("open",filename,"OK",0,__get_stage()); |
241 |
+ __log_event("read",filename,"OK",0,__get_stage()); |
242 |
else |
243 |
__log_event("open",filename,"ERR",2,__get_stage()); |