Merge lp:~f-turgis/ubuntu/natty/systemtap/systemtap.2.6.38 into lp:ubuntu/natty/systemtap

Proposed by Frederic Turgis
Status: Merged
Merged at revision: 19
Proposed branch: lp:~f-turgis/ubuntu/natty/systemtap/systemtap.2.6.38
Merge into: lp:ubuntu/natty/systemtap
Diff against target: 10383 lines (+9776/-122)
47 files modified
.pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/doc/SystemTap_Tapset_Reference/tapsets.tmpl (+286/-0)
.pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/tapset/irq.stp (+172/-0)
.pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/tapset/irq.stp (+152/-0)
.pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/testsuite/buildok/irq-detailed.stp (+46/-0)
.pc/Fix-for-undefined-STAPCONF_PERF_STRUCTPID.patch/runtime/perf.c (+86/-0)
.pc/Fixed-PR11940-by-getting-scripts-w-global-variables-.patch/runtime/runtime.h (+204/-0)
.pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/tapset/ip.stp (+86/-0)
.pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/testsuite/systemtap.examples/process/pfiles.stp (+612/-0)
.pc/Updated-__ip_sock_daddr-for-2.6.38-kernels.patch/tapset/ip.stp (+96/-0)
.pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/memory.stp (+635/-0)
.pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/rpc.stp (+1185/-0)
.pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/task.stp (+384/-0)
.pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/vfs.stp (+1018/-0)
.pc/Use-linux-blk_types.h-and-REQ_WRITE-for-2.6.36-and-n.patch/buildrun.cxx (+650/-0)
.pc/Use-linux-blk_types.h-and-REQ_WRITE-for-2.6.36-and-n.patch/tapset/ioblock.stp (+316/-0)
.pc/adding-ifdef-CLONE_STOPPED-to-stop-module-compilatio.patch/tapset/aux_syscalls.stp (+2048/-0)
.pc/applied-patches (+10/-0)
.pc/compatibility-perf_event.h-updates-for-kernel-2.6.37.patch/buildrun.cxx (+651/-0)
.pc/compatibility-perf_event.h-updates-for-kernel-2.6.37.patch/runtime/perf.c (+81/-0)
buildrun.cxx (+2/-0)
debian/changelog (+8/-0)
debian/patches/01-Add-irq.stp-to-Tapset-Reference-manual.patch (+210/-0)
debian/patches/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch (+72/-0)
debian/patches/Fix-for-undefined-STAPCONF_PERF_STRUCTPID.patch (+25/-0)
debian/patches/Fixed-PR11940-by-getting-scripts-w-global-variables-.patch (+57/-0)
debian/patches/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch (+60/-0)
debian/patches/Updated-__ip_sock_daddr-for-2.6.38-kernels.patch (+37/-0)
debian/patches/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch (+214/-0)
debian/patches/Use-linux-blk_types.h-and-REQ_WRITE-for-2.6.36-and-n.patch (+60/-0)
debian/patches/adding-ifdef-CLONE_STOPPED-to-stop-module-compilatio.patch (+26/-0)
debian/patches/compatibility-perf_event.h-updates-for-kernel-2.6.37.patch (+68/-0)
debian/patches/series (+10/-0)
doc/SystemTap_Tapset_Reference/tapsets.tmpl (+10/-0)
runtime/autoconf-blk-types.c (+2/-0)
runtime/autoconf-perf-structpid.c (+14/-0)
runtime/perf.c (+6/-1)
runtime/runtime.h (+14/-3)
tapset/aux_syscalls.stp (+2/-0)
tapset/ioblock.stp (+6/-1)
tapset/ip.stp (+18/-5)
tapset/irq.stp (+62/-74)
tapset/memory.stp (+2/-1)
tapset/rpc.stp (+8/-6)
tapset/task.stp (+10/-12)
tapset/vfs.stp (+41/-18)
testsuite/buildok/irq-detailed.stp (+1/-1)
testsuite/systemtap.examples/process/pfiles.stp (+13/-0)
To merge this branch: bzr merge lp:~f-turgis/ubuntu/natty/systemtap/systemtap.2.6.38
Reviewer Review Type Date Requested Status
Ubuntu branches Pending
Review via email: mp+54333@code.launchpad.net

Description of the change

