-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathio-trace-patch.diff
269 lines (248 loc) · 7.07 KB
/
io-trace-patch.diff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
This patch, inspired by Arjan, and Scott James Remnant's work adds
the ability to easily add trace points that refer to files, and
print full paths.
It also adds three of these trace points to open(), exec() and uselib()
Signed-off-by: Michael Meeks <[email protected]>
diff --git a/fs/exec.c b/fs/exec.c
index 172ceb6..02e3d33 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -56,6 +56,8 @@
#include <linux/fsnotify.h>
#include <linux/fs_struct.h>
+#include <trace/events/fs.h>
+
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
#include <asm/tlb.h>
@@ -130,6 +132,8 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
fsnotify_open(file->f_path.dentry);
+ trace_uselib(file);
+
error = -ENOEXEC;
if(file->f_op) {
struct linux_binfmt * fmt;
@@ -665,6 +669,8 @@ struct file *open_exec(const char *name)
fsnotify_open(file->f_path.dentry);
+ trace_open_exec(file);
+
err = deny_write_access(file);
if (err)
goto exit;
diff --git a/fs/open.c b/fs/open.c
index dd98e80..9a4dc6c 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -31,6 +31,9 @@
#include <linux/falloc.h>
#include <linux/fs_struct.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/fs.h>
+
int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
int retval = -ENODEV;
@@ -1040,6 +1043,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
} else {
fsnotify_open(f->f_path.dentry);
fd_install(fd, f);
+ trace_do_sys_open(f, flags, mode);
}
}
putname(tmp);
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index a81170d..50c5b6c 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -169,4 +169,8 @@ do { \
if (ret) \
return ret;
+/* file pointer helpers */
+extern int ftrace_file_name_len (const struct file *f);
+extern void ftrace_assign_file (char *dest, int dest_len, const struct file *f);
+
#endif /* _LINUX_FTRACE_EVENT_H */
diff --git a/include/trace/events/fs.h b/include/trace/events/fs.h
new file mode 100644
index 0000000..254be7e
--- /dev/null
+++ b/include/trace/events/fs.h
@@ -0,0 +1,66 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM fs
+
+#if !defined(_TRACE_FS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_FS_H
+
+#include <linux/fs.h>
+#include <linux/tracepoint.h>
+
+/*
+ * Here we have a problem; the __string macro uses __dynamic_array,
+ * which requires the ability to know it's own length before we
+ * allocate the buffer - in the get_offsets_ call - which does not
+ * know the length of the resulting path we create in TP_fast_assign.
+ * So - give up and use a fixed length.
+ */
+TRACE_EVENT(do_sys_open,
+
+ TP_PROTO(struct file *filp, int flags, int mode),
+
+ TP_ARGS(filp, flags, mode),
+
+ TP_STRUCT__entry(
+ __file_p( filename, filp )
+ __field( int, flags )
+ __field( int, mode )
+ ),
+
+ TP_fast_assign(
+ __assign_file_p(filename, filp);
+ __entry->flags = flags;
+ __entry->mode = mode;
+ ),
+
+ TP_printk("\"%s\" %x %o", __get_str(filename),
+ __entry->flags, __entry->mode)
+);
+
+TRACE_EVENT(uselib,
+ TP_PROTO(struct file *filp),
+ TP_ARGS(filp),
+ TP_STRUCT__entry(
+ __file_p(filename, filp)
+ ),
+ TP_fast_assign(
+ __assign_file_p(filename, filp);
+ ),
+ TP_printk("\"%s\"", __get_str(filename))
+);
+
+TRACE_EVENT(open_exec,
+ TP_PROTO(struct file *filp),
+ TP_ARGS(filp),
+ TP_STRUCT__entry(
+ __file_p(filename, filp)
+ ),
+ TP_fast_assign(
+ __assign_file_p(filename, filp);
+ ),
+ TP_printk("\"%s\"", __get_str(filename))
+);
+
+#endif /* _TRACE_FS_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index f64fbaa..6ac1dab 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -30,6 +30,9 @@
#undef __string
#define __string(item, src) __dynamic_array(char, item, -1)
+#undef __file_p
+#define __file_p(item, src) __dynamic_array(char, item, -1)
+
#undef TP_STRUCT__entry
#define TP_STRUCT__entry(args...) args
@@ -72,6 +75,10 @@
#undef __string
#define __string(item, src) __dynamic_array(char, item, -1)
+#undef __file_p
+#define __file_p(item, src) int item; \
+ int item##__size;
+
#undef TRACE_EVENT
#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
struct ftrace_data_offsets_##call { \
@@ -131,6 +138,9 @@
#undef __string
#define __string(item, src) __dynamic_array(char, item, -1)
+#undef __file_p
+#define __file_p(item, src) __dynamic_array(char, item, -1)
+
#undef __entry
#define __entry REC
@@ -289,6 +299,9 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
#undef __string
#define __string(item, src) __dynamic_array(char, item, -1)
+#undef __file_p
+#define __file_p(item, src) __dynamic_array(char, item, -1)
+
#undef TRACE_EVENT
#define TRACE_EVENT(call, proto, args, tstruct, func, print) \
int \
@@ -333,6 +346,14 @@ ftrace_define_fields_##call(void) \
#undef __string
#define __string(item, src) __dynamic_array(char, item, strlen(src) + 1) \
+#undef __file_p
+#define __file_p(item, src) \
+ __data_offsets->item = __data_size + \
+ offsetof(typeof(*entry), __data); \
+ __data_offsets->item##__size = ftrace_file_name_len(src); \
+ __data_size += __data_offsets->item##__size;
+
+
#undef TRACE_EVENT
#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
static inline int ftrace_get_offsets_##call( \
@@ -526,10 +547,17 @@ static void ftrace_profile_disable_##call(struct ftrace_event_call *event_call)\
#undef __string
#define __string(item, src) __dynamic_array(char, item, -1) \
+#undef __file_p
+#define __file_p(item, src) __dynamic_array(char, item, -1) \
+
#undef __assign_str
#define __assign_str(dst, src) \
strcpy(__get_str(dst), src);
+#undef __assign_file_p
+#define __assign_file_p(dst, src) \
+ ftrace_assign_file(__get_str (dst), __data_offsets.dst##__size, src);
+
#undef TRACE_EVENT
#define TRACE_EVENT(call, proto, args, tstruct, assign, print) \
\
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index e75276a..8b5e7a7 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -60,6 +60,40 @@ err:
}
EXPORT_SYMBOL_GPL(trace_define_field);
+/* file pointer helpers */
+int ftrace_file_name_len (const struct file *f)
+{
+ /* This performs pretty terribly - obviously */
+ int len = 1;
+ char *buf, *fname;
+
+ if (!(buf = kzalloc(PAGE_SIZE, GFP_KERNEL)))
+ return len;
+ fname = d_path(&f->f_path, buf, PAGE_SIZE);
+ if (!IS_ERR (fname))
+ len += strlen (fname);
+ kfree(buf);
+ if (len >= 65536)
+ len = 65535;
+ return len;
+}
+
+void ftrace_assign_file (char *dest, int dest_len, const struct file *f)
+{
+ char *buf, *fname;
+
+ dest[0] = '\0';
+ if (!(buf = kzalloc(PAGE_SIZE, GFP_KERNEL)))
+ return;
+
+ /* it would be nicer to write this directly into the
+ * allocated buffer, but d_path doesn't like that */
+ fname = d_path(&f->f_path, buf, PAGE_SIZE);
+ if (!IS_ERR (fname))
+ strncpy (dest, fname, dest_len);
+ kfree(buf);
+}
+
#ifdef CONFIG_MODULES
static void trace_destroy_fields(struct ftrace_event_call *call)