From bd7bf7bd39b146f984631cb7ca6b89c3142520eb Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Sun, 2 Feb 2014 22:14:29 +0400 Subject: [PATCH] anon-inode: Don't readlink fd/fd multiple times The is_foo_link readlinks the lfd to check. This makes anon-inodes dumping readlink several times to find proper dump ops. Optimize this thing. Signed-off-by: Pavel Emelyanov --- eventfd.c | 4 ++-- eventpoll.c | 4 ++-- files.c | 35 ++++++++++++++++++++--------------- fsnotify.c | 8 ++++---- include/eventfd.h | 2 +- include/eventpoll.h | 2 +- include/fsnotify.h | 4 ++-- include/signalfd.h | 2 +- include/util.h | 2 +- signalfd.c | 4 ++-- util.c | 7 ++----- 11 files changed, 38 insertions(+), 36 deletions(-) diff --git a/eventfd.c b/eventfd.c index d4e7bf826..e975eece4 100644 --- a/eventfd.c +++ b/eventfd.c @@ -33,9 +33,9 @@ struct eventfd_file_info { }; /* Checks if file descriptor @lfd is eventfd */ -int is_eventfd_link(int lfd) +int is_eventfd_link(char *link) { - return is_anon_link_type(lfd, "[eventfd]"); + return is_anon_link_type(link, "[eventfd]"); } static void pr_info_eventfd(char *action, EventfdFileEntry *efe) diff --git a/eventpoll.c b/eventpoll.c index d82c19eff..603890093 100644 --- a/eventpoll.c +++ b/eventpoll.c @@ -41,9 +41,9 @@ struct eventpoll_tfd_file_info { static LIST_HEAD(eventpoll_tfds); /* Checks if file descriptor @lfd is eventfd */ -int is_eventpoll_link(int lfd) +int is_eventpoll_link(char *link) { - return is_anon_link_type(lfd, "[eventpoll]"); + return is_anon_link_type(link, "[eventpoll]"); } static void pr_info_eventpoll_tfd(char *action, EventpollTfdEntry *e) diff --git a/files.c b/files.c index df0e2f1f7..509d13bdf 100644 --- a/files.c +++ b/files.c @@ -316,24 +316,23 @@ static int dump_one_file(struct parasite_ctl *ctl, int fd, int lfd, struct fd_op return dump_chrdev(&p, lfd, fdinfo); if (p.fs_type == ANON_INODE_FS_MAGIC) { - if (is_eventfd_link(lfd)) + char link[32]; + + if (read_fd_link(lfd, link, sizeof(link)) < 0) + return -1; + + if (is_eventfd_link(link)) ops = &eventfd_dump_ops; - else if (is_eventpoll_link(lfd)) + else if (is_eventpoll_link(link)) ops = &eventpoll_dump_ops; - else if (is_inotify_link(lfd)) + else if (is_inotify_link(link)) ops = &inotify_dump_ops; - else if (is_fanotify_link(lfd)) + else if (is_fanotify_link(link)) ops = &fanotify_dump_ops; - else if (is_signalfd_link(lfd)) + else if (is_signalfd_link(link)) ops = &signalfd_dump_ops; - else { - char more[64]; - - if (read_fd_link(fd, more, sizeof(more)) < 0) - more[0] = '\0'; - - return dump_unsupp_fd(&p, lfd, fdinfo, "anon", more); - } + else + return dump_unsupp_fd(&p, lfd, fdinfo, "anon", link); return do_dump_gen_file(&p, lfd, ops, fdinfo); } @@ -416,6 +415,7 @@ static int predump_one_fd(int pid, int fd) int lfd, ret = 0; struct statfs buf; const struct fdtype_ops *ops; + char link[32]; /* * This should look like the dump_task_files_seized, @@ -435,9 +435,14 @@ static int predump_one_fd(int pid, int fd) if (buf.f_type != ANON_INODE_FS_MAGIC) goto out; - if (is_inotify_link(lfd)) + if (read_fd_link(lfd, link, sizeof(link)) < 0) { + ret = -1; + goto out; + } + + if (is_inotify_link(link)) ops = &inotify_dump_ops; - else if (is_fanotify_link(lfd)) + else if (is_fanotify_link(link)) ops = &fanotify_dump_ops; else goto out; diff --git a/fsnotify.c b/fsnotify.c index a9412a034..3f5ef6280 100644 --- a/fsnotify.c +++ b/fsnotify.c @@ -74,15 +74,15 @@ static LIST_HEAD(inotify_info_head); static LIST_HEAD(fanotify_info_head); /* Checks if file descriptor @lfd is inotify */ -int is_inotify_link(int lfd) +int is_inotify_link(char *link) { - return is_anon_link_type(lfd, "inotify"); + return is_anon_link_type(link, "inotify"); } /* Checks if file descriptor @lfd is fanotify */ -int is_fanotify_link(int lfd) +int is_fanotify_link(char *link) { - return is_anon_link_type(lfd, "[fanotify]"); + return is_anon_link_type(link, "[fanotify]"); } static void decode_handle(fh_t *handle, FhEntry *img) diff --git a/include/eventfd.h b/include/eventfd.h index 22a62a08c..65e0af7cd 100644 --- a/include/eventfd.h +++ b/include/eventfd.h @@ -3,7 +3,7 @@ #include "files.h" -extern int is_eventfd_link(int lfd); +extern int is_eventfd_link(char *link); extern const struct fdtype_ops eventfd_dump_ops; extern struct collect_image_info eventfd_cinfo; diff --git a/include/eventpoll.h b/include/eventpoll.h index 4e6c1122b..96a77bc98 100644 --- a/include/eventpoll.h +++ b/include/eventpoll.h @@ -3,7 +3,7 @@ #include "files.h" -extern int is_eventpoll_link(int lfd); +extern int is_eventpoll_link(char *link); extern const struct fdtype_ops eventpoll_dump_ops; extern struct collect_image_info epoll_tfd_cinfo; extern struct collect_image_info epoll_cinfo; diff --git a/include/fsnotify.h b/include/fsnotify.h index a882fd93e..cabf525ce 100644 --- a/include/fsnotify.h +++ b/include/fsnotify.h @@ -10,8 +10,8 @@ struct fsnotify_params { u32 evflags; }; -extern int is_inotify_link(int lfd); -extern int is_fanotify_link(int lfd); +extern int is_inotify_link(char *link); +extern int is_fanotify_link(char *link); extern const struct fdtype_ops inotify_dump_ops; extern const struct fdtype_ops fanotify_dump_ops; extern struct collect_image_info inotify_cinfo; diff --git a/include/signalfd.h b/include/signalfd.h index b36f9ac2f..a29b9be68 100644 --- a/include/signalfd.h +++ b/include/signalfd.h @@ -3,7 +3,7 @@ struct cr_fdset; struct fd_parms; -extern int is_signalfd_link(int lfd); +extern int is_signalfd_link(char *link); extern const struct fdtype_ops signalfd_dump_ops; extern struct collect_image_info signalfd_cinfo; diff --git a/include/util.h b/include/util.h index a7d196bf0..b633b123f 100644 --- a/include/util.h +++ b/include/util.h @@ -234,7 +234,7 @@ static inline dev_t kdev_to_odev(u32 kdev) } extern int copy_file(int fd_in, int fd_out, size_t bytes); -extern int is_anon_link_type(int lfd, char *type); +extern int is_anon_link_type(char *link, char *type); #define is_hex_digit(c) \ (((c) >= '0' && (c) <= '9') || \ diff --git a/signalfd.c b/signalfd.c index 48816ede6..ba7f5f697 100644 --- a/signalfd.c +++ b/signalfd.c @@ -20,9 +20,9 @@ struct signalfd_info { struct file_desc d; }; -int is_signalfd_link(int lfd) +int is_signalfd_link(char *link) { - return is_anon_link_type(lfd, "[signalfd]"); + return is_anon_link_type(link, "[signalfd]"); } struct signalfd_dump_arg { diff --git a/util.c b/util.c index 32a61b379..118ef89a6 100644 --- a/util.c +++ b/util.c @@ -425,12 +425,9 @@ int read_fd_link(int lfd, char *buf, size_t size) return ret; } -int is_anon_link_type(int lfd, char *type) +int is_anon_link_type(char *link, char *type) { - char link[32], aux[32]; - - if (read_fd_link(lfd, link, sizeof(link)) < 0) - return -1; + char aux[32]; snprintf(aux, sizeof(aux), "anon_inode:%s", type); return !strcmp(link, aux);