[CRIU] [PATCH] files: Rework is_X_link helpers
Cyrill Gorcunov
gorcunov at openvz.org
Fri Jan 31 11:05:16 PST 2014
Pavel noticed that is_X_link reads link several time
instead of doing that in one pass. So here is a rework.
We read link once and figure out its type same time.
I decided to move the helpers out of util.c, which is
overloaded with "util" routines too much.
Reported-by: Pavel Emelyanov <xemul at parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
Makefile.crtools | 1 +
anon-link.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++
eventfd.c | 6 ------
eventpoll.c | 6 ------
files.c | 24 +++++++++++++++-------
fsnotify.c | 13 +-----------
include/anon-link.h | 18 +++++++++++++++++
include/eventfd.h | 1 -
include/eventpoll.h | 1 -
include/fsnotify.h | 2 --
include/signalfd.h | 1 -
include/util.h | 3 ---
protobuf.c | 1 +
signalfd.c | 5 -----
util.c | 30 ----------------------------
15 files changed, 95 insertions(+), 74 deletions(-)
create mode 100644 anon-link.c
create mode 100644 include/anon-link.h
diff --git a/Makefile.crtools b/Makefile.crtools
index 094013e56ac9..872f36d33b33 100644
--- a/Makefile.crtools
+++ b/Makefile.crtools
@@ -61,6 +61,7 @@ obj-y += arch/$(ARCH)/vdso.o
obj-y += cr-service.o
obj-y += sd-daemon.o
obj-y += plugin.o
+obj-y += anon-link.o
ifneq ($(MAKECMDGOALS),clean)
incdeps := y
diff --git a/anon-link.c b/anon-link.c
new file mode 100644
index 000000000000..4e389e889e14
--- /dev/null
+++ b/anon-link.c
@@ -0,0 +1,57 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "anon-link.h"
+#include "log.h"
+
+static const char anon_inode[] = "anon_inode:";
+static const size_t anon_inode_len = sizeof(anon_inode) - 1;
+
+int read_fd_link(int fd, char *buf, size_t size)
+{
+ char t[32];
+ ssize_t ret;
+
+ snprintf(t, sizeof(t), "/proc/self/fd/%d", fd);
+ ret = readlink(t, buf, size);
+ if (ret < 0) {
+ pr_perror("Can't read link of fd %d", fd);
+ return -1;
+ } else if ((size_t)ret == size) {
+ pr_err("Buffer for read link of fd %d is too small\n", fd);
+ return -1;
+ }
+ buf[ret] = 0;
+
+ return ret;
+}
+
+int get_anon_link_type(int fd, int *type)
+{
+ char buf[64];
+ int len;
+
+ len = read_fd_link(fd, buf, sizeof(buf));
+ if (len < 0) {
+ return -1;
+ } else if (len < anon_inode_len) {
+ *type = ANON_LINK_UNKNOWN;
+ } else {
+ if (!strcmp(&buf[anon_inode_len], "[eventfd]")) {
+ *type = ANON_LINK_EVENTFD;
+ } else if (!strcmp(&buf[anon_inode_len], "[eventpoll]")) {
+ *type = ANON_LINK_EVENTPOLL;
+ } else if (!strcmp(&buf[anon_inode_len], "inotify")) {
+ *type = ANON_LINK_INOTIFY;
+ } else if (!strcmp(&buf[anon_inode_len], "[fanotify]")) {
+ *type = ANON_LINK_FANOTIFY;
+ } else if (!strcmp(&buf[anon_inode_len], "[signalfd]")) {
+ *type = ANON_LINK_SIGNALFD;
+ } else {
+ *type = ANON_LINK_UNKNOWN;
+ }
+ }
+
+ return 0;
+}
diff --git a/eventfd.c b/eventfd.c
index d4e7bf826b91..bac059ac8d31 100644
--- a/eventfd.c
+++ b/eventfd.c
@@ -32,12 +32,6 @@ struct eventfd_file_info {
struct file_desc d;
};
-/* Checks if file descriptor @lfd is eventfd */
-int is_eventfd_link(int lfd)
-{
- return is_anon_link_type(lfd, "[eventfd]");
-}
-
static void pr_info_eventfd(char *action, EventfdFileEntry *efe)
{
pr_info("%s: id %#08x flags %#04x counter %#016"PRIx64"\n",
diff --git a/eventpoll.c b/eventpoll.c
index d82c19eff65b..d12284fcbbd3 100644
--- a/eventpoll.c
+++ b/eventpoll.c
@@ -40,12 +40,6 @@ struct eventpoll_tfd_file_info {
static LIST_HEAD(eventpoll_tfds);
-/* Checks if file descriptor @lfd is eventfd */
-int is_eventpoll_link(int lfd)
-{
- return is_anon_link_type(lfd, "[eventpoll]");
-}
-
static void pr_info_eventpoll_tfd(char *action, EventpollTfdEntry *e)
{
pr_info("%seventpoll-tfd: id %#08x tfd %#08x events %#08x data %#016"PRIx64"\n",
diff --git a/files.c b/files.c
index df0e2f1f776f..34777599621b 100644
--- a/files.c
+++ b/files.c
@@ -33,6 +33,7 @@
#include "namespaces.h"
#include "tun.h"
#include "fdset.h"
+#include "anon-link.h"
#include "parasite.h"
#include "parasite-syscall.h"
@@ -316,15 +317,20 @@ 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))
+ int anon_type;
+
+ if (get_anon_link_type(lfd, &anon_type))
+ return -1;
+
+ if (anon_type == ANON_LINK_EVENTFD)
ops = &eventfd_dump_ops;
- else if (is_eventpoll_link(lfd))
+ else if (anon_type == ANON_LINK_EVENTPOLL)
ops = &eventpoll_dump_ops;
- else if (is_inotify_link(lfd))
+ else if (anon_type == ANON_LINK_INOTIFY)
ops = &inotify_dump_ops;
- else if (is_fanotify_link(lfd))
+ else if (anon_type == ANON_LINK_FANOTIFY)
ops = &fanotify_dump_ops;
- else if (is_signalfd_link(lfd))
+ else if (anon_type == ANON_LINK_SIGNALFD)
ops = &signalfd_dump_ops;
else {
char more[64];
@@ -416,6 +422,7 @@ static int predump_one_fd(int pid, int fd)
int lfd, ret = 0;
struct statfs buf;
const struct fdtype_ops *ops;
+ int anon_type;
/*
* This should look like the dump_task_files_seized,
@@ -435,9 +442,12 @@ 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 (get_anon_link_type(lfd, &anon_type))
+ goto out;
+
+ if (anon_type == ANON_LINK_INOTIFY)
ops = &inotify_dump_ops;
- else if (is_fanotify_link(lfd))
+ else if (anon_type == ANON_LINK_FANOTIFY)
ops = &fanotify_dump_ops;
else
goto out;
diff --git a/fsnotify.c b/fsnotify.c
index a9412a03431e..eca31e4c3a8c 100644
--- a/fsnotify.c
+++ b/fsnotify.c
@@ -26,6 +26,7 @@
#include "fdset.h"
#include "fsnotify.h"
#include "proc_parse.h"
+#include "anon-link.h"
#include "syscall.h"
#include "mount.h"
#include "image.h"
@@ -73,18 +74,6 @@ typedef struct {
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)
-{
- return is_anon_link_type(lfd, "inotify");
-}
-
-/* Checks if file descriptor @lfd is fanotify */
-int is_fanotify_link(int lfd)
-{
- return is_anon_link_type(lfd, "[fanotify]");
-}
-
static void decode_handle(fh_t *handle, FhEntry *img)
{
memzero(handle, sizeof(*handle));
diff --git a/include/anon-link.h b/include/anon-link.h
new file mode 100644
index 000000000000..70bf3351774a
--- /dev/null
+++ b/include/anon-link.h
@@ -0,0 +1,18 @@
+#ifndef __CR_ANON_LINK__
+#define __CR_ANON_LINK__
+
+#include <sys/types.h>
+
+enum {
+ ANON_LINK_UNKNOWN = 0,
+ ANON_LINK_EVENTFD = 1,
+ ANON_LINK_EVENTPOLL = 2,
+ ANON_LINK_INOTIFY = 3,
+ ANON_LINK_FANOTIFY = 4,
+ ANON_LINK_SIGNALFD = 5,
+};
+
+extern int read_fd_link(int fd, char *buf, size_t size);
+extern int get_anon_link_type(int fd, int *type);
+
+#endif /* __CR_ANON_LINK__ */
diff --git a/include/eventfd.h b/include/eventfd.h
index 22a62a08cb20..b38c0e3fba28 100644
--- a/include/eventfd.h
+++ b/include/eventfd.h
@@ -3,7 +3,6 @@
#include "files.h"
-extern int is_eventfd_link(int lfd);
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 4e6c1122bab6..4c09bfc50116 100644
--- a/include/eventpoll.h
+++ b/include/eventpoll.h
@@ -3,7 +3,6 @@
#include "files.h"
-extern int is_eventpoll_link(int lfd);
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 a882fd93e006..f2dd0315643e 100644
--- a/include/fsnotify.h
+++ b/include/fsnotify.h
@@ -10,8 +10,6 @@ struct fsnotify_params {
u32 evflags;
};
-extern int is_inotify_link(int lfd);
-extern int is_fanotify_link(int lfd);
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 b36f9ac2f35f..5469c189071c 100644
--- a/include/signalfd.h
+++ b/include/signalfd.h
@@ -3,7 +3,6 @@
struct cr_fdset;
struct fd_parms;
-extern int is_signalfd_link(int lfd);
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 a7d196bf0ffa..4d27bf78095f 100644
--- a/include/util.h
+++ b/include/util.h
@@ -234,7 +234,6 @@ 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);
#define is_hex_digit(c) \
(((c) >= '0' && (c) <= '9') || \
@@ -285,8 +284,6 @@ static inline bool dir_dots(struct dirent *de)
*/
#define PSFDS (sizeof("/proc/self/fd/2147483647"))
-extern int read_fd_link(int lfd, char *buf, size_t size);
-
#define USEC_PER_SEC 1000000L
#define NSEC_PER_SEC 1000000000L
diff --git a/protobuf.c b/protobuf.c
index 6bf3da90882b..4082ee4c13c4 100644
--- a/protobuf.c
+++ b/protobuf.c
@@ -17,6 +17,7 @@
#include "string.h"
#include "sockets.h"
#include "cr_options.h"
+#include "anon-link.h"
#include "protobuf.h"
diff --git a/signalfd.c b/signalfd.c
index 48816ede69e3..e1987d617a01 100644
--- a/signalfd.c
+++ b/signalfd.c
@@ -20,11 +20,6 @@ struct signalfd_info {
struct file_desc d;
};
-int is_signalfd_link(int lfd)
-{
- return is_anon_link_type(lfd, "[signalfd]");
-}
-
struct signalfd_dump_arg {
u32 id;
const struct fd_parms *p;
diff --git a/util.c b/util.c
index 32a61b379322..a02a8b86ab12 100644
--- a/util.c
+++ b/util.c
@@ -406,36 +406,6 @@ int copy_file(int fd_in, int fd_out, size_t bytes)
return 0;
}
-int read_fd_link(int lfd, char *buf, size_t size)
-{
- char t[32];
- ssize_t ret;
-
- snprintf(t, sizeof(t), "/proc/self/fd/%d", lfd);
- ret = readlink(t, buf, size);
- if (ret < 0) {
- pr_perror("Can't read link of fd %d", lfd);
- return -1;
- } else if ((size_t)ret == size) {
- pr_err("Buffer for read link of fd %d is too small\n", lfd);
- return -1;
- }
- buf[ret] = 0;
-
- return ret;
-}
-
-int is_anon_link_type(int lfd, char *type)
-{
- char link[32], aux[32];
-
- if (read_fd_link(lfd, link, sizeof(link)) < 0)
- return -1;
-
- snprintf(aux, sizeof(aux), "anon_inode:%s", type);
- return !strcmp(link, aux);
-}
-
void *shmalloc(size_t bytes)
{
return rst_mem_alloc(bytes, RM_SHARED);
--
1.8.3.1
More information about the CRIU
mailing list