如何在Linux中的内存中收到有关修改的通知 [英] How to get notified of modification in the memory in Linux

查看:69
本文介绍了如何在Linux中的内存中收到有关修改的通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Linux的用户空间程序中,我从堆中通过分配获得了一块内存,然后将指针分配给在其他线程中运行的许多其他组件以供使用.当上述内存被修改时,我想得到通知.我当然可以开发一个自定义用户空间解决方案,以供其他组件尝试修改内存时使用.在我的情况下,问题是这些是旧组件,它们可以在许多情况下写入内存.因此,我想知道是否有类似的API,例如inotify(在文件更改时得到通知)或其他方法,以便在内存变化时获得通知.

In a userspace program in Linux, I get a piece of memory via allocation from the heap, then the pointer is distributed to a lot of other components running in other threads to use. I would like to get notified when the said piece of memory is modified. I can of course develop a custom userspace solution for other components to use when they try to modify the memory. The problem in my case is that these are legacy components and they can write to memory in many occasions. So I'm wondering whether there is a similar API like inotify (get notified when file is changed) or other approaches in order to get notified when a piece of memory is changed.

我考虑过使用mmap和inotify,如果不清除更改,显然不起作用.任何建议表示赞赏:-)

I considered using mmap and inotify, which obviously won't work if the changes are not flushed. Any suggestions are appreciated :-)

推荐答案

CAN 添加 启动观看 ,它将在 <在mmap-ed文件上显示strong> msync() .

这需要将Linux内核修补到 启用对新inotify手表的支持 .该修补程序添加了一个新的标志 IN_SYNC -一个新的inotify事件,只要在mmap-ed文件上执行msync()就会触发该新事件.

This requires patching the Linux Kernel to enable support for a new inotify watch. The patch adds a new flag IN_SYNC - a new inotify event that is triggered whenever msync() is carried out on the mmap-ed file.

补丁已在Linux内核v2.6.37上进行了测试.

Patch has been tested on v2.6.37 of the Linux Kernel.

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上进行了测试.

Patch has been tested on v2.6.37 of the Linux Kernel.

这篇关于如何在Linux中的内存中收到有关修改的通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