mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 14:55:39 +00:00
files: Formalize fd restore priorities
There are places when we have to select which fd to ->open and which to ->receive. To avoid deadlocks we sort them in an ascending order on { pid, fd } pair. Make this idea more formal by introducing an explicit function doing this check and call it where appropriate (pipe.c master selection is also simplified to fit new ... API). Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
@@ -43,6 +43,12 @@ struct fdinfo_list_entry {
|
||||
FdinfoEntry *fe;
|
||||
};
|
||||
|
||||
/* reports whether fd_a takes prio over fd_b */
|
||||
static inline int fdinfo_rst_prio(struct fdinfo_list_entry *fd_a, struct fdinfo_list_entry *fd_b)
|
||||
{
|
||||
return (fd_a->pid < fd_b->pid) || ((fd_a->pid == fd_b->pid) && (fd_a->fe->fd < fd_b->fe->fd));
|
||||
}
|
||||
|
||||
struct file_desc_ops {
|
||||
unsigned int type;
|
||||
int (*open)(struct file_desc *d);
|
||||
|
14
pipes.c
14
pipes.c
@@ -112,7 +112,6 @@ void mark_pipe_master(void)
|
||||
while (1) {
|
||||
struct fdinfo_list_entry *fle;
|
||||
struct pipe_info *pi, *pic, *p;
|
||||
int fd, pid;
|
||||
|
||||
if (list_empty(&pipes))
|
||||
break;
|
||||
@@ -125,18 +124,15 @@ void mark_pipe_master(void)
|
||||
|
||||
fle = file_master(&pi->d);
|
||||
p = pi;
|
||||
fd = fle->fe->fd;
|
||||
pid = fle->pid;
|
||||
|
||||
list_for_each_entry(pic, &pi->pipe_list, pipe_list) {
|
||||
list_move(&pic->list, &head);
|
||||
struct fdinfo_list_entry *f;
|
||||
|
||||
fle = file_master(&pic->d);
|
||||
if (fle->pid < pid ||
|
||||
(pid == fle->pid && fle->fe->fd < fd)) {
|
||||
list_move(&pic->list, &head);
|
||||
f = file_master(&pic->d);
|
||||
if (fdinfo_rst_prio(f, fle)) {
|
||||
p = pic;
|
||||
fd = fle->fe->fd;
|
||||
pid = fle->pid;
|
||||
fle = f;
|
||||
}
|
||||
|
||||
show_saved_pipe_fds(pic);
|
||||
|
@@ -762,9 +762,7 @@ int resolve_unix_peers(void)
|
||||
fle = file_master(&ui->d);
|
||||
fle_peer = file_master(&peer->d);
|
||||
|
||||
if ((fle->pid < fle_peer->pid) ||
|
||||
(fle->pid == fle_peer->pid &&
|
||||
fle->fe->fd < fle_peer->fe->fd)) {
|
||||
if (fdinfo_rst_prio(fle, fle_peer)) {
|
||||
ui->flags |= USK_PAIR_MASTER;
|
||||
peer->flags |= USK_PAIR_SLAVE;
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user