[CRIU] [PATCH 2/3] fsnotify: merge fanotify mark image into fanotify image (v3)
Andrey Vagin
avagin at openvz.org
Tue Sep 2 07:49:31 PDT 2014
All marks are collected in a list and then they are written in
the fanotify image as a repeated field.
This images merge reduces the amount of image files criu
generates and may simplify the fix of mentioned above issue
v2: don't leak fe.mark_entry
v3: save the original order of marks
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
fsnotify.c | 77 +++++++++++++++++++++++++++++++++++--------------
include/fsnotify.h | 1 -
include/image-desc.h | 2 +-
protobuf/fsnotify.proto | 1 +
4 files changed, 58 insertions(+), 23 deletions(-)
diff --git a/fsnotify.c b/fsnotify.c
index dff548c..0d2a131 100644
--- a/fsnotify.c
+++ b/fsnotify.c
@@ -198,6 +198,7 @@ err:
}
struct watch_list {
+ struct fsnotify_params fsn_params;
struct list_head list;
int n;
};
@@ -227,7 +228,7 @@ static int dump_inotify_entry(union fdinfo_entries *e, void *arg)
static int dump_one_inotify(int lfd, u32 id, const struct fd_parms *p)
{
- struct watch_list wd_list = {LIST_HEAD_INIT(wd_list.list), 0};
+ struct watch_list wd_list = {.list = LIST_HEAD_INIT(wd_list.list), .n = 0};
InotifyFileEntry ie = INOTIFY_FILE_ENTRY__INIT;
union fdinfo_entries *we, *tmp;
int exit_code = -1, i;
@@ -285,11 +286,8 @@ const struct fdtype_ops inotify_dump_ops = {
static int dump_fanotify_entry(union fdinfo_entries *e, void *arg)
{
- struct fsnotify_params *fsn_params = arg;
+ struct watch_list *wd_list = (struct watch_list *) arg;
FanotifyMarkEntry *fme = &e->ffy.e;
- int ret = -1;
-
- fme->id = fsn_params->id;
if (fme->type == MARK_TYPE__INODE) {
@@ -323,34 +321,49 @@ static int dump_fanotify_entry(union fdinfo_entries *e, void *arg)
}
- ret = pb_write_one(fdset_fd(glob_fdset, CR_FD_FANOTIFY_MARK), fme, PB_FANOTIFY_MARK);
+ list_add_tail(&e->ffy.node, &wd_list->list);
+ wd_list->n++;
+ return 0;
out:
free_fanotify_mark_entry(e);
- return ret;
+ return -1;
}
static int dump_one_fanotify(int lfd, u32 id, const struct fd_parms *p)
{
+ struct watch_list wd_list = {.list = LIST_HEAD_INIT(wd_list.list), .n = 0};
FanotifyFileEntry fe = FANOTIFY_FILE_ENTRY__INIT;
- struct fsnotify_params fsn_params = { .id = id, };
- int ret;
+ union fdinfo_entries *we, *tmp;
+ int ret = -1, i;
fe.id = id;
fe.flags = p->flags;
fe.fown = (FownEntry *)&p->fown;
if (parse_fdinfo(lfd, FD_TYPES__FANOTIFY,
- dump_fanotify_entry, &fsn_params) < 0)
- return -1;
+ dump_fanotify_entry, &wd_list) < 0)
+ goto free;
+
+ fe.mark = xmalloc(sizeof(*fe.mark) * wd_list.n);
+ if (!fe.mark)
+ goto free;
+
+ i = 0;
+ list_for_each_entry(we, &wd_list.list, ify.node)
+ fe.mark[i++] = &we->ffy.e;
+ fe.n_mark = wd_list.n;
pr_info("id 0x%08x flags 0x%08x\n", fe.id, fe.flags);
- fe.faflags = fsn_params.faflags;
- fe.evflags = fsn_params.evflags;
+ fe.faflags = wd_list.fsn_params.faflags;
+ fe.evflags = wd_list.fsn_params.evflags;
ret = pb_write_one(fdset_fd(glob_fdset, CR_FD_FANOTIFY_FILE), &fe, PB_FANOTIFY_FILE);
-
+free:
+ xfree(fe.mark);
+ list_for_each_entry_safe(we, tmp, &wd_list.list, ify.node)
+ free_fanotify_mark_entry(we);
return ret;
}
@@ -669,18 +682,23 @@ static int collect_inotify_mark(struct fsnotify_mark_info *mark)
return __collect_inotify_mark(p, mark);
}
+static int __collect_fanotify_mark(struct fsnotify_file_info *p,
+ struct fsnotify_mark_info *mark)
+{
+ list_add(&mark->list, &p->marks);
+ if (mark->fme->type == MARK_TYPE__INODE)
+ mark->remap = lookup_ghost_remap(mark->fme->s_dev,
+ mark->fme->ie->i_ino);
+ return 0;
+}
+
static int collect_fanotify_mark(struct fsnotify_mark_info *mark)
{
struct fsnotify_file_info *p;
list_for_each_entry(p, &fanotify_info_head, list) {
- if (p->ffe->id == mark->fme->id) {
- list_add(&mark->list, &p->marks);
- if (mark->fme->type == MARK_TYPE__INODE)
- mark->remap = lookup_ghost_remap(mark->fme->s_dev,
- mark->fme->ie->i_ino);
- return 0;
- }
+ if (p->ffe->id == mark->fme->id)
+ return __collect_inotify_mark(p, mark);
}
pr_err("Can't find fanotify with id 0x%08x\n", mark->fme->id);
@@ -726,11 +744,28 @@ struct collect_image_info inotify_cinfo = {
static int collect_one_fanotify(void *o, ProtobufCMessage *msg)
{
struct fsnotify_file_info *info = o;
+ int i;
info->ffe = pb_msg(msg, FanotifyFileEntry);
INIT_LIST_HEAD(&info->marks);
list_add(&info->list, &fanotify_info_head);
pr_info("Collected id 0x%08x flags 0x%08x\n", info->ffe->id, info->ffe->flags);
+
+ for (i = 0; i < info->ffe->n_mark; i++) {
+ struct fsnotify_mark_info *mark;
+
+ mark = xmalloc(sizeof(*mark));
+ if (!mark)
+ return -1;
+
+ mark->fme = info->ffe->mark[i];
+ INIT_LIST_HEAD(&mark->list);
+ mark->remap = NULL;
+
+ if (__collect_fanotify_mark(info, mark))
+ return -1;
+ }
+
return file_desc_add(&info->d, info->ffe->id, &fanotify_desc_ops);
}
diff --git a/include/fsnotify.h b/include/fsnotify.h
index f631b09..3fd5307 100644
--- a/include/fsnotify.h
+++ b/include/fsnotify.h
@@ -8,7 +8,6 @@
#include "protobuf/fsnotify.pb-c.h"
struct fsnotify_params {
- u32 id;
u32 faflags;
u32 evflags;
};
diff --git a/include/image-desc.h b/include/image-desc.h
index 75e851c..20afa42 100644
--- a/include/image-desc.h
+++ b/include/image-desc.h
@@ -69,7 +69,6 @@ enum {
CR_FD_SIGNALFD,
CR_FD_INOTIFY_FILE,
CR_FD_FANOTIFY_FILE,
- CR_FD_FANOTIFY_MARK,
CR_FD_TUNFILE,
CR_FD_CGROUP,
CR_FD_TIMERFD,
@@ -93,6 +92,7 @@ enum {
CR_FD_SIGNAL,
CR_FD_PSIGNAL,
CR_FD_INOTIFY_WD,
+ CR_FD_FANOTIFY_MARK,
CR_FD_MAX
};
diff --git a/protobuf/fsnotify.proto b/protobuf/fsnotify.proto
index b3fc080..871f1de 100644
--- a/protobuf/fsnotify.proto
+++ b/protobuf/fsnotify.proto
@@ -52,4 +52,5 @@ message fanotify_file_entry {
required uint32 faflags = 4;
required uint32 evflags = 5;
+ repeated fanotify_mark_entry mark = 6;
}
--
1.9.3
More information about the CRIU
mailing list