由于安全等问题,利用系统调用监控文件,并不能知道究竟是哪个进程对文件进行了修改。
这样我们就最多只能知道某个时间发生了时间,再根据时间点去查看相关的log,还是比较麻烦,不方便。
这种条件下,就只能修改kernel,以达到我们的效果,修改 fsnotify 函数如下:
void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, const char *file_name, u32 cookie)
{
struct fsnotify_group *group;
struct fsnotify_event *event = NULL;
int idx;
/* global tests shouldn't care about events on child only the specific event */
__u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
if (list_empty(&fsnotify_groups))
return;
if (!(test_mask & fsnotify_mask))
return;
if (!(test_mask & to_tell->i_fsnotify_mask))
return;
/*
* SRCU!! the groups list is very very much read only and the path is
* very hot. The VAST majority of events are not going to need to do
* anything other than walk the list so it's crazy to pre-allocate.
*/
idx = srcu_read_lock(&fsnotify_grp_srcu);
list_for_each_entry_rcu(group, &fsnotify_groups, group_list) {
if (test_mask & group->mask) {
if (!group->ops->should_send_event(group, to_tell, mask))
continue;
if (!event) {
// added by yongming.li for test
char my_info [256]= {0x00};
sprintf(my_info, "%d_%s:%d_%s:", current->pid,current->comm,current->real_parent->pid,current->real_parent->comm);
event = fsnotify_create_event(to_tell, mask, data,
data_is,strcat(my_info,file_name), cookie,
GFP_KERNEL);
/* shit, we OOM'd and now we can't tell, maybe
* someday someone else will want to do something
* here */
if (!event)
break;
}
group->ops->handle_event(group, event);
}
}
srcu_read_unlock(&fsnotify_grp_srcu, idx);
其中current 为当前运行的进程的tast_struct的指针,通过current->pid,current->comm 就可以得到,当前操作文件的进程的ID和名字,并一起传给user空间。
最后看下效果图,红线部分即为新加的进程信息功能:
关于为什么不在系统调用的时候显示具体哪个用户或者哪个进程修改了文件,可以看如下解释:(随便说下Robert Love 写的linux kernel书真的很不错)
Hi, Chris.
> On a newsgroup someone was using inotify, but was asking if there was
> any way to also determine which process/user had caused the notification.
> Is this something that would make sense (as an optional bit of
> information) in inotify?
It is definitely something that could be added, technically speaking.
I have been hesitant, though. I do not want feature creep to be a
deterrent to acceptance into the Linux kernel. I also think that there
could be arguments about security. Sending the event is one thing,
telling which pid (and thus what user, etc.) caused the event is
another. For example, we can make the argument that read rights on a
file are tantamount to the right to receive a read event. But can we
say that read rights are enough for a unprivileged user to know that
root at pid 820 is writing the file? I don't know.
I'd add it if there were consensus. I don't know that it makes sense,
though.
Robert Love