Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions criu/cr-dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -2225,6 +2225,9 @@ int cr_dump_tasks(pid_t pid)
goto err;
}

if(run_plugins(DUMP_DEVICE_LATE, pid))
goto err;

if (parent_ie) {
inventory_entry__free_unpacked(parent_ie, NULL);
parent_ie = NULL;
Expand Down
3 changes: 3 additions & 0 deletions criu/cr-restore.c
Original file line number Diff line number Diff line change
Expand Up @@ -1651,6 +1651,9 @@ static int __restore_task_with_children(void *_arg)
if (open_transport_socket())
goto err;

if (run_plugins(RESUME_DEVICES_EARLY, current->pid->real))
goto err;

timing_start(TIME_FORK);

if (create_children_and_session())
Expand Down
16 changes: 10 additions & 6 deletions criu/files-ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@ static int open_fd(struct file_desc *d, int *new_fd)
{
struct ext_file_info *xfi;
int fd;
bool retry_needed;

xfi = container_of(d, struct ext_file_info, d);

fd = run_plugins(RESTORE_EXT_FILE, xfi->xfe->id);
fd = run_plugins(RESTORE_EXT_FILE, xfi->xfe->id, &retry_needed);
if (fd < 0) {
pr_err("Unable to restore %#x\n", xfi->xfe->id);
return -1;
Expand All @@ -57,8 +58,11 @@ static int open_fd(struct file_desc *d, int *new_fd)
if (restore_fown(fd, xfi->xfe->fown))
return -1;

*new_fd = fd;
return 0;
if (!retry_needed)
*new_fd = fd;
else
*new_fd = -1;
return retry_needed;
}

static struct file_desc_ops ext_desc_ops = {
Expand All @@ -83,14 +87,14 @@ struct collect_image_info ext_file_cinfo = {
.collect = collect_one_ext,
};

int dump_unsupp_fd(struct fd_parms *p, int lfd, char *more, char *info, FdinfoEntry *e)
int dump_unsupp_fd(struct fd_parms *p, int lfd, char *more, char *info, FdinfoEntry *e, bool force)
{
int ret;

ret = do_dump_gen_file(p, lfd, &ext_dump_ops, e);
ret = do_dump_gen_file(p, lfd, &ext_dump_ops, e, force);
if (ret == 0)
return 0;
if (ret == -ENOTSUP)
pr_err("Can't dump file %d of that type [%o] (%s %s)\n", p->fd, p->stat.st_mode, more, info);
return -1;
return ret;
}
62 changes: 48 additions & 14 deletions criu/files.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,9 @@ uint32_t make_gen_id(uint32_t st_dev, uint32_t st_ino, uint64_t pos)
return st_dev ^ st_ino ^ pos_hi ^ pos_low;
}

int do_dump_gen_file(struct fd_parms *p, int lfd, const struct fdtype_ops *ops, FdinfoEntry *e)
/* Use "force" to override cache */
int do_dump_gen_file(struct fd_parms *p, int lfd,
const struct fdtype_ops *ops, FdinfoEntry *e, bool force)
{
int ret = -1;

Expand All @@ -339,7 +341,7 @@ int do_dump_gen_file(struct fd_parms *p, int lfd, const struct fdtype_ops *ops,
e->flags = p->fd_flags;

ret = fd_id_generate(p->pid, e, p);
if (ret == 1) /* new ID generated */
if (ret == 1 || force) /* new ID generated */
ret = ops->dump(lfd, e->id, p);
else
/* Remove locks generated by the fd before going to the next */
Expand Down Expand Up @@ -484,19 +486,19 @@ static int dump_chrdev(struct fd_parms *p, int lfd, FdinfoEntry *e)
}

sprintf(more, "%d:%d", maj, minor(p->stat.st_rdev));
err = dump_unsupp_fd(p, lfd, "chr", more, e);
err = dump_unsupp_fd(p, lfd, "chr", more, e, false);
p->link = link_old;
return err;
}
}

err = do_dump_gen_file(p, lfd, ops, e);
err = do_dump_gen_file(p, lfd, ops, e, false);
p->link = link_old;
return err;
}