Backporting of Redhat patches to get systemtap working on 2.6.38 (Redhat has currently ported to 2.6.37 but fixing 2.6.38 issues mentioned to them). Patches identified by running systemtap testsuite

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory '.pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch'
2=== added directory '.pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/doc'
3=== added directory '.pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/doc/SystemTap_Tapset_Reference'
4=== added file '.pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/doc/SystemTap_Tapset_Reference/tapsets.tmpl'
5--- .pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/doc/SystemTap_Tapset_Reference/tapsets.tmpl 1970-01-01 00:00:00 +0000
6+++ .pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/doc/SystemTap_Tapset_Reference/tapsets.tmpl 2011-03-22 12:11:00 +0000
7@@ -0,0 +1,286 @@
8+<?xml version="1.0" encoding="UTF-8"?>
9+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
10+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
11+
12+<book id="TapsetRef">
13+ <bookinfo>
14+ <title>SystemTap Tapset Reference Manual</title>
15+<!--starthere-->
16+ <copyright>
17+ <year>2008-2009</year>
18+ <holder>Red Hat, Inc. and others</holder>
19+ </copyright>
20+
21+ <authorgroup>
22+ <author>
23+ <othername>SystemTap</othername>
24+ <contrib>Hackers</contrib>
25+ </author>
26+ </authorgroup>
27+
28+
29+ <legalnotice>
30+ <para>
31+ This documentation is free software; you can redistribute
32+ it and/or modify it under the terms of the GNU General Public
33+ License version 2 as published by the Free Software Foundation.
34+ </para>
35+
36+ <para>
37+ This program is distributed in the hope that it will be
38+ useful, but WITHOUT ANY WARRANTY; without even the implied
39+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
40+ See the GNU General Public License for more details.
41+ </para>
42+
43+ <para>
44+ You should have received a copy of the GNU General Public
45+ License along with this program; if not, write to the Free
46+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
47+ MA 02111-1307 USA
48+ </para>
49+
50+ <para>
51+ For more details see the file COPYING in the source
52+ distribution of Linux.
53+ </para>
54+ </legalnotice>
55+ </bookinfo>
56+<!-- pls dont remove marker comments, as they are used in publican conversion-->
57+<toc></toc>
58+<chapter id="introduction">
59+ <title>Introduction</title>
60+ <para>
61+ SystemTap provides free software (GPL) infrastructure to simplify the
62+ gathering of information about the running Linux system. This assists
63+ diagnosis of a performance or functional problem. SystemTap eliminates the
64+ need for the developer to go through the tedious and disruptive instrument,
65+ recompile, install, and reboot sequence that may be otherwise required to
66+ collect data.
67+ </para>
68+
69+ <para>
70+ SystemTap provides a simple command line interface and scripting language
71+ for writing instrumentation for a live running kernel. The instrumentation
72+ makes extensive use of the probe points and functions provided in the
73+ <firstterm>tapset</firstterm> library. This document describes the various
74+ probe points and functions.
75+ </para>
76+
77+ <section id="format">
78+ <title>Tapset Name Format</title>
79+
80+ <para>In this guide, tapset definitions appear in the following format:</para>
81+
82+ <screen>
83+ name:return (parameters)
84+ definition
85+ </screen>
86+
87+ <para>
88+ The <replaceable>return</replaceable> field specifies what data type the
89+ tapset extracts and returns from the kernel during a probe (and thus,
90+ returns). Tapsets use 2 data types for
91+ <replaceable>return</replaceable>: <literal>long</literal> (tapset
92+ extracts and returns an integer) and <literal>string</literal> (tapset
93+ extracts and returns a string).
94+ </para>
95+
96+ <para>
97+ In some cases, tapsets do not have a <replaceable>return</replaceable>
98+ value. This simply means that the tapset does not extract anything from
99+ the kernel. This is common among asynchronous events such as timers,
100+ exit functions, and print functions.
101+ </para>
102+<!--
103+<varlistentry>
104+<term></term>
105+<listitem>
106+ <para></para>
107+</listitem>
108+</varlistentry>
109+-->
110+
111+ </section>
112+
113+ </chapter>
114+<!--endhere-->
115+<!--markerforxi-->
116+<!-- pls dont remove marker comments, as they are used in publican conversion-->
117+ <chapter id="context_stp">
118+ <title>Context Functions</title>
119+ <para>
120+ The context functions provide additional information about where
121+ an event occurred.
122+ These functions can provide information such as a backtrace to
123+ where the event occurred
124+ and the current register values for the processor.
125+ </para>
126+!Itapset/context.stp
127+!Itapset/context-symbols.stp
128+!Itapset/ucontext-symbols.stp
129+!Itapset/context-unwind.stp
130+!Itapset/ucontext-unwind.stp
131+!Itapset/task.stp
132+!Itapset/pn.stp
133+ </chapter>
134+
135+ <chapter id="timestamp_stp">
136+ <title>Timestamp Functions</title>
137+ <para>
138+ Each timestamp function returns a value to indicate when
139+ a function is executed.
140+ These returned values can then be used to indicate
141+ when an event occurred, provide an ordering for events, or compute
142+ the amount of time elapsed between two time stamps.
143+ </para>
144+!Itapset/timestamp.stp
145+!Itapset/timestamp_gtod.stp
146+ </chapter>
147+
148+ <chapter id="ctime.stp">
149+ <title>Time string utility function</title>
150+ <para>
151+ Utility function to turn seconds since the epoch (as returned by
152+ the timestamp function gettimeofday_s()) into a human readable
153+ date/time string.
154+ </para>
155+!Itapset/ctime.stp
156+ </chapter>
157+
158+ <chapter id="memory_stp">
159+ <title>Memory Tapset</title>
160+ <para>
161+ This family of probe points is used to probe memory-related events
162+ or query the memory usage of the current process.
163+ It contains the following probe points:
164+ </para>
165+!Itapset/memory.stp
166+!Itapset/proc_mem.stp
167+ </chapter>
168+
169+ <chapter id="task_time_stp">
170+ <title>Task Time Tapset</title>
171+ <para>
172+ This tapset defines utility functions to query time related
173+ properties of the current tasks, translate those in miliseconds
174+ and human readable strings.
175+ </para>
176+!Itapset/task_time.stp
177+ </chapter>
178+
179+ <chapter id="iosched.stp">
180+ <title>IO Scheduler and block IO Tapset</title>
181+ <para>
182+ This family of probe points is used to probe block IO layer and IO scheduler activities.
183+ It contains the following probe points:
184+ </para>
185+!Itapset/ioscheduler.stp
186+!Itapset/ioblock.stp
187+ </chapter>
188+
189+ <chapter id="scsi.stp">
190+ <title>SCSI Tapset</title>
191+ <para>
192+ This family of probe points is used to probe SCSI activities.
193+ It contains the following probe points:
194+ </para>
195+!Itapset/scsi.stp
196+ </chapter>
197+
198+ <chapter id="tty.stp">
199+ <title>TTY Tapset</title>
200+ <para>
201+ This family of probe points is used to probe TTY (Teletype) activities.
202+ It contains the following probe points:
203+ </para>
204+!Itapset/tty.stp
205+ </chapter>
206+
207+ <chapter id="networking.stp">
208+ <title>Networking Tapset</title>
209+ <para>
210+ This family of probe points is used to probe the activities of
211+ the network device and protocol layers.
212+ </para>
213+!Itapset/networking.stp
214+!Itapset/tcp.stp
215+!Itapset/udp.stp
216+!Itapset/ip.stp
217+ </chapter>
218+
219+ <chapter id="socket.stp">
220+ <title>Socket Tapset</title>
221+ <para>
222+ This family of probe points is used to probe socket activities.
223+ It contains the following probe points:
224+ </para>
225+!Itapset/socket.stp
226+ </chapter>
227+ <chapter id="kprocess.stp">
228+ <title>Kernel Process Tapset</title>
229+ <para>
230+ This family of probe points is used to probe process-related activities.
231+ It contains the following probe points:
232+ </para>
233+!Itapset/kprocess.stp
234+ </chapter>
235+ <chapter id="signal.stp">
236+ <title>Signal Tapset</title>
237+ <para>
238+ This family of probe points is used to probe signal activities.
239+ It contains the following probe points:
240+ </para>
241+!Itapset/signal.stp
242+ </chapter>
243+ <chapter id="dentry.stp">
244+ <title>Directory-entry (dentry) Tapset</title>
245+ <para>
246+ This family of functions is used to map kernel VFS
247+ directory entry pointers to file or full path names.
248+ </para>
249+!Itapset/dentry.stp
250+ </chapter>
251+ <chapter id="logging.stp">
252+ <title>Logging Tapset</title>
253+ <para>
254+ This family of functions is used to send simple
255+ message strings to various destinations.
256+ </para>
257+!Itapset/logging.stp
258+ </chapter>
259+ <chapter id="random.stp">
260+ <title>Random functions Tapset</title>
261+ <para>
262+ These functions deal with random number generation.
263+ </para>
264+!Itapset/random.stp
265+ </chapter>
266+ <chapter id="conversions.stp">
267+ <title>String and data retrieving functions Tapset</title>
268+ <para>
269+ Functions to retrieve strings and other primitive types from
270+ the kernel or a user space programs based on addresses. All
271+ strings are of a maximum length given by MAXSTRINGLEN.
272+ </para>
273+!Itapset/conversions.stp
274+ </chapter>
275+ <chapter id="string.stp">
276+ <title>A collection of standard string functions</title>
277+ <para>
278+ Functions to get the length, a substring, getting at individual
279+ characters, string seaching, escaping, tokenizing, and converting
280+ strings to longs.
281+ </para>
282+!Itapset/string.stp
283+ </chapter>
284+ <chapter id="ansi.stp">
285+ <title>Utility functions for using ansi control chars in logs</title>
286+ <para>
287+ Utility functions for logging using ansi control characters. This
288+ lets you manipulate the cursor position and character color output
289+ and attributes of log messages.
290+ </para>
291+!Itapset/ansi.stp
292+ </chapter>
293+</book>
294
295=== added directory '.pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/tapset'
296=== added file '.pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/tapset/irq.stp'
297--- .pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/tapset/irq.stp 1970-01-01 00:00:00 +0000
298+++ .pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/tapset/irq.stp 2011-03-22 12:11:00 +0000
299@@ -0,0 +1,172 @@
300+/*
301+ * Copyright (C) 2009 IBM Corp.
302+ * This file is part of systemtap, and is free software. You can
303+ * redistribute it and/or modify it under the terms of the GNU General
304+ * Public License (GPL); either version 2, or (at your option) any
305+ * later version.
306+ *
307+ * Version 1.0 prerna@linux.vnet.ibm.com 2009-10-28
308+ *
309+ * Tracepoint based tapset for IRQs, Workqueues, etc
310+ *
311+ */
312+// Probes for workqueues.
313+
314+/**
315+ * probe workqueue.create : probes creation of a new workqueue
316+ * @wq_thread : task_struct of the workqueue thread.
317+ * @cpu : cpu for which the worker thread is created.
318+ */
319+probe workqueue.create = kernel.trace("workqueue_creation") ?
320+{
321+ wq_thread = $wq_thread
322+ cpu = $cpu
323+}
324+
325+/**
326+ * probe workqueue.insert : probes queuing of work on a workqueue
327+ * @wq_thread : task_struct of the workqueue thread.
328+ * @work : work_struct* being queued.
329+ * @work_func : pointer to handler func.
330+ */
331+probe workqueue.insert = kernel.trace("workqueue_insertion") ?
332+{
333+ wq_thread = $wq_thread
334+ work = $work
335+ work_func = $work->func
336+}
337+
338+/**
339+ * probe workqueue.execute : probes execution of deferred work.
340+ * @wq_thread : task_struct of the workqueue thread.
341+ * @work : work_struct* being executed.
342+ * @work_func : pointer to handler func.
343+ */
344+probe workqueue.execute = kernel.trace("workqueue_execution") ?
345+{
346+ wq_thread = $wq_thread
347+ work = $work
348+ work_func = $work->func
349+}
350+
351+/**
352+ * probe workqueue.destroy : probes destruction of each worker thread of each cpu for a workqueue.
353+ * @wq_thread : task_struct of the workqueue thread.
354+ */
355+probe workqueue.destroy = kernel.trace("workqueue_destruction") ?
356+{
357+ wq_thread = $wq_thread
358+}
359+
360+// Probes for IRQ handlers.
361+
362+/**
363+ * probe irq_handler.entry : Fires prior to execution of interrupt handler.
364+ * @irq : irq number.
365+ * @action : struct irqaction* for this interrupt num.
366+ * @handler : interrupt handler function.
367+ * @flags : Flags for IRQ handler
368+ * IRQF_DISABLED [0x00000020] : keep irqs disabled when calling action handler.
369+ * IRQF_SAMPLE_RANDOM [0x00000040] : irq is used to feed the random generator
370+ * IRQF_SHARED [0x00000080] : allow sharing the irq among several devices
371+ * IRQF_PROBE_SHARED [0x00000100] : set by callers when they expect sharing mismatches to occur
372+ * IRQF_TIMER [0x00000200] : Flag to mark this interrupt as timer interrupt
373+ * IRQF_PERCPU [0x00000400] : Interrupt is per cpu.
374+ * IRQF_NOBALANCING [0x00000800] : Flag to exclude this interrupt from irq balancing
375+ * IRQF_IRQPOLL [0x00001000] : Interrupt is used for polling.
376+ * IRQF_ONESHOT [0x00002000] : Interrupt is not reenabled after the hardirq handler finished.
377+ * @flags_str : symbolic string representation of IRQ flags.
378+ * @dev_name : name of device.
379+ * @dev_id : Cookie to identify device.
380+ * @next_irqaction : pointer to next irqaction for shared interrupts.
381+ * @dir : pointer to the proc/irq/NN/name entry
382+ * @thread_fn : interupt handler function for threaded interrupts.
383+ * @thread : thread pointer for threaded interrupts.
384+ * @thread_flags : Flags related to thread.
385+ */
386+probe irq_handler.entry = kernel.trace("irq_handler_entry") ?
387+{
388+ irq = $irq
389+ action = $action
390+ handler = $action->handler
391+ flags = $action->flags
392+ flags_str = irqflags_str(flags)
393+ dev_name = $action->name
394+ dev_id = $action->dev_id
395+ next_irqaction = $action->next
396+ dir = $action->dir
397+ thread_fn = $action->thread_fn
398+ thread = $action->thread
399+ thread_flags = $action->thread_flags
400+}
401+
402+/**
403+ * probe irq_handler.exit : Fires just after execution of interrupt handler.
404+ * @irq : interrupt number
405+ * @action : struct irqaction*
406+ * @ret : return value of the handler
407+ * @handler : interrupt handler function that was executed.
408+ * @flags : flags for IRQ handler
409+ * IRQF_DISABLED [0x00000020] : keep irqs disabled when calling action handler.
410+ * IRQF_SAMPLE_RANDOM [0x00000040] : irq is used to feed the random generator
411+ * IRQF_SHARED [0x00000080] : allow sharing the irq among several devices
412+ * IRQF_PROBE_SHARED [0x00000100] : set by callers when they expect sharing mismatches to occur
413+ * IRQF_TIMER [0x00000200] : Flag to mark this interrupt as timer interrupt
414+ * IRQF_PERCPU [0x00000400] : Interrupt is per cpu.
415+ * IRQF_NOBALANCING [0x00000800] : Flag to exclude this interrupt from irq balancing
416+ * IRQF_IRQPOLL [0x00001000] : Interrupt is used for polling.
417+ * IRQF_ONESHOT [0x00002000] : Interrupt is not reenabled after the hardirq handler finished.
418+ * @flags_str : symbolic string representation of IRQ flags.
419+ * @dev_name : name of device.
420+ * @dev_id : Cookie to identify device.
421+ * @next_irqaction : pointer to next irqaction for shared interrupts.
422+ * @dir : pointer to the proc/irq/NN/name entry
423+ * @thread_fn : interupt handler function for threaded interrupts.
424+ * @thread : thread pointer for threaded interrupts.
425+ * @thread_flags : Flags related to thread.
426+ */
427+probe irq_handler.exit = kernel.trace("irq_handler_exit") ?
428+{
429+ irq = $irq
430+ action = $action
431+ ret = $ret
432+ handler = $action->handler
433+ flags = $action->flags
434+ flags_str = irqflags_str(flags)
435+ dev_name = $action->name
436+ dev_id = $action->dev_id
437+ next_irqaction = $action->next
438+ dir = $action->dir
439+ thread_fn = $action->thread_fn
440+ thread = $action->thread
441+ thread_flags = $action->thread_flags
442+}
443+
444+// Softirq based probes.
445+/**
446+ * probe softirq.entry : triggered just before executing handler
447+ * for a pending softirq.
448+ * @h : struct softirq_action* for current pending softirq.
449+ * @vec : softirq_action vector.
450+ * @action : pointer to softirq handler just about to execute.
451+ */
452+probe softirq.entry = kernel.trace("softirq_entry") ?
453+{
454+ h = $h
455+ vec = $vec
456+ action = $h->action
457+}
458+
459+/**
460+ * probe softirq.exit : triggered just after executing handler for a pending
461+ * softirq.
462+ * @h : struct softirq_action* for just executed softirq.
463+ * @vec : softirq_action vector.
464+ * @action : pointer to softirq handler that just finished execution.
465+ */
466+probe softirq.exit = kernel.trace("softirq_exit") ?
467+{
468+ h = $h
469+ vec = $vec
470+ action = $h->action
471+}
472
473=== added directory '.pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch'
474=== added directory '.pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/tapset'
475=== added file '.pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/tapset/irq.stp'
476--- .pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/tapset/irq.stp 1970-01-01 00:00:00 +0000
477+++ .pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/tapset/irq.stp 2011-03-22 12:11:00 +0000
478@@ -0,0 +1,152 @@
479+/*
480+ * Copyright (C) 2009 IBM Corp.
481+ * This file is part of systemtap, and is free software. You can
482+ * redistribute it and/or modify it under the terms of the GNU General
483+ * Public License (GPL); either version 2, or (at your option) any
484+ * later version.
485+ *
486+ * Version 1.0 prerna@linux.vnet.ibm.com 2009-10-28
487+ *
488+ * Tracepoint based tapset for IRQs, Workqueues, etc
489+ *
490+ */
491+// Probes for workqueues.
492+
493+/**
494+ * probe workqueue.create - Creating a new workqueue
495+ * @wq_thread: task_struct of the workqueue thread
496+ * @cpu: cpu for which the worker thread is created
497+ */
498+probe workqueue.create = kernel.trace("workqueue_creation") ?
499+{
500+ wq_thread = $wq_thread
501+ cpu = $cpu
502+}
503+
504+/**
505+ * probe workqueue.insert - Queuing work on a workqueue
506+ * @wq_thread: task_struct of the workqueue thread
507+ * @work: work_struct* being queued
508+ * @work_func: pointer to handler function
509+ */
510+probe workqueue.insert = kernel.trace("workqueue_insertion") ?
511+{
512+ wq_thread = $wq_thread
513+ work = $work
514+ work_func = $work->func
515+}
516+
517+/**
518+ * probe workqueue.execute - Executing deferred work
519+ * @wq_thread: task_struct of the workqueue thread
520+ * @work: work_struct* being executed
521+ * @work_func: pointer to handler function
522+ */
523+probe workqueue.execute = kernel.trace("workqueue_execution") ?
524+{
525+ wq_thread = $wq_thread
526+ work = $work
527+ work_func = $work->func
528+}
529+
530+/**
531+ * probe workqueue.destroy - Destroying workqueue
532+ * @wq_thread: task_struct of the workqueue thread
533+ */
534+probe workqueue.destroy = kernel.trace("workqueue_destruction") ?
535+{
536+ wq_thread = $wq_thread
537+}
538+
539+// Probes for IRQ handlers.
540+
541+/**
542+ * probe irq_handler.entry - Execution of interrupt handler starting
543+ * @irq: irq number
544+ * @action: struct irqaction* for this interrupt num
545+ * @handler: interrupt handler function
546+ * @flags: Flags for IRQ handler
547+ * @flags_str: symbolic string representation of IRQ flags
548+ * @dev_name: name of device
549+ * @dev_id: Cookie to identify device
550+ * @next_irqaction: pointer to next irqaction for shared interrupts
551+ * @dir: pointer to the proc/irq/NN/name entry
552+ * @thread_fn: interrupt handler function for threaded interrupts
553+ * @thread: thread pointer for threaded interrupts
554+ * @thread_flags: Flags related to thread
555+ */
556+probe irq_handler.entry = kernel.trace("irq_handler_entry") ?
557+{
558+ irq = $irq
559+ action = $action
560+ handler = $action->handler
561+ flags = $action->flags
562+ flags_str = irqflags_str(flags)
563+ dev_name = $action->name
564+ dev_id = $action->dev_id
565+ next_irqaction = $action->next
566+ dir = $action->dir
567+ thread_fn = $action->thread_fn
568+ thread = $action->thread
569+ thread_flags = $action->thread_flags
570+}
571+
572+/**
573+ * probe irq_handler.exit - Execution of interrupt handler completed
574+ * @irq: interrupt number
575+ * @action: struct irqaction*
576+ * @ret: return value of the handler
577+ * @handler: interrupt handler function that was executed
578+ * @flags: flags for IRQ handler
579+ * @flags_str: symbolic string representation of IRQ flags
580+ * @dev_name: name of device
581+ * @dev_id: Cookie to identify device
582+ * @next_irqaction: pointer to next irqaction for shared interrupts
583+ * @dir: pointer to the proc/irq/NN/name entry
584+ * @thread_fn: interrupt handler function for threaded interrupts
585+ * @thread: thread pointer for threaded interrupts
586+ * @thread_flags: Flags related to thread
587+ */
588+probe irq_handler.exit = kernel.trace("irq_handler_exit") ?
589+{
590+ irq = $irq
591+ action = $action
592+ ret = $ret
593+ handler = $action->handler
594+ flags = $action->flags
595+ flags_str = irqflags_str(flags)
596+ dev_name = $action->name
597+ dev_id = $action->dev_id
598+ next_irqaction = $action->next
599+ dir = $action->dir
600+ thread_fn = $action->thread_fn
601+ thread = $action->thread
602+ thread_flags = $action->thread_flags
603+}
604+
605+// Softirq based probes.
606+/**
607+ * probe softirq.entry - Execution of handler for a pending softirq starting
608+ * @h: struct softirq_action* for current pending softirq
609+ * @vec: softirq_action vector
610+ * @action: pointer to softirq handler just about to execute
611+ */
612+probe softirq.entry = kernel.trace("softirq_entry") ?
613+{
614+ h = $h
615+ vec = $vec
616+ action = $h->action
617+}
618+
619+/**
620+ * probe softirq.exit - Execution of handler for a pending softirq completed
621+ * @h: struct softirq_action* for just executed softirq
622+ * @vec: softirq_action vector
623+ * @action: pointer to softirq handler that just finished execution
624+ */
625+probe softirq.exit = kernel.trace("softirq_exit") ?
626+{
627+ h = $h
628+ vec = $vec
629+ action = $h->action
630+}
631
632=== added directory '.pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/testsuite'
633=== added directory '.pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/testsuite/buildok'
634=== added file '.pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/testsuite/buildok/irq-detailed.stp'
635--- .pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/testsuite/buildok/irq-detailed.stp 1970-01-01 00:00:00 +0000
636+++ .pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/testsuite/buildok/irq-detailed.stp 2011-03-22 12:11:00 +0000
637@@ -0,0 +1,46 @@
638+#! stap -p4
639+
640+#
641+# workqueue probes
642+#
643+
644+probe workqueue.create ?
645+{
646+ printf("%p %d\n", wq_thread, cpu)
647+}
648+
649+probe workqueue.insert ?, workqueue.execute ?
650+{
651+ printf("%p %p %p\n", wq_thread, work, work_func)
652+}
653+
654+probe workqueue.destroy ?
655+{
656+ printf("%p\n", wq_thread)
657+}
658+
659+#
660+# irq_handler probes
661+#
662+
663+probe irq_handler.entry ?, irq_handler.exit ?
664+{
665+ printf("%d %p %p %d(%s)\n", irq, action, handler, flags, flags_str)
666+ printf("%d %d %p %p\n", dev_name, dev_id, next_irqaction, dir)
667+ printf("%p %p %d\n", thread_fn, thread, thread_flags)
668+}
669+
670+#
671+# softirq probes
672+#
673+
674+probe softirq.entry ?, softirq.exit ?
675+{
676+ printf("%p %p %p\n", h, vec, action)
677+}
678+
679+# Make sure we've got at least one probe.
680+probe never
681+{
682+ printf("never\n")
683+}
684
685=== added directory '.pc/Fix-for-undefined-STAPCONF_PERF_STRUCTPID.patch'
686=== added directory '.pc/Fix-for-undefined-STAPCONF_PERF_STRUCTPID.patch/runtime'
687=== added file '.pc/Fix-for-undefined-STAPCONF_PERF_STRUCTPID.patch/runtime/perf.c'
688--- .pc/Fix-for-undefined-STAPCONF_PERF_STRUCTPID.patch/runtime/perf.c 1970-01-01 00:00:00 +0000
689+++ .pc/Fix-for-undefined-STAPCONF_PERF_STRUCTPID.patch/runtime/perf.c 2011-03-22 12:11:00 +0000
690@@ -0,0 +1,86 @@
691+/* -*- linux-c -*-
692+ * Perf Functions
693+ * Copyright (C) 2006 Red Hat Inc.
694+ * Copyright (C) 2010 Red Hat Inc.
695+ *
696+ * This file is part of systemtap, and is free software. You can
697+ * redistribute it and/or modify it under the terms of the GNU General
698+ * Public License (GPL); either version 2, or (at your option) any
699+ * later version.
700+ */
701+
702+#ifndef _PERF_C_
703+#define _PERF_C_
704+
705+#include <linux/perf_event.h>
706+
707+#include "perf.h"
708+
709+/** @file perf.c
710+ * @brief Implements performance monitoring hardware support
711+ */
712+
713+/** Initialize performance sampling
714+ * Call this during probe initialization to set up performance event sampling
715+ * for all online cpus. Returns non-zero on error.
716+ *
717+ * @param stp Handle for the event to be registered.
718+ */
719+static long _stp_perf_init (struct stap_perf_probe *stp)
720+{
721+ int cpu;
722+
723+ /* allocate space for the event descriptor for each cpu */
724+ stp->events = _stp_alloc_percpu (sizeof(struct perf_event*));
725+ if (stp->events == NULL) {
726+ return -ENOMEM;
727+ }
728+
729+ /* initialize event on each processor */
730+ stp_for_each_cpu(cpu) {
731+ struct perf_event **event = per_cpu_ptr (stp->events, cpu);
732+ if (cpu_is_offline(cpu)) {
733+ *event = NULL;
734+ continue;
735+ }
736+ *event = perf_event_create_kernel_counter(&stp->attr,
737+ cpu,
738+#if STAPCONF_PERF_STRUCTPID
739+ NULL,
740+#else
741+ -1,
742+#endif
743+ stp->callback);
744+
745+ if (IS_ERR(*event)) {
746+ long rc = PTR_ERR(*event);
747+ *event = NULL;
748+ _stp_perf_del(stp);
749+ return rc;
750+ }
751+ }
752+ return 0;
753+}
754+
755+/** Delete performance event.
756+ * Call this to shutdown performance event sampling
757+ *
758+ * @param stp Handle for the event to be unregistered.
759+ */
760+static void _stp_perf_del (struct stap_perf_probe *stp)
761+{
762+ if (stp && stp->events) {
763+ int cpu;
764+ /* shut down performance event sampling */
765+ stp_for_each_cpu(cpu) {
766+ struct perf_event **event = per_cpu_ptr (stp->events, cpu);
767+ if (*event) {
768+ perf_event_release_kernel(*event);
769+ }
770+ }
771+ _stp_free_percpu (stp->events);
772+ stp->events = NULL;
773+ }
774+}
775+
776+#endif /* _PERF_C_ */
777
778=== added directory '.pc/Fixed-PR11940-by-getting-scripts-w-global-variables-.patch'
779=== added directory '.pc/Fixed-PR11940-by-getting-scripts-w-global-variables-.patch/runtime'
780=== added file '.pc/Fixed-PR11940-by-getting-scripts-w-global-variables-.patch/runtime/runtime.h'
781--- .pc/Fixed-PR11940-by-getting-scripts-w-global-variables-.patch/runtime/runtime.h 1970-01-01 00:00:00 +0000
782+++ .pc/Fixed-PR11940-by-getting-scripts-w-global-variables-.patch/runtime/runtime.h 2011-03-22 12:11:00 +0000
783@@ -0,0 +1,204 @@
784+/* main header file
785+ * Copyright (C) 2005-2008 Red Hat Inc.
786+ * Copyright (C) 2005, 2006 Intel Corporation.
787+ *
788+ * This file is part of systemtap, and is free software. You can
789+ * redistribute it and/or modify it under the terms of the GNU General
790+ * Public License (GPL); either version 2, or (at your option) any
791+ * later version.
792+ */
793+
794+#ifndef _RUNTIME_H_
795+#define _RUNTIME_H_
796+
797+#include <linux/module.h>
798+#include <linux/ctype.h>
799+#include <linux/kernel.h>
800+#include <linux/miscdevice.h>
801+#include <linux/init.h>
802+#include <linux/hash.h>
803+#include <linux/string.h>
804+#include <linux/kprobes.h>
805+#include <linux/proc_fs.h>
806+#include <linux/vmalloc.h>
807+#include <linux/time.h>
808+#include <linux/spinlock.h>
809+#include <linux/hardirq.h>
810+#include <asm/uaccess.h>
811+#include <linux/kallsyms.h>
812+#include <linux/version.h>
813+#include <linux/compat.h>
814+#include <linux/sched.h>
815+#include <linux/mm.h>
816+
817+
818+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
819+#if !defined (CONFIG_DEBUG_FS) && !defined (CONFIG_DEBUG_FS_MODULE)
820+#error "DebugFS is required and was not found in the kernel."
821+#endif
822+#ifdef CONFIG_RING_BUFFER
823+#define STP_TRANSPORT_VERSION 3
824+#else
825+#define STP_TRANSPORT_VERSION 2
826+#endif
827+#else
828+/* older kernels have no debugfs and older version of relayfs. */
829+#define STP_TRANSPORT_VERSION 1
830+#endif
831+
832+#ifndef stp_for_each_cpu
833+#define stp_for_each_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map)
834+#endif
835+
836+#ifndef clamp
837+#define clamp(val, low, high) min(max(low, val), high)
838+#endif
839+
840+#ifndef clamp_t
841+#define clamp_t(type, val, low, high) min_t(type, max_t(type, low, val), high)
842+#endif
843+
844+static void _stp_dbug (const char *func, int line, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
845+static void _stp_error (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
846+static void _stp_warn (const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
847+
848+static void _stp_exit(void);
849+
850+
851+
852+/* unprivileged user support */
853+
854+#ifdef STAPCONF_TASK_UID
855+#define STP_CURRENT_EUID (current->euid)
856+#else
857+#define STP_CURRENT_EUID (task_euid(current))
858+#endif
859+
860+#define is_myproc() (STP_CURRENT_EUID == _stp_uid)
861+
862+#ifndef STP_PRIVILEGED
863+#define assert_is_myproc() do { \
864+ if (! is_myproc()) { \
865+ snprintf (CONTEXT->error_buffer, MAXSTRINGLEN, "semi-privileged tapset function called without is_myproc checking for pid %d (euid %d)", \
866+ current->tgid, STP_CURRENT_EUID); \
867+ CONTEXT->last_error = CONTEXT->error_buffer; \
868+ goto out; \
869+ } } while (0)
870+#else
871+#define assert_is_myproc() do {} while (0)
872+#endif
873+
874+
875+
876+#include "debug.h"
877+
878+/* atomic globals */
879+static atomic_t _stp_transport_failures = ATOMIC_INIT (0);
880+
881+static struct
882+{
883+ atomic_t ____cacheline_aligned_in_smp seq;
884+} _stp_seq = { ATOMIC_INIT (0) };
885+
886+#define _stp_seq_inc() (atomic_inc_return(&_stp_seq.seq))
887+
888+#ifndef MAXSTRINGLEN
889+#define MAXSTRINGLEN 128
890+#endif
891+
892+#ifndef MAXTRACE
893+#define MAXTRACE 20
894+#endif
895+
896+/* dwarf unwinder only tested so far on i386 and x86_64. */
897+#if (defined(__i386__) || defined(__x86_64__))
898+#ifndef STP_USE_DWARF_UNWINDER
899+#define STP_USE_DWARF_UNWINDER
900+#endif
901+#endif
902+
903+#ifdef CONFIG_FRAME_POINTER
904+/* Just because frame pointers are available does not mean we can trust them. */
905+#ifndef STP_USE_DWARF_UNWINDER
906+#define STP_USE_FRAME_POINTER
907+#endif
908+#endif
909+
910+#include "alloc.c"
911+#include "print.c"
912+#include "string.c"
913+#include "io.c"
914+#include "arith.c"
915+#include "copy.c"
916+#include "regs.c"
917+#include "regs-ia64.c"
918+#include "time.c"
919+
920+#include "task_finder.c"
921+
922+#include "sym.c"
923+#ifdef STP_PERFMON
924+#include "perf.c"
925+#endif
926+#include "addr-map.c"
927+
928+
929+
930+/* Support functions for int64_t module parameters. */
931+static int param_set_int64_t(const char *val, struct kernel_param *kp)
932+{
933+ char *endp;
934+ long long ll;
935+
936+ if (!val)
937+ return -EINVAL;
938+
939+ /* simple_strtoll isn't exported... */
940+ if (*val == '-')
941+ ll = -simple_strtoull(val+1, &endp, 0);
942+ else
943+ ll = simple_strtoull(val, &endp, 0);
944+
945+ if ((endp == val) || ((int64_t)ll != ll))
946+ return -EINVAL;
947+
948+ *((int64_t *)kp->arg) = ll;
949+ return 0;
950+}
951+
952+static int param_get_int64_t(char *buffer, struct kernel_param *kp)
953+{
954+ return sprintf(buffer, "%lli", (long long)*((int64_t *)kp->arg));
955+}
956+
957+#define param_check_int64_t(name, p) __param_check(name, p, int64_t)
958+
959+
960+/************* Module Stuff ********************/
961+
962+int init_module (void)
963+{
964+ return _stp_transport_init();
965+}
966+
967+static int probe_start(void);
968+
969+void cleanup_module(void)
970+{
971+ _stp_transport_close();
972+}
973+
974+#define pseudo_atomic_cmpxchg(v, old, new) ({\
975+ int ret;\
976+ unsigned long flags;\
977+ local_irq_save(flags);\
978+ ret = atomic_read(v);\
979+ if (likely(ret == old))\
980+ atomic_set(v, new);\
981+ local_irq_restore(flags);\
982+ ret; })
983+
984+
985+MODULE_LICENSE("GPL");
986+
987+#endif /* _RUNTIME_H_ */
988
989=== added directory '.pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch'
990=== added directory '.pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/tapset'
991=== added file '.pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/tapset/ip.stp'
992--- .pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/tapset/ip.stp 1970-01-01 00:00:00 +0000
993+++ .pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/tapset/ip.stp 2011-03-22 12:11:00 +0000
994@@ -0,0 +1,86 @@
995+// IP tapset
996+//
997+// Copyright (C) 2009, IBM Inc.
998+// Copyright (C) 2010, Red Hat Inc.
999+//
1000+// Author : Breno Leitao <leitao@linux.vnet.ibm.com>
1001+//
1002+// This file is free software. You can redistribute it and/or modify it under
1003+// the terms of the GNU General Public License (GPL), version 2.
1004+//
1005+// Based on previous work done by Arnaldo Carvalho de Melo <acme@redhat.com>
1006+
1007+%{
1008+#include <linux/skbuff.h>
1009+%}
1010+
1011+/**
1012+ * sfunction ip_ntop - returns a string representation from an integer IP number
1013+ * @addr: the ip represented as an integer
1014+ */
1015+function ip_ntop:string (addr:long)
1016+%{
1017+ __be32 ip;
1018+
1019+ ip = THIS->addr;
1020+ snprintf(THIS->__retvalue, MAXSTRINGLEN, NIPQUAD_FMT, NIPQUAD(ip));
1021+%}
1022+
1023+/* return the source IP address for a given sock */
1024+function __ip_sock_saddr:long (sock:long)
1025+{
1026+ return (@defined(@cast(sock, "inet_sock")->inet_saddr)
1027+ ? @cast(sock, "inet_sock")->inet_saddr # kernel >= 2.6.33
1028+ : (@defined(@cast(sock, "inet_sock")->saddr)
1029+ ? @cast(sock, "inet_sock", "kernel")->saddr # kernel >= 2.6.11
1030+ : @cast(sock, "inet_sock", "kernel<net/ip.h>")->inet->saddr))
1031+}
1032+
1033+/* return the destination IP address for a given sock */
1034+function __ip_sock_daddr:long (sock:long)
1035+{
1036+ return (@defined(@cast(sock, "inet_sock")->inet_daddr)
1037+ ? @cast(sock, "inet_sock")->inet_daddr # kernel >= 2.6.33
1038+ : (@defined(@cast(sock, "inet_sock")->daddr)
1039+ ? @cast(sock, "inet_sock", "kernel")->daddr # kernel >= 2.6.11
1040+ : @cast(sock, "inet_sock", "kernel<net/ip.h>")->inet->daddr))
1041+}
1042+
1043+/* Get the IP header from a sk_buff struct */
1044+function __get_skb_iphdr:long(skb:long)
1045+%( kernel_v < "2.6.21" %?
1046+{
1047+ iphdr = @cast(skb, "sk_buff")->nh->raw
1048+ return iphdr
1049+}
1050+%:
1051+%{ /* pure */
1052+ struct sk_buff *skb;
1053+ skb = (struct sk_buff *)(long)THIS->skb;
1054+ /* as done by skb_network_header() */
1055+ #ifdef NET_SKBUFF_DATA_USES_OFFSET
1056+ THIS->__retvalue = (long)(kread(&(skb->head)) + kread(&(skb->network_header)));
1057+ #else
1058+ THIS->__retvalue = (long)kread(&(skb->network_header));
1059+ #endif
1060+ CATCH_DEREF_FAULT();
1061+%}
1062+%)
1063+
1064+/* return the source next layer protocol for a given sk_buff structure */
1065+function __ip_skb_proto:long (iphdr)
1066+{
1067+ return @cast(iphdr, "iphdr")->protocol
1068+}
1069+
1070+/* return the source IP address for a given sk_buff structure */
1071+function __ip_skb_saddr:long (iphdr)
1072+{
1073+ return @cast(iphdr, "iphdr")->saddr
1074+}
1075+
1076+/* return the destination IP address for a given skb */
1077+function __ip_skb_daddr:long (iphdr)
1078+{
1079+ return @cast(iphdr, "iphdr")->daddr
1080+}
1081
1082=== added directory '.pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/testsuite'
1083=== added directory '.pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/testsuite/systemtap.examples'
1084=== added directory '.pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/testsuite/systemtap.examples/process'
1085=== added file '.pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/testsuite/systemtap.examples/process/pfiles.stp'
1086--- .pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/testsuite/systemtap.examples/process/pfiles.stp 1970-01-01 00:00:00 +0000
1087+++ .pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/testsuite/systemtap.examples/process/pfiles.stp 2011-03-22 12:11:00 +0000
1088@@ -0,0 +1,612 @@
1089+#! /bin/sh
1090+
1091+//bin/true && exec stap -g $0 ${1+"$@"}
1092+
1093+# pfiles
1094+# Copyright (C) 2007-2010 Red Hat, Inc., Eugene Teo <eteo@redhat.com>
1095+#
1096+# This program is free software; you can redistribute it and/or modify
1097+# it under the terms of the GNU General Public License version 2 as
1098+# published by the Free Software Foundation.
1099+#
1100+# pfiles report information for all open files by the process id.
1101+#
1102+# pfiles is not a port of Solaris' pfiles tool. It was written based on the
1103+# example outputs in:
1104+# - https://bugzilla.redhat.com/show_bug.cgi?id=223489
1105+# - http://blogs.sun.com/peteh/entry/pfiles_1_locked_files_and
1106+# - http://lists.samba.org/archive/samba-technical/2001-May/014293.html
1107+# - http://mail.gnome.org/archives/gconf-list/2004-December/msg00005.html
1108+#
1109+# systemtap SNAPSHOT c9116e9980ad6e417697737f8d54a4a625811245
1110+# on kernel 2.6.18-128.1.13.el5
1111+# and on kernel 2.6.27.21-170.2.56.fc10.i686.PAE
1112+#
1113+# Last updated: Thu May 28 20:37:57 SGT 2009
1114+#
1115+# pfiles is able to:
1116+# - report locked open files
1117+# - report pathname information
1118+# - report socket information (thanks Luis Henriques)
1119+# - report sk_userlocks (thanks Arnaldo Carvalho de Melo)
1120+# - report socket options
1121+#
1122+# Example:
1123+# $ ./pfiles.stp `pgrep udevd`
1124+# 787: udevd
1125+# Current rlimit: 32 file descriptors
1126+# 0: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
1127+# O_RDWR|O_LARGEFILE
1128+# /dev/null
1129+# 1: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
1130+# O_RDWR|O_LARGEFILE
1131+# /dev/null
1132+# 2: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
1133+# O_RDWR|O_LARGEFILE
1134+# /dev/null
1135+# 3: S_IFDIR mode:0600 dev:0,9 ino:1 uid:0 gid:0 rdev:0,0
1136+# O_RDONLY
1137+# inotify
1138+# 4: S_IFSOCK mode:0777 dev:0,4 ino:2353 uid:0 gid:0 rdev:0,0
1139+# O_RDWR
1140+# socket:[2353]
1141+# SO_PASSCRED,SO_TYPE(2),SO_SNDBUF(111616),SO_RCVBUF(111616)
1142+# sockname: AF_UNIX
1143+# 5: S_IFSOCK mode:0777 dev:0,4 ino:2354 uid:0 gid:0 rdev:0,0
1144+# O_RDWR
1145+# socket:[2354]
1146+# SO_TYPE(2),SO_SNDBUF(111616),SO_RCVBUF(33554432)
1147+# ulocks: rcv
1148+# 6: S_IFIFO mode:0600 dev:0,6 ino:2355 uid:0 gid:0 rdev:0,0
1149+# O_RDONLY|O_NONBLOCK
1150+# pipe:[2355]
1151+# 7: S_IFIFO mode:0600 dev:0,6 ino:2355 uid:0 gid:0 rdev:0,0
1152+# O_WRONLY|O_NONBLOCK
1153+# pipe:[2355]
1154+#
1155+# I used Andrew Tridgell's locktst.c to test the advisory lock code.
1156+# You can download it at http://samba.org/ftp/unpacked/junkcode/locktst.c
1157+#
1158+# $ ./locktst file &
1159+# fcntl_lock 3 6 1 1 1
1160+# $ pfiles 10126 | grep advisory -A1 -B2
1161+# 3: S_IFREG mode:0644 dev:253,0 ino:15237159 uid:500 gid:500 rdev:0,0
1162+# O_RDWR
1163+# advisory write lock set by process 10126
1164+# /home/eteo/pfiles/file
1165+#
1166+
1167+%{
1168+#include <linux/file.h>
1169+#include <net/sock.h>
1170+#include <linux/un.h>
1171+#include <linux/tcp.h>
1172+%}
1173+
1174+function task_valid_file_handle:long (task:long, fd:long) %{ /* pure */
1175+ struct task_struct *p = (struct task_struct *)((long)THIS->task);
1176+ struct files_struct *files = kread(&p->files);
1177+ struct file *filp;
1178+
1179+ rcu_read_lock();
1180+ filp = fcheck_files(files, THIS->fd);
1181+ if (!filp) {
1182+ THIS->__retvalue = 0;
1183+ rcu_read_unlock();
1184+ return;
1185+ }
1186+ THIS->__retvalue = (long)filp;
1187+ rcu_read_unlock();
1188+
1189+ CATCH_DEREF_FAULT();
1190+%}
1191+
1192+function i_mode2str:string (i_mode:long) %{ /* pure */
1193+ snprintf(THIS->__retvalue, MAXSTRINGLEN, "%d", (int)THIS->i_mode);
1194+ THIS->i_mode = simple_strtol(THIS->__retvalue, NULL, 10);
1195+
1196+ if (S_ISLNK(THIS->i_mode)) strlcpy (THIS->__retvalue, "S_IFLNK", MAXSTRINGLEN);
1197+ else if (S_ISREG(THIS->i_mode)) strlcpy (THIS->__retvalue, "S_IFREG", MAXSTRINGLEN);
1198+ else if (S_ISDIR(THIS->i_mode)) strlcpy (THIS->__retvalue, "S_IFDIR", MAXSTRINGLEN);
1199+ else if (S_ISCHR(THIS->i_mode)) strlcpy (THIS->__retvalue, "S_IFCHR", MAXSTRINGLEN);
1200+ else if (S_ISBLK(THIS->i_mode)) strlcpy (THIS->__retvalue, "S_IFBLK", MAXSTRINGLEN);
1201+ else if (S_ISFIFO(THIS->i_mode)) strlcpy (THIS->__retvalue, "S_IFIFO", MAXSTRINGLEN);
1202+ else if (S_ISSOCK(THIS->i_mode)) strlcpy (THIS->__retvalue, "S_IFSOCK", MAXSTRINGLEN);
1203+%}
1204+
1205+function task_file_handle_i_mode:long (task:long, fd:long) %{ /* pure */
1206+ struct task_struct *p = (struct task_struct *)((long)THIS->task);
1207+ struct files_struct *files = kread(&p->files);
1208+ struct file *filp;
1209+
1210+ rcu_read_lock();
1211+ filp = fcheck_files(files, THIS->fd);
1212+ THIS->__retvalue = kread(&filp->f_dentry->d_inode->i_mode);
1213+ rcu_read_unlock();
1214+
1215+ CATCH_DEREF_FAULT();
1216+%}
1217+
1218+function task_file_handle_majmin_dev:string (task:long, fd:long) %{ /* pure */
1219+ struct task_struct *p = (struct task_struct *)((long)THIS->task);
1220+ struct files_struct *files = kread(&p->files);
1221+ struct file *filp;
1222+ int dev_nr;
1223+
1224+ rcu_read_lock();
1225+ filp = fcheck_files(files, THIS->fd);
1226+ dev_nr = kread(&filp->f_dentry->d_inode->i_sb->s_dev);
1227+ snprintf(THIS->__retvalue, MAXSTRINGLEN,
1228+ "%d,%d", MAJOR(dev_nr), MINOR(dev_nr));
1229+ rcu_read_unlock();
1230+
1231+ CATCH_DEREF_FAULT();
1232+%}
1233+
1234+function task_file_handle_majmin_rdev:string (task:long, fd:long) %{ /* pure */
1235+ struct task_struct *p = (struct task_struct *)((long)THIS->task);
1236+ struct files_struct *files = kread(&p->files);
1237+ struct file *filp;
1238+ int rdev_nr;
1239+
1240+ rcu_read_lock();
1241+ filp = fcheck_files(files, THIS->fd);
1242+ rdev_nr = kread(&filp->f_dentry->d_inode->i_rdev);
1243+ snprintf(THIS->__retvalue, MAXSTRINGLEN,
1244+ "%d,%d", MAJOR(rdev_nr), MINOR(rdev_nr));
1245+ rcu_read_unlock();
1246+
1247+ CATCH_DEREF_FAULT();
1248+%}
1249+
1250+function task_file_handle_i_node:long (task:long, fd:long) %{ /* pure */
1251+ struct task_struct *p = (struct task_struct *)((long)THIS->task);
1252+ struct files_struct *files = kread(&p->files);
1253+ struct file *filp;
1254+
1255+ rcu_read_lock();
1256+ filp = fcheck_files(files, THIS->fd);
1257+ THIS->__retvalue = kread(&filp->f_dentry->d_inode->i_ino);
1258+ rcu_read_unlock();
1259+
1260+ CATCH_DEREF_FAULT();
1261+%}
1262+
1263+function task_file_handle_uid:long (task:long, fd:long) %{ /* pure */
1264+ struct task_struct *p = (struct task_struct *)((long)THIS->task);
1265+ struct files_struct *files = kread(&p->files);
1266+ struct file *filp;
1267+
1268+ rcu_read_lock();
1269+ filp = fcheck_files(files, THIS->fd);
1270+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
1271+ /* git commit d76b0d9b */
1272+ THIS->__retvalue = kread(&filp->f_cred->fsuid);
1273+#else
1274+ THIS->__retvalue = kread(&filp->f_uid);
1275+#endif
1276+ rcu_read_unlock();
1277+
1278+ CATCH_DEREF_FAULT();
1279+%}
1280+
1281+function task_file_handle_gid:long (task:long, fd:long) %{ /* pure */
1282+ struct task_struct *p = (struct task_struct *)((long)THIS->task);
1283+ struct files_struct *files = kread(&p->files);
1284+ struct file *filp;
1285+
1286+ rcu_read_lock();
1287+ filp = fcheck_files(files, THIS->fd);
1288+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
1289+ /* git commit d76b0d9b */
1290+ THIS->__retvalue = kread(&filp->f_cred->fsgid);
1291+#else
1292+ THIS->__retvalue = kread(&filp->f_gid);
1293+#endif
1294+ rcu_read_unlock();
1295+
1296+ CATCH_DEREF_FAULT();
1297+%}
1298+
1299+function task_file_handle_f_flags:long (task:long, fd:long) %{ /* pure */
1300+ struct task_struct *p = (struct task_struct *)((long)THIS->task);
1301+ struct files_struct *files = kread(&p->files);
1302+ struct file *filp;
1303+
1304+ rcu_read_lock();
1305+ filp = fcheck_files(files, THIS->fd);
1306+ THIS->__retvalue = kread(&filp->f_flags);
1307+ rcu_read_unlock();
1308+
1309+ CATCH_DEREF_FAULT();
1310+%}
1311+
1312+function task_file_handle_fd_flags:string (task:long, fd:long) %{ /* pure */
1313+ struct task_struct *p = (struct task_struct *)((long)THIS->task);
1314+ struct files_struct *files = kread(&p->files);
1315+ struct fdtable *fdt;
1316+ int gcoe;
1317+
1318+ rcu_read_lock();
1319+ fdt = files_fdtable(files);
1320+ gcoe = FD_ISSET(THIS->fd, kread(&fdt->close_on_exec));
1321+ snprintf(THIS->__retvalue, MAXSTRINGLEN,
1322+ "%s", gcoe ? "FD_CLOEXEC" : "");
1323+ rcu_read_unlock();
1324+
1325+ CATCH_DEREF_FAULT();
1326+%}
1327+
1328+function task_file_handle_flock:string (task:long, fd:long) %{ /* pure */
1329+ struct task_struct *p = (struct task_struct *)((long)THIS->task);
1330+ struct files_struct *files = kread(&p->files);
1331+ struct file_lock *flock;
1332+ int fl_type, fl_pid;
1333+ struct file *filp;
1334+
1335+ rcu_read_lock();
1336+ filp = fcheck_files(files, THIS->fd);
1337+ flock = kread(&filp->f_dentry->d_inode->i_flock);
1338+ fl_type = fl_pid = -1;
1339+ if (flock) {
1340+ fl_type = kread(&flock->fl_type);
1341+ fl_pid = kread(&flock->fl_pid);
1342+ }
1343+
1344+ if (fl_type != -1) /* !flock */
1345+ snprintf(THIS->__retvalue, MAXSTRINGLEN,
1346+ " advisory %s lock set by process %d",
1347+ fl_type ? "write" : "read", fl_pid);
1348+ else
1349+ snprintf(THIS->__retvalue, MAXSTRINGLEN, "NULL");
1350+ rcu_read_unlock();
1351+
1352+ CATCH_DEREF_FAULT();
1353+%}
1354+
1355+function task_file_handle_d_path:string (task:long, fd:long) %{ /* pure */
1356+ struct task_struct *p = (struct task_struct *)((long)THIS->task);
1357+ struct files_struct *files = kread(&p->files);
1358+ char *page = (char *)__get_free_page(GFP_KERNEL);
1359+ struct file *filp;
1360+ struct dentry *dentry;
1361+ struct vfsmount *vfsmnt;
1362+
1363+ /* TODO: handle !page */
1364+ if (!page)
1365+ return;
1366+
1367+ rcu_read_lock();
1368+ filp = fcheck_files(files, THIS->fd);
1369+ dentry = kread(&filp->f_dentry);
1370+ vfsmnt = kread(&filp->f_vfsmnt);
1371+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
1372+ /* git commit 9d1bc601 */
1373+ snprintf(THIS->__retvalue, MAXSTRINGLEN, "%s",
1374+ d_path(&filp->f_path, page, PAGE_SIZE));
1375+#else
1376+ snprintf(THIS->__retvalue, MAXSTRINGLEN, "%s",
1377+ d_path(dentry, vfsmnt, page, PAGE_SIZE));
1378+#endif
1379+ free_page((unsigned long)page);
1380+ rcu_read_unlock();
1381+
1382+ CATCH_DEREF_FAULT();
1383+%}
1384+
1385+function task_file_handle_socket:long (task:long, fd:long) %{ /* pure */
1386+ struct task_struct *p = (struct task_struct *)((long)THIS->task);
1387+ struct files_struct *files = kread(&p->files);
1388+ struct inode *inode;
1389+ struct file *filp;
1390+
1391+ rcu_read_lock();
1392+ filp = fcheck_files(files, THIS->fd);
1393+ if (!filp) {
1394+ THIS->__retvalue = 0;
1395+ rcu_read_unlock();
1396+ return;
1397+ }
1398+ inode = kread(&filp->f_dentry->d_inode);
1399+ if (S_ISSOCK(kread(&inode->i_mode)))
1400+ THIS->__retvalue = (long)SOCKET_I(inode);
1401+ rcu_read_unlock();
1402+
1403+ CATCH_DEREF_FAULT();
1404+%}
1405+
1406+function socket_userlocks:string (sock:long) %{ /* pure */
1407+ struct socket *sock = (struct socket *)((long)THIS->sock);
1408+ struct sock *sk = (struct sock *)kread(&sock->sk);
1409+ unsigned char locks = sk->sk_userlocks;
1410+ int printed = 0;
1411+
1412+ THIS->__retvalue[0] = '\0';
1413+
1414+ if (locks & SOCK_RCVBUF_LOCK)
1415+ printed = snprintf(THIS->__retvalue, MAXSTRINGLEN,
1416+ "ulocks: rcv");
1417+
1418+ if (locks & SOCK_SNDBUF_LOCK)
1419+ snprintf(THIS->__retvalue, MAXSTRINGLEN,
1420+ "ulocks: %ssnd",
1421+ printed ? "rcv, " : "");
1422+
1423+ CATCH_DEREF_FAULT();
1424+%}
1425+
1426+function socket_optname:string (sock:long) %{ /* pure */
1427+ struct socket *sock = (struct socket *)((long)THIS->sock);
1428+ int optval;
1429+ int optlen;
1430+ int ret, a;
1431+ char str[30];
1432+ struct linger ling;
1433+ struct optname_item {
1434+ int optfam;
1435+ int optnum;
1436+ const char *optname;
1437+ int show_val;
1438+ } *p;
1439+ struct optname_item optname_entries[] = {
1440+ { SOL_SOCKET, SO_DEBUG, "SO_DEBUG", 0 },
1441+ { SOL_SOCKET, SO_REUSEADDR, "SO_REUSEADDR", 0 },
1442+ { SOL_SOCKET, SO_DONTROUTE, "SO_DONTROUTE", 0 },
1443+ { SOL_SOCKET, SO_BROADCAST, "SO_BROADCAST", 0 },
1444+ { SOL_SOCKET, SO_KEEPALIVE, "SO_KEEPALIVE", 0 },
1445+ { SOL_SOCKET, SO_OOBINLINE, "SO_OOBINLINE", 0 },
1446+ { SOL_SOCKET, SO_PASSCRED, "SO_PASSCRED", 0 },
1447+/* { SOL_SOCKET, SO_SNDLOWAT, "SO_SNDLOWAT", 0 },*/
1448+ { SOL_SOCKET, SO_TYPE, "SO_TYPE", 1 },
1449+ { SOL_SOCKET, SO_ERROR, "SO_ERROR", 1 },
1450+ { SOL_SOCKET, SO_SNDBUF, "SO_SNDBUF", 1 },
1451+ { SOL_SOCKET, SO_RCVBUF, "SO_RCVBUF", 1 },
1452+ { SOL_SOCKET, SO_NO_CHECK, "SO_NO_CHECK", 1 },
1453+ { SOL_TCP, TCP_NODELAY, "TCP_NODELAY", 0 },
1454+ { 0, 0, NULL, 0 },
1455+ };
1456+
1457+ for (p = optname_entries; p->optname; ++p) {
1458+ optlen = sizeof(optval);
1459+ ret = kernel_getsockopt(sock, p->optfam, p->optnum, (char *)&optval, &optlen);
1460+ if (ret == 0 && optval != 0) {
1461+ if (!p->show_val)
1462+ snprintf(str, MAXSTRINGLEN, "%s,", p->optname);
1463+ else
1464+ snprintf(str, MAXSTRINGLEN, "%s(%d),", p->optname, optval);
1465+ strcat(THIS->__retvalue, str);
1466+ }
1467+ }
1468+
1469+ optlen = sizeof(ling);
1470+ ret = kernel_getsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&ling, &optlen);
1471+ if (ret == 0 && ling.l_onoff != 0) {
1472+ snprintf(str, MAXSTRINGLEN, "SO_LINGER(%d),", ling.l_linger);
1473+ strcat(THIS->__retvalue, str);
1474+ }
1475+
1476+ THIS->__retvalue[strlen(THIS->__retvalue) - 1] = '\0';
1477+ CATCH_DEREF_FAULT();
1478+%}
1479+
1480+function socket_family:long (sock:long) %{ /* pure */
1481+ struct socket *sock = (struct socket *)((long)THIS->sock);
1482+ THIS->__retvalue = (long)kread(&sock->ops->family);
1483+ CATCH_DEREF_FAULT();
1484+%}
1485+
1486+function socket_unix_sockname:string (sock:long) %{ /* pure */
1487+ struct socket *sock = (struct socket *)((long)THIS->sock);
1488+ struct sockaddr_un un_addr;
1489+ int err, len;
1490+
1491+ err = sock->ops->getname(sock, (struct sockaddr *)(&un_addr), &len, 0);
1492+// err = kernel_getsockname(kread(&sock), (struct sockaddr *)(&un_addr), &len);
1493+ if (!err) {
1494+ if (kread(&un_addr.sun_path[0]) != 0)
1495+ snprintf(THIS->__retvalue, MAXSTRINGLEN,
1496+ " sockname: AF_UNIX %s", un_addr.sun_path);
1497+ else
1498+ snprintf(THIS->__retvalue, MAXSTRINGLEN, " sockname: AF_UNIX");
1499+ }
1500+ CATCH_DEREF_FAULT();
1501+%}
1502+
1503+function socket_unix_peername:string (sock:long) %{ /* pure */
1504+ struct socket *sock = (struct socket *)((long)THIS->sock);
1505+ struct sockaddr_un un_addr;
1506+ int err, len;
1507+
1508+ err = sock->ops->getname(sock, (struct sockaddr *)(&un_addr), &len, 1);
1509+// err = kernel_getpeername(kread(&sock), (struct sockaddr *)(&un_addr), &len);
1510+ if (!err) {
1511+ if (kread(&un_addr.sun_path[0]) != 0)
1512+ snprintf(THIS->__retvalue, MAXSTRINGLEN,
1513+ " peername: AF_UNIX %s", un_addr.sun_path);
1514+ else
1515+ snprintf(THIS->__retvalue, MAXSTRINGLEN, " peername: AF_UNIX");
1516+ }
1517+ CATCH_DEREF_FAULT();
1518+%}
1519+
1520+function socket_ipv4_sockname:string (sock:long) %{ /* pure */
1521+ struct socket *sock = (struct socket *)((long)THIS->sock);
1522+ struct sockaddr_in in_addr;
1523+ __be32 addr, port;
1524+ int err, len;
1525+
1526+ err = sock->ops->getname (sock, (struct sockaddr*)(&in_addr), &len, 0);
1527+ if (!err) {
1528+ addr = kread(&in_addr.sin_addr.s_addr);
1529+ port = htons(kread(&in_addr.sin_port));
1530+ snprintf(THIS->__retvalue, MAXSTRINGLEN,
1531+ " sockname: AF_INET " NIPQUAD_FMT " port: %d",
1532+ NIPQUAD(addr), port);
1533+ }
1534+ CATCH_DEREF_FAULT();
1535+%}
1536+
1537+function socket_ipv4_peername:string (sock:long) %{ /* pure */
1538+ struct socket *sock = (struct socket *)((long)THIS->sock);
1539+ struct sockaddr_in in_addr;
1540+ __be32 addr, port;
1541+ int err, len;
1542+
1543+ err = sock->ops->getname (sock, (struct sockaddr*)(&in_addr), &len, 1);
1544+ if (!err) {
1545+ addr = kread(&in_addr.sin_addr.s_addr);
1546+ port = htons(kread(&in_addr.sin_port));
1547+ snprintf(THIS->__retvalue, MAXSTRINGLEN,
1548+ " peername: AF_INET " NIPQUAD_FMT " port: %d",
1549+ NIPQUAD(addr), port);
1550+ }
1551+ CATCH_DEREF_FAULT();
1552+%}
1553+
1554+%{
1555+#ifndef NIP6_FMT
1556+#define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
1557+#endif
1558+#ifndef NIP6
1559+#define NIP6(addr) \
1560+ ntohs((addr).s6_addr16[0]), \
1561+ ntohs((addr).s6_addr16[1]), \
1562+ ntohs((addr).s6_addr16[2]), \
1563+ ntohs((addr).s6_addr16[3]), \
1564+ ntohs((addr).s6_addr16[4]), \
1565+ ntohs((addr).s6_addr16[5]), \
1566+ ntohs((addr).s6_addr16[6]), \
1567+ ntohs((addr).s6_addr16[7])
1568+#endif
1569+
1570+%}
1571+
1572+function socket_ipv6_sockname:string (sock:long) %{ /* pure */
1573+ struct socket *sock = (struct socket *)((long)THIS->sock);
1574+ struct sockaddr_in6 in_addr;
1575+ __be32 port;
1576+ int err, len;
1577+
1578+ err = sock->ops->getname (sock, (struct sockaddr*)(&in_addr), &len, 0);
1579+ if (!err) {
1580+ port = htons(kread(&in_addr.sin6_port));
1581+ snprintf(THIS->__retvalue, MAXSTRINGLEN,
1582+ " sockname: AF_INET6 " NIP6_FMT " port: %d",
1583+ NIP6(in_addr.sin6_addr), port);
1584+ }
1585+ CATCH_DEREF_FAULT();
1586+%}
1587+
1588+function socket_ipv6_peername:string (sock:long) %{ /* pure */
1589+ struct socket *sock = (struct socket *)((long)THIS->sock);
1590+ struct sockaddr_in6 in_addr;
1591+ __be32 port;
1592+ int err, len;
1593+
1594+ err = sock->ops->getname (sock, (struct sockaddr*)(&in_addr), &len, 1);
1595+ if (!err) {
1596+ port = htons(kread(&in_addr.sin6_port));
1597+ snprintf(THIS->__retvalue, MAXSTRINGLEN,
1598+ " peername: AF_INET6 " NIP6_FMT " port: %d",
1599+ NIP6(in_addr.sin6_addr), port);
1600+ }
1601+ CATCH_DEREF_FAULT();
1602+%}
1603+
1604+function print_file_handle_general(task, fd) {
1605+ printf("%4d: %s mode:%04o dev:%s ino:%d uid:%d gid:%d rdev:%s\n",
1606+ fd, i_mode2str(task_file_handle_i_mode(task, fd)),
1607+ task_file_handle_i_mode(task, fd) & 0777,
1608+ task_file_handle_majmin_dev(task, fd),
1609+ task_file_handle_i_node(task, fd),
1610+ task_file_handle_uid(task, fd),
1611+ task_file_handle_gid(task, fd),
1612+ task_file_handle_majmin_rdev(task, fd));
1613+}
1614+
1615+function print_file_handle_flags(task, fd) {
1616+ printf(" %s %s\n",
1617+ _sys_open_flag_str(task_file_handle_f_flags(task, fd)),
1618+ task_file_handle_fd_flags(task, fd));
1619+}
1620+
1621+function print_file_handle_flock(task, fd) {
1622+ flock = task_file_handle_flock(task, fd)
1623+ if (!isinstr(flock, "NULL"))
1624+ printf("%s\n", flock)
1625+}
1626+
1627+function print_file_handle_d_path(task, fd) {
1628+ printf(" %s\n", task_file_handle_d_path(task, fd))
1629+}
1630+
1631+function print_socket_userlocks(sock) {
1632+ slocks = socket_userlocks(sock)
1633+ if (strlen(slocks) > 0)
1634+ printf(" %s\n", slocks)
1635+}
1636+
1637+function print_unix_socket(sock) {
1638+ sockname = socket_unix_sockname(sock)
1639+ peername = socket_unix_peername(sock)
1640+ printf("%s%s", strlen(sockname) > 0 ? sockname . "\n" : "",
1641+ strlen(peername) > 0 ? peername . "\n" : "")
1642+}
1643+
1644+function print_ipv4_socket(sock) {
1645+ sockname = socket_ipv4_sockname(sock)
1646+ peername = socket_ipv4_peername(sock)
1647+ printf("%s%s", strlen(sockname) > 0 ? sockname . "\n" : "",
1648+ strlen(peername) > 0 ? peername . "\n" : "")
1649+}
1650+
1651+function print_ipv6_socket(sock) {
1652+ sockname = socket_ipv6_sockname(sock)
1653+ peername = socket_ipv6_peername(sock)
1654+ printf("%s%s", strlen(sockname) > 0 ? sockname . "\n" : "",
1655+ strlen(peername) > 0 ? peername . "\n" : "")
1656+}
1657+
1658+function print_socket_optname(sock) {
1659+ str = socket_optname(sock)
1660+ printf(" %s", strlen(str) > 0 ? str . "\n" : "")
1661+}
1662+
1663+probe begin {
1664+%( $# < 1
1665+ %? pid = target()
1666+ %: pid = $1
1667+%)
1668+ # if (pid == 0) error ("Please provide valid target process-id as $1 or -x PID");
1669+ task = pid2task(pid)
1670+ if (task == 0) error (sprintf("Process-id %d is invalid, please provide valid PID as $1 or -x PID", pid))
1671+
1672+ max_fds = task_max_file_handles(task)
1673+
1674+ printf("%6d: %s\n", pid, pid2execname(pid))
1675+ printf(" Current rlimit: %d file descriptors\n", max_fds)
1676+
1677+ for (fd = 0; fd < max_fds; fd++) {
1678+ if (task_valid_file_handle(task, fd)) {
1679+ print_file_handle_general(task, fd)
1680+ print_file_handle_flags(task, fd)
1681+ print_file_handle_flock(task, fd)
1682+ print_file_handle_d_path(task, fd)
1683+ sock = task_file_handle_socket(task, fd)
1684+ if (sock) {
1685+ print_socket_optname(sock)
1686+ fam = socket_family(sock)
1687+ if (fam == 1) { /* AF_UNIX */
1688+ print_unix_socket(sock)
1689+ } else if (fam == 2) { /* AF_INET */
1690+ print_ipv4_socket(sock)
1691+ } else if (fam == 10) { /* AF_INET6 */
1692+ print_ipv6_socket(sock)
1693+ }
1694+ print_socket_userlocks(sock)
1695+ }
1696+ }
1697+ }
1698+
1699+ exit()
1700+}
1701
1702=== added directory '.pc/Updated-__ip_sock_daddr-for-2.6.38-kernels.patch'
1703=== added directory '.pc/Updated-__ip_sock_daddr-for-2.6.38-kernels.patch/tapset'
1704=== added file '.pc/Updated-__ip_sock_daddr-for-2.6.38-kernels.patch/tapset/ip.stp'
1705--- .pc/Updated-__ip_sock_daddr-for-2.6.38-kernels.patch/tapset/ip.stp 1970-01-01 00:00:00 +0000
1706+++ .pc/Updated-__ip_sock_daddr-for-2.6.38-kernels.patch/tapset/ip.stp 2011-03-22 12:11:00 +0000
1707@@ -0,0 +1,96 @@
1708+// IP tapset
1709+//
1710+// Copyright (C) 2009, IBM Inc.
1711+// Copyright (C) 2010, Red Hat Inc.
1712+//
1713+// Author : Breno Leitao <leitao@linux.vnet.ibm.com>
1714+//
1715+// This file is free software. You can redistribute it and/or modify it under
1716+// the terms of the GNU General Public License (GPL), version 2.
1717+//
1718+// Based on previous work done by Arnaldo Carvalho de Melo <acme@redhat.com>
1719+
1720+%{
1721+#include <linux/skbuff.h>
1722+#ifndef NIPQUAD
1723+#define NIPQUAD(addr) \
1724+ ((unsigned char *)&addr)[0], \
1725+ ((unsigned char *)&addr)[1], \
1726+ ((unsigned char *)&addr)[2], \
1727+ ((unsigned char *)&addr)[3]
1728+#endif
1729+#ifndef NIPQUAD_FMT
1730+#define NIPQUAD_FMT "%u.%u.%u.%u"
1731+#endif
1732+%}
1733+
1734+/**
1735+ * sfunction ip_ntop - returns a string representation from an integer IP number
1736+ * @addr: the ip represented as an integer
1737+ */
1738+function ip_ntop:string (addr:long)
1739+%{
1740+ __be32 ip;
1741+
1742+ ip = THIS->addr;
1743+ snprintf(THIS->__retvalue, MAXSTRINGLEN, NIPQUAD_FMT, NIPQUAD(ip));
1744+%}
1745+
1746+/* return the source IP address for a given sock */
1747+function __ip_sock_saddr:long (sock:long)
1748+{
1749+ return (@defined(@cast(sock, "inet_sock")->inet_saddr)
1750+ ? @cast(sock, "inet_sock")->inet_saddr # kernel >= 2.6.33
1751+ : (@defined(@cast(sock, "inet_sock")->saddr)
1752+ ? @cast(sock, "inet_sock", "kernel")->saddr # kernel >= 2.6.11
1753+ : @cast(sock, "inet_sock", "kernel<net/ip.h>")->inet->saddr))
1754+}
1755+
1756+/* return the destination IP address for a given sock */
1757+function __ip_sock_daddr:long (sock:long)
1758+{
1759+ return (@defined(@cast(sock, "inet_sock")->inet_daddr)
1760+ ? @cast(sock, "inet_sock")->inet_daddr # kernel >= 2.6.33
1761+ : (@defined(@cast(sock, "inet_sock")->daddr)
1762+ ? @cast(sock, "inet_sock", "kernel")->daddr # kernel >= 2.6.11
1763+ : @cast(sock, "inet_sock", "kernel<net/ip.h>")->inet->daddr))
1764+}
1765+
1766+/* Get the IP header from a sk_buff struct */
1767+function __get_skb_iphdr:long(skb:long)
1768+%( kernel_v < "2.6.21" %?
1769+{
1770+ iphdr = @cast(skb, "sk_buff")->nh->raw
1771+ return iphdr
1772+}
1773+%:
1774+%{ /* pure */
1775+ struct sk_buff *skb;
1776+ skb = (struct sk_buff *)(long)THIS->skb;
1777+ /* as done by skb_network_header() */
1778+ #ifdef NET_SKBUFF_DATA_USES_OFFSET
1779+ THIS->__retvalue = (long)(kread(&(skb->head)) + kread(&(skb->network_header)));
1780+ #else
1781+ THIS->__retvalue = (long)kread(&(skb->network_header));
1782+ #endif
1783+ CATCH_DEREF_FAULT();
1784+%}
1785+%)
1786+
1787+/* return the source next layer protocol for a given sk_buff structure */
1788+function __ip_skb_proto:long (iphdr)
1789+{
1790+ return @cast(iphdr, "iphdr")->protocol
1791+}
1792+
1793+/* return the source IP address for a given sk_buff structure */
1794+function __ip_skb_saddr:long (iphdr)
1795+{
1796+ return @cast(iphdr, "iphdr")->saddr
1797+}
1798+
1799+/* return the destination IP address for a given skb */
1800+function __ip_skb_daddr:long (iphdr)
1801+{
1802+ return @cast(iphdr, "iphdr")->daddr
1803+}
1804
1805=== added directory '.pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch'
1806=== added directory '.pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset'
1807=== added file '.pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/memory.stp'
1808--- .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/memory.stp 1970-01-01 00:00:00 +0000
1809+++ .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/memory.stp 2011-03-22 12:11:00 +0000
1810@@ -0,0 +1,635 @@
1811+// memory/vm related tapset
1812+// Copyright (C) 2005, 2006 IBM Corp.
1813+// Copyright (C) 2006 Intel Corporation.
1814+// Copyright (C) 2010 Red Hat Inc.
1815+//
1816+// This file is part of systemtap, and is free software. You can
1817+// redistribute it and/or modify it under the terms of the GNU General
1818+// Public License (GPL); either version 2, or (at your option) any
1819+// later version.
1820+// <tapsetdescription>
1821+// This family of probe points is used to probe memory-related events.
1822+// </tapsetdescription>
1823+%{
1824+#include <linux/mm.h>
1825+%}
1826+
1827+global VM_FAULT_OOM=0, VM_FAULT_SIGBUS=1, VM_FAULT_MINOR=2, VM_FAULT_MAJOR=3
1828+global VM_FAULT_NOPAGE=4, VM_FAULT_LOCKED=5, VM_FAULT_ERROR=6
1829+global FAULT_FLAG_WRITE=1
1830+
1831+/**
1832+ * sfunction vm_fault_contains - Test return value for page fault reason
1833+ * @value: The fault_type returned by vm.page_fault.return
1834+ * @test: The type of fault to test for (VM_FAULT_OOM or similar)
1835+ */
1836+function vm_fault_contains:long (value:long, test:long)
1837+%{
1838+ int res;
1839+ switch (THIS->test){
1840+ case 0: res = THIS->value & VM_FAULT_OOM; break;
1841+ case 1: res = THIS->value & VM_FAULT_SIGBUS; break;
1842+#if defined(VM_FAULT_MINOR) && VM_FAULT_MINOR != 0
1843+ case 2: /* VM_FAULT_MINOR infered by that flags off */
1844+ res = !((VM_FAULT_OOM | VM_FAULT_SIGBUS | VM_FAULT_MAJOR) &
1845+ THIS->value);
1846+ break;
1847+#else
1848+ case 2: res = THIS->value == VM_FAULT_MINOR; break;
1849+#endif
1850+ case 3: res = THIS->value & VM_FAULT_MAJOR; break;
1851+#ifdef VM_FAULT_NOPAGE
1852+ case 4: res = THIS->value & VM_FAULT_NOPAGE; break;
1853+#endif
1854+#ifdef VM_FAULT_LOCKED
1855+ case 5: res = THIS->value & VM_FAULT_LOCKED; break;
1856+#endif
1857+#ifdef VM_FAULT_ERROR
1858+ case 6: res = THIS->value & VM_FAULT_ERROR; break;
1859+#endif
1860+ default: res = 0; break;
1861+ }
1862+ THIS->__retvalue = (res != 0);
1863+ return;
1864+%}
1865+
1866+/**
1867+ * probe vm.pagefault - Records that a page fault occurred.
1868+ * @name: Name of the probe point
1869+ * @address: The address of the faulting memory access; i.e. the address that caused the page fault.
1870+ * @write_access: Indicates whether this was a write or read access; 1 indicates a write,
1871+ * while 0 indicates a read.
1872+ *
1873+ * Context: The process which triggered the fault
1874+ */
1875+probe vm.pagefault = kernel.function("__handle_mm_fault@mm/memory.c") ?,
1876+ kernel.function("handle_mm_fault@mm/memory.c") ?
1877+{
1878+ name = "pagefault"
1879+ write_access = (@defined($flags)
1880+ ? $flags & FAULT_FLAG_WRITE : $write_access)
1881+ address = $address
1882+}
1883+
1884+/**
1885+ * probe vm.pagefault.return - Indicates what type of fault occurred.
1886+ * @name: Name of the probe point
1887+ * @fault_type: Returns either
1888+ * 0 (VM_FAULT_OOM) for out of memory faults,
1889+ * 2 (VM_FAULT_MINOR) for minor faults, 3 (VM_FAULT_MAJOR) for
1890+ * major faults, or 1 (VM_FAULT_SIGBUS) if the fault was neither OOM, minor fault,
1891+ * nor major fault.
1892+ */
1893+probe vm.pagefault.return =
1894+ kernel.function("__handle_mm_fault@mm/memory.c").return ?,
1895+ kernel.function("handle_mm_fault@mm/memory.c").return ?
1896+{
1897+ name = "pagefault"
1898+ fault_type = $return
1899+}
1900+
1901+/**
1902+ * sfunction addr_to_node - Returns which node a given address belongs to within a NUMA system.
1903+ *
1904+ * General Syntax: addr_to_node:long(addr:long)
1905+ *
1906+ * @addr: The address of the faulting memory access.
1907+ *
1908+ * Description: This function accepts an address, and returns the
1909+ * node that the given address belongs to in a NUMA system.
1910+ */
1911+function addr_to_node:long(addr:long) %{ /* pure */
1912+ int pfn = __pa(THIS->addr) >> PAGE_SHIFT;
1913+ int nid;
1914+#ifdef for_each_online_node
1915+ for_each_online_node(nid)
1916+#else
1917+ for (nid=0; nid<MAX_NUMNODES; nid++) /* if (node_online(nid)) */
1918+#endif
1919+ if ( NODE_DATA(nid)->node_start_pfn <= pfn &&
1920+ pfn < (NODE_DATA(nid)->node_start_pfn +
1921+ NODE_DATA(nid)->node_spanned_pages) )
1922+ {
1923+ THIS->__retvalue = nid;
1924+ break;
1925+ }
1926+%}
1927+
1928+// Return whether a page to be copied is a zero page.
1929+function _IS_ZERO_PAGE:long(from:long, vaddr:long) %{ /* pure */
1930+ THIS->__retvalue = (THIS->from == (long) ZERO_PAGE(THIS->vaddr));
1931+%}
1932+
1933+
1934+/**
1935+ * probe vm.write_shared - Attempts at writing to a shared page.
1936+ * @name: Name of the probe point
1937+ * @address: The address of the shared write.
1938+ *
1939+ * Context:
1940+ * The context is the process attempting the write.
1941+ *
1942+ * Fires when a process attempts to write to a shared page.
1943+ * If a copy is necessary, this will be followed by a
1944+ * vm.write_shared_copy.
1945+ */
1946+probe vm.write_shared = kernel.function("do_wp_page") {
1947+ name = "write_shared"
1948+ address = $address
1949+}
1950+
1951+/**
1952+ * probe vm.write_shared_copy - Page copy for shared page write.
1953+ * @name: Name of the probe point
1954+ * @address: The address of the shared write.
1955+ * @zero: Boolean indicating whether it is a zero page
1956+ * (can do a clear instead of a copy).
1957+ *
1958+ * Context:
1959+ * The process attempting the write.
1960+ *
1961+ * Fires when a write to a shared page requires a page copy. This is
1962+ * always preceded by a vm.shared_write.
1963+ */
1964+probe vm.write_shared_copy = kernel.function("copy_cow_page") ?
1965+{
1966+ name = "write_shared_copy"
1967+ address = $address
1968+ zero = _IS_ZERO_PAGE($from, $address);
1969+}
1970+
1971+
1972+/**
1973+ * probe vm.mmap - Fires when an mmap is requested.
1974+ * @name: Name of the probe point
1975+ * @address: The requested address
1976+ * @length: The length of the memory segment
1977+ *
1978+ * Context:
1979+ * The process calling mmap.
1980+ */
1981+probe vm.mmap = kernel.function("do_mmap"), kernel.function("do_mmap2") ?
1982+{
1983+ name = "mmap"
1984+ address = $addr
1985+ length = $len
1986+}
1987+
1988+
1989+/**
1990+ * probe vm.munmap - Fires when an munmap is requested.
1991+ * @name: Name of the probe point
1992+ * @address: The requested address
1993+ * @length: The length of the memory segment
1994+ *
1995+ * Context:
1996+ * The process calling munmap.
1997+ */
1998+probe vm.munmap = kernel.function("do_munmap") {
1999+ name = "munmap"
2000+ address = $start
2001+ length = $len
2002+}
2003+
2004+/**
2005+ * probe vm.brk - Fires when a brk is requested (i.e. the heap will be resized).
2006+ * @name: Name of the probe point
2007+ * @address: The requested address
2008+ * @length: The length of the memory segment
2009+ *
2010+ * Context:
2011+ * The process calling brk.
2012+ */
2013+probe vm.brk = kernel.function("do_brk") {
2014+ name = "brk"
2015+ address = $addr
2016+ length = $len
2017+}
2018+
2019+/**
2020+ * probe vm.oom_kill - Fires when a thread is selected for termination by the OOM killer.
2021+ * @name: Name of the probe point
2022+ * @task: The task being killed
2023+ *
2024+ * Context:
2025+ * The process that tried to consume excessive memory, and thus
2026+ * triggered the OOM.
2027+ */
2028+probe vm.oom_kill = kernel.function("__oom_kill_task")
2029+{
2030+ name = "oom_kill"
2031+ task = $p
2032+}
2033+
2034+function GFP_KERNEL:long()
2035+%{ /* pure */ /* unprivileged */
2036+ THIS->__retvalue = GFP_KERNEL;
2037+%}
2038+
2039+function __gfp_flag_str:string(gfp_flag:long)
2040+%{
2041+ long gfp_flag = THIS->gfp_flag;
2042+ THIS->__retvalue[0] = '\0';
2043+
2044+/* Older kernels < 2.6.32 didn't have some of these GFP defines yet. */
2045+#ifndef __GFP_DMA32
2046+#define __GFP_DMA32 ((__force gfp_t)0x04u)
2047+#endif
2048+#ifndef GFP_DMA32
2049+#define GFP_DMA32 __GFP_DMA32
2050+#endif
2051+
2052+#ifndef __GFP_MOVABLE
2053+#define __GFP_MOVABLE ((__force gfp_t)0x08u) /* Page is movable */
2054+#endif
2055+
2056+#ifndef GFP_ZONEMASK
2057+#define GFP_ZONEMASK (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE)
2058+#endif
2059+
2060+#ifndef __GFP_NOTRACK
2061+#ifdef CONFIG_KMEMCHECK
2062+#define __GFP_NOTRACK ((__force gfp_t)0x200000u) /* Don't track with kmemcheck */
2063+#else
2064+#define __GFP_NOTRACK ((__force gfp_t)0)
2065+#endif
2066+#endif
2067+
2068+#ifndef __GFP_THISNODE
2069+#define __GFP_THISNODE ((__force gfp_t)0x40000u)
2070+#endif
2071+
2072+#ifndef __GFP_RECLAIMABLE
2073+#define __GFP_RECLAIMABLE ((__force gfp_t)0x80000u)
2074+#endif
2075+
2076+#ifndef __GFP_ZERO
2077+#define __GFP_ZERO ((__force gfp_t)0x8000u)
2078+#endif
2079+
2080+#ifndef __GFP_NOMEMALLOC
2081+#define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u)
2082+#endif
2083+
2084+#ifndef __GFP_HARDWALL
2085+#define __GFP_HARDWALL ((__force gfp_t)0x20000u)
2086+#endif
2087+
2088+#ifndef GFP_TEMPORARY
2089+#define GFP_TEMPORARY (__GFP_WAIT | __GFP_IO | __GFP_FS | \
2090+ __GFP_RECLAIMABLE)
2091+#endif
2092+
2093+#ifndef GFP_HIGHUSER_MOVABLE
2094+#define GFP_HIGHUSER_MOVABLE (__GFP_WAIT | __GFP_IO | __GFP_FS | \
2095+ __GFP_HARDWALL | __GFP_HIGHMEM | \
2096+ __GFP_MOVABLE)
2097+#endif
2098+
2099+#ifndef GFP_THISNODE
2100+#ifdef CONFIG_NUMA
2101+#define GFP_THISNODE (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY)
2102+#else
2103+#define GFP_THISNODE ((__force gfp_t)0)
2104+#endif
2105+#endif
2106+
2107+/* Macro for GFP Bitmasks. */
2108+/* The resulted GFP_FLAGS may be either single or concatenation of the multiple bitmasks. */
2109+
2110+
2111+#define __GFP_BITMASKS(FLAG) if(gfp_flag & FLAG) { if(THIS->__retvalue[0] != '\0') \
2112+ strlcat(THIS->__retvalue, " | "#FLAG, MAXSTRINGLEN); \
2113+ else strlcat(THIS->__retvalue, #FLAG, MAXSTRINGLEN); }
2114+
2115+
2116+/* Macro for Composite Flags. */
2117+/* Each Composite GFP_FLAG is the combination of multiple bitmasks. */
2118+
2119+
2120+#define __GFP_COMPOSITE_FLAG(FLAG) if(gfp_flag == FLAG) { \
2121+ strlcat(THIS->__retvalue, #FLAG, MAXSTRINGLEN); return; }
2122+
2123+
2124+/* Composite GFP FLAGS of the BitMasks. */
2125+
2126+ __GFP_COMPOSITE_FLAG(GFP_ZONEMASK)
2127+ __GFP_COMPOSITE_FLAG(GFP_ATOMIC)
2128+ __GFP_COMPOSITE_FLAG(GFP_NOIO)
2129+ __GFP_COMPOSITE_FLAG(GFP_NOFS)
2130+ __GFP_COMPOSITE_FLAG(GFP_KERNEL)
2131+ __GFP_COMPOSITE_FLAG(GFP_TEMPORARY)
2132+ __GFP_COMPOSITE_FLAG(GFP_USER)
2133+ __GFP_COMPOSITE_FLAG(GFP_HIGHUSER)
2134+ __GFP_COMPOSITE_FLAG(GFP_HIGHUSER_MOVABLE)
2135+ __GFP_COMPOSITE_FLAG(GFP_THISNODE)
2136+ __GFP_COMPOSITE_FLAG(GFP_DMA)
2137+ __GFP_COMPOSITE_FLAG(GFP_DMA32)
2138+
2139+/* GFP BitMasks */
2140+
2141+ __GFP_BITMASKS(__GFP_DMA)
2142+ __GFP_BITMASKS(__GFP_HIGHMEM)
2143+ __GFP_BITMASKS(__GFP_MOVABLE)
2144+ __GFP_BITMASKS(__GFP_WAIT)
2145+ __GFP_BITMASKS(__GFP_HIGH)
2146+ __GFP_BITMASKS(__GFP_IO)
2147+ __GFP_BITMASKS(__GFP_FS)
2148+ __GFP_BITMASKS(__GFP_COLD)
2149+ __GFP_BITMASKS(__GFP_NOWARN)
2150+ __GFP_BITMASKS(__GFP_REPEAT)
2151+ __GFP_BITMASKS(__GFP_NOFAIL)
2152+ __GFP_BITMASKS(__GFP_COMP)
2153+ __GFP_BITMASKS(__GFP_ZERO)
2154+ __GFP_BITMASKS(__GFP_NOMEMALLOC)
2155+ __GFP_BITMASKS(__GFP_HARDWALL)
2156+ __GFP_BITMASKS(__GFP_THISNODE)
2157+ __GFP_BITMASKS(__GFP_RECLAIMABLE)
2158+ __GFP_BITMASKS(__GFP_NOTRACK)
2159+
2160+
2161+#undef __GFP_BITMASKS
2162+#undef __GFP_COMPOSITE_FLAG
2163+%}
2164+
2165+/* The Formal Parameters will be displayed if available, otherwise \
2166+ "0" or "unknown" will be displayed */
2167+
2168+probe __vm.kmalloc.tp = kernel.trace("kmalloc")
2169+{
2170+ call_site = $call_site
2171+ caller_function = symname(call_site)
2172+ bytes_req = $bytes_req
2173+ bytes_alloc = $bytes_alloc
2174+ gfp_flags = $gfp_flags
2175+ gfp_flag_name = __gfp_flag_str($gfp_flags)
2176+ ptr = $ptr
2177+}
2178+
2179+/*
2180+ * It is unsafe to invoke __builtin_return_address() presently (to get
2181+ * call_site for kprobe based probes) and that it can be improved
2182+ * later when fix for bugs bz#6961 and bz#6580 is available.
2183+ */
2184+
2185+probe __vm.kmalloc.kp = kernel.function("kmem_cache_alloc_notrace").return !,
2186+ kernel.function("kmem_cache_alloc").return
2187+{
2188+ call_site = 0
2189+ caller_function = "unknown"
2190+ // Note that 'bytes_req' could be wrong. By the time
2191+ // kmem_cache_alloc* gets called the requested size could have
2192+ // rounded up to the nearest cache alloc size.
2193+ if (@defined($s)) {
2194+ bytes_req = $s->size
2195+ bytes_alloc = $s->size
2196+ }
2197+ else if (@defined($cachep->buffer_size)) {
2198+ bytes_req = $cachep->buffer_size
2199+ bytes_alloc = $cachep->buffer_size
2200+ }
2201+ else {
2202+ bytes_req = $cachep->objsize
2203+ bytes_alloc = $cachep->objsize
2204+ }
2205+ if (@defined($gfpflags)) {
2206+ gfp_flags = $gfpflags
2207+ gfp_flag_name = __gfp_flag_str($gfpflags)
2208+ }
2209+ else {
2210+ gfp_flags = $flags
2211+ gfp_flag_name = __gfp_flag_str($flags)
2212+ }
2213+ ptr = $return
2214+}
2215+
2216+/**
2217+ * probe vm.kmalloc - Fires when kmalloc is requested.
2218+ * @name: Name of the probe point
2219+ * @call_site: Address of the kmemory function.
2220+ * @caller_function: Name of the caller function.
2221+ * @bytes_req: Requested Bytes
2222+ * @bytes_alloc: Allocated Bytes
2223+ * @gfp_flags: type of kmemory to allocate
2224+ * @gfp_flag_name: type of kmemory to allocate (in String format)
2225+ * @ptr: Pointer to the kmemory allocated
2226+ */
2227+probe vm.kmalloc = __vm.kmalloc.tp !, __vm.kmalloc.kp
2228+{
2229+ name = "kmalloc"
2230+}
2231+
2232+
2233+probe __vm.kmem_cache_alloc.tp = kernel.trace("kmem_cache_alloc")
2234+{
2235+ call_site = $call_site
2236+ caller_function = symname(call_site)
2237+ bytes_req = $bytes_req
2238+ bytes_alloc = $bytes_alloc
2239+ gfp_flags = $gfp_flags
2240+ gfp_flag_name = __gfp_flag_str($gfp_flags)
2241+ ptr = $ptr
2242+}
2243+
2244+probe __vm.kmem_cache_alloc.kp = kernel.function("kmem_cache_alloc").return
2245+{
2246+ call_site = 0
2247+ caller_function = "unknown"
2248+ // Note that 'bytes_req' could be wrong. By the time
2249+ // kmem_cache_alloc* gets called the requested size could have
2250+ // rounded up to the nearest cache alloc size.
2251+ if (@defined($s)) {
2252+ bytes_req = $s->size
2253+ bytes_alloc = $s->size
2254+ }
2255+ else if (@defined($cachep->buffer_size)) {
2256+ bytes_req = $cachep->buffer_size
2257+ bytes_alloc = $cachep->buffer_size
2258+ }
2259+ else {
2260+ bytes_req = $cachep->objsize
2261+ bytes_alloc = $cachep->objsize
2262+ }
2263+ if (@defined($gfpflags)) {
2264+ gfp_flags = $gfpflags
2265+ gfp_flag_name = __gfp_flag_str($gfpflags)
2266+ }
2267+ else {
2268+ gfp_flags = $flags
2269+ gfp_flag_name = __gfp_flag_str($flags)
2270+ }
2271+ ptr = $return
2272+}
2273+
2274+/**
2275+ * probe vm.kmem_cache_alloc - Fires when \
2276+ * kmem_cache_alloc is requested.
2277+ * @name: Name of the probe point
2278+ * @call_site: Address of the function calling this kmemory function.
2279+ * @caller_function: Name of the caller function.
2280+ * @bytes_req: Requested Bytes
2281+ * @bytes_alloc: Allocated Bytes
2282+ * @gfp_flags: type of kmemory to allocate
2283+ * @gfp_flag_name: Type of kmemory to allocate(in string format)
2284+ * @ptr: Pointer to the kmemory allocated
2285+ */
2286+
2287+probe vm.kmem_cache_alloc = __vm.kmem_cache_alloc.tp !,
2288+ __vm.kmem_cache_alloc.kp
2289+{
2290+ name = "kmem_cache_alloc"
2291+}
2292+
2293+probe __vm.kmalloc_node.tp = kernel.trace("kmalloc_node") ?
2294+{
2295+ call_site = $call_site
2296+ caller_function = symname(call_site)
2297+ bytes_req = $bytes_req
2298+ bytes_alloc = $bytes_alloc
2299+ gfp_flags = $gfp_flags
2300+ gfp_flag_name = __gfp_flag_str($gfp_flags)
2301+ ptr = $ptr
2302+}
2303+
2304+probe __vm.kmalloc_node.kp = kernel.function("kmalloc_node").return ?
2305+{
2306+ call_site = 0
2307+ caller_function = "unknown"
2308+ bytes_req = $size
2309+ bytes_alloc = bytes_req // pretend they are always the same
2310+
2311+ # Unfortunately, on i686 f11 (2.6.29.4-167.fc11.i686.PAE), we
2312+ # can't see the '$flags' argument (even though we can see the
2313+ # '$size' argument above). Note that we can see the '$flags'
2314+ # argument on x86_64 f11 (2.6.29.4-167.fc11.x86_64). So, the
2315+ # best we can do here is just use 0 when $flags isn't defined.
2316+ gfp_flags = (@defined($flags) ? $flags : 0)
2317+ gfp_flag_name = __gfp_flag_str(@defined($flags) ? $flags : 0)
2318+
2319+ ptr = $return
2320+}
2321+
2322+/**
2323+ * probe vm.kmalloc_node - Fires when kmalloc_node is requested.
2324+ * @name: Name of the probe point
2325+ * @call_site: Address of the function caling this kmemory function.
2326+ * @caller_function: Name of the caller function.
2327+ * @bytes_req: Requested Bytes
2328+ * @bytes_alloc: Allocated Bytes
2329+ * @gfp_flags: type of kmemory to allocate
2330+ * @gfp_flag_name: Type of kmemory to allocate(in string format)
2331+ * @ptr: Pointer to the kmemory allocated
2332+ */
2333+probe vm.kmalloc_node = __vm.kmalloc_node.tp !, __vm.kmalloc_node.kp ?
2334+{
2335+ name = "kmalloc_node"
2336+}
2337+
2338+probe __vm.kmem_cache_alloc_node.tp = kernel.trace("kmem_cache_alloc_node") ?
2339+{
2340+ call_site = $call_site
2341+ caller_function = symname(call_site)
2342+ bytes_req = $bytes_req
2343+ bytes_alloc = $bytes_alloc
2344+ gfp_flags = $gfp_flags
2345+ gfp_flag_name = __gfp_flag_str($gfp_flags)
2346+ ptr = $ptr
2347+}
2348+
2349+probe __vm.kmem_cache_alloc_node.kp =
2350+ kernel.function("kmem_cache_alloc_node").return ?
2351+{
2352+ call_site = 0
2353+ caller_function = "unknown"
2354+ // Note that 'bytes_req' could be wrong. By the time
2355+ // kmem_cache_alloc* gets called the requested size could have
2356+ // rounded up to the nearest cache alloc size.
2357+ if (@defined($s)) {
2358+ bytes_req = $s->size
2359+ bytes_alloc = $s->size
2360+ }
2361+ else if (@defined($cachep->buffer_size)) {
2362+ bytes_req = $cachep->buffer_size
2363+ bytes_alloc = $cachep->buffer_size
2364+ }
2365+ else {
2366+ bytes_req = $cachep->objsize
2367+ bytes_alloc = $cachep->objsize
2368+ }
2369+
2370+ // kmem_cache_alloc_node() doesn't get a flags argument. But,
2371+ // internally it uses GFP_KERNEL().
2372+ gfp_flags = GFP_KERNEL()
2373+ gfp_flag_name = __gfp_flag_str(gfp_flags)
2374+ ptr = $return
2375+}
2376+
2377+/**
2378+ * probe vm.kmem_cache_alloc_node - Fires when \
2379+ * kmem_cache_alloc_node is requested.
2380+ * @name: Name of the probe point
2381+ * @call_site: Address of the function calling this kmemory function.
2382+ * @caller_function: Name of the caller function.
2383+ * @bytes_req: Requested Bytes
2384+ * @bytes_alloc: Allocated Bytes
2385+ * @gfp_flags: type of kmemory to allocate
2386+ * @gfp_flag_name: Type of kmemory to allocate(in string format)
2387+ * @ptr: Pointer to the kmemory allocated
2388+ */
2389+probe vm.kmem_cache_alloc_node = __vm.kmem_cache_alloc_node.tp !,
2390+ __vm.kmem_cache_alloc_node.kp ?
2391+{
2392+ name = "kmem_cache_alloc_node"
2393+}
2394+
2395+probe __vm.kfree.tp = kernel.trace("kfree")
2396+{
2397+ call_site = $call_site
2398+ caller_function = symname(call_site)
2399+ ptr = $ptr
2400+}
2401+
2402+probe __vm.kfree.kp = kernel.function("kfree").return
2403+{
2404+ call_site = 0
2405+ caller_function = "unknown"
2406+ ptr = (@defined($x) ? $x : $objp)
2407+}
2408+
2409+/**
2410+ * probe vm.kfree - Fires when kfree is requested.
2411+ * @name: Name of the probe point
2412+ * @call_site: Address of the function calling this kmemory function.
2413+ * @caller_function: Name of the caller function.
2414+ * @ptr: Pointer to the kmemory allocated which is returned by kmalloc
2415+ */
2416+probe vm.kfree = __vm.kfree.tp !, __vm.kfree.kp
2417+{
2418+ name = "kfree"
2419+}
2420+
2421+probe __vm.kmem_cache_free.tp = kernel.trace("kmem_cache_free")
2422+{
2423+ call_site = $call_site
2424+ caller_function = symname(call_site)
2425+ ptr = $ptr
2426+}
2427+probe __vm.kmem_cache_free.kp = kernel.function("kmem_cache_free").return
2428+{
2429+ call_site = 0
2430+ caller_function = "unknown"
2431+ ptr = (@defined($x) ? $x : $objp)
2432+}
2433+
2434+/**
2435+ * probe vm.kmem_cache_free - Fires when \
2436+ * kmem_cache_free is requested.
2437+ * @name: Name of the probe point
2438+ * @call_site: Address of the function calling this kmemory function.
2439+ * @caller_function: Name of the caller function.
2440+ * @ptr: Pointer to the kmemory allocated which is returned by kmem_cache
2441+ */
2442+probe vm.kmem_cache_free = __vm.kmem_cache_free.tp !, __vm.kmem_cache_free.kp
2443+{
2444+ name = "kmem_cache_free"
2445+}
2446
2447=== added file '.pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/rpc.stp'
2448--- .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/rpc.stp 1970-01-01 00:00:00 +0000
2449+++ .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/rpc.stp 2011-03-22 12:11:00 +0000
2450@@ -0,0 +1,1185 @@
2451+// rpc tapset
2452+// Copyright (C) 2006 IBM Corp.
2453+// Copyright (C) 2007 Bull S.A.S
2454+// Copyright (C) 2008, 2010 Red Hat
2455+//
2456+// This file is part of systemtap, and is free software. You can
2457+// redistribute it and/or modify it under the terms of the GNU General
2458+// Public License (GPL); either version 2, or (at your option) any
2459+// later version.
2460+
2461+%{
2462+// Includes everything needed for __rpc_prot_from_protocol().
2463+#include <linux/sunrpc/clnt.h>
2464+%}
2465+
2466+probe sunrpc.entry =
2467+ sunrpc.clnt.entry,
2468+ sunrpc.svc.entry,
2469+ sunrpc.sched.entry
2470+{}
2471+
2472+probe sunrpc.return =
2473+ sunrpc.clnt.return,
2474+ sunrpc.svc.return,
2475+ sunrpc.sched.return
2476+{}
2477+
2478+/******************************************************************
2479+ * Probe points on RPC client functions *
2480+ ******************************************************************/
2481+
2482+probe sunrpc.clnt.entry =
2483+ sunrpc.clnt.create_client,
2484+ sunrpc.clnt.clone_client,
2485+ sunrpc.clnt.bind_new_program,
2486+ sunrpc.clnt.shutdown_client,
2487+ sunrpc.clnt.call_sync,
2488+ sunrpc.clnt.call_async,
2489+ sunrpc.clnt.restart_call
2490+{}
2491+
2492+probe sunrpc.clnt.return =
2493+ sunrpc.clnt.create_client.return,
2494+ sunrpc.clnt.clone_client.return,
2495+ sunrpc.clnt.bind_new_program.return,
2496+ sunrpc.clnt.shutdown_client.return,
2497+ sunrpc.clnt.call_sync.return,
2498+ sunrpc.clnt.call_async.return,
2499+ sunrpc.clnt.restart_call.return
2500+{}
2501+
2502+/*
2503+ * Fires when an RPC client is to be created
2504+ *
2505+ * kernels > 2.6.18
2506+ *
2507+ * struct rpc_clnt *
2508+ * rpc_create(struct rpc_create_args *args)
2509+ * The rpc_create() function is used to create an RPC client. It
2510+ * calculates some arguments (such as args->servername), then
2511+ * calls rpc_new_client(). We need the calculated arguments, so
2512+ * we'll probe rpc_new_client(). But, see discussion of
2513+ * sunrpc.clnt.create_client.return below.
2514+ *
2515+ * static struct rpc_clnt *
2516+ * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt)
2517+ *
2518+ * kernels <= 2.6.18
2519+ *
2520+ * static struct rpc_clnt *
2521+ * rpc_new_client(struct rpc_xprt *xprt, char *servname,
2522+ * struct rpc_program *program, u32 vers,
2523+ * rpc_authflavor_t flavor)
2524+ *
2525+ * struct rpc_clnt *
2526+ * rpc_create_client(struct rpc_xprt *xprt, char *servname,
2527+ * struct rpc_program *info, u32 version,
2528+ * rpc_authflavor_t authflavor)
2529+ *
2530+ * @servername: the server machine name
2531+ * @progname: the RPC program name
2532+ * @prog: the RPC program number
2533+ * @vers: the RPC program version number
2534+ * @prot: the IP protocol number
2535+ * @port: the port number
2536+ * @authflavor: the authentication flavor
2537+ */
2538+probe sunrpc.clnt.create_client =
2539+ _sunrpc.clnt.create_client.rpc_new_client_inline !,
2540+ _sunrpc.clnt.create_client.rpc_new_client ?,
2541+ _sunrpc.clnt.create_client.rpc_create_client ?
2542+{
2543+ name = "sunrpc.clnt.create_client"
2544+ argstr = sprintf("%s %s %d %d %d %d %d", servername, progname,
2545+ prog, vers, prot, port, authflavor)
2546+}
2547+
2548+/*
2549+ * Newer kernels (> 2.6.18) compiled with gcc less than version
2550+ * 4.4.3-16, tend to have debuginfo that doesn't include location
2551+ * information for inline function arguments. This is a problem, since
2552+ * we need the arguments to rpc_new_client(), which is inline. Since
2553+ * we can't get them for those kernels, we stash (and delete) the value
2554+ * of the 'args' parameter of rpc_create(). We then use this value
2555+ * when probing the inline version of rpc_new_client() (if we don't
2556+ * have the real arguments to that inline function).
2557+ */
2558+
2559+global __rpc_create_args
2560+
2561+probe kernel.function("rpc_create") !,
2562+ module("sunrpc").function("rpc_create") ?
2563+{
2564+ __rpc_create_args[tid()] = $args
2565+}
2566+
2567+probe kernel.function("rpc_create").return !,
2568+ module("sunrpc").function("rpc_create").return ?
2569+{
2570+ delete __rpc_create_args[tid()]
2571+}
2572+
2573+
2574+/*
2575+ * This function could be written in script language, but we'd need
2576+ * embedded-C functions for XPRT_TRANSPORT_{UDP,TCP,BC_TCP} and
2577+ * IPPROTO_{UDP,TCP}. So, do it all in embedded-C.
2578+ */
2579+
2580+function __rpc_prot_from_protocol:long(protocol:long)
2581+%{
2582+ switch (THIS->protocol) {
2583+#ifdef XPRT_TRANSPORT_BC
2584+ case XPRT_TRANSPORT_UDP:
2585+ THIS->__retvalue = IPPROTO_UDP;
2586+ break;
2587+ case XPRT_TRANSPORT_TCP:
2588+ case XPRT_TRANSPORT_BC_TCP:
2589+ THIS->__retvalue = IPPROTO_TCP;
2590+ break;
2591+#endif
2592+ default:
2593+ THIS->__retvalue = -1;
2594+ break;
2595+ }
2596+%}
2597+
2598+/*
2599+ * The probe for the inline version of "rpc_new_client" (kernels >
2600+ * 2.6.18) and the non-inline version of "rpc_new_client" (kernels <=
2601+ * 2.6.18) could be combined. However, the optimizer isn't smart
2602+ * enough to optimize away the '__rpc_create_args' global then.
2603+ */
2604+
2605+probe _sunrpc.clnt.create_client.rpc_new_client_inline =
2606+ kernel.function("rpc_new_client").inline !,
2607+ module("sunrpc").function("rpc_new_client").inline
2608+{
2609+ if (@defined($args)) { # kernel > 2.6.18 (with good debuginfo)
2610+ servername = kernel_string($args->servername)
2611+ progname = kernel_string($args->program->name)
2612+ prog = $args->prognumber
2613+ vers = vers_from_prog($args->program, $args->version)
2614+ authflavor = $args->authflavor
2615+
2616+ prot = $xprt->prot
2617+ port = (@defined($xprt->port)
2618+ ? $xprt->port : port_from_xprt($xprt))
2619+ }
2620+ else { # kernel > 2.6.18 (with bad debuginfo)
2621+ args = __rpc_create_args[tid()]
2622+ servername = kernel_string(@cast(args, "rpc_create_args", "kernel:sunrpc")->servername)
2623+ progname = kernel_string(@cast(args, "rpc_create_args", "kernel:sunrpc")->program->name)
2624+ prog = @cast(args, "rpc_create_args", "kernel:sunrpc")->prognumber
2625+ vers = vers_from_prog(@cast(args, "rpc_create_args", "kernel:sunrpc")->program, @cast(args, "rpc_create_args", "kernel:sunrpc")->version)
2626+ authflavor = @cast(args, "rpc_create_args", "kernel:sunrpc")->authflavor
2627+
2628+ prot = __rpc_prot_from_protocol(@cast(args, "rpc_create_args", "kernel:sunrpc")->protocol)
2629+ # Since we can't find $xprt, we can't know the port
2630+ port = -1
2631+ }
2632+}
2633+
2634+probe _sunrpc.clnt.create_client.rpc_new_client =
2635+ kernel.function("rpc_new_client").call !,
2636+ module("sunrpc").function("rpc_new_client").call
2637+{
2638+ # kernel <= 2.6.18
2639+ servername = kernel_string($servname)
2640+ progname = kernel_string($program->name)
2641+ prog = $program->number
2642+ vers = vers = vers_from_prog($program, $vers)
2643+ authflavor = $flavor
2644+
2645+ prot = $xprt->prot
2646+ port = (@defined($xprt->port)
2647+ ? $xprt->port : port_from_xprt($xprt))
2648+}
2649+
2650+probe _sunrpc.clnt.create_client.rpc_create_client =
2651+ kernel.function("rpc_create_client") !,
2652+ module("sunrpc").function("rpc_create_client")
2653+{
2654+ servername = kernel_string($servname)
2655+ if (@defined($info)) {
2656+ progname = kernel_string($info->name)
2657+ prog = $info->number
2658+ vers = vers_from_prog($info, $version)
2659+ authflavor = $authflavor
2660+ }
2661+ else {
2662+ progname = kernel_string($program->name)
2663+ prog = $program->number
2664+ vers = vers_from_prog($program, $vers)
2665+ authflavor = $flavor
2666+ }
2667+
2668+ prot = $xprt->prot
2669+ port = (@defined($xprt->port)
2670+ ? $xprt->port : port_from_xprt($xprt))
2671+}
2672+
2673+/*
2674+ * On newer kernels, we want to probe the return of rpc_new_client()
2675+ * here. But because of problems with return probes on inline
2676+ * functions (PR 4413), we have to probe the return of rpc_create()
2677+ * instead. So, if we find the return of rpc_create() (the only
2678+ * caller of rpc_new_client()), we're done.
2679+ */
2680+probe sunrpc.clnt.create_client.return =
2681+ _sunrpc.clnt.create_client.return.rpc_create !,
2682+ _sunrpc.clnt.create_client.return.rpc_new_client ?,
2683+ _sunrpc.clnt.create_client.return.rpc_create_client ?
2684+{
2685+ name = "sunrpc.clnt.create_client.return"
2686+ retstr = returnstr(2)
2687+}
2688+
2689+probe _sunrpc.clnt.create_client.return.rpc_create =
2690+ kernel.function("rpc_create").return !,
2691+ module("sunrpc").function("rpc_create").return
2692+{
2693+}
2694+
2695+probe _sunrpc.clnt.create_client.return.rpc_new_client =
2696+ kernel.function("rpc_new_client").return !,
2697+ module("sunrpc").function("rpc_new_client").return
2698+{
2699+}
2700+
2701+probe _sunrpc.clnt.create_client.return.rpc_create_client =
2702+ kernel.function("rpc_create_client").return !,
2703+ module("sunrpc").function("rpc_create_client").return
2704+{
2705+}
2706+
2707+/*
2708+ * Fires when the RPC client structure is to be cloned
2709+ *
2710+ * struct rpc_clnt * rpc_clone_client(struct rpc_clnt *clnt)
2711+ *
2712+ * @servername: the server machine name
2713+ * @progname: the RPC program name
2714+ * @prog: the RPC program number
2715+ * @vers: the RPC program version number
2716+ * @prot: the IP protocol number
2717+ * @port: the port number
2718+ * @authflavor: the authentication flavor
2719+ */
2720+probe sunrpc.clnt.clone_client = kernel.function("rpc_clone_client") !,
2721+ module("sunrpc").function("rpc_clone_client")
2722+{
2723+ servername = kernel_string($clnt->cl_server)
2724+ progname = kernel_string($clnt->cl_protname)
2725+ prog = prog_from_clnt($clnt)
2726+ vers = vers_from_clnt($clnt)
2727+ prot = prot_from_clnt($clnt)
2728+ port = port_from_clnt($clnt)
2729+ authflavor = $clnt->cl_auth->au_flavor
2730+
2731+ name = "sunrpc.clnt.clone_client"
2732+ argstr = sprintf("%s %s %d %d %d %d %d", servername, progname,
2733+ prog, vers, prot, port, authflavor)
2734+}
2735+
2736+probe sunrpc.clnt.clone_client.return =
2737+ kernel.function("rpc_clone_client").return !,
2738+ module("sunrpc").function("rpc_clone_client").return
2739+{
2740+ name = "sunrpc.clnt.clone_client.return"
2741+ retstr = returnstr(2)
2742+}
2743+
2744+/*
2745+ * Fires when an RPC client is to be shut down.
2746+ *
2747+ * int rpc_shutdown_client(struct rpc_clnt *clnt)
2748+ *
2749+ * @servername: the server machine name
2750+ * @progname: the RPC program name
2751+ * @prog: the RPC program number
2752+ * @vers: the RPC program version number
2753+ * @prot: the IP protocol number
2754+ * @port: the port number
2755+ * @authflavor: the authentication flavor
2756+ *
2757+ * @clones: the number of clones
2758+ * @tasks: the number of references
2759+ *
2760+ * @netreconn: the count of reconnections
2761+ * @rpccnt: the count of RPC calls
2762+ * @om_ops: the count of operations
2763+ * @om_ntrans: the count of RPC transmissions
2764+ * @om_bytes_sent: the count of bytes out
2765+ * @om_bytes_recv: the count of bytes in
2766+ * @om_queue: the jiffies queued for xmit
2767+ * @om_rtt: the RPC RTT jiffies
2768+ * @om_execute: the RPC execution jiffies
2769+ */
2770+probe sunrpc.clnt.shutdown_client = kernel.function("rpc_shutdown_client") !,
2771+ module("sunrpc").function("rpc_shutdown_client")
2772+{
2773+ servername = kernel_string($clnt->cl_server)
2774+ progname = kernel_string($clnt->cl_protname)
2775+ prog = prog_from_clnt($clnt)
2776+ vers = vers_from_clnt($clnt)
2777+ prot = prot_from_clnt($clnt)
2778+ port = port_from_clnt($clnt)
2779+ authflavor = $clnt->cl_auth->au_flavor
2780+ clones = clones_from_clnt($clnt)
2781+ tasks = tasks_from_clnt($clnt)
2782+
2783+ /* per-program statistics */
2784+ netreconn = $clnt->cl_stats->netreconn
2785+ rpccnt = $clnt->cl_stats->rpccnt
2786+
2787+ /* per-client statistics */
2788+ if (@defined($clnt->cl_metrics)) {
2789+ om_ops = $clnt->cl_metrics->om_ops
2790+ om_ntrans = $clnt->cl_metrics->om_ntrans
2791+ om_bytes_sent = $clnt->cl_metrics->om_bytes_sent
2792+ om_bytes_recv = $clnt->cl_metrics->om_bytes_recv
2793+ if (@defined($clnt->cl_metrics->om_queue->tv64)) {
2794+ om_queue = $clnt->cl_metrics->om_queue->tv64
2795+ om_rtt = $clnt->cl_metrics->om_rtt->tv64
2796+ om_execute = $clnt->cl_metrics->om_execute->tv64
2797+ }
2798+ else
2799+ {
2800+ om_queue = $clnt->cl_metrics->om_queue
2801+ om_rtt = $clnt->cl_metrics->om_rtt
2802+ om_execute = $clnt->cl_metrics->om_execute
2803+ }
2804+ }
2805+ else {
2806+ om_ops = -1
2807+ om_ntrans = -1
2808+ om_bytes_sent = -1
2809+ om_bytes_recv = -1
2810+ om_queue = -1
2811+ om_rtt = -1
2812+ om_execute = -1
2813+ }
2814+
2815+ name = "sunrpc.clnt.shutdown_client"
2816+ argstr = sprintf("%s %s %d %d %d %d %d %d %d", servername, progname,
2817+ prog, vers, prot, port, authflavor, clones, tasks)
2818+}
2819+
2820+probe sunrpc.clnt.shutdown_client.return =
2821+ kernel.function("rpc_shutdown_client").return !,
2822+ module("sunrpc").function("rpc_shutdown_client").return
2823+{
2824+ name = "sunrpc.clnt.shutdown_client.return"
2825+ retstr = returnstr(1)
2826+}
2827+
2828+/*
2829+ * Fires when a new RPC program is to be bound an existing client
2830+ *
2831+ * struct rpc_clnt * rpc_bind_new_program(struct rpc_clnt *old,
2832+ * struct rpc_program *program, int vers)
2833+ *
2834+ * @servername: the server machine name
2835+ * @old_progname: the name of old RPC program
2836+ * @old_prog: the number of old RPC program
2837+ * @old_vers: the version of old RPC program
2838+ * @progname: the name of new RPC program
2839+ * @prog: the number of new RPC program
2840+ * @vers: the version of new RPC program
2841+ */
2842+probe sunrpc.clnt.bind_new_program =
2843+ kernel.function("rpc_bind_new_program") !,
2844+ module("sunrpc").function("rpc_bind_new_program")
2845+{
2846+ servername = kernel_string($old->cl_server)
2847+ old_progname = kernel_string($old->cl_protname)
2848+ old_prog = prog_from_clnt($old)
2849+ old_vers = vers_from_clnt($old)
2850+ progname = kernel_string($program->name)
2851+ prog = $program->number
2852+ vers = vers_from_prog($program, $vers)
2853+
2854+ name = "sunrpc.clnt.bind_new_program"
2855+ argstr = sprintf("%s %s %d %s %d", servername, old_progname,
2856+ old_vers, progname, vers)
2857+}
2858+
2859+probe sunrpc.clnt.bind_new_program.return =
2860+ kernel.function("rpc_bind_new_program").return !,
2861+ module("sunrpc").function("rpc_bind_new_program").return
2862+{
2863+ name = "sunrpc.clnt.bind_new_program.return"
2864+ retstr = returnstr(2)
2865+}
2866+
2867+/*
2868+ * int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg,
2869+ * int flags)
2870+ *
2871+ * @servername: the server machine name
2872+ * @progname: the RPC program name
2873+ * @prog: the RPC program number
2874+ * @vers: the RPC program version number
2875+ * @prot: the IP protocol number
2876+ * @port: the port number
2877+ * @xid: current transmission id
2878+ * @dead: whether this client is abandoned
2879+ * @procname: the procedure name in this RPC call
2880+ * @proc: the procedure number in this RPC call
2881+ * @flags: flags
2882+ */
2883+probe sunrpc.clnt.call_sync = kernel.function("rpc_call_sync") !,
2884+ module("sunrpc").function("rpc_call_sync")
2885+{
2886+ servername = kernel_string($clnt->cl_server)
2887+ progname = kernel_string($clnt->cl_protname)
2888+ prog = prog_from_clnt($clnt)
2889+ vers = vers_from_clnt($clnt)
2890+ prot = prot_from_clnt($clnt)
2891+ port = port_from_clnt($clnt)
2892+ xid = xid_from_clnt($clnt)
2893+ dead = (! @defined($clnt->cl_dead)
2894+ ? (atomic_read(&$clnt->cl_kref->refcount) == 0)
2895+ : $clnt->cl_dead)
2896+
2897+ proc = proc_from_msg($msg)
2898+ procname = (@defined($msg->rpc_proc->p_name)
2899+ ? ($msg->rpc_proc->p_name
2900+ ? kernel_string($msg->rpc_proc->p_name) : "NULL")
2901+ : "NULL")
2902+ flags = $flags
2903+
2904+ name = "sunrpc.clnt.call_sync"
2905+ argstr = sprintf("%s %d %s %d %s %d", servername, xid, progname,
2906+ vers, procname, flags)
2907+}
2908+
2909+probe sunrpc.clnt.call_sync.return = kernel.function("rpc_call_sync").return !,
2910+ module("sunrpc").function("rpc_call_sync").return
2911+{
2912+ name = "sunrpc.clnt.call_sync.return"
2913+ retstr = returnstr(1)
2914+}
2915+
2916+/*
2917+ * int rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg,
2918+ * int flags, const struct rpc_call_ops *tk_ops, void *data)
2919+ *
2920+ * @servername: the server machine name
2921+ * @progname: the RPC program name
2922+ * @prog: the RPC program number
2923+ * @vers: the RPC program version number
2924+ * @prot: the IP protocol number
2925+ * @port: the port number
2926+ * @xid: current transmission id
2927+ * @dead: whether this client is abandoned
2928+ * @procname: the procedure name in this RPC call
2929+ * @proc: the procedure number in this RPC call
2930+ * @flags: flags
2931+ */
2932+probe sunrpc.clnt.call_async = kernel.function("rpc_call_async") !,
2933+ module("sunrpc").function("rpc_call_async")
2934+{
2935+ servername = kernel_string($clnt->cl_server)
2936+ progname = kernel_string($clnt->cl_protname)
2937+ prog = prog_from_clnt($clnt)
2938+ vers = vers_from_clnt($clnt)
2939+ prot = prot_from_clnt($clnt)
2940+ port = port_from_clnt($clnt)
2941+ xid = xid_from_clnt($clnt)
2942+ dead = (! @defined($clnt->cl_dead)
2943+ ? (atomic_read(&$clnt->cl_kref->refcount) == 0)
2944+ : $clnt->cl_dead)
2945+
2946+ proc = proc_from_msg($msg)
2947+ procname = (@defined($msg->rpc_proc->p_name)
2948+ ? ($msg->rpc_proc->p_name
2949+ ? kernel_string($msg->rpc_proc->p_name) : "NULL")
2950+ : "NULL")
2951+ flags = $flags
2952+
2953+ name = "sunrpc.clnt.call_async"
2954+ argstr = sprintf("%s %d %s %d %s %d", servername, xid, progname,
2955+ vers, procname, flags)
2956+}
2957+
2958+probe sunrpc.clnt.call_async.return =
2959+ kernel.function("rpc_call_async").return !,
2960+ module("sunrpc").function("rpc_call_async").return
2961+{
2962+ name = "sunrpc.clnt.call_async.return"
2963+ retstr = returnstr(1)
2964+}
2965+
2966+/*
2967+ * Fires when an (async) RPC call is to be restarted
2968+ *
2969+ * void rpc_restart_call(struct rpc_task *task)
2970+ *
2971+ * @servername: the server machine name
2972+ * @prog: the RPC program number
2973+ * @xid: the transmission id
2974+ * @tk_pid: the debugging aid of task
2975+ * @tk_flags: the task flags
2976+ * @tk_priority: the task priority
2977+ * @tk_runstate: the task run status
2978+ */
2979+probe sunrpc.clnt.restart_call = kernel.function("rpc_restart_call") !,
2980+ module("sunrpc").function("rpc_restart_call")
2981+{
2982+ servername = kernel_string($task->tk_client->cl_server)
2983+ prog = prog_from_clnt($task->tk_client)
2984+ xid = $task->tk_rqstp->rq_xid
2985+ tk_pid = $task->tk_pid
2986+ tk_flags = $task->tk_flags
2987+ tk_priority = $task->tk_priority
2988+ tk_runstate = $task->tk_runstate
2989+
2990+ name = "sunrpc.clnt.restart_call"
2991+ argstr = sprintf("%s %d %d %d %d %d %d", servername, prog, xid, tk_pid,
2992+ tk_flags, tk_priority, tk_runstate)
2993+}
2994+
2995+probe sunrpc.clnt.restart_call.return =
2996+ kernel.function("rpc_restart_call").return !,
2997+ module("sunrpc").function("rpc_restart_call").return
2998+{
2999+ name = "sunrpc.clnt.restart_call.return"
3000+ retstr = "N/A"
3001+}
3002+
3003+/*********************************************
3004+ * Probe points on RPC server interface *
3005+ ********************************************/
3006+probe sunrpc.svc.entry =
3007+ sunrpc.svc.register,
3008+ sunrpc.svc.create,
3009+ sunrpc.svc.destroy,
3010+ sunrpc.svc.process,
3011+ sunrpc.svc.authorise,
3012+ sunrpc.svc.recv,
3013+ sunrpc.svc.send,
3014+ sunrpc.svc.drop
3015+{}
3016+
3017+probe sunrpc.svc.return =
3018+ sunrpc.svc.register.return,
3019+ sunrpc.svc.create.return,
3020+ sunrpc.svc.destroy.return,
3021+ sunrpc.svc.process.return,
3022+ sunrpc.svc.authorise.return,
3023+ sunrpc.svc.recv.return,
3024+ sunrpc.svc.send.return,
3025+ sunrpc.svc.drop.return
3026+{}
3027+
3028+/*
3029+ * Fires when an RPC service is to be registered with the local portmapper.
3030+ * If proto and port == 0, it means to unregister a service.
3031+ *
3032+ * int svc_register(struct svc_serv *serv, int proto, unsigned short port)
3033+ *
3034+ * @sv_name: the service name
3035+ * @progname: the name of the program
3036+ * @prog: the number of the program
3037+ * @prot: the IP protocol number
3038+ * @port: the port number
3039+ */
3040+probe sunrpc.svc.register = kernel.function("svc_register") !,
3041+ module("sunrpc").function("svc_register")
3042+{
3043+ sv_name = kernel_string($serv->sv_name)
3044+ progname = kernel_string($serv->sv_program->pg_name)
3045+ prog = $serv->sv_program->pg_prog
3046+ prot = $proto
3047+ port = $port
3048+
3049+ name = "sunrpc.svc.register"
3050+ argstr = sprintf("%s %s %d %d", sv_name, progname, prot, port)
3051+}
3052+
3053+probe sunrpc.svc.register.return = kernel.function("svc_register").return !,
3054+ module("sunrpc").function("svc_register").return
3055+{
3056+ name = "sunrpc.svc.register.return"
3057+ retstr = returnstr(1)
3058+}
3059+
3060+/*
3061+ * Fires when an RPC service is to be created
3062+ *
3063+ * struct svc_serv *
3064+ * svc_create(struct svc_program *prog, unsigned int bufsize)
3065+ *
3066+ * @progname: the name of the program
3067+ * @prog: the number of the program
3068+ * @pg_nvers: the number of supported versions
3069+ * @bufsize: the buffer size
3070+ */
3071+probe sunrpc.svc.create = kernel.function("svc_create") !,
3072+ module("sunrpc").function("svc_create")
3073+{
3074+ progname = kernel_string($prog->pg_name)
3075+ prog = $prog->pg_prog
3076+ pg_nvers = $prog->pg_nvers
3077+ bufsize = $bufsize
3078+
3079+ name = "sunrpc.svc.create"
3080+ argstr = sprintf("%s %d %d %d", progname, prog, pg_nvers, bufsize)
3081+}
3082+
3083+probe sunrpc.svc.create.return = kernel.function("svc_create").return !,
3084+ module("sunrpc").function("svc_create").return
3085+{
3086+ name = "sunrpc.svc.create.return"
3087+ retstr = returnstr(2)
3088+}
3089+
3090+/*
3091+ * Fires when an RPC service is to be destroyed
3092+ *
3093+ * void svc_destroy(struct svc_serv *serv)
3094+ *
3095+ * @sv_name: the service name
3096+ * @sv_progname: the name of the program
3097+ * @sv_prog: the number of the program
3098+ * @sv_nrthreads:the number of concurrent threads
3099+ * @netcnt: the count of received RPC requests
3100+ * @nettcpconn: the count of accepted TCP connections
3101+ * @rpccnt: the count of valid RPC requests
3102+ * @rpcbadfmt: the count of requests dropped for bad formats
3103+ * @rpcbadauth: the count of requests drooped for authentication failure
3104+ */
3105+probe sunrpc.svc.destroy = kernel.function("svc_destroy") !,
3106+ module("sunrpc").function("svc_destroy")
3107+{
3108+ sv_name = kernel_string($serv->sv_name) /* service name */
3109+ sv_progname = kernel_string($serv->sv_program->pg_name)
3110+ sv_prog = $serv->sv_program->pg_prog
3111+ sv_nrthreads = $serv->sv_nrthreads
3112+
3113+ /* RPC statistics */
3114+ netcnt = $serv->sv_stats->netcnt
3115+ netcpconn = $serv->sv_stats->nettcpconn
3116+ rpccnt = $serv->sv_stats->rpccnt
3117+ rpcbadfmt = $serv->sv_stats->rpcbadfmt
3118+ rpcbadauth = $serv->sv_stats->rpcbadauth
3119+
3120+ name = "sunrpc.svc.destroy"
3121+ argstr = sprintf("%s %d %d", sv_name, sv_prog, sv_nrthreads)
3122+}
3123+
3124+probe sunrpc.svc.destroy.return = kernel.function("svc_destroy").return !,
3125+ module("sunrpc").function("svc_destroy").return
3126+{
3127+ name = "sunrpc.svc.destroy.return"
3128+ retstr = "N/A"
3129+}
3130+
3131+/*
3132+ * Fires when an RPC request is to be processed
3133+ *
3134+ * int svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
3135+ *
3136+ * @sv_name: the service name
3137+ * @sv_prog: the number of the program
3138+ * @sv_nrthreads:the number of concurrent threads
3139+ * @peer_ip: the peer address where the request is from
3140+ * @rq_xid: the transmission id in the request
3141+ * @rq_prog: the program number in the request
3142+ * @rq_vers: the program version in the request
3143+ * @rq_proc: the procedure number in the request
3144+ * @rq_prot: the IP protocol of the reqeust
3145+ */
3146+probe sunrpc.svc.process = kernel.function("svc_process") !,
3147+ module("sunrpc").function("svc_process")
3148+{
3149+ if (! @defined($serv)) {
3150+ sv_name = kernel_string($rqstp->rq_server->sv_name)
3151+ sv_prog = $rqstp->rq_server->sv_program->pg_prog
3152+ sv_nrthreads = $rqstp->rq_server->sv_nrthreads
3153+ }
3154+ else {
3155+ sv_name = kernel_string($serv->sv_name) /* service name */
3156+ sv_prog = $serv->sv_program->pg_prog
3157+ sv_nrthreads = $serv->sv_nrthreads
3158+ }
3159+ peer_ip = addr_from_rqst($rqstp)
3160+ rq_xid = $rqstp->rq_xid
3161+ rq_prog = $rqstp->rq_prog
3162+ rq_vers = $rqstp->rq_vers
3163+ rq_proc = $rqstp->rq_proc
3164+ rq_prot = $rqstp->rq_prot
3165+
3166+ name = "sunrpc.svc.process"
3167+ argstr = sprintf("%s %d %d %d %d %d %d", sv_name, sv_prog, peer_ip,
3168+ rq_xid, rq_prog, rq_vers, rq_proc)
3169+}
3170+
3171+probe sunrpc.svc.process.return = kernel.function("svc_process").return !,
3172+ module("sunrpc").function("svc_process").return
3173+{
3174+ name = "sunrpc.svc.process.return"
3175+ retstr = returnstr(1)
3176+}
3177+
3178+/*
3179+ * Fires when an RPC request is to be authorised
3180+ *
3181+ * int svc_authorise(struct svc_rqst *rqstp)
3182+ *
3183+ * @sv_name: the service name
3184+ * @peer_ip: the peer address where the request is from
3185+ * @rq_xid: the transmission id in the request
3186+ * @rq_prog: the program number in the request
3187+ * @rq_vers: the program version in the request
3188+ * @rq_proc: the procedure number in the request
3189+ * @rq_prot: the IP protocol of the reqeust
3190+ */
3191+probe sunrpc.svc.authorise = kernel.function("svc_authorise") !,
3192+ module("sunrpc").function("svc_authorise")
3193+{
3194+ sv_name = kernel_string($rqstp->rq_server->sv_name)
3195+ peer_ip = addr_from_rqst($rqstp)
3196+ rq_xid = $rqstp->rq_xid
3197+ rq_prog = $rqstp->rq_prog
3198+ rq_vers = $rqstp->rq_vers
3199+ rq_proc = $rqstp->rq_proc
3200+ rq_prot = $rqstp->rq_prot
3201+
3202+ name = "sunrpc.svc.authorise"
3203+ argstr = sprintf("%d %d %d %d %d %d", peer_ip, rq_xid, rq_prog,
3204+ rq_vers, rq_proc, rq_prot)
3205+}
3206+
3207+probe sunrpc.svc.authorise.return = kernel.function("svc_authorise").return !,
3208+ module("sunrpc").function("svc_authorise").return
3209+{
3210+ name = "sunrpc.svc.authorise.return"
3211+ retstr = returnstr(1)
3212+}
3213+
3214+/*
3215+ * Fires when the server is to receive the next request on any socket.
3216+ *
3217+ * int svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
3218+ *
3219+ * @sv_name: the service name
3220+ * @sv_prog: the number of the program
3221+ * @sv_nrthreads:the number of concurrent threads
3222+ * @timeout: the timeout of waiting for data
3223+ */
3224+probe sunrpc.svc.recv = kernel.function("svc_recv") !,
3225+ module("sunrpc").function("svc_recv")
3226+{
3227+ if (! @defined($serv)) {
3228+ sv_name = kernel_string($rqstp->rq_server->sv_name)
3229+ sv_prog = $rqstp->rq_server->sv_program->pg_prog
3230+ sv_nrthreads = $rqstp->rq_server->sv_nrthreads
3231+ }
3232+ else {
3233+ sv_name = kernel_string($serv->sv_name)
3234+ sv_prog = $serv->sv_program->pg_prog
3235+ sv_nrthreads = $serv->sv_nrthreads
3236+ }
3237+ timeout = $timeout
3238+
3239+ name = "sunrpc.svc.recv"
3240+ argstr = sprintf("%s %d", sv_name, timeout)
3241+}
3242+
3243+probe sunrpc.svc.recv.return = kernel.function("svc_recv").return !,
3244+ module("sunrpc").function("svc_recv").return
3245+{
3246+ name = "sunrpc.svc.recv.return"
3247+ retstr = returnstr(1)
3248+}
3249+
3250+/*
3251+ * Fires when want to return reply to client.
3252+ *
3253+ * int svc_send(struct svc_rqst *rqstp)
3254+ *
3255+ * @sv_name: the service name
3256+ * @peer_ip: the peer address where the request is from
3257+ * @rq_xid: the transmission id in the request
3258+ * @rq_prog: the program number in the request
3259+ * @rq_vers: the program version in the request
3260+ * @rq_proc: the procedure number in the request
3261+ * @rq_prot: the IP protocol of the reqeust
3262+ */
3263+probe sunrpc.svc.send = kernel.function("svc_send") !,
3264+ module("sunrpc").function("svc_send")
3265+{
3266+ sv_name = kernel_string($rqstp->rq_server->sv_name)
3267+ peer_ip = addr_from_rqst($rqstp)
3268+ rq_xid = $rqstp->rq_xid
3269+ rq_prog = $rqstp->rq_prog
3270+ rq_vers = $rqstp->rq_vers
3271+ rq_proc = $rqstp->rq_proc
3272+ rq_prot = $rqstp->rq_prot
3273+
3274+ name = "sunrpc.svc.send"
3275+ argstr = sprintf("%s %d %d %d %d %d %d", sv_name, peer_ip,
3276+ rq_xid, rq_prog, rq_vers, rq_proc, rq_prot)
3277+}
3278+
3279+probe sunrpc.svc.send.return = kernel.function("svc_send").return !,
3280+ module("sunrpc").function("svc_send").return
3281+{
3282+ name = "sunrpc.svc.send.return"
3283+ retstr = returnstr(1)
3284+}
3285+
3286+/*
3287+ * Fires when a request is to be dropped
3288+ *
3289+ * void svc_drop(struct svc_rqst *rqstp)
3290+ *
3291+ * @sv_name: the service name
3292+ * @peer_ip: the peer address where the request is from
3293+ * @rq_xid: the transmission id in the request
3294+ * @rq_prog: the program number in the request
3295+ * @rq_vers: the program version in the request
3296+ * @rq_proc: the procedure number in the request
3297+ * @rq_prot: the IP protocol of the reqeust
3298+ */
3299+probe sunrpc.svc.drop = kernel.function("svc_drop") !,
3300+ module("sunrpc").function("svc_drop")
3301+{
3302+ sv_name = kernel_string($rqstp->rq_server->sv_name)
3303+ peer_ip = addr_from_rqst($rqstp)
3304+ rq_xid = $rqstp->rq_xid
3305+ rq_prog = $rqstp->rq_prog
3306+ rq_vers = $rqstp->rq_vers
3307+ rq_proc = $rqstp->rq_proc
3308+ rq_prot = $rqstp->rq_prot
3309+
3310+ name = "sunrpc.svc.drop"
3311+ argstr = sprintf("%s %d %d %d %d %d %d", sv_name, peer_ip,
3312+ rq_xid, rq_prog, rq_vers, rq_proc, rq_prot)
3313+}
3314+
3315+probe sunrpc.svc.drop.return = kernel.function("svc_drop").return !,
3316+ module("sunrpc").function("svc_drop").return
3317+{
3318+ name = "sunrpc.svc.drop.return"
3319+ retstr = "N/A"
3320+}
3321+
3322+/*******************************************************************
3323+ * Probe points on RPC scheduler *
3324+ ******************************************************************/
3325+probe sunrpc.sched.entry =
3326+ sunrpc.sched.new_task,
3327+ sunrpc.sched.release_task ?,
3328+ sunrpc.sched.execute,
3329+ sunrpc.sched.delay
3330+{}
3331+
3332+probe sunrpc.sched.return =
3333+ sunrpc.sched.new_task.return,
3334+ sunrpc.sched.release_task.return ?,
3335+ sunrpc.sched.execute.return,
3336+ sunrpc.sched.delay.return
3337+{}
3338+
3339+/*
3340+ * Fires when a new task is to be created for the specified client.
3341+ *
3342+ * struct rpc_task * rpc_new_task(struct rpc_clnt *clnt, int flags,
3343+ * const struct rpc_call_ops *tk_ops, void *calldata)
3344+ *
3345+ * @xid: the transmission id in the RPC call
3346+ * @prog: the program number in the RPC call
3347+ * @vers: the program version in the RPC call
3348+ * @prot: the IP protocol in the RPC call
3349+ * @tk_flags: the flags of the task
3350+ */
3351+probe sunrpc.sched.new_task = kernel.function("rpc_new_task") !,
3352+ module("sunrpc").function("rpc_new_task")
3353+{
3354+ if (@defined($setup_data)) {
3355+ xid = xid_from_clnt($setup_data->rpc_client)
3356+ prog = prog_from_clnt($setup_data->rpc_client)
3357+ vers = vers_from_clnt($setup_data->rpc_client)
3358+ prot = prot_from_clnt($setup_data->rpc_client)
3359+ flags = $setup_data->flags
3360+ }
3361+ else {
3362+ xid = xid_from_clnt($clnt)
3363+ prog = prog_from_clnt($clnt)
3364+ vers = vers_from_clnt($clnt)
3365+ prot = prot_from_clnt($clnt)
3366+ flags = $flags
3367+ }
3368+
3369+ name = "sunrpc.sched.new_task"
3370+ argstr = sprintf("%d %d %d %d %d", xid, prog, vers, prot, flags)
3371+}
3372+
3373+probe sunrpc.sched.new_task.return = kernel.function("rpc_new_task").return !,
3374+ module("sunrpc").function("rpc_new_task").return
3375+{
3376+ name = "sunrpc.sched.new_task.return"
3377+ retstr = returnstr(2)
3378+}
3379+
3380+/*
3381+ * Fires when all resources associated with a task are to be released
3382+ *
3383+ * void rpc_release_task(struct rpc_task *task)
3384+ *
3385+ * @xid: the transmission id in the RPC call
3386+ * @prog: the program number in the RPC call
3387+ * @vers: the program version in the RPC call
3388+ * @prot: the IP protocol in the RPC call
3389+ * @tk_flags: the flags of the task
3390+ *
3391+ * rpc_release_task() might not be found for a particular kernel. So,
3392+ * if we can't find it, just return '-1' for everything.
3393+ *
3394+ * The '.call' here is so that we're sure to grab the non-inline
3395+ * version of rpc_release_task() (assuming it exists). We can't find
3396+ * the return of rpc_release_task() if it is inline (PR 4413).
3397+ */
3398+
3399+probe sunrpc.sched.release_task = kernel.function("rpc_release_task").call !,
3400+ module("sunrpc").function("rpc_release_task").call !,
3401+ never
3402+{
3403+ if (@defined($task)) {
3404+ xid = xid_from_clnt($task->tk_client)
3405+ prog = prog_from_clnt($task->tk_client)
3406+ vers = vers_from_clnt($task->tk_client)
3407+ prot = prot_from_clnt($task->tk_client)
3408+ tk_flags = $task->tk_flags
3409+ }
3410+ else {
3411+ xid = -1
3412+ prog = -1
3413+ vers = -1
3414+ prot = -1
3415+ tk_flags = -1
3416+ }
3417+ name = "sunrpc.sched.release_task"
3418+ argstr = sprintf("%d %d %d %d %d", xid, prog, vers, prot, tk_flags)
3419+}
3420+
3421+probe sunrpc.sched.release_task.return =
3422+ kernel.function("rpc_release_task").return !,
3423+ module("sunrpc").function("rpc_release_task").return ?
3424+{
3425+ name = "sunrpc.sched.release_task.return"
3426+ retstr = "N/A"
3427+}
3428+
3429+/*
3430+ * Fires when the RPC `scheduler'(or rather, the finite state machine)
3431+ * is to be executed
3432+ *
3433+ * static int __rpc_execute(struct rpc_task *task)
3434+ *
3435+ * @xid: the transmission id in the RPC call
3436+ * @prog: the program number in the RPC call
3437+ * @vers: the program version in the RPC call
3438+ * @prot: the IP protocol in the RPC call
3439+ * @tk_pid: the debugging id of the task
3440+ * @tk_flags: the flags of the task
3441+ */
3442+probe sunrpc.sched.execute = kernel.function("__rpc_execute") !,
3443+ module("sunrpc").function("__rpc_execute")
3444+{
3445+ xid = xid_from_clnt($task->tk_client)
3446+ prog = prog_from_clnt($task->tk_client)
3447+ vers = vers_from_clnt($task->tk_client)
3448+ prot = prot_from_clnt($task->tk_client)
3449+ tk_pid = $task->tk_pid
3450+ tk_flags = $task->tk_flags
3451+
3452+ name = "sunrpc.sched.execute"
3453+ argstr = sprintf("%d %d %d %d %d %d", xid, prog, vers, prot,
3454+ tk_pid, tk_flags)
3455+}
3456+
3457+probe sunrpc.sched.execute.return = kernel.function("__rpc_execute").return !,
3458+ module("sunrpc").function("__rpc_execute").return
3459+{
3460+ name = "sunrpc.sched.execute.return"
3461+
3462+ # On kernels > 2.6.20, __rpc_execute() is a void function.
3463+ if (@defined($return)) {
3464+ retstr = returnstr(1)
3465+ }
3466+ else {
3467+ retstr = "N/A"
3468+ }
3469+}
3470+
3471+/*
3472+ * Fires when a task is to be delayed
3473+ *
3474+ * void rpc_delay(struct rpc_task *task, unsigned long delay)
3475+ *
3476+ * @xid: the transmission id in the RPC call
3477+ * @prog: the program number in the RPC call
3478+ * @vers: the program version in the RPC call
3479+ * @prot: the IP protocol in the RPC call
3480+ * @tk_pid: the debugging id of the task
3481+ * @tk_flags: the flags of the task
3482+ * @delay: the time delayed
3483+ */
3484+probe sunrpc.sched.delay = kernel.function("rpc_delay") !,
3485+ module("sunrpc").function("rpc_delay")
3486+{
3487+ xid = xid_from_clnt($task->tk_client)
3488+ prog = prog_from_clnt($task->tk_client)
3489+ vers = vers_from_clnt($task->tk_client)
3490+ prot = prot_from_clnt($task->tk_client)
3491+ tk_pid = $task->tk_pid
3492+ tk_flags = $task->tk_flags
3493+ delay = $delay
3494+
3495+ name = "sunrpc.sched.delay"
3496+ argstr = sprintf("%d %d %d %d %d %d %d", xid, prog, vers,
3497+ prot, tk_pid, tk_flags, delay)
3498+}
3499+
3500+probe sunrpc.sched.delay.return = kernel.function("rpc_delay").return !,
3501+ module("sunrpc").function("rpc_delay").return
3502+{
3503+ name = "sunrpc.sched.delay.return"
3504+ retstr = "N/A"
3505+}
3506+
3507+/******************************************************************
3508+ * Helper functions *
3509+ *****************************************************************/
3510+
3511+function xid_from_clnt:long(clnt:long)
3512+{
3513+ if (clnt == 0)
3514+ return 0
3515+ return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_xprt->xid
3516+}
3517+
3518+function prog_from_clnt:long(clnt:long)
3519+{
3520+ if (clnt == 0)
3521+ return 0
3522+ if (@defined(@cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_prog))
3523+ return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_prog
3524+ else
3525+ return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_pmap->pm_prog
3526+}
3527+
3528+function vers_from_clnt:long(clnt:long)
3529+{
3530+ if (clnt == 0)
3531+ return 0
3532+ if (@defined(@cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_vers))
3533+ return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_vers
3534+ else
3535+ return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_pmap->pm_vers
3536+}
3537+
3538+function prot_from_clnt:long(clnt:long)
3539+{
3540+ if (clnt == 0)
3541+ return 0
3542+ return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_xprt->prot
3543+}
3544+
3545+function port_from_xprt:long(cl_xprt:long)
3546+{
3547+ if (cl_xprt == 0)
3548+ return 0
3549+
3550+ addr = &@cast(cl_xprt, "rpc_xprt", "kernel:sunrpc")->addr
3551+ if (addr == 0)
3552+ return 0
3553+
3554+ /* In reality, 'cl_xprt->addr' is of 'sockaddr_storage' type
3555+ * (since 2.6.19). But when used, you cast it to what is
3556+ * inside that buffer. */
3557+ if (@cast(addr, "sockaddr_in")->sin_family == AF_INET()) {
3558+ /* Now consider ipv4 only */
3559+ return ntohs(@cast(addr, "sockaddr_in")->sin_port)
3560+ }
3561+ return 0
3562+}
3563+
3564+function port_from_clnt:long(clnt:long)
3565+{
3566+ if (clnt == 0)
3567+ return 0
3568+
3569+ cl_xprt = @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_xprt
3570+ return port_from_xprt(cl_xprt)
3571+}
3572+
3573+function clones_from_clnt:long(clnt:long)
3574+{
3575+ return (@defined(@cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_count)
3576+ ? atomic_read(&@cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_count)
3577+ : -1)
3578+}
3579+
3580+function tasks_from_clnt:long(clnt:long)
3581+{
3582+ return (@defined(@cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_users)
3583+ ? atomic_read(&@cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_users)
3584+ : -1)
3585+}
3586+
3587+function proc_from_msg:long(msg:long)
3588+{
3589+ if (msg == 0)
3590+ return 0
3591+ return @cast(msg, "rpc_message", "kernel:sunrpc")->rpc_proc->p_proc
3592+}
3593+
3594+function vers_from_prog:long(program:long, vers:long)
3595+{
3596+ if (program
3597+ && vers < @cast(program, "rpc_program", "kernel:sunrpc")->nrvers)
3598+ return @cast(program, "rpc_program", "kernel:sunrpc")->version[vers]->number
3599+ return 0
3600+}
3601+
3602+function addr_from_rqst:long(rqstp:long)
3603+{
3604+ if (rqstp) {
3605+ addr = &@cast(rqstp, "svc_rqst", "kernel:nfs")->rq_addr
3606+ if (addr == 0)
3607+ return 0
3608+
3609+ /* In reality, 'rq_addr' is of 'sockaddr_storage' type
3610+ * (since 2.6.19). But when used, you cast it to what is
3611+ * inside that buffer. */
3612+ if (@cast(addr, "sockaddr_in")->sin_family == AF_INET()) {
3613+ /* Now consider ipv4 only */
3614+ return @cast(addr, "sockaddr_in")->sin_addr->s_addr
3615+ }
3616+ }
3617+ return 0
3618+}
3619+
3620+function addr_from_rqst_str:string(rqstp:long)
3621+{
3622+ if (rqstp == 0)
3623+ return "Null"
3624+
3625+ addr = &@cast(rqstp, "svc_rqst", "kernel:nfs")->rq_addr
3626+ if (addr == 0)
3627+ return "Null"
3628+
3629+ s_addr = addr_from_rqst(rqstp)
3630+ if (s_addr == 0)
3631+ return "Unsupported Address Family"
3632+ return sprintf("%s:%d", daddr_to_string(s_addr),
3633+ @cast(addr, "sockaddr_in")->sin_port)
3634+}
3635+
3636
3637=== added file '.pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/task.stp'
3638--- .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/task.stp 1970-01-01 00:00:00 +0000
3639+++ .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/task.stp 2011-03-22 12:11:00 +0000
3640@@ -0,0 +1,384 @@
3641+// task information tapset
3642+// Copyright (C) 2006 Intel Corporation.
3643+// Copyright (C) 2010 Red Hat Inc.
3644+//
3645+// This file is part of systemtap, and is free software. You can
3646+// redistribute it and/or modify it under the terms of the GNU General
3647+// Public License (GPL); either version 2, or (at your option) any
3648+// later version.
3649+
3650+%{
3651+#include <linux/version.h>
3652+#include <linux/file.h>
3653+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
3654+#include <linux/fdtable.h>
3655+#endif
3656+#ifndef STAPCONF_TASK_UID
3657+#include <linux/cred.h>
3658+#endif
3659+%}
3660+
3661+/**
3662+ * sfunction task_current - The current task_struct of the current task.
3663+ *
3664+ * General Syntax: task_current:long()
3665+ *
3666+ * Description: This function returns the task_struct representing the current process.
3667+ * This address can be passed to the various task_*() functions to extract
3668+ * more task-specific data.
3669+ */
3670+function task_current:long () %{ /* pure */
3671+ THIS->__retvalue = (long)current;
3672+%}
3673+
3674+/**
3675+ * sfunction task_parent - The task_struct of the parent task.
3676+ *
3677+ * General Syntax: task_parent:long(task:long)
3678+ *
3679+ * @task: task_struct pointer.
3680+ *
3681+ * Description: This function returns the parent task_struct of
3682+ * the given task. This address can be passed to the various
3683+ * task_*() functions to extract more task-specific data.
3684+ */
3685+function task_parent:long(task:long)
3686+{
3687+ return (@defined(@cast(task, "task_struct",
3688+ "kernel<linux/sched.h>")->real_parent)
3689+ ? @cast(task, "task_struct", "kernel<linux/sched.h>")->real_parent
3690+ : @cast(task, "task_struct", "kernel<linux/sched.h>")->parent)
3691+}
3692+
3693+/**
3694+ * sfunction task_state - The state of the task.
3695+ *
3696+ * General Syntax: task_state:long(task:long)
3697+ *
3698+ * @task: task_struct pointer.
3699+ *
3700+ * Description: Return the state of the given task, one of:
3701+ * TASK_RUNNING (0), TASK_INTERRUPTIBLE (1), TASK_UNINTERRUPTIBLE (2),
3702+ * TASK_STOPPED (4), TASK_TRACED (8), EXIT_ZOMBIE (16), EXIT_DEAD (32).
3703+ */
3704+function task_state:long (task:long)
3705+{
3706+ return @cast(task, "task_struct", "kernel<linux/sched.h>")->state
3707+}
3708+
3709+/**
3710+ * sfunction task_execname - The name of the task.
3711+ *
3712+ * General Syntax: task_execname:string(task:long)
3713+ *
3714+ * @task: task_struct pointer.
3715+ *
3716+ * Description: Return the name of the given task.
3717+ */
3718+function task_execname:string (task:long)
3719+{
3720+ return kernel_string(@cast(task, "task_struct", "kernel<linux/sched.h>")->comm)
3721+}
3722+
3723+/**
3724+ * sfunction task_pid - The process identifier of the task.
3725+ *
3726+ * General Syntax: task_pid:long (task:long)
3727+ *
3728+ * @task: task_struct pointer.
3729+ *
3730+ * Description: This fucntion returns the process id of the given task.
3731+ */
3732+function task_pid:long (task:long)
3733+{
3734+ return @cast(task, "task_struct", "kernel<linux/sched.h>")->tgid
3735+}
3736+
3737+/**
3738+ * sfunction pid2task - The task_struct of the given process identifier.
3739+ * @pid: Process identifier.
3740+ *
3741+ * Description: Return the task struct of the given process id.
3742+ */
3743+function pid2task:long (pid:long) %{ /* pure */
3744+ struct task_struct *t = NULL;
3745+ pid_t t_pid = (pid_t)(long)THIS->pid;
3746+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
3747+ struct pid *p_pid = find_get_pid(t_pid);
3748+ t = pid_task(p_pid, PIDTYPE_PID);
3749+ put_pid(p_pid);
3750+#else
3751+ rcu_read_lock();
3752+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
3753+ t = find_task_by_vpid (t_pid);
3754+#else
3755+ t = find_task_by_pid (t_pid);
3756+#endif /* 2.6.24 */
3757+ rcu_read_unlock();
3758+#endif /* 2.6.31 */
3759+ THIS->__retvalue = (long)t;
3760+%}
3761+
3762+/**
3763+ * sfunction pid2execname - The name of the given process identifier.
3764+ * @pid: Process identifier.
3765+ *
3766+ * Description: Return the name of the given process id.
3767+ */
3768+function pid2execname:string (pid:long) {
3769+ tsk = pid2task(pid)
3770+ if (tsk)
3771+ return task_execname(tsk)
3772+ return ""
3773+}
3774+
3775+/**
3776+ * sfunction task_tid - The thread identifier of the task.
3777+ *
3778+ * General Syntax: task_tid:long(task:long)
3779+ *
3780+ * @task: task_struct pointer.
3781+ *
3782+ * Description: This function returns the thread id of the given task.
3783+ */
3784+function task_tid:long (task:long)
3785+{
3786+ return @cast(task, "task_struct", "kernel<linux/sched.h>")->pid
3787+}
3788+
3789+
3790+/**
3791+ * sfunction task_gid - The group identifier of the task.
3792+ *
3793+ * General Syntax: task_gid:long(task:long)
3794+ *
3795+ * @task: task_struct pointer.
3796+ *
3797+ * Description: This function returns the group id of the given task.
3798+ */
3799+function task_gid:long (task:long) %{ /* pure */
3800+ struct task_struct *t = (struct task_struct *)(long)THIS->task;
3801+#ifdef STAPCONF_TASK_UID
3802+ THIS->__retvalue = kread(&(t->gid));
3803+ CATCH_DEREF_FAULT();
3804+#else
3805+ /* XXX: We can't easily kread this rcu-protected field. */
3806+ /* XXX: no task_gid() in 2.6.28 */
3807+ struct cred *cred;
3808+ rcu_read_lock();
3809+ cred = get_task_cred (t);
3810+ rcu_read_unlock();
3811+ THIS->__retvalue = cred->gid;
3812+#endif
3813+%}
3814+
3815+
3816+/**
3817+ * sfunction task_egid - The effective group identifier of the task.
3818+ *
3819+ * General Syntax: task_egid:long(task:long)
3820+ *
3821+ * @task: task_struct pointer.
3822+ *
3823+ * Description: This function returns the effective group id of the given task.
3824+ */
3825+function task_egid:long (task:long) %{ /* pure */
3826+ struct task_struct *t = (struct task_struct *)(long)THIS->task;
3827+#ifdef STAPCONF_TASK_UID
3828+ THIS->__retvalue = kread(&(t->egid));
3829+ CATCH_DEREF_FAULT();
3830+#else
3831+ /* XXX: We can't easily kread this rcu-protected field. */
3832+ /* XXX: no task_egid() in 2.6.28 */
3833+ struct cred *cred;
3834+ rcu_read_lock();
3835+ cred = get_task_cred (t);
3836+ rcu_read_unlock();
3837+ THIS->__retvalue = cred->egid;
3838+#endif
3839+%}
3840+
3841+/**
3842+ * sfunction task_uid - The user identifier of the task.
3843+ *
3844+ * General Syntax: task_uid:long(task:long)
3845+ *
3846+ * @task: task_struct pointer.
3847+ *
3848+ * Description: This function returns the user id of the given task.
3849+ */
3850+function task_uid:long (task:long) %{ /* pure */
3851+ struct task_struct *t = (struct task_struct *)(long)THIS->task;
3852+#ifdef STAPCONF_TASK_UID
3853+ THIS->__retvalue = kread(&(t->uid));
3854+ CATCH_DEREF_FAULT();
3855+#else
3856+ /* XXX: We can't easily kread this rcu-protected field. */
3857+ THIS->__retvalue = task_uid (t);
3858+#endif
3859+%}
3860+
3861+/**
3862+ * sfunction task_euid - The effective user identifier of the task.
3863+ *
3864+ * General Syntax: task_euid:long(task:long)
3865+ *
3866+ * @task: task_struct pointer.
3867+ *
3868+ * Description: This function returns the effective user id of the given task.
3869+ */
3870+function task_euid:long (task:long) %{ /* pure */
3871+ struct task_struct *t = (struct task_struct *)(long)THIS->task;
3872+#ifdef STAPCONF_TASK_UID
3873+ THIS->__retvalue = kread(&(t->euid));
3874+ CATCH_DEREF_FAULT();
3875+#else
3876+ /* XXX: We can't easily kread this rcu-protected field. */
3877+ THIS->__retvalue = task_euid (t);
3878+#endif
3879+%}
3880+
3881+
3882+/**
3883+ * sfunction task_prio - The priority value of the task.
3884+ *
3885+ * General Syntax: task_prio:long(task:long)
3886+ *
3887+ * @task: task_struct pointer.
3888+ *
3889+ * Description: This function returns the priority value of the given task.
3890+ */
3891+function task_prio:long (task:long) %{ /* pure */
3892+ struct task_struct *t = (struct task_struct *)(long)THIS->task;
3893+ THIS->__retvalue = kread(&(t->prio)) - MAX_RT_PRIO;
3894+ CATCH_DEREF_FAULT();
3895+%}
3896+
3897+
3898+/**
3899+ * sfunction task_nice - The nice value of the task.
3900+ *
3901+ * General Syntax: task_nice:long(task:long)
3902+ *
3903+ * @task: task_struct pointer.
3904+ *
3905+ * Description: This function returns the nice value of the given task.
3906+ */
3907+function task_nice:long (task:long) %{ /* pure */
3908+ struct task_struct *t = (struct task_struct *)(long)THIS->task;
3909+ THIS->__retvalue = kread(&(t->static_prio)) - MAX_RT_PRIO - 20;
3910+ CATCH_DEREF_FAULT();
3911+%}
3912+
3913+/**
3914+ * sfunction task_cpu - The scheduled cpu of the task.
3915+ *
3916+ * General Syntax: task_cpu:long(task:long)
3917+ *
3918+ * @task: task_struct pointer.
3919+ *
3920+ * Description: This function returns the scheduled cpu for the given task.
3921+ */
3922+function task_cpu:long (task:long)
3923+{
3924+ ti = (@defined(@cast(task, "task_struct", "kernel<linux/sched.h>")->stack)
3925+ ? @cast(task, "task_struct", "kernel<linux/sched.h>")->stack
3926+ : @cast(task, "task_struct", "kernel<linux/sched.h>")->thread_info);
3927+ return @cast(ti, "thread_info", "kernel<linux/sched.h>")->cpu
3928+}
3929+
3930+/**
3931+ * sfunction task_open_file_handles - The number of open files of the task.
3932+ *
3933+ * General Syntax: task_open_file_handles:long(task:long)
3934+ *
3935+ * @task: task_struct pointer.
3936+ *
3937+ * Description: This function returns the number of open file handlers for the given task.
3938+ */
3939+function task_open_file_handles:long (task:long)
3940+%( kernel_v >= "2.6.15" %?
3941+%{ /* pure */
3942+ int locked = 0;
3943+ unsigned int count=0, fd, max;
3944+ struct task_struct *t;
3945+ struct files_struct *fs;
3946+ struct fdtable *f;
3947+ t = (struct task_struct *)(long)THIS->task;
3948+ fs = kread(&(t->files));
3949+ f = kread(&(fs->fdt));
3950+ rcu_read_lock();
3951+ locked = 1;
3952+ max = kread(&(f->max_fds));
3953+ for (fd = 0; fd < max; fd++) {
3954+ if ( kread(&(f->fd[fd])) != NULL)
3955+ count ++;
3956+ }
3957+ THIS->__retvalue = count;
3958+ CATCH_DEREF_FAULT();
3959+ if (locked)
3960+ rcu_read_unlock();
3961+%}
3962+%:
3963+%{ /* pure */
3964+ int locked = 0;
3965+ unsigned int count=0, fd, max;
3966+ struct task_struct *t;
3967+ struct files_struct *f;
3968+ t = (struct task_struct *)(long)THIS->task;
3969+ f = kread(&(t->files));
3970+ rcu_read_lock();
3971+ locked = 1;
3972+ max = kread(&(f->max_fds));
3973+ for (fd = 0; fd < max; fd++) {
3974+ if ( kread(&(f->fd[fd])) != NULL)
3975+ count ++;
3976+ }
3977+ THIS->__retvalue = count;
3978+ CATCH_DEREF_FAULT();
3979+ if (locked)
3980+ rcu_read_unlock();
3981+%}
3982+%)
3983+
3984+/**
3985+ * sfunction task_max_file_handles - The max number of open files for the task.
3986+ *
3987+ * General Syntax: task_max_file_handles:long(task:long)
3988+ *
3989+ * @task: task_struct pointer.
3990+ *
3991+ * Description: This function returns the maximum number of file handlers for the given task.
3992+ */
3993+function task_max_file_handles:long (task:long)
3994+%( kernel_v >= "2.6.15" %?
3995+%{ /* pure */
3996+ int locked = 0;
3997+ struct task_struct *t;
3998+ struct files_struct *fs;
3999+ struct fdtable *f;
4000+ t = (struct task_struct *)(long)THIS->task;
4001+ fs = kread (&(t->files));
4002+ f = kread(&(fs->fdt));
4003+ rcu_read_lock();
4004+ locked = 1;
4005+ THIS->__retvalue = kread(&(f->max_fds));
4006+ CATCH_DEREF_FAULT();
4007+ if (locked)
4008+ rcu_read_unlock();
4009+%}
4010+%:
4011+%{ /* pure */
4012+ int locked = 0;
4013+ struct task_struct *t;
4014+ struct files_struct *f;
4015+ t = (struct task_struct *)(long)THIS->task;
4016+ f = kread(&(t->files));
4017+ rcu_read_lock();
4018+ locked = 1;
4019+ THIS->__retvalue = kread(&(f->max_fds));
4020+ CATCH_DEREF_FAULT();
4021+ if (locked)
4022+ rcu_read_unlock();
4023+%}
4024+%)
4025
4026=== added file '.pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/vfs.stp'
4027--- .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/vfs.stp 1970-01-01 00:00:00 +0000
4028+++ .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/vfs.stp 2011-03-22 12:11:00 +0000
4029@@ -0,0 +1,1018 @@
4030+// vfs tapset
4031+// Copyright (C) 2006-2007 IBM Corp.
4032+// Copyright (C) 2007 Intel Corporation.
4033+// Copyright (C) 2007 Bull S.A.S
4034+// Copyright (c) 2008, 2010 Red Hat Inc.
4035+//
4036+// This file is part of systemtap, and is free software. You can
4037+// redistribute it and/or modify it under the terms of the GNU General
4038+// Public License (GPL); either version 2, or (at your option) any
4039+// later version.
4040+
4041+/* generic vfs probes */
4042+
4043+/*
4044+ We don't want to have to do a bdevname() call every time
4045+ we want a devname, so we'll hash them here.
4046+*/
4047+/* XXX: Is this hashing really that helpful? The call to bdevname()
4048+ * isn't very involved... */
4049+global __devnames
4050+function __find_bdevname:string(dev:long, bdev:long)
4051+{
4052+ if (dev in __devnames)
4053+ return __devnames[dev]
4054+ else
4055+ return __devnames[dev] = bdevname(bdev)
4056+}
4057+
4058+/* deprecated */
4059+function ppos_pos:long (ppos:long)
4060+{
4061+ return kernel_pointer(ppos)
4062+}
4063+
4064+function __address_inode:long (page:long)
4065+{
4066+ mapping = page? @cast(page, "page", "kernel")->mapping : 0
4067+ if (mapping == 0)
4068+ return -1
4069+ else
4070+ return @cast(mapping, "address_space", "kernel")->host
4071+}
4072+
4073+function __page_ino:long (page:long)
4074+{
4075+ host = __address_inode(page)
4076+ if (host == -1)
4077+ return -1
4078+ else
4079+ return @cast(host, "inode", "kernel")->i_ino
4080+}
4081+
4082+function __page_dev:long (page:long)
4083+{
4084+ host = __address_inode(page)
4085+ if (host == -1)
4086+ return -1
4087+ return @cast(host, "inode", "kernel")->i_sb->s_dev
4088+}
4089+
4090+function __page_bdev:long (page:long)
4091+{
4092+ host = __address_inode(page)
4093+ if (host == -1)
4094+ return 0
4095+ return @cast(host, "inode", "kernel")->i_sb->s_bdev
4096+}
4097+
4098+function __page_index:long (page:long)
4099+{
4100+ return @cast(page, "page", "kernel")->index
4101+}
4102+
4103+function __file_dev:long (file:long)
4104+{
4105+ d_inode = __file_inode(file)
4106+ if (d_inode == 0)
4107+ return 0
4108+ return @cast(d_inode, "inode", "kernel")->i_sb->s_dev
4109+}
4110+
4111+function __file_bdev:long (file:long)
4112+{
4113+ d_inode = __file_inode(file)
4114+ if (d_inode == 0)
4115+ return 0
4116+ return @cast(d_inode, "inode", "kernel")->i_sb->s_bdev
4117+}
4118+
4119+function __file_ino:long (file:long)
4120+{
4121+ d_inode = __file_inode(file)
4122+ if (d_inode == 0)
4123+ return 0
4124+ return @cast(d_inode, "inode", "kernel")->i_ino
4125+}
4126+
4127+function __file_maxbytes:long (file:long)
4128+{
4129+ d_inode = __file_inode(file)
4130+ if (d_inode == 0)
4131+ return 0
4132+ return @cast(d_inode, "inode", "kernel")->i_sb->s_maxbytes
4133+}
4134+
4135+function __file_filename:string (file:long)
4136+{
4137+ dentry = file
4138+ ? (@defined(@cast(file, "file", "kernel")->f_path->dentry)
4139+ ? @cast(file, "file", "kernel")->f_path->dentry
4140+ : @cast(file, "file", "kernel")->f_dentry)
4141+ : 0
4142+ name = dentry? @cast(dentry, "dentry", "kernel")->d_name->name : 0
4143+ if (name == 0)
4144+ return "NULL"
4145+ else
4146+ return kernel_string(name)
4147+}
4148+
4149+function _get_fopv_size:long (iovp:long, nr_segs:long)
4150+{
4151+ if (iovp) {
4152+ val = 0
4153+ for (i = 0; i < nr_segs; i++)
4154+ val += @cast(iovp, "iovec")[i]->iov_len
4155+ return val
4156+ }
4157+ return -1
4158+}
4159+
4160+/* deprecated */
4161+function _dev_minor:long (dev:long)
4162+{
4163+ return MINOR(dev)
4164+}
4165+
4166+/* deprecated */
4167+function _dev_major:long (dev:long)
4168+{
4169+ return MAJOR(dev)
4170+}
4171+
4172+probe generic.fop.llseek = kernel.function("generic_file_llseek")
4173+{
4174+ dev = __file_dev($file)
4175+ devname = __find_bdevname(dev, __file_bdev($file))
4176+ ino = __file_ino($file)
4177+ file = $file
4178+
4179+ offset = $offset
4180+ origin = $origin
4181+ maxbyte = __file_maxbytes($file)
4182+
4183+ name = "generic_file_llseek"
4184+ argstr = sprintf("%d, %d", $offset, $origin)
4185+}
4186+probe generic.fop.llseek.return = kernel.function("generic_file_llseek").return
4187+{
4188+ name = "generic_file_llseek"
4189+ retstr = sprintf("%d", $return)
4190+ file = $file
4191+ offset = $offset
4192+ origin = $origin
4193+
4194+ error = $return < 0 ? $return : 0
4195+ error_str = error ? errno_str(error) : ""
4196+}
4197+
4198+probe generic.fop.aio_read =
4199+ kernel.function("__generic_file_aio_read") !,
4200+ kernel.function("generic_file_aio_read")
4201+{
4202+ file = $iocb->ki_filp
4203+ dev = __file_dev($iocb->ki_filp)
4204+ devname = __find_bdevname(dev, __file_bdev($iocb->ki_filp))
4205+ ino = __file_ino($iocb->ki_filp)
4206+
4207+ pos = (@defined($pos) ? $pos : kernel_pointer($ppos))
4208+ buf = $iov->iov_base
4209+ count = __iov_length($iov,$nr_segs,1,1) /*FIX ME: should be VERIFY_WRITE instead of 1*/
4210+ name = "generic_file_aio_read"
4211+ argstr = sprintf("%d, %d, %p", count, pos, buf)
4212+
4213+ size = count
4214+ units = "bytes"
4215+}
4216+
4217+probe generic.fop.aio_read.return =
4218+ kernel.function("__generic_file_aio_read").return !,
4219+ kernel.function("generic_file_aio_read").return
4220+{
4221+ file = $iocb->ki_filp
4222+ nr_segs = $nr_segs
4223+ name = "generic_file_aio_read"
4224+ retstr = sprintf("%d", $return)
4225+
4226+ bytes_read = $return > 0 ? $return : 0
4227+ error = $return < 0 ? $return : 0
4228+ error_str = error ? errno_str(error) : ""
4229+
4230+ if ($return > 0) {
4231+ size = $return
4232+ units = "bytes"
4233+ }
4234+}
4235+
4236+probe generic.fop.aio_write = kernel.function("generic_file_aio_write")
4237+{
4238+ file = $iocb->ki_filp
4239+ dev = __file_dev($iocb->ki_filp)
4240+ devname = __find_bdevname(dev, __file_bdev($iocb->ki_filp))
4241+ ino = __file_ino($iocb->ki_filp)
4242+
4243+ pos = $pos
4244+
4245+ count = (@defined($iov)
4246+ ? __iov_length($iov,$nr_segs,1,0) /*FIX ME: should be VERIFY_READ instead of 0*/
4247+ : $count)
4248+ buf = (@defined($iov->iov_base) ? $iov->iov_base : $buf)
4249+ name = "generic_file_aio_write"
4250+ argstr = sprintf("%d, %d, %p", count, pos, buf)
4251+
4252+ size = count
4253+ units = "bytes"
4254+}
4255+probe generic.fop.aio_write.return =
4256+ kernel.function("generic_file_aio_write").return
4257+{
4258+ file = $iocb->ki_filp
4259+ name = "generic_file_aio_write"
4260+ retstr = sprintf("%d", $return)
4261+
4262+ if ($return > 0) {
4263+ size = $return
4264+ units = "bytes"
4265+ }
4266+}
4267+
4268+probe generic.fop.readv = kernel.function("generic_file_readv") ?
4269+{
4270+ dev = __file_dev($filp)
4271+ devname = __find_bdevname(dev, __file_bdev($filp))
4272+ ino = __file_ino($filp)
4273+ file = $filp
4274+
4275+ nr_segs = $nr_segs
4276+ pos = kernel_pointer($ppos)
4277+
4278+ name = "generic_file_readv"
4279+ argstr = sprintf("%d, %d", $nr_segs, pos)
4280+
4281+ size = nr_segs
4282+ units = "segs"
4283+}
4284+probe generic.fop.readv.return = kernel.function("generic_file_readv").return ?
4285+{
4286+ file = $filp
4287+ name = "generic_file_readv"
4288+ retstr = sprintf("%d", $return)
4289+
4290+ bytes_read = $return > 0 ? $return : 0
4291+ error = $return < 0 ? $return : 0
4292+ error_str = error ? errno_str(error) : ""
4293+
4294+ if ($return > 0) {
4295+ size = $return
4296+ units = "bytes"
4297+ }
4298+}
4299+
4300+/* calls __generic_file_write_nolock */
4301+probe generic.fop.writev = kernel.function("generic_file_writev") ?
4302+{
4303+ dev = __file_dev($file)
4304+ devname = __find_bdevname(dev, __file_bdev($file))
4305+ ino = __file_ino($file)
4306+ file = $file
4307+
4308+ nr_segs = $nr_segs
4309+ pos = kernel_pointer($ppos)
4310+
4311+ name = "generic_file_writev"
4312+ argstr = sprintf("%d, %d", $nr_segs, pos)
4313+
4314+ size = nr_segs
4315+ units = "segs"
4316+}
4317+probe generic.fop.writev.return =
4318+ kernel.function("generic_file_writev").return ?
4319+{
4320+ file = $file
4321+ name = "generic_file_writev"
4322+ retstr = sprintf("%d", $return)
4323+
4324+ bytes_written = $return > 0 ? $return : 0
4325+ error = $return < 0 ? $return : 0
4326+ error_str = error ? errno_str(error) : ""
4327+
4328+ if ($return > 0) {
4329+ size = $return
4330+ units = "bytes"
4331+ }
4332+}
4333+
4334+/* checks for aops->readpage, if not defined, return -ENOEXEC
4335+ else assigns generic_file_vm_ops to vma
4336+ add filemap_nopage, filemap_populate */
4337+probe generic.fop.mmap = kernel.function("generic_file_mmap")
4338+{
4339+ file = $file
4340+ dev = __file_dev($file)
4341+ devname = __find_bdevname(dev, __file_bdev($file))
4342+ ino = __file_ino($file)
4343+
4344+ vm_start = $vma->vm_start
4345+ vm_end = $vma->vm_end
4346+ vm_flags = $vma->vm_flags
4347+
4348+ name = "generic_file_mmap"
4349+ argstr = sprintf("0x%x, 0x%x, 0x%x", $vma->vm_start,
4350+ $vma->vm_end, $vma->vm_flags)
4351+}
4352+probe generic.fop.mmap.return = kernel.function("generic_file_mmap").return
4353+{
4354+ file = $file
4355+ name = "generic_file_mmap"
4356+ retstr = sprintf("%d", $return)
4357+
4358+ error = $return < 0 ? $return : 0
4359+ error_str = error ? errno_str(error) : ""
4360+}
4361+
4362+probe generic.fop.open = kernel.function("generic_file_open")
4363+{
4364+ dev = __file_dev($filp)
4365+ devname = __find_bdevname(dev, __file_bdev($filp))
4366+ ino = $inode->i_ino
4367+ file = $filp
4368+
4369+ filename = __file_filename($filp)
4370+ flag = $filp->f_flags
4371+ size = $inode->i_size
4372+
4373+ name = "generic_file_open"
4374+ argstr = sprintf("%d, %d, %s", $inode->i_ino, $filp->f_flags, filename)
4375+}
4376+probe generic.fop.open.return = kernel.function("generic_file_open").return
4377+{
4378+ name = "generic_file_open"
4379+ retstr = sprintf("%d", $return)
4380+}
4381+
4382+probe generic.fop.sendfile = kernel.function("generic_file_sendfile") ?
4383+{
4384+ dev = __file_dev($in_file)
4385+ devname = __find_bdevname($in_file, __file_bdev($in_file))
4386+ ino = __file_ino($in_file)
4387+ file = $in_file
4388+
4389+ count = $count
4390+ ppos = $ppos
4391+
4392+ name = "generic_file_sendfile"
4393+ argstr = sprintf("%d", $count)
4394+
4395+ size = $count
4396+ units = "bytes"
4397+}
4398+probe generic.fop.sendfile.return =
4399+ kernel.function("generic_file_sendfile").return ?
4400+{
4401+ name = "generic_file_sendfile"
4402+ retstr = sprintf("%d", $return)
4403+
4404+ if ($return > 0) {
4405+ size = $return
4406+ units = "bytes"
4407+ }
4408+}
4409+
4410+probe generic.fop.splice_read = kernel.function("generic_file_splice_read") ?
4411+{
4412+ dev = __file_dev($in)
4413+ devname = __find_bdevname(dev, __file_bdev($in))
4414+ ino = __file_ino($in)
4415+ file = $in
4416+ dev_major = MAJOR(dev)
4417+ dev_minor = MINOR(dev)
4418+
4419+ len = $len
4420+ flags = $flags
4421+
4422+ name = "generic_file_splice_read"
4423+ argstr = sprintf("%d, %x", $len, $flags)
4424+
4425+ size = $len
4426+ units = "bytes"
4427+}
4428+probe generic.fop.splice_read.return =
4429+ kernel.function("generic_file_splice_read").return ?
4430+{
4431+ name = "generic_file_splice_read"
4432+ retstr = sprintf("%d", $return)
4433+ file = $in
4434+ ino = __file_ino($in)
4435+ dev = __file_dev($in)
4436+ dev_major = MAJOR(dev)
4437+ dev_minor = MINOR(dev)
4438+
4439+ ret = $return
4440+ error = $return < 0 ? $return : 0
4441+ error_str = error ? errno_str(error) : ""
4442+
4443+ if ($return > 0) {
4444+ size = $return
4445+ units = "bytes"
4446+ }
4447+}
4448+
4449+probe generic.fop.splice_write = kernel.function("generic_file_splice_write") ?
4450+{
4451+ dev = __file_dev($out)
4452+ devname = __find_bdevname(dev, __file_bdev($out))
4453+ ino = __file_ino($out)
4454+ file = $out
4455+
4456+ len = $len
4457+ flags = $flags
4458+
4459+ name = "generic_file_splice_write"
4460+ argstr = sprintf("%d, %x", $len, $flags)
4461+
4462+ size = $len
4463+ units = "bytes"
4464+}
4465+probe generic.fop.splice_write.return =
4466+ kernel.function("generic_file_splice_write").return ?
4467+{
4468+ name = "generic_file_splice_write"
4469+ retstr = sprintf("%d", $return)
4470+
4471+ file = $out
4472+
4473+ error = $return < 0 ? $return : 0
4474+ error_str = error ? errno_str(error) : ""
4475+
4476+ if (error) {
4477+ size = $return
4478+ units = "bytes"
4479+ }
4480+}
4481+
4482+probe generic.fop.read = kernel.function("generic_file_read") ?
4483+{
4484+ dev = __file_dev($filp)
4485+ devname = __find_bdevname(dev, __file_bdev($filp))
4486+ ino = __file_ino($filp)
4487+ file = $filp
4488+
4489+ count = $count
4490+
4491+ name = "generic_file_read"
4492+ argstr = sprintf("%d", $count)
4493+
4494+ size = $count
4495+ units = "bytes"
4496+}
4497+probe generic.fop.read.return = kernel.function("generic_file_read").return ?
4498+{
4499+ name = "generic_file_read"
4500+ retstr = sprintf("%d", $return)
4501+
4502+ if ($return > 0) {
4503+ size = $return
4504+ units = "bytes"
4505+ }
4506+}
4507+
4508+probe generic.fop.write = kernel.function("generic_file_write") ?
4509+{
4510+ dev = __file_dev($file)
4511+ devname = __find_bdevname(dev, __file_bdev($file))
4512+ ino = __file_ino($file)
4513+ file = $file
4514+
4515+ count = $count
4516+
4517+ name = "generic_file_write"
4518+ argstr = sprintf("%d", $count)
4519+
4520+ size = $count
4521+ units = "bytes"
4522+}
4523+probe generic.fop.write.return = kernel.function("generic_file_write").return ?
4524+{
4525+ name = "generic_file_write"
4526+ retstr = sprintf("%d", $return)
4527+
4528+ if ($return > 0) {
4529+ size = $return
4530+ units = "bytes"
4531+ }
4532+}
4533+
4534+/* generic_writepages calls mpage_writepages(mapping, wbc, NULL) */
4535+probe generic.aop.writepages = kernel.function("mpage_writepages")
4536+{
4537+ dev = $mapping->host->i_sb->s_dev
4538+ devname = __find_bdevname(dev, $mapping->host->i_sb->s_bdev)
4539+ ino = $mapping->host->i_ino
4540+
4541+ nr_to_write = $wbc->nr_to_write
4542+
4543+ name = "generic_writepages"
4544+ argstr = sprintf("%d", $wbc->nr_to_write)
4545+
4546+ size = $wbc->nr_to_write
4547+ units = "pages"
4548+}
4549+probe generic.aop.writepages.return = kernel.function("mpage_writepages").return
4550+{
4551+ name = "generic_writepages"
4552+ retstr = sprintf("%d", $return)
4553+}
4554+
4555+probe vfs.do_sync_read = kernel.function("do_sync_read")
4556+{
4557+ dev = __file_dev($filp)
4558+ devname = __find_bdevname(dev, __file_bdev($filp))
4559+ ino = __file_ino($filp)
4560+ file = $filp
4561+
4562+ len = $len
4563+ pos = kernel_pointer($ppos)
4564+ buf = $buf
4565+
4566+ name = "do_sync_read"
4567+ argstr = sprintf("%d, %d, %p", $len, pos, $buf)
4568+
4569+ size = $len
4570+ units = "bytes"
4571+ bytes_to_read = $len
4572+}
4573+probe vfs.do_sync_read.return = kernel.function("do_sync_read").return
4574+{
4575+ name = "do_sync_read"
4576+ retstr = sprintf("%d", $return)
4577+
4578+ bytes_to_read = $len
4579+ ret = $return
4580+ bytes_read = $return > 0 ? $return : 0
4581+ error = $return < 0 ? $return : 0
4582+ error_str = error ? errno_str(error) : ""
4583+
4584+ if ($return > 0) {
4585+ size = $return
4586+ units = "bytes"
4587+ }
4588+}
4589+
4590+probe vfs.do_sync_write = kernel.function("do_sync_write")
4591+{
4592+ dev = __file_dev($filp)
4593+ devname = __find_bdevname(dev, __file_bdev($filp))
4594+ ino = __file_ino($filp)
4595+ file = $filp
4596+
4597+ len = $len
4598+ pos = kernel_pointer($ppos)
4599+ buf = $buf
4600+ bytes_to_write = $len
4601+
4602+ name = "do_sync_write"
4603+ argstr = sprintf("%d, %d , %p", $len, pos, $buf)
4604+
4605+ size = $len
4606+ units = "bytes"
4607+}
4608+probe vfs.do_sync_write.return = kernel.function("do_sync_write").return
4609+{
4610+ name = "do_sync_write"
4611+ retstr = sprintf("%d", $return)
4612+
4613+ bytes_to_write = $len
4614+ pos = kernel_pointer($ppos)
4615+ ret = $return
4616+ bytes_written = $return > 0 ? $return : 0
4617+ error = $return < 0 ? $return : 0
4618+ error_str = error ? errno_str(error) : ""
4619+
4620+ if (error) {
4621+ size = $return
4622+ units = "bytes"
4623+ }
4624+}
4625+
4626+probe vfs.block_sync_page = kernel.function("block_sync_page")
4627+{
4628+ dev = __page_dev($page)
4629+ devname = __find_bdevname(dev, __page_bdev($page))
4630+ ino = __page_ino($page)
4631+
4632+ # 'page_index' is deprecated
4633+ page_index = __page_index($page)
4634+ index = __page_index($page)
4635+
4636+ name = "block_sync_page"
4637+ argstr = sprintf("%d", index)
4638+
4639+ size = 1
4640+ units = "pages"
4641+}
4642+probe vfs.block_sync_page.return = kernel.function("block_sync_page").return
4643+{
4644+ name = "block_sync_page"
4645+ retstr = sprintf("N/A")
4646+}
4647+
4648+probe vfs.buffer_migrate_page = kernel.function("buffer_migrate_page") ?
4649+{
4650+ dev = __page_dev($page)
4651+ ino = __page_ino($page)
4652+ devname = __find_bdevname(dev,__page_bdev($page))
4653+
4654+ # 'page_index' is deprecated
4655+ page_index = __page_index($page)
4656+ index = __page_index($page)
4657+
4658+ name = "buffer_migrate_page"
4659+ argstr = sprintf("%d", index)
4660+
4661+ size = 1
4662+ units = "pages"
4663+}
4664+probe vfs.buffer_migrate_page.return =
4665+ kernel.function("buffer_migrate_page").return ?
4666+{
4667+ name = "buffer_migrate_page"
4668+ retstr = sprintf("%d", $return)
4669+
4670+ if ($return == 0) {
4671+ size = 1
4672+ units = "pages"
4673+ }
4674+}
4675+
4676+/* default if aop not set, __set_page_dirty_nobuffers usually used if set */
4677+probe vfs.__set_page_dirty_buffers = kernel.function("__set_page_dirty_buffers")
4678+{
4679+ dev = __page_dev($page)
4680+ devname = __find_bdevname(dev, __page_bdev($page))
4681+ ino = __page_ino($page)
4682+
4683+ index = __page_index($page)
4684+
4685+ name = "__set_page_dirty_buffers"
4686+ argstr = sprintf("%d", index)
4687+
4688+ size = 1
4689+ units = "pages"
4690+}
4691+probe vfs.__set_page_dirty_buffers.return =
4692+ kernel.function("__set_page_dirty_buffers").return
4693+{
4694+ name = "__set_page_dirty_buffers"
4695+ retstr = sprintf("%d", $return)
4696+
4697+%( kernel_v >= "2.6.17" %?
4698+ if ($return == 1)
4699+%:
4700+ if ($return == 0)
4701+%)
4702+ {
4703+ size = 1
4704+ units = "pages"
4705+ }
4706+}
4707+
4708+probe vfs.do_mpage_readpage = kernel.function("do_mpage_readpage")
4709+{
4710+ dev = __page_dev($page)
4711+ devname = __find_bdevname(dev, __page_bdev($page))
4712+ ino = __page_ino($page)
4713+
4714+ index = __page_index($page)
4715+
4716+ name = "do_mpage_readpage"
4717+ argstr = sprintf("%d", index)
4718+
4719+ size = 1
4720+ units = "pages"
4721+}
4722+probe vfs.do_mpage_readpage.return = kernel.function("do_mpage_readpage").return
4723+{
4724+ name = "do_mpage_readpage"
4725+ retstr = sprintf("0x%x", $return)
4726+
4727+ size = 1
4728+ units = "pages"
4729+}
4730+
4731+probe vfs.add_to_page_cache =
4732+ kernel.function("add_to_page_cache_locked") !,
4733+ kernel.function("add_to_page_cache")
4734+{
4735+ dev = $mapping->host->i_sb->s_dev
4736+ devname = __find_bdevname(dev, $mapping->host->i_sb->s_bdev)
4737+ ino = $mapping->host->i_ino
4738+
4739+ index = $offset
4740+ nrpages = $mapping->nrpages
4741+ size = $mapping->nrpages
4742+ units = "pages"
4743+
4744+ name = "vfs.add_to_page_cache"
4745+ argstr = sprintf("%d, %d", ino, $offset)
4746+}
4747+
4748+probe vfs.add_to_page_cache.return =
4749+ kernel.function("add_to_page_cache_locked").return !,
4750+ kernel.function("add_to_page_cache").return
4751+{
4752+ name = "vfs.add_to_page_cache"
4753+ retstr = sprintf("%d", $return)
4754+
4755+ if ($return == 0) {
4756+ size = 1
4757+ units = "pages"
4758+ }
4759+}
4760+
4761+probe vfs.remove_from_page_cache = kernel.function("__remove_from_page_cache")
4762+{
4763+ dev = __page_dev($page)
4764+ devname = __find_bdevname(dev, __page_bdev($page))
4765+ ino = __page_ino($page)
4766+
4767+ index = __page_index($page)
4768+
4769+ name = "vfs.remove_from_page_cache"
4770+ argstr = sprintf("%d", ino)
4771+}
4772+probe vfs.remove_from_page_cache.return =
4773+ kernel.function("__remove_from_page_cache").return
4774+{
4775+ name = "vfs.remove_from_page_cache"
4776+ retstr = sprintf("N/A")
4777+}
4778+
4779+probe vfs.read = kernel.function("vfs_read")
4780+{
4781+ file = $file
4782+ pos = $pos
4783+ buf = $buf
4784+ bytes_to_read = $count
4785+ dev = __file_dev($file)
4786+ devname = __find_bdevname(dev, __file_bdev($file))
4787+ ino = __file_ino($file)
4788+
4789+ name = "vfs.read"
4790+ argstr = sprintf("%d, %d, %p", $count, $pos, $buf)
4791+}
4792+
4793+probe vfs.read.return = kernel.function("vfs_read").return
4794+{
4795+ name = "vfs.read"
4796+ retstr = sprintf("%d", $return)
4797+
4798+ file = $file
4799+ pos = $pos
4800+ buf = $buf
4801+ bytes_to_read = $count
4802+ dev = __file_dev($file)
4803+ devname = __find_bdevname(dev, __file_bdev($file))
4804+ ino = __file_ino($file)
4805+
4806+ ret = $return
4807+ bytes_read = $return > 0 ? $return : 0
4808+ error = $return < 0 ? $return : 0
4809+ error_str = error ? errno_str(error) : ""
4810+}
4811+
4812+probe vfs.readv = kernel.function("vfs_readv")
4813+{
4814+ file = $file
4815+ dev = __file_dev($file)
4816+ devname = __find_bdevname(dev, __file_bdev($file))
4817+ ino = __file_ino($file)
4818+ pos = $pos
4819+ vec = $vec
4820+ vlen = $vlen
4821+ bytes_to_read = _get_fopv_size($vec, $vlen)
4822+
4823+ name = "vfs.read"
4824+ argstr = sprintf("%d, %d, %p", bytes_to_read, $pos, $vec)
4825+}
4826+
4827+probe vfs.readv.return = kernel.function("vfs_readv").return
4828+{
4829+ name = "vfs.readv"
4830+ retstr = sprintf("%d", $return)
4831+
4832+ file = $file
4833+ dev = __file_dev($file)
4834+ devname = __find_bdevname(dev, __file_bdev($file))
4835+ ino = __file_ino($file)
4836+ pos = $pos
4837+ vec = $vec
4838+ vlen = $vlen
4839+ bytes_to_read = _get_fopv_size($vec, $vlen)
4840+
4841+ ret = $return
4842+ bytes_read = $return > 0 ? $return : 0
4843+ error = $return < 0 ? $return : 0
4844+ error_str = error ? errno_str(error) : ""
4845+}
4846+
4847+probe vfs.write = kernel.function("vfs_write")
4848+{
4849+ file = $file
4850+ pos = $pos
4851+ buf = $buf
4852+ bytes_to_write = $count
4853+ dev = __file_dev($file)
4854+ devname = __find_bdevname(dev, __file_bdev($file))
4855+ ino = __file_ino($file)
4856+
4857+ name = "vfs.write"
4858+ argstr = sprintf("%d, %d, %p", $count, $pos, $buf)
4859+}
4860+
4861+probe vfs.write.return = kernel.function("vfs_write").return
4862+{
4863+ name = "vfs.write"
4864+ retstr = sprintf("%d", $return)
4865+
4866+ file = $file
4867+ pos = $pos
4868+ buf = $buf
4869+ bytes_to_write = $count
4870+ dev = __file_dev($file)
4871+ devname = __find_bdevname(dev, __file_bdev($file))
4872+ ino = __file_ino($file)
4873+
4874+ ret = $return
4875+ bytes_written = $return > 0 ? $return : 0
4876+ error = $return < 0 ? $return : 0
4877+ error_str = error ? errno_str(error) : ""
4878+}
4879+
4880+probe vfs.writev = kernel.function("vfs_writev")
4881+{
4882+ file = $file
4883+ dev = __file_dev($file)
4884+ devname = __find_bdevname(dev, __file_bdev($file))
4885+ ino = __file_ino($file)
4886+ pos = $pos
4887+ vlen = $vlen
4888+ vec = $vec
4889+ bytes_to_write = _get_fopv_size($vec, $vlen)
4890+
4891+ name = "vfs.writev"
4892+ argstr = sprintf("%d, %d, %p", bytes_to_write, $pos, $vec)
4893+}
4894+
4895+probe vfs.writev.return = kernel.function("vfs_writev").return
4896+{
4897+ name = "vfs.writev"
4898+ retstr = sprintf("%d", $return)
4899+
4900+ file = $file
4901+ dev = __file_dev($file)
4902+ devname = __find_bdevname(dev, __file_bdev($file))
4903+ ino = __file_ino($file)
4904+ pos = $pos
4905+ vlen = $vlen
4906+ vec = $vec
4907+ bytes_to_write = _get_fopv_size($vec, $vlen)
4908+
4909+ ret = $return
4910+ bytes_written = $return > 0 ? $return : 0
4911+ error = $return < 0 ? $return : 0
4912+ error_str = error ? errno_str(error) : ""
4913+}
4914+
4915+probe _vfs.generic_file_readonly_mmap =
4916+ kernel.function("generic_file_readonly_mmap")
4917+{
4918+ file = $file
4919+ vma = $vma
4920+
4921+ name = "_vfs.generic_file_readonly_mmap"
4922+ argstr = sprintf("%p, %p", $file, $vma)
4923+}
4924+
4925+probe _vfs.generic_file_readonly_mmap.return =
4926+ kernel.function("generic_file_readonly_mmap").return
4927+{
4928+ name = "_vfs.generic_file_readonly_mmap"
4929+ retstr = sprintf("%d", $return)
4930+
4931+ file = $file
4932+ vma = $vma
4933+
4934+ ret = $return
4935+ error = $return < 0 ? $return : 0
4936+ error_str = error ? errno_str(error) : ""
4937+}
4938+
4939+probe _vfs.generic_block_bmap = kernel.function("generic_block_bmap")
4940+{
4941+ mapping = $mapping
4942+ block = $block
4943+ get_block = $get_block
4944+
4945+ name = "_vfs.generic_block_bmap"
4946+ argstr = sprintf("%p, %p, %p", $mapping, $block, $get_block)
4947+}
4948+
4949+probe _vfs.generic_commit_write = kernel.function("generic_commit_write") ?
4950+{
4951+ file = $file
4952+ page = $page
4953+ from = $from
4954+ to = $to
4955+
4956+ name = "_vfs.generic_commit_write"
4957+ argstr = sprintf("%p, %p, %d, %d", $file, $page, $from, $to)
4958+}
4959+
4960+probe _vfs.block_prepare_write = kernel.function("__block_prepare_write")
4961+{
4962+ _inode = $inode
4963+ page = $page
4964+ # write_from and write_upto are deprecated
4965+ write_from = $from
4966+ write_upto = $to
4967+ from = $from
4968+ to = $to
4969+
4970+ name = "_vfs.generic_commit_write"
4971+ argstr = sprintf("%p, %d, %d", $page, $from, $to)
4972+}
4973+
4974+probe _vfs.block_prepare_write.return =
4975+ kernel.function("__block_prepare_write").return
4976+{
4977+ name = "_vfs.block_prepare_write"
4978+ retstr = sprintf("%d", $return)
4979+
4980+ _inode = $inode
4981+ page = $page
4982+ # write_from and write_upto are deprecated
4983+ write_from = $from
4984+ write_upto = $to
4985+ from = $from
4986+ to = $to
4987+
4988+ ret = $return
4989+ error = ret < 0 ? ret : 0
4990+ error_str = error ? errno_str(error) : ""
4991+}
4992+
4993+probe _vfs.block_write_begin = kernel.function("block_write_begin") ?
4994+{
4995+ file = $file
4996+ pos = $pos
4997+ len = $len
4998+ flags = $flags
4999+
5000+ _inode = __address_inode($mapping)
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches