Commit 527b67b9 authored by Pavel Emelyanov's avatar Pavel Emelyanov

files: Generalize fd restore, introduce file_desc

The struct replaces bare list_head on all of the _info-s we've
introduced recently.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent c406b063
......@@ -36,11 +36,23 @@ int prepare_shared_fdinfo(void)
return 0;
}
void file_desc_add(struct file_desc *d)
{
INIT_LIST_HEAD(&d->fd_info_head);
}
struct fdinfo_list_entry *file_master(struct file_desc *d)
{
BUG_ON(list_empty(&d->fd_info_head));
return list_first_entry(&d->fd_info_head,
struct fdinfo_list_entry, list);
}
struct reg_file_info {
struct reg_file_entry rfe;
char *path;
struct list_head list;
struct list_head fd_head;
struct file_desc d;
};
#define REG_FILES_HSIZE 32
......@@ -57,7 +69,7 @@ void show_saved_files(void)
struct fdinfo_list_entry *le;
pr_info(" `- ID %x\n", rfi->rfe.id);
list_for_each_entry(le, &rfi->fd_head, list)
list_for_each_entry(le, &rfi->d.fd_info_head, list)
pr_info(" `- FD %d pid %d\n", le->fd, le->pid);
}
}
......@@ -74,24 +86,24 @@ static struct reg_file_info *find_reg_file(int id)
return NULL;
}
static struct list_head *find_reg_fd(int id)
static struct file_desc *find_reg_desc(int id)
{
struct reg_file_info *rfi;
rfi = find_reg_file(id);
return &rfi->fd_head;
return &rfi->d;
}
static struct list_head *find_fi_list(struct fdinfo_entry *fe)
static struct file_desc *find_file_desc(struct fdinfo_entry *fe)
{
if (fe->type == FDINFO_REG)
return find_reg_fd(fe->id);
return find_reg_desc(fe->id);
if (fe->type == FDINFO_INETSK)
return find_inetsk_fd(fe->id);
return find_inetsk_desc(fe->id);
if (fe->type == FDINFO_PIPE)
return find_pipe_fd(fe->id);
return find_pipe_desc(fe->id);
if (fe->type == FDINFO_UNIXSK)
return find_unixsk_fd(fe->id);
return find_unixsk_desc(fe->id);
BUG_ON(1);
return NULL;
......@@ -135,7 +147,7 @@ int collect_reg_files(void)
rfi->path[len] = '\0';
pr_info("Collected [%s] ID %x\n", rfi->path, rfi->rfe.id);
INIT_LIST_HEAD(&rfi->fd_head);
file_desc_add(&rfi->d);
chain = rfi->rfe.id % REG_FILES_HSIZE;
list_add_tail(&rfi->list, &reg_files[chain]);
}
......@@ -153,7 +165,7 @@ static int collect_fd(int pid, struct fdinfo_entry *e)
{
int i;
struct fdinfo_list_entry *l, *le = &fdinfo_list[nr_fdinfo_list];
struct list_head *fi_list;
struct file_desc *fdesc;
pr_info("Collect fdinfo pid=%d fd=%ld id=%16x\n",
pid, e->addr, e->id);
......@@ -168,13 +180,13 @@ static int collect_fd(int pid, struct fdinfo_entry *e)
le->fd = e->addr;
futex_init(&le->real_pid);
fi_list = find_fi_list(e);
if (fi_list == NULL) {
fdesc = find_file_desc(e);
if (fdesc == NULL) {
pr_err("No file for fd %d id %d\n", (int)e->addr, e->id);
return -1;
}
list_for_each_entry(l, fi_list, list)
list_for_each_entry(l, &fdesc->fd_info_head, list)
if (l->pid > le->pid)
break;
......@@ -214,12 +226,12 @@ int prepare_fd_pid(int pid)
return ret;
}
static int open_fe_fd(struct list_head *l)
static int open_fe_fd(struct file_desc *d)
{
struct reg_file_info *rfi;
int tmp;
rfi = container_of(l, struct reg_file_info, fd_head);
rfi = container_of(d, struct reg_file_info, d);
tmp = open(rfi->path, rfi->rfe.flags);
if (tmp < 0) {
......@@ -242,7 +254,7 @@ static int find_open_fe_fd(struct fdinfo_entry *fe)
return -1;
}
return open_fe_fd(&rfi->fd_head);
return open_fe_fd(&rfi->d);
}
static int restore_cwd(struct fdinfo_entry *fe, int fd)
......@@ -294,29 +306,29 @@ void transport_name_gen(struct sockaddr_un *addr, int *len,
*addr->sun_path = '\0';
}
static int should_open_transport(struct fdinfo_entry *fe, struct list_head *fd_list)
static int should_open_transport(struct fdinfo_entry *fe, struct file_desc *fd)
{
if (fe->type == FDINFO_PIPE)
return pipe_should_open_transport(fe, fd_list);
return pipe_should_open_transport(fe, fd);
if (fe->type == FDINFO_UNIXSK)
return unixsk_should_open_transport(fe, fd_list);
return unixsk_should_open_transport(fe, fd);
return 0;
}
static int open_transport_fd(int pid, struct fdinfo_entry *fe, struct list_head *fd_list)
static int open_transport_fd(int pid, struct fdinfo_entry *fe, struct file_desc *d)
{
struct fdinfo_list_entry *fle;
struct sockaddr_un saddr;
int sock;
int ret, sun_len;
fle = file_master(fd_list);
fle = file_master(d);
if (fle->pid == pid) {
if (fle->fd == fe->addr) {
/* file master */
if (!should_open_transport(fe, fd_list))
if (!should_open_transport(fe, d))
return 0;
} else
return 0;
......@@ -326,11 +338,11 @@ static int open_transport_fd(int pid, struct fdinfo_entry *fe, struct list_head
pr_info("\t%d: Create transport fd for %lx\n", pid, fe->addr);
list_for_each_entry(fle, fd_list, list)
list_for_each_entry(fle, &d->fd_info_head, list)
if ((fle->pid == pid) && (fle->fd == fe->addr))
break;
BUG_ON(fd_list == &fle->list);
BUG_ON(&d->fd_info_head == &fle->list);
sock = socket(PF_UNIX, SOCK_DGRAM, 0);
if (sock < 0) {
......@@ -354,29 +366,29 @@ static int open_transport_fd(int pid, struct fdinfo_entry *fe, struct list_head
}
static int open_fd(int pid, struct fdinfo_entry *fe,
struct list_head *fd_list, int *fdinfo_fd)
struct file_desc *d, int *fdinfo_fd)
{
int tmp;
int serv, sock;
struct sockaddr_un saddr;
struct fdinfo_list_entry *fle;
fle = file_master(fd_list);
fle = file_master(d);
if ((fle->pid != pid) || (fe->addr != fle->fd))
return 0;
switch (fe->type) {
case FDINFO_REG:
tmp = open_fe_fd(fd_list);
tmp = open_fe_fd(d);
break;
case FDINFO_INETSK:
tmp = open_inet_sk(fd_list);
tmp = open_inet_sk(d);
break;
case FDINFO_PIPE:
tmp = open_pipe(fd_list);
tmp = open_pipe(d);
break;
case FDINFO_UNIXSK:
tmp = open_unix_sk(fd_list);
tmp = open_unix_sk(d);
break;
default:
tmp = -1;
......@@ -397,7 +409,7 @@ static int open_fd(int pid, struct fdinfo_entry *fe,
pr_info("\t%d: Create fd for %lx\n", pid, fe->addr);
list_for_each_entry(fle, fd_list, list) {
list_for_each_entry(fle, &d->fd_info_head, list) {
int len;
if (pid == fle->pid) {
......@@ -437,12 +449,12 @@ out:
return 0;
}
static int receive_fd(int pid, struct fdinfo_entry *fe, struct list_head *fd_list)
static int receive_fd(int pid, struct fdinfo_entry *fe, struct file_desc *d)
{
int tmp;
struct fdinfo_list_entry *fle;
fle = file_master(fd_list);
fle = file_master(d);
if (fle->pid == pid)
return 0;
......@@ -490,9 +502,9 @@ static int open_fdinfo(int pid, struct fdinfo_entry *fe, int *fdinfo_fd, int sta
{
u32 mag;
int ret = 0;
struct list_head *fi_list;
struct file_desc *fdesc;
fi_list = find_fi_list(fe);
fdesc = find_file_desc(fe);
if (move_img_fd(fdinfo_fd, (int)fe->addr))
return -1;
......@@ -502,13 +514,13 @@ static int open_fdinfo(int pid, struct fdinfo_entry *fe, int *fdinfo_fd, int sta
switch (state) {
case FD_STATE_PREP:
ret = open_transport_fd(pid, fe, fi_list);
ret = open_transport_fd(pid, fe, fdesc);
break;
case FD_STATE_CREATE:
ret = open_fd(pid, fe, fi_list, fdinfo_fd);
ret = open_fd(pid, fe, fdesc, fdinfo_fd);
break;
case FD_STATE_RECV:
ret = receive_fd(pid, fe, fi_list);
ret = receive_fd(pid, fe, fdesc);
break;
}
......
......@@ -39,12 +39,15 @@ struct fdinfo_list_entry {
futex_t real_pid;
};
struct file_desc {
struct list_head fd_info_head;
};
extern void file_desc_add(struct file_desc *d);
extern struct fdinfo_list_entry *file_master(struct file_desc *d);
extern void transport_name_gen(struct sockaddr_un *addr,
int *len, int pid, long fd);
static inline struct fdinfo_list_entry *file_master(struct list_head *fd_list)
{
return list_first_entry(fd_list, struct fdinfo_list_entry, list);
}
void show_saved_files(void);
extern int collect_reg_files(void);
......@@ -55,11 +58,12 @@ extern int get_filemap_fd(int pid, struct vma_entry *vma_entry);
extern int self_exe_fd;
struct file_desc;
extern int collect_pipes(void);
extern void mark_pipe_master(void);
extern int open_pipe(struct list_head *l);
struct list_head *find_pipe_fd(int id);
extern int open_pipe(struct file_desc *);
struct file_desc *find_pipe_desc(int id);
extern int pipe_should_open_transport(struct fdinfo_entry *fe,
struct list_head *fd_list);
struct file_desc *d);
#endif /* FILES_H_ */
......@@ -11,18 +11,19 @@ extern int dump_socket(struct fd_parms *p, int lfd,
const struct cr_fdset *cr_fdset);
struct fdinfo_list_entry;
struct list_head *find_inetsk_fd(int id);
struct list_head *find_unixsk_fd(int id);
struct file_desc;
struct file_desc *find_inetsk_desc(int id);
struct file_desc *find_unixsk_desc(int id);
struct fdinfo_entry;
extern int unixsk_should_open_transport(struct fdinfo_entry *,
struct list_head *);
struct file_desc *);
extern int collect_sockets(void);
extern int collect_inet_sockets(void);
extern int collect_unix_sockets(void);
extern int resolve_unix_peers(void);
extern int run_unix_connections(void);
extern int open_inet_sk(struct list_head *);
extern int open_unix_sk(struct list_head *);
extern int open_inet_sk(struct file_desc *);
extern int open_unix_sk(struct file_desc *);
struct cr_options;
extern void show_unixsk(int fd, struct cr_options *);
extern void show_inetsk(int fd, struct cr_options *);
......
......@@ -19,7 +19,7 @@ struct pipe_info {
struct list_head pipe_list; /* all pipe_info with the same pipe_id
* This is pure circular list whiout head */
struct list_head list; /* list head for fdinfo_list_entry-s */
struct list_head fd_head;
struct file_desc d;
int create;
int bytes;
off_t off;
......@@ -37,12 +37,12 @@ static struct pipe_info *find_pipe(int id)
return NULL;
}
struct list_head *find_pipe_fd(int id)
struct file_desc *find_pipe_desc(int id)
{
struct pipe_info *pi;
pi = find_pipe(id);
return &pi->fd_head;
return &pi->d;
}
int collect_pipes(void)
......@@ -68,7 +68,7 @@ int collect_pipes(void)
pr_info("Collected pipe entry ID %x PIPE ID %x\n",
pi->pe.id, pi->pe.pipe_id);
INIT_LIST_HEAD(&pi->fd_head);
file_desc_add(&pi->d);
list_for_each_entry(tmp, &pipes, list)
if (pi->pe.pipe_id == tmp->pe.pipe_id)
......@@ -93,7 +93,7 @@ static void show_saved_pipe_fds(struct pipe_info *pi)
struct fdinfo_list_entry *fle;
pr_info(" `- ID %p %xpn", pi, pi->pe.id);
list_for_each_entry(fle, &pi->fd_head, list)
list_for_each_entry(fle, &pi->d.fd_info_head, list)
pr_info(" `- FD %d pid %d\n", fle->fd, fle->pid);
}
......@@ -155,7 +155,7 @@ void mark_pipe_master()
pr_info(" `- PIPE ID %x\n", pi->pe.pipe_id);
show_saved_pipe_fds(pi);
fle = file_master(&pi->fd_head);
fle = file_master(&pi->d);
p = pi;
fd = fle->fd;
pid = fle->pid;
......@@ -163,7 +163,7 @@ void mark_pipe_master()
list_for_each_entry(pic, &pi->pipe_list, pipe_list) {
list_move(&pic->list, &head);
fle = file_master(&p->fd_head);
fle = file_master(&p->d);
if (fle->pid < pid ||
(pid == fle->pid && fle->fd < fd)) {
p = pic;
......@@ -183,10 +183,11 @@ void mark_pipe_master()
}
int pipe_should_open_transport(struct fdinfo_entry *fe,
struct list_head *fd_list)
struct file_desc *d)
{
struct pipe_info *pi = container_of(fd_list, struct pipe_info, fd_head);
struct pipe_info *pi;
pi = container_of(d, struct pipe_info, d);
return !pi->create;
}
......@@ -196,7 +197,7 @@ static int recv_pipe_fd(struct pipe_info *pi)
char path[PATH_MAX];
int tmp, fd;
fle = file_master(&pi->fd_head);
fle = file_master(&pi->d);
fd = fle->fd;
pr_info("\tWaiting fd for %d\n", fd);
......@@ -264,7 +265,7 @@ err:
return ret;
}
int open_pipe(struct list_head *l)
int open_pipe(struct file_desc *d)
{
unsigned long time = 1000;
struct pipe_info *pi, *pc, *p;
......@@ -273,7 +274,7 @@ int open_pipe(struct list_head *l)
int sock;
int create;
pi = container_of(l, struct pipe_info, fd_head);
pi = container_of(d, struct pipe_info, d);
pr_info("\tCreating pipe pipe_id=%x id=%x\n", pi->pe.pipe_id, pi->pe.id);
......@@ -298,8 +299,7 @@ int open_pipe(struct list_head *l)
struct sockaddr_un saddr;
struct fdinfo_list_entry *fle;
BUG_ON(list_empty(&p->fd_head));
fle = file_master(&p->fd_head);
fle = file_master(&p->d);
pr_info("\t\tWait fdinfo pid=%d fd=%d\n", fle->pid, fle->fd);
futex_wait_while(&fle->real_pid, 0);
......
......@@ -790,7 +790,7 @@ struct unix_sk_info {
char *name;
unsigned flags;
struct unix_sk_info *peer;
struct list_head fd_head;
struct file_desc d;
};
#define USK_PAIR_MASTER 0x1
......@@ -808,12 +808,12 @@ static struct unix_sk_info *find_unix_sk(int id)
return NULL;
}
struct list_head *find_unixsk_fd(int id)
struct file_desc *find_unixsk_desc(int id)
{
struct unix_sk_info *ui;
ui = find_unix_sk(id);
return &ui->fd_head;
return &ui->d;
}
struct sk_packet {
......@@ -902,7 +902,7 @@ static int restore_socket_queue(int fd, unsigned int peer_id)
struct inet_sk_info {
struct inet_sk_entry ie;
struct list_head list;
struct list_head fd_head;
struct file_desc d;
};
#define INET_SK_HSIZE 32
......@@ -920,12 +920,12 @@ static struct inet_sk_info *find_inet_sk(int id)
return NULL;
}
struct list_head *find_inetsk_fd(int id)
struct file_desc *find_inetsk_desc(int id)
{
struct inet_sk_info *ii;
ii = find_inet_sk(id);
return &ii->fd_head;
return &ii->d;
}
int collect_inet_sockets(void)
......@@ -950,7 +950,7 @@ int collect_inet_sockets(void)
if (ret <= 0)
break;
INIT_LIST_HEAD(&ii->fd_head);
file_desc_add(&ii->d);
chain = ii->ie.id % INET_SK_HSIZE;
list_add_tail(&ii->list, &inet_sockets[chain]);
}
......@@ -962,13 +962,13 @@ int collect_inet_sockets(void)
return 0;
}
int open_inet_sk(struct list_head *l)
int open_inet_sk(struct file_desc *d)
{
int sk;
struct sockaddr_in addr;
struct inet_sk_info *ii;
ii = container_of(l, struct inet_sk_info, fd_head);
ii = container_of(d, struct inet_sk_info, d);
show_one_inet_img("Restore", &ii->ie);
......@@ -1219,7 +1219,7 @@ int run_unix_connections(void)
pr_info("\tConnect %x to %x\n", ui->ue.id, peer->ue.id);
fle = file_master(&ui->fd_head);
fle = file_master(&ui->d);
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
......@@ -1275,11 +1275,11 @@ done:
}
int unixsk_should_open_transport(struct fdinfo_entry *fe,
struct list_head *fd_list)
struct file_desc *d)
{
struct unix_sk_info *ui;
ui = container_of(fd_list, struct unix_sk_info, fd_head);
ui = container_of(d, struct unix_sk_info, d);
return ui->flags & USK_PAIR_SLAVE;
}
......@@ -1313,7 +1313,7 @@ static int open_unixsk_pair_master(struct unix_sk_info *ui)
return -1;
}
fle = file_master(&peer->fd_head);
fle = file_master(&peer->d);
futex_wait_while(&fle->real_pid, 0);
pr_info("\tSending pair to %d's %d\n",
......@@ -1337,7 +1337,7 @@ static int open_unixsk_pair_slave(struct unix_sk_info *ui)
struct fdinfo_list_entry *fle;
int sk;
fle = file_master(&ui->fd_head);
fle = file_master(&ui->d);
pr_info("Opening pair slave (id %x peer %x) on %d\n",
ui->ue.id, ui->ue.peer, fle->fd);
......@@ -1386,11 +1386,11 @@ static int open_unixsk_standalone(struct unix_sk_info *ui)
return sk;
}
int open_unix_sk(struct list_head *l)
int open_unix_sk(struct file_desc *d)
{
struct unix_sk_info *ui;
ui = container_of(l, struct unix_sk_info, fd_head);
ui = container_of(d, struct unix_sk_info, d);
if (ui->flags & USK_PAIR_MASTER)
return open_unixsk_pair_master(ui);
else if (ui->flags & USK_PAIR_SLAVE)
......@@ -1454,7 +1454,7 @@ int collect_unix_sockets(void)
ui->peer = NULL;
ui->flags = 0;
INIT_LIST_HEAD(&ui->fd_head);
file_desc_add(&ui->d);
pr_info(" `- Got %u peer %u\n", ui->ue.id, ui->ue.peer);
list_add_tail(&ui->list, &unix_sockets);
}
......@@ -1497,10 +1497,9 @@ int resolve_unix_peers(void)
* the one in pipes.c and makes sure tasks wait for each other
* in pids sorting order (ascending).
*/
BUG_ON(list_empty(&ui->fd_head) || list_empty(&peer->fd_head));
fle = file_master(&ui->fd_head);
fle_peer = file_master(&peer->fd_head);
fle = file_master(&ui->d);
fle_peer = file_master(&peer->d);
if ((fle->pid < fle_peer->pid) ||
(fle->pid == fle_peer->pid &&
......@@ -1519,7 +1518,7 @@ int resolve_unix_peers(void)
pr_info("\t%x -> %x (%x) flags %x\n", ui->ue.id, ui->ue.peer,
ui->peer ? ui->peer->ue.id : 0, ui->flags);
list_for_each_entry(fle, &ui->fd_head, list)
list_for_each_entry(fle, &ui->d.fd_info_head, list)
pr_info("\t\tfd %d in pid %d\n",
fle->fd, fle->pid);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment