如何在Linux中获得内存修改通知
发布时间:2020-12-13 23:03:08 所属栏目:Linux 来源:网络整理
导读:在 Linux中的用户空间程序中,我通过堆中的分配获得一块内存,然后将指针分发给在其他线程中运行的许多其他组件以供使用.我希望在修改所述内存时得到通知.我当然可以开发一个自定义用户空间解决方案,供其他组件在尝试修改内存时使用.我的问题是这些是遗留组件,
在
Linux中的用户空间程序中,我通过堆中的分配获得一块内存,然后将指针分发给在其他线程中运行的许多其他组件以供使用.我希望在修改所述内存时得到通知.我当然可以开发一个自定义用户空间解决方案,供其他组件在尝试修改内存时使用.我的问题是这些是遗留组件,它们可以在很多场合写入内存.所以我想知道是否有像inotify这样的类似API(在文件被更改时得到通知)或其他方法,以便在更改内存时得到通知.
我考虑过使用mmap和inotify,如果没有刷新更改,这显然是行不通的.任何建议表示赞赏:-) 解决方法
您可以添加一个
inotify watch,它将在mmap-ed文件的
msync()上触发.
这需要将Linux内核修补到enable support for a new inotify watch.修补程序添加一个新标志IN_SYNC – 一个新的inotify事件,只要在mmap-ed文件上执行msync()就会触发该事件. 补丁已经在Linux内核的v2.6.37上进行了测试. From 83edf446e92c86c738337ca4a35eab48e2f4e0eb Mon Sep 17 00:00:00 2001 From: Chinmay V S <cvs268@gmail.com> Date: Mon,17 Jun 2013 13:53:57 +0800 Subject: [PATCH] Add mmap-ed file support to inotify This patch adds a new flag IN_SYNC. This is a new inotify event that is triggered whenever msync() is carried out on a mmap-ed file. Signed-off-by: Chinmay V S <cvs268@gmail.com> --- fs/sync.c | 5 +++++ include/linux/fsnotify.h | 16 ++++++++++++++++ include/linux/fsnotify_backend.h | 1 + include/linux/inotify.h | 3 ++- mm/msync.c | 4 ++++ 5 files changed,28 insertions(+),3 deletions(-) diff --git a/fs/sync.c b/fs/sync.c index ba76b96..174c2af 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -16,6 +16,7 @@ #include <linux/buffer_head.h> #include <linux/backing-dev.h> #include "internal.h" +#include <linux/fsnotify.h> #define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| SYNC_FILE_RANGE_WAIT_AFTER) @@ -190,6 +191,10 @@ static int do_fsync(unsigned int fd,int datasync) ret = vfs_fsync(file,datasync); fput(file); } + + if (!ret) + fsnotify_sync(file->f_path.dentry); + return ret; } diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index b10bcde..ef211fb 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -224,6 +224,22 @@ static inline void fsnotify_modify(struct file *file) } /* + * fsnotify_sync - file was synced + */ +static inline void fsnotify_sync(struct dentry *dentry) +{ + struct inode *inode = dentry->d_inode; + u32 mask = FS_SYNC; + + if (S_ISDIR(inode->i_mode)) + mask |= FS_ISDIR; + + fsnotify_parent(NULL,dentry,mask); + fsnotify(inode,mask,inode,FSNOTIFY_EVENT_INODE,NULL,0); + +} + +/* * fsnotify_open - file was opened */ static inline void fsnotify_open(struct file *file) diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 7380763..35b5cb8 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -36,6 +36,7 @@ #define FS_DELETE 0x00000200 /* Subfile was deleted */ #define FS_DELETE_SELF 0x00000400 /* Self was deleted */ #define FS_MOVE_SELF 0x00000800 /* Self was moved */ +#define FS_SYNC 0x00001000 /* File was synced */ #define FS_UNMOUNT 0x00002000 /* inode on umount fs */ #define FS_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ diff --git a/include/linux/inotify.h b/include/linux/inotify.h index d33041e..244a132 100644 --- a/include/linux/inotify.h +++ b/include/linux/inotify.h @@ -38,6 +38,7 @@ struct inotify_event { #define IN_DELETE 0x00000200 /* Subfile was deleted */ #define IN_DELETE_SELF 0x00000400 /* Self was deleted */ #define IN_MOVE_SELF 0x00000800 /* Self was moved */ +#define IN_SYNC 0x00001000 /* File was synced */ /* the following are legal events. they are sent as needed to any watch */ #define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted */ @@ -64,7 +65,7 @@ struct inotify_event { #define IN_ALL_EVENTS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF | - IN_MOVE_SELF) + IN_MOVE_SELF | IN_SYNC) /* Flags for sys_inotify_init1. */ #define IN_CLOEXEC O_CLOEXEC diff --git a/mm/msync.c b/mm/msync.c index 632df45..b1665ac 100644 --- a/mm/msync.c +++ b/mm/msync.c @@ -13,6 +13,7 @@ #include <linux/file.h> #include <linux/syscalls.h> #include <linux/sched.h> +#include <linux/fsnotify.h> /* * MS_SYNC syncs the entire file - including mappings. @@ -83,6 +84,9 @@ SYSCALL_DEFINE3(msync,unsigned long,start,size_t,len,int,flags) get_file(file); up_read(&mm->mmap_sem); error = vfs_fsync(file,0); + if (!error) + fsnotify_sync(file->f_path.dentry); + fput(file); if (error || start >= end) goto out; -- 1.8.2 补丁已经在Linux内核的v2.6.37上进行了测试. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |