[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