mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-02 07:15:31 +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;
|
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 {
|
struct file_desc_ops {
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
int (*open)(struct file_desc *d);
|
int (*open)(struct file_desc *d);
|
||||||
|
14
pipes.c
14
pipes.c
@@ -112,7 +112,6 @@ void mark_pipe_master(void)
|
|||||||
while (1) {
|
while (1) {
|
||||||
struct fdinfo_list_entry *fle;
|
struct fdinfo_list_entry *fle;
|
||||||
struct pipe_info *pi, *pic, *p;
|
struct pipe_info *pi, *pic, *p;
|
||||||
int fd, pid;
|
|
||||||
|
|
||||||
if (list_empty(&pipes))
|
if (list_empty(&pipes))
|
||||||
break;
|
break;
|
||||||
@@ -125,18 +124,15 @@ void mark_pipe_master(void)
|
|||||||
|
|
||||||
fle = file_master(&pi->d);
|
fle = file_master(&pi->d);
|
||||||
p = pi;
|
p = pi;
|
||||||
fd = fle->fe->fd;
|
|
||||||
pid = fle->pid;
|
|
||||||
|
|
||||||
list_for_each_entry(pic, &pi->pipe_list, pipe_list) {
|
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);
|
list_move(&pic->list, &head);
|
||||||
if (fle->pid < pid ||
|
f = file_master(&pic->d);
|
||||||
(pid == fle->pid && fle->fe->fd < fd)) {
|
if (fdinfo_rst_prio(f, fle)) {
|
||||||
p = pic;
|
p = pic;
|
||||||
fd = fle->fe->fd;
|
fle = f;
|
||||||
pid = fle->pid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
show_saved_pipe_fds(pic);
|
show_saved_pipe_fds(pic);
|
||||||
|
@@ -762,9 +762,7 @@ int resolve_unix_peers(void)
|
|||||||
fle = file_master(&ui->d);
|
fle = file_master(&ui->d);
|
||||||
fle_peer = file_master(&peer->d);
|
fle_peer = file_master(&peer->d);
|
||||||
|
|
||||||
if ((fle->pid < fle_peer->pid) ||
|
if (fdinfo_rst_prio(fle, fle_peer)) {
|
||||||
(fle->pid == fle_peer->pid &&
|
|
||||||
fle->fe->fd < fle_peer->fe->fd)) {
|
|
||||||
ui->flags |= USK_PAIR_MASTER;
|
ui->flags |= USK_PAIR_MASTER;
|
||||||
peer->flags |= USK_PAIR_SLAVE;
|
peer->flags |= USK_PAIR_SLAVE;
|
||||||
} else {
|
} else {
|
||||||
|
3
tty.c
3
tty.c
@@ -670,8 +670,7 @@ static void tty_setup_orphan_slavery(void)
|
|||||||
* waiting for each other.
|
* waiting for each other.
|
||||||
*/
|
*/
|
||||||
b = file_master(&peer->d);
|
b = file_master(&peer->d);
|
||||||
if (a->pid > b->pid ||
|
if (fdinfo_rst_prio(b, a)) {
|
||||||
(a->pid == b->pid && a->fe->fd > b->fe->fd)) {
|
|
||||||
a = b;
|
a = b;
|
||||||
m = peer;
|
m = peer;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user