0

I'd like to trace writes on a specific file, so I've had the idea that I could do this:

I create a probe on do_sys_open, if the filename argument matches the pattern I'm looking for I use a trigger to enable a return probe that fetches the returned file descriptor id (it's $retval). This return probe would have a filter on the common_pid because I'm only interested in the fds returned by do_sys_open calls that just opened the filename I want to monitor. The return probe takes the fd and enables another probe on sys_write with a filter on the common_pid and the fd. My hope is that this way I would be able to only trace write operations on the one file that I'm monitoring.

The problem is that this doesn't work with multi threaded processes. If one process calls open twice at the same time (using two threads) the above described mechanism could fail. Now I'm trying to figure out a way to do this association between the entry of do_sys_open and the return probe on do_sys_open and I would be happy about any suggestions.

PS: I'm not sure if that question belongs to stackoverflow or unix & linux.

replay
  • 3,569
  • 3
  • 21
  • 30

1 Answers1

0

Your approach is wrong.

First of all file descriptor numbers are per process, so you automagically catch virtually anyone writing anything to using such an fd number, which may or may not result in writing to the file you are interested in.

Further, sys_write is too high in the stack to catch all legitimate writers.

Normally you would look up the inode of the file you are interested in and filter based on that on an appropriate write func.

However, "monitoring writes to a file" is still somewhat ambiguous, as it is unclear what would you like to happen if someone was to unlink the original name and create a new file with that name. If you want to deal with, you indeed be better off with catching threads somewhere in open, seeing what inode was looked up and adding them to your primitives so that you know to monitor it.

In any case, fd-based monitoring is fundamentally broken.

  • Thanks a lot for that. In fact today I came to the same conclusion which is to filter by inode number in a probe on the `vfs_write` function and that seems to work. As you mentioned already it doesn't cover the case that this file gets deleted and recreated, but that's fine, I don't need that. – replay Jan 27 '16 at 16:07
  • 1
    You are not supposed to filter by inode number, but a pointer to an inode. Otherwise you risk confusion with threads writing stuff on a separate filesystem. –  Jan 27 '16 at 16:09
  • Ok, that makes sense. But in that case how do I even know the memory address of this `struct inode` which I'd need to filter for? Would I first need to setup another kprobe to output the address of that struct and then I could filter for it? Does the memory address of the `struct inode` never change? – replay Jan 27 '16 at 16:11
  • 1
    Well you have to look it up before you set up the probe and stop monitoring it as references to the inode drop and it gets freed, forgot to explicitly state this. Regardless, all of this can be reasonably easily done with systemtap. Also what you are missing is writes through mmapped areas, which is likely acceptable. –  Jan 27 '16 at 16:41