static int dump_one_file(struct pid *pid, int fd, int lfd, struct fd_opts *opts, struct parasite_ctl *ctl,
FdinfoEntry *e, struct parasite_drain_fd *dfds)
FdinfoEntry *e, struct parasite_drain_fd *dfds, bool force)
{
struct fd_parms p = FD_PARMS_INIT;
const struct fdtype_ops *ops;
Expand Down Expand Up @@ -552,14 +554,14 @@ static int dump_one_file(struct pid *pid, int fd, int lfd, struct fd_opts *opts,
ops = &bpfmap_dump_ops;
#endif
else
return dump_unsupp_fd(&p, lfd, "anon", link, e);
return dump_unsupp_fd(&p, lfd, "anon", link, e, force);

return do_dump_gen_file(&p, lfd, ops, e);
return do_dump_gen_file(&p, lfd, ops, e, force);
}

if (p.fs_type == PID_FS_MAGIC) {
ops = &pidfd_dump_ops;
return do_dump_gen_file(&p, lfd, ops, e);
return do_dump_gen_file(&p, lfd, ops, e, force);
}

if (S_ISREG(p.stat.st_mode) || S_ISDIR(p.stat.st_mode) || S_ISLNK(p.stat.st_mode)) {
Expand All @@ -576,9 +578,9 @@ static int dump_one_file(struct pid *pid, int fd, int lfd, struct fd_opts *opts,
else if (check_ns_proc(&link))
ops = &nsfile_dump_ops;
else
return dump_unsupp_fd(&p, lfd, "reg", link.name + 1, e);
return dump_unsupp_fd(&p, lfd, "reg", link.name + 1, e, force);

return do_dump_gen_file(&p, lfd, ops, e);
return do_dump_gen_file(&p, lfd, ops, e, force);
}

if (S_ISFIFO(p.stat.st_mode)) {
Expand All @@ -587,7 +589,7 @@ static int dump_one_file(struct pid *pid, int fd, int lfd, struct fd_opts *opts,
else
ops = &fifo_dump_ops;

return do_dump_gen_file(&p, lfd, ops, e);
return do_dump_gen_file(&p, lfd, ops, e, force);
}

/*
Expand All @@ -598,7 +600,7 @@ static int dump_one_file(struct pid *pid, int fd, int lfd, struct fd_opts *opts,
if (fill_fdlink(lfd, &p, &link))
memzero(&link, sizeof(link));

return dump_unsupp_fd(&p, lfd, "unknown", link.name + 1, e);
return dump_unsupp_fd(&p, lfd, "unknown", link.name + 1, e, force);
}

int dump_my_file(int lfd, u32 *id, int *type)
Expand All @@ -610,7 +612,7 @@ int dump_my_file(int lfd, u32 *id, int *type)
me.real = getpid();
me.ns[0].virt = -1; /* FIXME */

if (dump_one_file(&me, lfd, lfd, &fdo, NULL, &e, NULL))
if (dump_one_file(&me, lfd, lfd, &fdo, NULL, &e, NULL, false))
return -1;

*id = e.id;
Expand All @@ -625,6 +627,8 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, s
struct fd_opts *opts = NULL;
int i, ret = -1;
int off, nr_fds = min((int)PARASITE_MAX_FDS, dfds->nr_fds);
int *retry_indices = NULL;
int retry_count = 0;

pr_info("\n");
pr_info("Dumping opened files (pid: %d)\n", item->pid->real);
Expand All @@ -642,6 +646,10 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, s
if (!img)
goto err;

retry_indices = xmalloc(dfds->nr_fds * sizeof(int)); /* Allocate memory for retry indices*/
if (!retry_indices)
goto err;

ret = 0; /* Don't fail if nr_fds == 0 */
for (off = 0; ret == 0 && off < dfds->nr_fds; off += nr_fds) {
if (nr_fds + off > dfds->nr_fds)
Expand All @@ -654,9 +662,30 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, s
for (i = 0; i < nr_fds; i++) {
FdinfoEntry e = FDINFO_ENTRY__INIT;

ret = dump_one_file(item->pid, dfds->fds[i + off], lfds[i], opts + i, ctl, &e, dfds);
ret = dump_one_file(item->pid, dfds->fds[i + off], lfds[i], opts + i, ctl, &e, dfds, false);
if (ret == -EAGAIN) {
retry_indices[retry_count++] = i;
ret = 0; //* Reset ret to continue the loop */
continue;
} else if (ret)
break;

ret = pb_write_one(img, &e, PB_FDINFO);
if (ret)
break;
}
/* Some handles like dmabuf handles should be dealt with after
drm handles. Do that here, if necessary. */
for (i = 0; i < retry_count; i++) {
int idx = retry_indices[i];
FdinfoEntry e = FDINFO_ENTRY__INIT;

ret = dump_one_file(item->pid, dfds->fds[idx + off], lfds[idx],
opts + idx, ctl, &e, dfds, true);
if (ret) {
pr_err("Retry failed for fd index %d\n", idx);
break;
}

ret = pb_write_one(img, &e, PB_FDINFO);
if (ret)
Expand All @@ -673,6 +702,8 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, s
close_image(img);
xfree(opts);
xfree(lfds);
xfree(retry_indices);

return ret;
}

Expand Down Expand Up @@ -836,6 +867,9 @@ struct fdinfo_list_entry *collect_fd_to(int pid, FdinfoEntry *e, struct rst_info
{
struct fdinfo_list_entry *new_le;

if (fdesc->ops->type == FD_TYPES__EXT)
run_plugins(COLLECT_FILE, pid, fdesc->id);

new_le = alloc_fle(pid, e);
if (new_le) {
new_le->fake = (!!fake);
Expand Down
11 changes: 10 additions & 1 deletion criu/include/criu-plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ enum {

CR_PLUGIN_HOOK__CHECKPOINT_DEVICES = 11,

CR_PLUGIN_HOOK__RESUME_DEVICES_EARLY = 12,

CR_PLUGIN_HOOK__COLLECT_FILE = 13,

CR_PLUGIN_HOOK__DUMP_DEVICE_LATE = 14,

CR_PLUGIN_HOOK__MAX
};

Expand All @@ -68,7 +74,7 @@ enum {
DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__DUMP_UNIX_SK, int fd, int id);
DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__RESTORE_UNIX_SK, int id);
DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__DUMP_EXT_FILE, int fd, int id);
DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__RESTORE_EXT_FILE, int id);
DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__RESTORE_EXT_FILE, int id, bool *retry_needed);
DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__DUMP_EXT_MOUNT, char *mountpoint, int id);
DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__RESTORE_EXT_MOUNT, int id, char *mountpoint, char *old_root, int *is_file);
DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__DUMP_EXT_LINK, int index, int type, char *kind);
Expand All @@ -78,6 +84,9 @@ DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__UPDATE_VMA_MAP, const char *path, const
DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__RESUME_DEVICES_LATE, int pid);
DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__PAUSE_DEVICES, int pid);
DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__CHECKPOINT_DEVICES, int pid);
DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__RESUME_DEVICES_EARLY, int pid);
DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__COLLECT_FILE, int pid, int fd);
DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__DUMP_DEVICE_LATE, int id);

