Commit 05e3c4d2 authored by Pavel Emelyanov's avatar Pavel Emelyanov

fd: Handle close-on-exec bits

This bit is not per-file, but per-fd, thus put it on the fdinfo_entry.
Draing these bits from parasite together with the fds themselves, save
into image and restore with fcntl F_SETFD cmd where applicable.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 30224abc
......@@ -305,6 +305,7 @@ static int do_dump_gen_file(const struct fd_parms *p, int lfd,
e.type = p->type;
e.fd = p->fd;
e.id = p->id;
e.flags = p->fd_flags;
ret = fd_id_generate(p->pid, &e);
if (ret == 1) /* new ID generated */
......@@ -368,7 +369,7 @@ static int dump_task_exe_link(pid_t pid, struct mm_entry *mm)
return ret;
}
static int fill_fd_params(pid_t pid, int fd, int lfd, struct fd_parms *p)
static int fill_fd_params(pid_t pid, int fd, int lfd, char fd_flags, struct fd_parms *p)
{
if (fstat(lfd, &p->stat) < 0) {
pr_perror("Can't stat fd %d\n", lfd);
......@@ -380,9 +381,10 @@ static int fill_fd_params(pid_t pid, int fd, int lfd, struct fd_parms *p)
p->flags = fcntl(lfd, F_GETFL);
p->pid = pid;
p->id = FD_ID_INVALID;
p->fd_flags = fd_flags;
pr_info("%d fdinfo %d: pos: %16lx flags: %16o\n",
pid, fd, p->pos, p->flags);
pr_info("%d fdinfo %d: pos: %16lx flags: %16o/%x\n",
pid, fd, p->pos, p->flags, (int)fd_flags);
return 0;
}
......@@ -411,12 +413,12 @@ static int dump_chrdev(struct fd_parms *p, int lfd, const struct cr_fdset *set)
return dump_unsupp_fd(p);
}
static int dump_one_file(pid_t pid, int fd, int lfd,
static int dump_one_file(pid_t pid, int fd, int lfd, char fd_flags,
const struct cr_fdset *cr_fdset)
{
struct fd_parms p;
if (fill_fd_params(pid, fd, lfd, &p) < 0) {
if (fill_fd_params(pid, fd, lfd, fd_flags, &p) < 0) {
pr_perror("Can't get stat on %d", fd);
return -1;
}
......@@ -439,6 +441,7 @@ static int dump_task_files_seized(struct parasite_ctl *ctl, const struct cr_fdse
int *fds, int nr_fds)
{
int *lfds;
char *flags;
int i, ret = -1;
pr_info("\n");
......@@ -449,20 +452,27 @@ static int dump_task_files_seized(struct parasite_ctl *ctl, const struct cr_fdse
if (!lfds)
goto err;
ret = parasite_drain_fds_seized(ctl, fds, lfds, nr_fds);
flags = xmalloc(PARASITE_MAX_FDS * sizeof(char));
if (!flags)
goto err1;
ret = parasite_drain_fds_seized(ctl, fds, lfds, nr_fds, flags);
if (ret)
goto err;
goto err2;
for (i = 0; i < nr_fds; i++) {
ret = dump_one_file(ctl->pid, fds[i], lfds[i], cr_fdset);
ret = dump_one_file(ctl->pid, fds[i], lfds[i], flags[i], cr_fdset);
close(lfds[i]);
if (ret)
goto err;
goto err2;
}
pr_info("----------------------------------------\n");
err:
err2:
xfree(flags);
err1:
xfree(lfds);
err:
return ret;
}
......
......@@ -83,8 +83,8 @@ void show_files(int fd_files, struct cr_options *o)
if (ret <= 0)
goto out;
pr_msg("type: %5s fd: %5d id: %8x",
fdtype2s(e.type), e.fd, e.id);
pr_msg("type: %5s fd: %5d id: %8x flags %x",
fdtype2s(e.type), e.fd, e.id, e.flags);
pr_msg("\n");
}
......
......@@ -172,6 +172,7 @@ static int collect_fd(int pid, struct fdinfo_entry *e)
le->pid = pid;
le->fd = e->fd;
le->flags = e->flags;
futex_init(&le->real_pid);
fdesc = find_file_desc(e);
......@@ -344,6 +345,8 @@ static int open_fd(int pid, struct fdinfo_entry *fe,
if (reopen_fd_as(fe->fd, tmp))
return -1;
fcntl(tmp, F_SETFD, fe->flags);
sock = socket(PF_UNIX, SOCK_DGRAM, 0);
if (sock < 0) {
pr_perror("Can't create socket");
......@@ -369,6 +372,8 @@ static int open_fd(int pid, struct fdinfo_entry *fe,
return -1;
}
fcntl(fle->fd, F_SETFD, fle->flags);
continue;
}
......@@ -402,7 +407,11 @@ static int receive_fd(int pid, struct fdinfo_entry *fe, struct file_desc *d)
}
close(fe->fd);
return reopen_fd_as(fe->fd, tmp);
if (reopen_fd_as(fe->fd, tmp) < 0)
return -1;
fcntl(tmp, F_SETFD, fe->flags);
return 0;
}
static int open_fdinfo(int pid, struct fdinfo_entry *fe, int *fdinfo_fd, int state)
......
......@@ -12,6 +12,7 @@ struct fd_parms {
unsigned long pos;
unsigned int flags;
unsigned int type;
char fd_flags;
struct stat stat;
u32 id;
pid_t pid;
......@@ -29,6 +30,7 @@ struct fdinfo_list_entry {
struct list_head list;
int fd;
int pid;
int flags;
futex_t real_pid;
};
......
......@@ -58,6 +58,7 @@ struct reg_file_entry {
struct fdinfo_entry {
u32 fd;
u8 type;
u8 flags;
u32 id;
} __packed;
......
......@@ -41,7 +41,7 @@ struct parasite_dump_tid_addr;
extern int parasite_dump_tid_addr_seized(struct parasite_ctl *ctl,
pid_t pid, unsigned int **tid_add);
extern int parasite_drain_fds_seized(struct parasite_ctl *ctl, int *fds, int *lfds, int nr_fds);
extern int parasite_drain_fds_seized(struct parasite_ctl *ctl, int *fds, int *lfds, int nr_fds, char *flags);
extern int parasite_cure_seized(struct parasite_ctl *ctl);
extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
......
......@@ -547,7 +547,7 @@ out:
return ret;
}
int parasite_drain_fds_seized(struct parasite_ctl *ctl, int *fds, int *lfds, int nr_fds)
int parasite_drain_fds_seized(struct parasite_ctl *ctl, int *fds, int *lfds, int nr_fds, char *flags)
{
struct parasite_drain_fd *args;
parasite_status_t *st;
......@@ -583,7 +583,7 @@ int parasite_drain_fds_seized(struct parasite_ctl *ctl, int *fds, int *lfds, int
goto err;
}
ret = recv_fds(sock, lfds, nr_fds, NULL);
ret = recv_fds(sock, lfds, nr_fds, flags);
if (ret) {
pr_err("Can't retrieve FDs from socket\n");
goto err;
......
......@@ -373,7 +373,7 @@ static int drain_fds(struct parasite_drain_fd *args)
int ret;
ret = send_fds(tsock, &args->saddr, args->sun_len,
args->fds, args->nr_fds, false);
args->fds, args->nr_fds, true);
if (ret) {
sys_write_msg("send_fds failed\n");
SET_PARASITE_RET(st, ret);
......
......@@ -307,6 +307,7 @@ static int dump_one_inet(struct socket_desc *_sk, struct fd_parms *p,
fe.fd = p->fd;
fe.type = FDINFO_INETSK;
fe.id = sk->sd.ino;
fe.flags = p->fd_flags;
if (write_img(fdset_fd(cr_fdset, CR_FD_FDINFO), &fe))
goto err;
......@@ -378,6 +379,7 @@ static int dump_one_unix(const struct socket_desc *_sk, struct fd_parms *p,
fe.fd = p->fd;
fe.type = FDINFO_UNIXSK;
fe.id = sk->sd.ino;
fe.flags = p->fd_flags;
if (write_img(fdset_fd(cr_fdset, CR_FD_FDINFO), &fe))
goto err;
......
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