[CRIU] [PATCH v3 1/2] locks: Remove duplicated locks
Pavel Begunkov (Silence)
asml.silence at gmail.com
Tue Nov 21 05:54:55 MSK 2017
From: Pavel Begunkov <asml.silence at gmail.com>
CRIU creates dictinct lock record for each file descriptor on the same
OFD. The patch removes this duplicates. To do so, it adds new field into
struct file_lock, which stores pid of fd, on which lock was found.
'owner pid' is not actually helpful, because the original fd, on which
lock have been set, can be already closed.
Also it purges crutches doing the same stuff but only for file leases.
Signed-off-by: Pavel Begunkov <asml.silence at gmail.com>
---
criu/file-lock.c | 20 ++++++++++++++++----
criu/files.c | 3 +++
criu/include/file-lock.h | 6 +++---
criu/proc_parse.c | 3 +--
4 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/criu/file-lock.c b/criu/file-lock.c
index b7adc097..8be7589d 100644
--- a/criu/file-lock.c
+++ b/criu/file-lock.c
@@ -58,6 +58,7 @@ struct file_lock *alloc_file_lock(void)
INIT_LIST_HEAD(&flock->list);
flock->real_owner = -1;
flock->owners_fd = -1;
+ flock->fl_holder = -1;
return flock;
}
@@ -106,8 +107,6 @@ int dump_file_locks(void)
continue;
}
- if (fl->fl_kind == FL_LEASE && !fl->updated)
- continue;
file_lock_entry__init(&fle);
fle.pid = fl->real_owner;
@@ -410,6 +409,7 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
continue;
}
+ fl->fl_holder = pid->real;
fl->real_owner = pid->ns[0].virt;
fl->owners_fd = fd;
@@ -421,6 +421,19 @@ int note_file_lock(struct pid *pid, int fd, int lfd, struct fd_parms *p)
return 0;
}
+void discard_dup_locks_tail(pid_t pid, int fd)
+{
+ struct file_lock *fl, *p;
+
+ list_for_each_entry_safe_reverse(fl, p, &file_lock_list, list) {
+ if (fl->owners_fd != fd || pid != fl->fl_holder)
+ break;
+
+ list_del(&fl->list);
+ xfree(fl);
+ }
+}
+
int correct_file_leases_type(struct pid *pid, int fd, int lfd)
{
struct file_lock *fl;
@@ -428,10 +441,9 @@ int correct_file_leases_type(struct pid *pid, int fd, int lfd)
list_for_each_entry(fl, &file_lock_list, list) {
/* owners_fd should be set before usage */
- if (fl->fl_owner != pid->real || fl->owners_fd != fd)
+ if (fl->fl_holder != pid->real || fl->owners_fd != fd)
continue;
- fl->updated = true;
if (fl->fl_kind == FL_LEASE &&
(fl->fl_ltype & LEASE_BREAKING)) {
/*
diff --git a/criu/files.c b/criu/files.c
index 30ecb4bb..4f6b0378 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -321,6 +321,9 @@ int do_dump_gen_file(struct fd_parms *p, int lfd,
ret = fd_id_generate(p->pid, e, p);
if (ret == 1) /* new ID generated */
ret = ops->dump(lfd, e->id, p);
+ else
+ /* Remove locks generated by the fd before going to the next */
+ discard_dup_locks_tail(p->pid, e->fd);
return ret;
}
diff --git a/criu/include/file-lock.h b/criu/include/file-lock.h
index 14a33b43..dc4f3821 100644
--- a/criu/include/file-lock.h
+++ b/criu/include/file-lock.h
@@ -46,7 +46,8 @@ struct file_lock {
int fl_kind;
int fl_ltype;
- pid_t fl_owner;
+ pid_t fl_owner; /* process, which created the lock */
+ pid_t fl_holder; /* pid of fd on whose the lock is found */
int maj, min;
unsigned long i_no;
long long start;
@@ -56,8 +57,6 @@ struct file_lock {
int real_owner;
int owners_fd;
-
- bool updated; /* used to remove duplicate leases */
};
extern struct list_head file_lock_list;
@@ -70,6 +69,7 @@ extern struct collect_image_info file_locks_cinfo;
struct pid;
struct fd_parms;
+extern void discard_dup_locks_tail(pid_t pid, int fd);
extern int correct_file_leases_type(struct pid *, int fd, int lfd);
extern int note_file_lock(struct pid *, int fd, int lfd, struct fd_parms *);
extern int dump_file_locks(void);
diff --git a/criu/proc_parse.c b/criu/proc_parse.c
index 299649fa..4ab11a31 100644
--- a/criu/proc_parse.c
+++ b/criu/proc_parse.c
@@ -1788,6 +1788,7 @@ static int parse_fdinfo_pid_s(int pid, int fd, int type, void *arg)
}
fl->real_owner = fdinfo->owner;
+ fl->fl_holder = pid;
fl->owners_fd = fd;
list_add_tail(&fl->list, &file_lock_list);
}
@@ -2081,8 +2082,6 @@ static int parse_file_lock_buf(char *buf, struct file_lock *fl,
return -1;
}
- fl->updated = false;
-
if (!strcmp(fl_flag, "POSIX"))
fl->fl_kind = FL_POSIX;
else if (!strcmp(fl_flag, "FLOCK"))
--
2.14.1.473.g3ec7d702a8
More information about the CRIU
mailing list