There might be a better tool or easier way to do this, but the method works for me 🙂
I was looking into a large number of getfattr requests on one of our CentOS 6 NFS Servers, and was curious what files all the requests were for and where they were coming from. The where part just requires the always helpful tcpdump…
# tcpdump -i bond0 'tcp port nfs'
....
08:58:18.971667 IP xxxxxx.3434118295 > xxxxx.sdsc.edu.nfs: 128 getattr fh Unknown/0100060188D45B4900CC684F00000000000000000...
This alone gets us most of the information we are looking for with the exception of which file was being acted on. It does give us the NFS file handle though, and that is easy enough to translate. Using the chart on page 5 of the following pdf, we see the file handle has the format…
Length | Bytes | Field Name | Meaning | Typical Values |
1 | 1 | fb_version | NFS version | Always 1 |
1 | 2 | fb_auth_type | Authentication method | Always 0 |
1 | 3 | fb_fsid_type | File system ID encoding method | Always 0 |
1 | 4 | fb_fileid_type | File ID encoding method | Always either 0, 1, or 2 |
4 | 5-8 | xdev | Major/Minor number of exported device | Major number 3 (IDE), 8 (SCSI) |
4 | 9-12 | xino | Export inode number | Almost always 2 |
4 | 13-16 | ino | Inode number | 2 for /, 19 for /home/foo |
4 | 17-20 | gen_no | Generation number | 0xFF16DDF1, 0x3F6AE3C0 |
4 | 21-24 | par_ino_no | Parent’s inode number | 2 for /, 19 for /home |
8 | 25-32 | Padding for NFSv2 | Always 0 | |
32 | 33-64 | Unused by Linux |
…so now we just need to split up our file handle to get the inode.
0 | fb_version |
1 | fb_auth_type |
0 | fb_fsid_type |
0 | fb_fileid_type |
0601 | xdev |
88D4 | xino |
5B49 | ino (what we want) |
00CC | gen_no |
684F | par_ino_no |
00000000 | Padding |
000000000… | ?? |
Then we just need to convert from hex to decimal and pass it to find…
$ echo $((0x5b49))
23369
find /path/to/export -inum 23369
And we get to take a bit of a shortcut here as this system only had a single export, so no need to figure out what filesystem it was coming from.