enum {
CR_PLUGIN_STAGE__DUMP,
Expand Down
6 changes: 4 additions & 2 deletions criu/include/files.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ struct fdtype_ops {
struct cr_img;

extern int dump_my_file(int lfd, u32 *, int *type);
extern int do_dump_gen_file(struct fd_parms *p, int lfd, const struct fdtype_ops *ops, FdinfoEntry *e);
extern int do_dump_gen_file(struct fd_parms *p, int lfd,
const struct fdtype_ops *ops, FdinfoEntry *e, bool force);
struct parasite_drain_fd;
int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, struct parasite_drain_fd *dfds);
int predump_task_files(int pid);
Expand Down Expand Up @@ -177,7 +178,8 @@ extern int close_old_fds(void);
extern int shared_fdt_prepare(struct pstree_item *item);

extern struct collect_image_info ext_file_cinfo;
extern int dump_unsupp_fd(struct fd_parms *p, int lfd, char *more, char *info, FdinfoEntry *);
extern int dump_unsupp_fd(struct fd_parms *p, int lfd, char *more,
char *info, FdinfoEntry *, bool force);

extern int inherit_fd_parse(char *optarg);
extern int inherit_fd_add(int fd, char *key);
Expand Down
1 change: 1 addition & 0 deletions criu/include/servicefd.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,6 @@ extern int install_service_fd(enum sfd_type type, int fd);
extern int close_service_fd(enum sfd_type type);
extern void __close_service_fd(enum sfd_type type);
extern int clone_service_fd(struct pstree_item *me);
extern int get_unused_high_fd(void);

#endif /* __CR_SERVICE_FD_H__ */
4 changes: 4 additions & 0 deletions criu/pie/restorer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1920,6 +1920,10 @@ __visible long __export_restore_task(struct task_restore_args *args)

for (m = 0; m < sizeof(vma_entry->madv) * 8; m++) {
if (vma_entry->madv & (1ul << m)) {

if (!(vma_entry_is(vma_entry, VMA_AREA_REGULAR)))
continue;

ret = sys_madvise(vma_entry->start, vma_entry_len(vma_entry), m);
if (ret) {
pr_err("madvise(%" PRIx64 ", %" PRIu64 ", %ld) "
Expand Down
3 changes: 3 additions & 0 deletions criu/plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ static cr_plugin_desc_t *cr_gen_plugin_desc(void *h, char *path)
__assign_hook(RESUME_DEVICES_LATE, "cr_plugin_resume_devices_late");
__assign_hook(PAUSE_DEVICES, "cr_plugin_pause_devices");
__assign_hook(CHECKPOINT_DEVICES, "cr_plugin_checkpoint_devices");
__assign_hook(RESUME_DEVICES_EARLY, "cr_plugin_resume_devices_early");
__assign_hook(COLLECT_FILE, "cr_plugin_collect_file");
__assign_hook(DUMP_DEVICE_LATE, "cr_plugin_dump_device_late");

#undef __assign_hook

Expand Down
11 changes: 11 additions & 0 deletions criu/servicefd.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ int service_fd_rlim_cur;

/* Base of current process service fds set */
static int service_fd_base;
static int next_high_fd;

/* Id of current process in shared fdt */
static int service_fd_id = 0;
Expand Down Expand Up @@ -312,5 +313,15 @@ int clone_service_fd(struct pstree_item *me)
service_fd_id = id;
ret = 0;

next_high_fd = service_fd_base + 1024;

return ret;
}

int get_unused_high_fd(void)
{
if (next_high_fd > service_fd_rlim_cur)
return -1;
next_high_fd += 1;
return next_high_fd - 1;
}
2 changes: 1 addition & 1 deletion criu/sockets.c
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ int dump_socket(struct fd_parms *p, int lfd, FdinfoEntry *e)
return -1;
}

return do_dump_gen_file(p, lfd, ops, e);
return do_dump_gen_file(p, lfd, ops, e, false);
}

static int inet_receive_one(struct nlmsghdr *h, struct ns_id *ns, void *arg)
Expand Down
2 changes: 1 addition & 1 deletion plugins/amdgpu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ endif
criu-amdgpu.pb-c.c: criu-amdgpu.proto
protoc-c --proto_path=. --c_out=. criu-amdgpu.proto

amdgpu_plugin.so: amdgpu_plugin.c amdgpu_plugin_drm.c amdgpu_plugin_topology.c amdgpu_plugin_util.c criu-amdgpu.pb-c.c
amdgpu_plugin.so: amdgpu_plugin.c amdgpu_plugin_drm.c amdgpu_plugin_dmabuf.c amdgpu_plugin_topology.c amdgpu_plugin_util.c criu-amdgpu.pb-c.c
$(CC) $(PLUGIN_CFLAGS) $(shell $(COMPEL) includes) $^ -o $@ $(PLUGIN_INCLUDE) $(PLUGIN_LDFLAGS) $(LIBDRM_INC)

amdgpu_plugin_clean:
Expand Down
Loading