Commit e5b4ef20 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Andrei Vagin

fanotify: Rework parse_fdinfo not to use callback

Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 3150b56d
...@@ -296,12 +296,6 @@ err: ...@@ -296,12 +296,6 @@ err:
return -1; return -1;
} }
struct watch_list {
struct fsnotify_params fsn_params;
struct list_head list;
int n;
};
static int check_one_wd(InotifyWdEntry *we) static int check_one_wd(InotifyWdEntry *we)
{ {
pr_info("wd: wd %#08x s_dev %#08x i_ino %#16"PRIx64" mask %#08x\n", pr_info("wd: wd %#08x s_dev %#08x i_ino %#16"PRIx64" mask %#08x\n",
...@@ -381,11 +375,8 @@ const struct fdtype_ops inotify_dump_ops = { ...@@ -381,11 +375,8 @@ const struct fdtype_ops inotify_dump_ops = {
.pre_dump = pre_dump_one_inotify, .pre_dump = pre_dump_one_inotify,
}; };
static int dump_fanotify_entry(union fdinfo_entries *e, void *arg) static int check_one_mark(FanotifyMarkEntry *fme)
{ {
struct watch_list *wd_list = (struct watch_list *) arg;
FanotifyMarkEntry *fme = &e->ffy.e;
if (fme->type == MARK_TYPE__INODE) { if (fme->type == MARK_TYPE__INODE) {
BUG_ON(!fme->ie); BUG_ON(!fme->ie);
...@@ -398,7 +389,7 @@ static int dump_fanotify_entry(union fdinfo_entries *e, void *arg) ...@@ -398,7 +389,7 @@ static int dump_fanotify_entry(union fdinfo_entries *e, void *arg)
fme->ie->f_handle->handle[0], fme->ie->f_handle->handle[1]); fme->ie->f_handle->handle[0], fme->ie->f_handle->handle[1]);
if (check_open_handle(fme->s_dev, fme->ie->i_ino, fme->ie->f_handle)) if (check_open_handle(fme->s_dev, fme->ie->i_ino, fme->ie->f_handle))
goto out; return -1;
} }
if (fme->type == MARK_TYPE__MOUNT) { if (fme->type == MARK_TYPE__MOUNT) {
...@@ -409,7 +400,7 @@ static int dump_fanotify_entry(union fdinfo_entries *e, void *arg) ...@@ -409,7 +400,7 @@ static int dump_fanotify_entry(union fdinfo_entries *e, void *arg)
m = lookup_mnt_id(fme->me->mnt_id); m = lookup_mnt_id(fme->me->mnt_id);
if (!m) { if (!m) {
pr_err("Can't find mnt_id 0x%x\n", fme->me->mnt_id); pr_err("Can't find mnt_id 0x%x\n", fme->me->mnt_id);
goto out; return -1;
} }
if (!(root_ns_mask & CLONE_NEWNS)) if (!(root_ns_mask & CLONE_NEWNS))
fme->me->path = m->mountpoint + 1; fme->me->path = m->mountpoint + 1;
...@@ -420,20 +411,12 @@ static int dump_fanotify_entry(union fdinfo_entries *e, void *arg) ...@@ -420,20 +411,12 @@ static int dump_fanotify_entry(union fdinfo_entries *e, void *arg)
} }
list_add_tail(&e->ffy.node, &wd_list->list);
wd_list->n++;
return 0; return 0;
out:
free_fanotify_mark_entry(e);
return -1;
} }
static int dump_one_fanotify(int lfd, u32 id, const struct fd_parms *p) 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; FanotifyFileEntry fe = FANOTIFY_FILE_ENTRY__INIT;
union fdinfo_entries *we, *tmp;
int ret = -1, i; int ret = -1, i;
ret = fd_has_data(lfd); ret = fd_has_data(lfd);
...@@ -447,49 +430,43 @@ static int dump_one_fanotify(int lfd, u32 id, const struct fd_parms *p) ...@@ -447,49 +430,43 @@ static int dump_one_fanotify(int lfd, u32 id, const struct fd_parms *p)
fe.flags = p->flags; fe.flags = p->flags;
fe.fown = (FownEntry *)&p->fown; fe.fown = (FownEntry *)&p->fown;
if (parse_fdinfo(lfd, FD_TYPES__FANOTIFY, if (parse_fdinfo(lfd, FD_TYPES__FANOTIFY, NULL, &fe) < 0)
dump_fanotify_entry, &wd_list) < 0)
goto free; goto free;
fe.mark = xmalloc(sizeof(*fe.mark) * wd_list.n); for (i = 0; i < fe.n_mark; i++)
if (!fe.mark) if (check_one_mark(fe.mark[i]))
goto free; goto free;
i = 0;
list_for_each_entry(we, &wd_list.list, ffy.node)
fe.mark[i++] = &we->ffy.e;
fe.n_mark = wd_list.n;
pr_info("id %#08x flags %#08x\n", fe.id, fe.flags); pr_info("id %#08x flags %#08x\n", fe.id, fe.flags);
fe.faflags = wd_list.fsn_params.faflags;
fe.evflags = wd_list.fsn_params.evflags;
ret = pb_write_one(img_from_set(glob_imgset, CR_FD_FANOTIFY_FILE), &fe, PB_FANOTIFY_FILE); ret = pb_write_one(img_from_set(glob_imgset, CR_FD_FANOTIFY_FILE), &fe, PB_FANOTIFY_FILE);
free: free:
for (i = 0; i < fe.n_mark; i++)
xfree(fe.mark[i]);
xfree(fe.mark); xfree(fe.mark);
list_for_each_entry_safe(we, tmp, &wd_list.list, ffy.node)
free_fanotify_mark_entry(we);
return ret; return ret;
} }
static int pre_dump_fanotify_entry(union fdinfo_entries *e, void *arg) static int pre_dump_one_fanotify(int pid, int lfd)
{ {
FanotifyMarkEntry *fme = &e->ffy.e; FanotifyFileEntry fe = FANOTIFY_FILE_ENTRY__INIT;
int ret = 0; int i;
if (fme->type == MARK_TYPE__INODE) if (parse_fdinfo_pid(pid, lfd, FD_TYPES__FANOTIFY, NULL, &fe))
ret = irmap_queue_cache(fme->s_dev, fme->ie->i_ino, return -1;
fme->ie->f_handle);
free_fanotify_mark_entry(e); for (i = 0; i < fe.n_mark; i++) {
return ret; FanotifyMarkEntry *me = fe.mark[i];
}
static int pre_dump_one_fanotify(int pid, int lfd) if (me->type == MARK_TYPE__INODE &&
{ irmap_queue_cache(me->s_dev, me->ie->i_ino,
struct fsnotify_params fsn_params = { }; me->ie->f_handle))
return parse_fdinfo_pid(pid, lfd, FD_TYPES__FANOTIFY, pre_dump_fanotify_entry, &fsn_params); return -1;
xfree(me);
}
xfree(fe.mark);
return 0;
} }
const struct fdtype_ops fanotify_dump_ops = { const struct fdtype_ops fanotify_dump_ops = {
......
...@@ -9,23 +9,10 @@ ...@@ -9,23 +9,10 @@
#include "images/fsnotify.pb-c.h" #include "images/fsnotify.pb-c.h"
#include "images/timerfd.pb-c.h" #include "images/timerfd.pb-c.h"
struct fanotify_mark_entry {
FanotifyMarkEntry e;
FhEntry f_handle;
struct list_head node;
union {
FanotifyInodeMarkEntry ie;
FanotifyMountMarkEntry me;
};
};
union fdinfo_entries { union fdinfo_entries {
struct fanotify_mark_entry ffy;
TimerfdEntry tfy; TimerfdEntry tfy;
}; };
extern void free_fanotify_mark_entry(union fdinfo_entries *e);
struct fdinfo_common { struct fdinfo_common {
off64_t pos; off64_t pos;
int flags; int flags;
......
...@@ -8,11 +8,6 @@ ...@@ -8,11 +8,6 @@
#define KERNEL_FS_EVENT_ON_CHILD 0x08000000 #define KERNEL_FS_EVENT_ON_CHILD 0x08000000
struct fsnotify_params {
u32 faflags;
u32 evflags;
};
extern int is_inotify_link(char *link); extern int is_inotify_link(char *link);
extern int is_fanotify_link(char *link); extern int is_fanotify_link(char *link);
extern const struct fdtype_ops inotify_dump_ops; extern const struct fdtype_ops inotify_dump_ops;
......
...@@ -1520,27 +1520,6 @@ static char nybble(const char n) ...@@ -1520,27 +1520,6 @@ static char nybble(const char n)
return 0; return 0;
} }
static int alloc_fhandle(FhEntry *fh)
{
fh->n_handle = FH_ENTRY_SIZES__min_entries;
fh->handle = xmalloc(pb_repeated_size(fh, handle));
return fh->handle == NULL ? -1 : 0;
}
static void free_fhandle(FhEntry *fh)
{
if (fh->handle)
xfree(fh->handle);
}
void free_fanotify_mark_entry(union fdinfo_entries *e)
{
if (e->ffy.e.ie)
free_fhandle(e->ffy.ie.f_handle);
xfree(e);
}
static void parse_fhandle_encoded(char *tok, FhEntry *fh) static void parse_fhandle_encoded(char *tok, FhEntry *fh)
{ {
char *d = (char *)fh->handle; char *d = (char *)fh->handle;
...@@ -1774,89 +1753,107 @@ static int parse_fdinfo_pid_s(int pid, int fd, int type, ...@@ -1774,89 +1753,107 @@ static int parse_fdinfo_pid_s(int pid, int fd, int type,
continue; continue;
} }
if (fdinfo_field(str, "fanotify flags")) { if (fdinfo_field(str, "fanotify flags")) {
struct fsnotify_params *p = arg; FanotifyFileEntry *fe = arg;
if (type != FD_TYPES__FANOTIFY) if (type != FD_TYPES__FANOTIFY)
goto parse_err; goto parse_err;
ret = sscanf(str, "fanotify flags:%x event-flags:%x", ret = sscanf(str, "fanotify flags:%x event-flags:%x",
&p->faflags, &p->evflags); &fe->faflags, &fe->evflags);
if (ret != 2) if (ret != 2)
goto parse_err; goto parse_err;
entry_met = true; entry_met = true;
continue; continue;
} }
if (fdinfo_field(str, "fanotify ino")) { if (fdinfo_field(str, "fanotify ino")) {
union fdinfo_entries *e; void *buf, *ob;
int hoff = 0; FanotifyFileEntry *fe = arg;
FanotifyMarkEntry *me;
int hoff = 0, i;
if (type != FD_TYPES__FANOTIFY) if (type != FD_TYPES__FANOTIFY)
goto parse_err; goto parse_err;
e = xmalloc(sizeof(*e)); ob = buf = xmalloc(sizeof(FanotifyMarkEntry) +
if (!e) sizeof(FanotifyInodeMarkEntry) +
goto parse_err; sizeof(FhEntry) +
FH_ENTRY_SIZES__min_entries * sizeof(uint64_t));
if (!buf)
goto out;
fanotify_mark_entry__init(&e->ffy.e); me = xptr_pull(&buf, FanotifyMarkEntry);
fanotify_inode_mark_entry__init(&e->ffy.ie); fanotify_mark_entry__init(me);
fh_entry__init(&e->ffy.f_handle); me->ie = xptr_pull(&buf, FanotifyInodeMarkEntry);
e->ffy.e.ie = &e->ffy.ie; fanotify_inode_mark_entry__init(me->ie);
e->ffy.ie.f_handle = &e->ffy.f_handle; me->ie->f_handle = xptr_pull(&buf, FhEntry);
fh_entry__init(me->ie->f_handle);
me->ie->f_handle->n_handle = FH_ENTRY_SIZES__min_entries;
me->ie->f_handle->handle = xptr_pull_s(&buf,
FH_ENTRY_SIZES__min_entries * sizeof(uint64_t));
ret = sscanf(str, ret = sscanf(str,
"fanotify ino:%"PRIx64" sdev:%x mflags:%x mask:%x ignored_mask:%x " "fanotify ino:%"PRIx64" sdev:%x mflags:%x mask:%x ignored_mask:%x "
"fhandle-bytes:%x fhandle-type:%x f_handle: %n", "fhandle-bytes:%x fhandle-type:%x f_handle: %n",
&e->ffy.ie.i_ino, &e->ffy.e.s_dev, &me->ie->i_ino, &me->s_dev,
&e->ffy.e.mflags, &e->ffy.e.mask, &e->ffy.e.ignored_mask, &me->mflags, &me->mask, &me->ignored_mask,
&e->ffy.f_handle.bytes, &e->ffy.f_handle.type, &me->ie->f_handle->bytes, &me->ie->f_handle->type,
&hoff); &hoff);
if (ret != 7 || hoff == 0) { if (ret != 7 || hoff == 0) {
free_fanotify_mark_entry(e); xfree(ob);
goto parse_err; goto parse_err;
} }
if (alloc_fhandle(&e->ffy.f_handle)) { parse_fhandle_encoded(str + hoff, me->ie->f_handle);
free_fanotify_mark_entry(e); me->type = MARK_TYPE__INODE;
goto out;
}
parse_fhandle_encoded(str + hoff, &e->ffy.f_handle);
e->ffy.e.type = MARK_TYPE__INODE;
ret = cb(e, arg);
if (ret) i = fe->n_mark++;
if (xrealloc_safe(&fe->mark, fe->n_mark * sizeof(FanotifyMarkEntry *))) {
xfree(ob);
goto out; goto out;
}
fe->mark[i] = me;
entry_met = true; entry_met = true;
continue; continue;
} }
if (fdinfo_field(str, "fanotify mnt_id")) { if (fdinfo_field(str, "fanotify mnt_id")) {
union fdinfo_entries *e; void *buf, *ob;
FanotifyFileEntry *fe = arg;
FanotifyMarkEntry *me;
int i;
if (type != FD_TYPES__FANOTIFY) if (type != FD_TYPES__FANOTIFY)
goto parse_err; goto parse_err;
e = xmalloc(sizeof(*e));
if (!e)
goto parse_err;
fanotify_mark_entry__init(&e->ffy.e); ob = buf = xmalloc(sizeof(FanotifyMarkEntry) +
fanotify_mount_mark_entry__init(&e->ffy.me); sizeof(FanotifyMountMarkEntry));
e->ffy.e.me = &e->ffy.me; if (!buf)
goto out;
me = xptr_pull(&buf, FanotifyMarkEntry);
fanotify_mark_entry__init(me);
me->me = xptr_pull(&buf, FanotifyMountMarkEntry);
fanotify_mount_mark_entry__init(me->me);
ret = sscanf(str, ret = sscanf(str,
"fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x", "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x",
&e->ffy.e.me->mnt_id, &e->ffy.e.mflags, &me->me->mnt_id, &me->mflags,
&e->ffy.e.mask, &e->ffy.e.ignored_mask); &me->mask, &me->ignored_mask);
if (ret != 4) if (ret != 4) {
xfree(ob);
goto parse_err; goto parse_err;
}
e->ffy.e.type = MARK_TYPE__MOUNT; me->type = MARK_TYPE__MOUNT;
ret = cb(e, arg);
if (ret) i = fe->n_mark++;
if (xrealloc_safe(&fe->mark, fe->n_mark * sizeof(FanotifyMarkEntry *))) {
xfree(ob);
goto out; goto out;
}
fe->mark[i] = me;
entry_met = true; entry_met = true;
continue; continue;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment