#! /usr/bin/env stap # nfsd client tables global file_to_path_hash global nfsd_stat_read global nfsd_stat_write function nullstr:long (str:string) %{ THIS->__retvalue = (STAP_ARG_str[0] == '\0'); return; %} function daddr_to_string:string(daddr:long) %{ /* pure */ union { __u32 d; unsigned char addr[4]; } u; u.d = STAP_ARG_daddr; snprintf(THIS->__retvalue, MAXSTRINGLEN, "%d.%d.%d.%d", u.addr[0], u.addr[1], u.addr[2], u.addr[3]); %} probe module("nfsd").function("nfsd_vfs_read").return { uid = $rqstp->rq_cred->cr_uid if($file) { if($file->f_path->dentry) { path = file_to_path_hash[$file->f_path->dentry->d_inode, $file->f_path->mnt->mnt_mountpoint->d_inode] if(nullstr(path)) { path = sprintf("%s/%s", d_name($file->f_path->mnt->mnt_mountpoint), reverse_path_walk($file->f_path->dentry)) file_to_path_hash[$file->f_path->dentry->d_inode, $file->f_path->mnt->mnt_mountpoint->d_inode] = path } } nfsd_stat_read[uid,path,addr_from_rqst($rqstp)] += $count[0] } } probe module("nfsd").function("nfsd_vfs_write").return { uid = $rqstp->rq_cred->cr_uid if($file) { if($file->f_path->dentry) { path = file_to_path_hash[$file->f_path->dentry->d_inode, $file->f_path->mnt->mnt_mountpoint->d_inode] if(nullstr(path)) { path = sprintf("%s/%s", d_name($file->f_path->mnt->mnt_mountpoint), reverse_path_walk($file->f_path->dentry)) file_to_path_hash[$file->f_path->dentry->d_inode, $file->f_path->mnt->mnt_mountpoint->d_inode] = path } } nfsd_stat_write[uid,path,addr_from_rqst($rqstp)] += $cnt[0] } } probe timer.ms(60000) { foreach ([uid,path,addr] in nfsd_stat_read) printf("%d,read,%d,%d,%s,%s\n", gettimeofday_s(), nfsd_stat_read[uid,path,addr], uid,path,daddr_to_string(addr)) foreach ([uid,path,addr] in nfsd_stat_write) printf("%d,write,%d,%d,%s,%s\n", gettimeofday_s(), nfsd_stat_write[uid,path,addr], uid,path,daddr_to_string(addr)) delete file_to_path_hash delete nfsd_stat_read delete nfsd_stat_write }