mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 06:45:35 +00:00
fown: get pid and uid-s from parasite
A task may be in another pidns and crtools should get a pid from this pidns. Signed-off-by: Andrey Vagin <avagin@openvz.org> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
committed by
Pavel Emelyanov
parent
05466cc38a
commit
97cfb70747
49
cr-dump.c
49
cr-dump.c
@@ -184,11 +184,9 @@ static int dump_task_exe_link(pid_t pid, MmEntry *mm)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fill_fd_params(pid_t pid, int fd, int lfd, char fd_flags, struct fd_parms *p)
|
||||
static int fill_fd_params(pid_t pid, int fd, int lfd,
|
||||
struct fd_opts *opts, struct fd_parms *p)
|
||||
{
|
||||
struct f_owner_ex owner_ex;
|
||||
u32 v[2];
|
||||
|
||||
if (fstat(lfd, &p->stat) < 0) {
|
||||
pr_perror("Can't stat fd %d\n", lfd);
|
||||
return -1;
|
||||
@@ -198,12 +196,12 @@ static int fill_fd_params(pid_t pid, int fd, int lfd, char fd_flags, struct fd_p
|
||||
p->pos = lseek(lfd, 0, SEEK_CUR);
|
||||
p->flags = fcntl(lfd, F_GETFL);
|
||||
p->pid = pid;
|
||||
p->fd_flags = fd_flags;
|
||||
p->fd_flags = opts->flags;
|
||||
|
||||
fown_entry__init(&p->fown);
|
||||
|
||||
pr_info("%d fdinfo %d: pos: 0x%16lx flags: %16o/%#x\n",
|
||||
pid, fd, p->pos, p->flags, (int)fd_flags);
|
||||
pid, fd, p->pos, p->flags, (int)p->fd_flags);
|
||||
|
||||
p->fown.signum = fcntl(lfd, F_GETSIG, 0);
|
||||
if (p->fown.signum < 0) {
|
||||
@@ -211,26 +209,13 @@ static int fill_fd_params(pid_t pid, int fd, int lfd, char fd_flags, struct fd_p
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fcntl(lfd, F_GETOWN_EX, (long)&owner_ex)) {
|
||||
pr_perror("Can't get owners on %d\n", lfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple case -- nothing is changed.
|
||||
*/
|
||||
if (owner_ex.pid == 0)
|
||||
if (opts->fown.pid == 0)
|
||||
return 0;
|
||||
|
||||
if (fcntl(lfd, F_GETOWNER_UIDS, (long)&v)) {
|
||||
pr_perror("Can't get owner uids on %d\n", lfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p->fown.uid = v[0];
|
||||
p->fown.euid = v[1];
|
||||
p->fown.pid_type = owner_ex.type;
|
||||
p->fown.pid = owner_ex.pid;
|
||||
p->fown.pid = opts->fown.pid;
|
||||
p->fown.pid_type = opts->fown.pid_type;
|
||||
p->fown.uid = opts->fown.uid;
|
||||
p->fown.euid = opts->fown.euid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -264,13 +249,13 @@ static int dump_chrdev(struct fd_parms *p, int lfd, const struct cr_fdset *set)
|
||||
#define PIPEFS_MAGIC 0x50495045
|
||||
#endif
|
||||
|
||||
static int dump_one_file(pid_t pid, int fd, int lfd, char fd_flags,
|
||||
static int dump_one_file(pid_t pid, int fd, int lfd, struct fd_opts *opts,
|
||||
const struct cr_fdset *cr_fdset)
|
||||
{
|
||||
struct fd_parms p;
|
||||
struct statfs statfs;
|
||||
|
||||
if (fill_fd_params(pid, fd, lfd, fd_flags, &p) < 0) {
|
||||
if (fill_fd_params(pid, fd, lfd, opts, &p) < 0) {
|
||||
pr_perror("Can't get stat on %d", fd);
|
||||
return -1;
|
||||
}
|
||||
@@ -316,7 +301,7 @@ static int dump_task_files_seized(struct parasite_ctl *ctl, const struct cr_fdse
|
||||
struct parasite_drain_fd *dfds)
|
||||
{
|
||||
int *lfds;
|
||||
char *flags;
|
||||
struct fd_opts *opts;
|
||||
int i, ret = -1;
|
||||
|
||||
pr_info("\n");
|
||||
@@ -327,16 +312,16 @@ static int dump_task_files_seized(struct parasite_ctl *ctl, const struct cr_fdse
|
||||
if (!lfds)
|
||||
goto err;
|
||||
|
||||
flags = xmalloc(dfds->nr_fds * sizeof(char));
|
||||
if (!flags)
|
||||
opts = xmalloc(dfds->nr_fds * sizeof(struct fd_opts));
|
||||
if (!opts)
|
||||
goto err1;
|
||||
|
||||
ret = parasite_drain_fds_seized(ctl, dfds, lfds, flags);
|
||||
ret = parasite_drain_fds_seized(ctl, dfds, lfds, opts);
|
||||
if (ret)
|
||||
goto err2;
|
||||
|
||||
for (i = 0; i < dfds->nr_fds; i++) {
|
||||
ret = dump_one_file(ctl->pid, dfds->fds[i], lfds[i], flags[i], cr_fdset);
|
||||
ret = dump_one_file(ctl->pid, dfds->fds[i], lfds[i], opts + i, cr_fdset);
|
||||
close(lfds[i]);
|
||||
if (ret)
|
||||
goto err2;
|
||||
@@ -344,7 +329,7 @@ static int dump_task_files_seized(struct parasite_ctl *ctl, const struct cr_fdse
|
||||
|
||||
pr_info("----------------------------------------\n");
|
||||
err2:
|
||||
xfree(flags);
|
||||
xfree(opts);
|
||||
err1:
|
||||
xfree(lfds);
|
||||
err:
|
||||
|
@@ -38,8 +38,10 @@ extern int parasite_dump_thread_seized(struct parasite_ctl *ctl, pid_t pid,
|
||||
unsigned int **tid_add, u32 *tid);
|
||||
|
||||
struct parasite_drain_fd;
|
||||
extern int parasite_drain_fds_seized(struct parasite_ctl *ctl, struct parasite_drain_fd *dfds,
|
||||
int *lfds, char *flags);
|
||||
struct fd_opts;
|
||||
extern int parasite_drain_fds_seized(struct parasite_ctl *ctl,
|
||||
struct parasite_drain_fd *dfds,
|
||||
int *lfds, struct fd_opts *flags);
|
||||
|
||||
extern int parasite_cure_seized(struct parasite_ctl *ctl);
|
||||
extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
|
||||
|
@@ -21,16 +21,27 @@
|
||||
#define CR_SCM_MSG_SIZE (1024)
|
||||
#define CR_SCM_MAX_FD (252)
|
||||
|
||||
struct fd_opts {
|
||||
char flags;
|
||||
struct {
|
||||
uint32_t uid;
|
||||
uint32_t euid;
|
||||
uint32_t signum;
|
||||
uint32_t pid_type;
|
||||
uint32_t pid;
|
||||
} fown;
|
||||
};
|
||||
|
||||
struct scm_fdset {
|
||||
struct msghdr hdr;
|
||||
struct iovec iov;
|
||||
char msg_buf[CR_SCM_MSG_SIZE];
|
||||
char msg[CR_SCM_MAX_FD];
|
||||
struct fd_opts opts[CR_SCM_MAX_FD];
|
||||
};
|
||||
|
||||
extern int send_fds(int sock, struct sockaddr_un *saddr, int saddr_len,
|
||||
int *fds, int nr_fds, bool with_flags);
|
||||
extern int recv_fds(int sock, int *fds, int nr_fds, char *flags);
|
||||
extern int recv_fds(int sock, int *fds, int nr_fds, struct fd_opts *opts);
|
||||
|
||||
static inline int send_fd(int sock, struct sockaddr_un *saddr, int saddr_len, int fd)
|
||||
{
|
||||
|
@@ -602,7 +602,7 @@ out:
|
||||
}
|
||||
|
||||
int parasite_drain_fds_seized(struct parasite_ctl *ctl,
|
||||
struct parasite_drain_fd *dfds, int *lfds, char *flags)
|
||||
struct parasite_drain_fd *dfds, int *lfds, struct fd_opts *opts)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
@@ -613,7 +613,7 @@ int parasite_drain_fds_seized(struct parasite_ctl *ctl,
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = recv_fds(ctl->tsock, lfds, dfds->nr_fds, flags);
|
||||
ret = recv_fds(ctl->tsock, lfds, dfds->nr_fds, opts);
|
||||
if (ret) {
|
||||
pr_err("Can't retrieve FDs from socket\n");
|
||||
goto err;
|
||||
|
40
util-net.c
40
util-net.c
@@ -28,8 +28,8 @@ static int *scm_fdset_init(struct scm_fdset *fdset, struct sockaddr_un *saddr,
|
||||
BUILD_BUG_ON(CR_SCM_MAX_FD > SCM_MAX_FD);
|
||||
BUILD_BUG_ON(sizeof(fdset->msg_buf) < (CMSG_SPACE(sizeof(int) * CR_SCM_MAX_FD)));
|
||||
|
||||
fdset->iov.iov_base = &fdset->msg;
|
||||
fdset->iov.iov_len = with_flags ? sizeof(fdset->msg) : 1;
|
||||
fdset->iov.iov_base = fdset->opts;
|
||||
fdset->iov.iov_len = with_flags ? sizeof(fdset->opts) : 1;
|
||||
|
||||
fdset->hdr.msg_iov = &fdset->iov;
|
||||
fdset->hdr.msg_iovlen = 1;
|
||||
@@ -64,13 +64,35 @@ int send_fds(int sock, struct sockaddr_un *saddr, int len,
|
||||
int j;
|
||||
|
||||
for (j = 0; j < min_fd; j++) {
|
||||
int flags;
|
||||
int flags, fd = fds[i + j];
|
||||
struct fd_opts *p = fdset.opts + j;
|
||||
struct f_owner_ex owner_ex;
|
||||
u32 v[2];
|
||||
|
||||
flags = sys_fcntl(fds[i + j], F_GETFD, 0);
|
||||
flags = sys_fcntl(fd, F_GETFD, 0);
|
||||
if (flags < 0)
|
||||
return -1;
|
||||
|
||||
fdset.msg[j] = (char)flags;
|
||||
p->flags = (char)flags;
|
||||
|
||||
if (sys_fcntl(fd, F_GETOWN_EX, (long)&owner_ex))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Simple case -- nothing is changed.
|
||||
*/
|
||||
if (owner_ex.pid == 0) {
|
||||
p->fown.pid = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sys_fcntl(fd, F_GETOWNER_UIDS, (long)&v))
|
||||
return -1;
|
||||
|
||||
p->fown.uid = v[0];
|
||||
p->fown.euid = v[1];
|
||||
p->fown.pid_type = owner_ex.type;
|
||||
p->fown.pid = owner_ex.pid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +104,7 @@ int send_fds(int sock, struct sockaddr_un *saddr, int len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int recv_fds(int sock, int *fds, int nr_fds, char *flags)
|
||||
int recv_fds(int sock, int *fds, int nr_fds, struct fd_opts *opts)
|
||||
{
|
||||
struct scm_fdset fdset;
|
||||
struct cmsghdr *cmsg;
|
||||
@@ -90,7 +112,7 @@ int recv_fds(int sock, int *fds, int nr_fds, char *flags)
|
||||
int ret;
|
||||
int i, min_fd;
|
||||
|
||||
cmsg_data = scm_fdset_init(&fdset, NULL, 0, flags != NULL);
|
||||
cmsg_data = scm_fdset_init(&fdset, NULL, 0, opts != NULL);
|
||||
for (i = 0; i < nr_fds; i += min_fd) {
|
||||
min_fd = min(CR_SCM_MAX_FD, nr_fds - i);
|
||||
scm_fdset_init_chunk(&fdset, min_fd);
|
||||
@@ -120,8 +142,8 @@ int recv_fds(int sock, int *fds, int nr_fds, char *flags)
|
||||
if (unlikely(min_fd <= 0))
|
||||
return -1;
|
||||
builtin_memcpy(&fds[i], cmsg_data, sizeof(int) * min_fd);
|
||||
if (flags)
|
||||
builtin_memcpy(flags + i, fdset.msg, sizeof(char) * min_fd);
|
||||
if (opts)
|
||||
builtin_memcpy(opts + i, fdset.opts, sizeof(struct fd_opts) * min_fd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user