This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
On Thu, Mar 20, 2008 at 12:17:58PM +0800, Eugene Teo wrote:
> Hi Dave,
>
> <quote sender="dave-systemtap@skeptech.org">
> > So, I'm looking at some of the existing code on the wiki
> > and the internet at large which probes vfs_(read|write) for various
> > things. For my purpose, it'd be handy to get a filename back from the
> > probe instead of (or in addition to) an inode number.
> >
> > for example:
> >
> > probe kernel.function ("vfs_write"),
> > kernel.function ("vfs_read")
> > {
> > fname = $file->f_dentry-> <something>
> >
> > printf ("%s(%d,%d) %s\n",
> > execname(), pid(), uid(), fname)
> > }
>
> It would be useful if you also include the kernel version, as structures
> may change in between versions.
This happens to be 2.6.16.19. I'm curious, how often do systemtap
scripts need to change in practice because of data struture changes in
the kernel?
>
> linux-2.6:
> 779 struct file {
> [...]
> 788 struct path f_path;
> 789 #define f_dentry f_path.dentry
> 790 #define f_vfsmnt f_path.mnt
>
> It is possible to get hold of the path name (including the filename)
> using d_path().
>
> I have not tested it, but I have a piece of code I used in a script
> elsewhere that you can probably amend and reuse:
>
> function get_d_path_info:string (task:long, fd:long) %{
> struct task_struct *p = (struct task_struct
> *)((long)THIS->task);
> struct files_struct *files = kread(&p->files);
> char *page = (char *)__get_free_page(GFP_KERNEL);
> struct file *filp;
> struct dentry *dentry;
> struct vfsmount *vfsmnt;
>
> spin_lock(&files->file_lock);
> filp = fcheck_files(files, THIS->fd);
> dentry = kread(&filp->f_path.dentry);
> vfsmnt = kread(&filp->f_path.mnt);
> snprintf(THIS->__retvalue, MAXSTRINGLEN, " %s",
> d_path(dentry, vfsmnt, page, PAGE_SIZE));
> free_page((unsigned long)page);
> spin_unlock(&files->file_lock);
> CATCH_DEREF_FAULT();
> %}
Cool thanks. So based on that code I've chopped out the following function:
function get_path:string (dentry:dentry *,vsmnt:vsmount *) %{
char *page = (char *)__get_free_page(GFP_KERNEL);
sprintf("%s",d_path(dentry, vfsmnt, page, PAGE_SIZE));
free_page((unsigned long)page);
%}
and am attempting to pass pointers to the requisite structs like so:
path=get_path($file->f_dentry, $file->f_vfsmnt)
This is, as you probably guessed, giving me a parse error:
parse error: expected 'string' or 'long'
I guess this means I'm only allowed to pass strings or longs into
embedded C functions. I guess it's time to do some more rtfm'ing.
parent=kernel_string($file->pathsearch) works perfectly btw.
Thanks
--dave
> Thanks,
> Eugene
Attachment:
pgp00000.pgp
Description: PGP signature
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |