mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-19 17:43:59 +00:00
fown: Don't fail on dumping files opened with O_PATH
O_PATH opened files are special: they have empty file operations in kernel space, so there not that much we can do with them, even setting position is not allowed. Same applies to a signal number for owner settings. Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com> Co-developed-by: Alexander Mikhalitsyn <alexander@mihalicyn.com> Signed-off-by: Alexander Mikhalitsyn (Virtuozzo) <alexander@mihalicyn.com>
This commit is contained in:
parent
58fd63042c
commit
f167d1f4e9
3 changed files with 64 additions and 32 deletions
|
|
@ -1776,11 +1776,17 @@ static int do_open_reg(int ns_root_fd, struct reg_file_info *rfi, void *arg)
|
|||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
if ((rfi->rfe->pos != -1ULL) &&
|
||||
lseek(fd, rfi->rfe->pos, SEEK_SET) < 0) {
|
||||
pr_perror("Can't restore file pos");
|
||||
close(fd);
|
||||
return -1;
|
||||
/*
|
||||
* O_PATH opened files carry empty fops in kernel,
|
||||
* just ignore positioning at all.
|
||||
*/
|
||||
if (!(rfi->rfe->flags & O_PATH)) {
|
||||
if (rfi->rfe->pos != -1ULL &&
|
||||
lseek(fd, rfi->rfe->pos, SEEK_SET) < 0) {
|
||||
pr_perror("Can't restore file pos");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return fd;
|
||||
|
|
|
|||
|
|
@ -399,7 +399,10 @@ static int fill_fd_params(struct pid *owner_pid, int fd, int lfd,
|
|||
pr_info("%d fdinfo %d: pos: %#16"PRIx64" flags: %16o/%#x\n",
|
||||
owner_pid->real, fd, p->pos, p->flags, (int)p->fd_flags);
|
||||
|
||||
ret = fcntl(lfd, F_GETSIG, 0);
|
||||
if (p->flags & O_PATH)
|
||||
ret = 0;
|
||||
else
|
||||
ret = fcntl(lfd, F_GETSIG, 0);
|
||||
if (ret < 0) {
|
||||
pr_perror("Can't get owner signum on %d", lfd);
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -317,15 +317,60 @@ grps_err:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int fill_fds_fown(int fd, struct fd_opts *p)
|
||||
{
|
||||
int flags, ret;
|
||||
struct f_owner_ex owner_ex;
|
||||
uint32_t v[2];
|
||||
|
||||
/*
|
||||
* For O_PATH opened files there is no owner at all.
|
||||
*/
|
||||
flags = sys_fcntl(fd, F_GETFL, 0);
|
||||
if (flags < 0) {
|
||||
pr_err("fcntl(%d, F_GETFL) -> %d\n", fd, flags);
|
||||
return -1;
|
||||
}
|
||||
if (flags & O_PATH) {
|
||||
p->fown.pid = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = sys_fcntl(fd, F_GETOWN_EX, (long)&owner_ex);
|
||||
if (ret) {
|
||||
pr_err("fcntl(%d, F_GETOWN_EX) -> %d\n", fd, ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple case -- nothing is changed.
|
||||
*/
|
||||
if (owner_ex.pid == 0) {
|
||||
p->fown.pid = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = sys_fcntl(fd, F_GETOWNER_UIDS, (long)&v);
|
||||
if (ret) {
|
||||
pr_err("fcntl(%d, F_GETOWNER_UIDS) -> %d\n", fd, ret);
|
||||
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;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fill_fds_opts(struct parasite_drain_fd *fds, struct fd_opts *opts)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < fds->nr_fds; i++) {
|
||||
int flags, fd = fds->fds[i], ret;
|
||||
int flags, fd = fds->fds[i];
|
||||
struct fd_opts *p = opts + i;
|
||||
struct f_owner_ex owner_ex;
|
||||
uint32_t v[2];
|
||||
|
||||
flags = sys_fcntl(fd, F_GETFD, 0);
|
||||
if (flags < 0) {
|
||||
|
|
@ -335,30 +380,8 @@ static int fill_fds_opts(struct parasite_drain_fd *fds, struct fd_opts *opts)
|
|||
|
||||
p->flags = (char)flags;
|
||||
|
||||
ret = sys_fcntl(fd, F_GETOWN_EX, (long)&owner_ex);
|
||||
if (ret) {
|
||||
pr_err("fcntl(%d, F_GETOWN_EX) -> %d\n", fd, ret);
|
||||
if (fill_fds_fown(fd, p))
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple case -- nothing is changed.
|
||||
*/
|
||||
if (owner_ex.pid == 0) {
|
||||
p->fown.pid = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = sys_fcntl(fd, F_GETOWNER_UIDS, (long)&v);
|
||||
if (ret) {
|
||||
pr_err("fcntl(%d, F_GETOWNER_UIDS) -> %d\n", fd, ret);
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue