[CRIU] [PATCH 2/2] lock: parse the lock field in fdinfo if it's avaliable (v2)

Andrey Vagin avagin at openvz.org
Fri Apr 24 04:49:15 PDT 2015


/proc/locks can contain a wrong pid for a lock and we always need to
check this fact.  Starting with the 4.1 kernel, locks are reported
in fdinfo.

v2: rebase to the curret master
    skip note_file_lock()

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 file-lock.c          |  4 ++++
 files.c              |  4 ++--
 include/proc_parse.h |  1 +
 proc_parse.c         | 40 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/file-lock.c b/file-lock.c
index 377c7eb..8e4e481 100644
--- a/file-lock.c
+++ b/file-lock.c
@@ -10,6 +10,7 @@
 #include "imgset.h"
 #include "files.h"
 #include "fs-magic.h"
+#include "kerndat.h"
 #include "image.h"
 #include "mount.h"
 #include "proc_parse.h"
@@ -209,6 +210,9 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
 	struct file_lock *fl;
 	int ret;
 
+	if (kdat.has_fdinfo_lock)
+		return 0;
+
 	list_for_each_entry(fl, &file_lock_list, list) {
 		ret = lock_file_match(pid->real, fd, fl, p);
 		if (ret < 0)
diff --git a/files.c b/files.c
index dfb9a64..0f7f107 100644
--- a/files.c
+++ b/files.c
@@ -213,7 +213,7 @@ static int fill_fd_params(struct parasite_ctl *ctl, int fd, int lfd,
 {
 	int ret;
 	struct statfs fsbuf;
-	struct fdinfo_common fdinfo = { .mnt_id = -1 };
+	struct fdinfo_common fdinfo = { .mnt_id = -1, .owner = ctl->pid.virt };
 
 	if (fstat(lfd, &p->stat) < 0) {
 		pr_perror("Can't stat fd %d", lfd);
@@ -225,7 +225,7 @@ static int fill_fd_params(struct parasite_ctl *ctl, int fd, int lfd,
 		return -1;
 	}
 
-	if (parse_fdinfo(lfd, FD_TYPES__UND, NULL, &fdinfo))
+	if (parse_fdinfo_pid(ctl->pid.real, fd, FD_TYPES__UND, NULL, &fdinfo))
 		return -1;
 
 	p->fs_type	= fsbuf.f_type;
diff --git a/include/proc_parse.h b/include/proc_parse.h
index e5d59d2..ebb5351 100644
--- a/include/proc_parse.h
+++ b/include/proc_parse.h
@@ -199,6 +199,7 @@ struct fdinfo_common {
 	off64_t pos;
 	int flags;
 	int mnt_id;
+	int owner;
 };
 
 extern int parse_fdinfo(int fd, int type,
diff --git a/proc_parse.c b/proc_parse.c
index 14ef589..fad4055 100644
--- a/proc_parse.c
+++ b/proc_parse.c
@@ -1233,6 +1233,8 @@ nodata:
 
 #define fdinfo_field(str, field)	!strncmp(str, field":", sizeof(field))
 
+static int parse_file_lock_buf(char *buf, struct file_lock *fl,
+				bool is_blocked);
 static int parse_fdinfo_pid_s(int pid, int fd, int type,
 		int (*cb)(union fdinfo_entries *e, void *arg), void *arg)
 {
@@ -1282,6 +1284,41 @@ static int parse_fdinfo_pid_s(int pid, int fd, int type,
 			continue;
 		}
 
+		if (fdinfo_field(str, "lock")) {
+			struct file_lock *fl;
+			struct fdinfo_common *fdinfo = arg;
+
+			if (type != FD_TYPES__UND)
+				continue;
+
+			fl = alloc_file_lock();
+			if (!fl) {
+				pr_perror("Alloc file lock failed!");
+				goto out;
+			}
+
+			if (parse_file_lock_buf(str + 6, fl, 0)) {
+				xfree(fl);
+				goto parse_err;
+			}
+
+			pr_info("lockinfo: %lld:%d %x %d %02x:%02x:%ld %lld %s\n",
+				fl->fl_id, fl->fl_kind, fl->fl_ltype,
+				fl->fl_owner, fl->maj, fl->min, fl->i_no,
+				fl->start, fl->end);
+
+
+			if (fl->fl_kind == FL_UNKNOWN) {
+				pr_err("Unknown file lock!\n");
+				xfree(fl);
+				goto out;
+			}
+
+			fl->real_owner = fdinfo->owner;
+			fl->owners_fd = fd;
+			list_add_tail(&fl->list, &file_lock_list);
+		}
+
 		if (type == FD_TYPES__UND)
 			continue;
 
@@ -1601,6 +1638,9 @@ int parse_file_locks(void)
 	int	exit_code = -1;
 	bool	is_blocked;
 
+	if (kdat.has_fdinfo_lock)
+		return 0;
+
 	fl_locks = fopen_proc(PROC_GEN, "locks");
 	if (!fl_locks) {
 		pr_perror("Can't open file locks file!");
-- 
2.1.0



More information about the CRIU mailing list