mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-01-23 02:14:37 +00:00
img: Introduce empty images
When an image of a certian type is not found, CRIU sometimes fails, sometimes ignores this fact. I propose to ignore this fact always and treat absent images and those containing no objects inside (i.e. -- empty). If the latter code flow will _need_ objects, then criu will fail later. Why object will be explicitly required? For example, due to restoring code reading the image with pb_read_one, w/o the _eof suffix thus required the object to be in the image. Another example is objects dependencies. E.g. fdinfo objects require various files objects. So missing image files will result in non-resolved searches later. Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
parent
45a0cc4234
commit
f7f76d6ba6
12 changed files with 82 additions and 104 deletions
8
cgroup.c
8
cgroup.c
|
|
@ -1292,12 +1292,8 @@ int prepare_cgroup(void)
|
|||
CgroupEntry *ce;
|
||||
|
||||
img = open_image(CR_FD_CGROUP, O_RSTR);
|
||||
if (!img) {
|
||||
if (errno == ENOENT) /* backward compatibility */
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if (!img)
|
||||
return -1;
|
||||
|
||||
ret = pb_read_one_eof(img, &ce, PB_CGROUP);
|
||||
close_image(img);
|
||||
|
|
|
|||
24
cr-restore.c
24
cr-restore.c
|
|
@ -2170,12 +2170,8 @@ static int prepare_posix_timers_from_fd(int pid)
|
|||
struct restore_posix_timer *t;
|
||||
|
||||
img = open_image(CR_FD_POSIX_TIMERS, O_RSTR, pid);
|
||||
if (!img) {
|
||||
if (errno == ENOENT) /* backward compatibility */
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if (!img)
|
||||
return -1;
|
||||
|
||||
while (1) {
|
||||
PosixTimerEntry *pte;
|
||||
|
|
@ -2420,14 +2416,8 @@ static int prepare_rlimits_from_fd(int pid)
|
|||
* Old image -- read from the file.
|
||||
*/
|
||||
img = open_image(CR_FD_RLIMIT, O_RSTR, pid);
|
||||
if (!img) {
|
||||
if (errno == ENOENT) {
|
||||
pr_info("Skip rlimits for %d\n", pid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!img)
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
RlimitEntry *re;
|
||||
|
|
@ -2512,12 +2502,8 @@ static int open_signal_image(int type, pid_t pid, unsigned int *nr)
|
|||
struct cr_img *img;
|
||||
|
||||
img = open_image(type, O_RSTR, pid);
|
||||
if (!img) {
|
||||
if (errno == ENOENT) /* backward compatibility */
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if (!img)
|
||||
return -1;
|
||||
|
||||
*nr = 0;
|
||||
while (1) {
|
||||
|
|
|
|||
|
|
@ -342,12 +342,8 @@ static int restore_file_locks_legacy(int pid)
|
|||
FileLockEntry *fle;
|
||||
|
||||
img = open_image(CR_FD_FILE_LOCKS_PID, O_RSTR, pid);
|
||||
if (!img) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if (!img)
|
||||
return -1;
|
||||
|
||||
while (1) {
|
||||
ret = pb_read_one_eof(img, &fle, PB_FILE_LOCK);
|
||||
|
|
|
|||
31
files.c
31
files.c
|
|
@ -610,11 +610,8 @@ int prepare_fd_pid(struct pstree_item *item)
|
|||
|
||||
if (!fdinfo_per_id) {
|
||||
img = open_image(CR_FD_FDINFO, O_RSTR, pid);
|
||||
if (!img) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
if (!img)
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (item->ids == NULL) /* zombie */
|
||||
return 0;
|
||||
|
|
@ -1115,19 +1112,16 @@ int prepare_fs_pid(struct pstree_item *item)
|
|||
struct rst_info *ri = rsti(item);
|
||||
struct cr_img *img;
|
||||
FsEntry *fe;
|
||||
int ret = -1;
|
||||
|
||||
img = open_image(CR_FD_FS, O_RSTR, pid);
|
||||
if (!img) {
|
||||
if (errno == ENOENT)
|
||||
goto ok;
|
||||
else
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pb_read_one(img, &fe, PB_FS) < 0)
|
||||
goto out_i;
|
||||
if (!img)
|
||||
goto out;
|
||||
|
||||
ret = pb_read_one_eof(img, &fe, PB_FS);
|
||||
close_image(img);
|
||||
if (ret <= 0)
|
||||
goto out;
|
||||
|
||||
ri->cwd = collect_special_file(fe->cwd_id);
|
||||
if (!ri->cwd) {
|
||||
|
|
@ -1144,18 +1138,11 @@ int prepare_fs_pid(struct pstree_item *item)
|
|||
ri->has_umask = fe->has_umask;
|
||||
ri->umask = fe->umask;
|
||||
|
||||
fs_entry__free_unpacked(fe, NULL);
|
||||
ok:
|
||||
return 0;
|
||||
|
||||
ret = 0;
|
||||
out_f:
|
||||
fs_entry__free_unpacked(fe, NULL);
|
||||
return -1;
|
||||
|
||||
out_i:
|
||||
close_image(img);
|
||||
out:
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int shared_fdt_prepare(struct pstree_item *item)
|
||||
|
|
|
|||
12
image.c
12
image.c
|
|
@ -226,10 +226,13 @@ struct cr_img *open_image_at(int dfd, int type, unsigned long flags, ...)
|
|||
|
||||
ret = openat(dfd, path, flags, CR_FD_PERM);
|
||||
if (ret < 0) {
|
||||
if (errno == ENOENT)
|
||||
if (!(flags & O_CREAT) && (errno == ENOENT)) {
|
||||
pr_info("No %s image\n", path);
|
||||
else
|
||||
pr_perror("Unable to open %s", path);
|
||||
img->_x.fd = EMPTY_IMG_FD;
|
||||
goto skip_magic;
|
||||
}
|
||||
|
||||
pr_perror("Unable to open %s", path);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
|
@ -270,7 +273,8 @@ err_close:
|
|||
|
||||
void close_image(struct cr_img *img)
|
||||
{
|
||||
bclose(&img->_x);
|
||||
if (!empty_image(img))
|
||||
bclose(&img->_x);
|
||||
xfree(img);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -127,6 +127,13 @@ struct cr_img {
|
|||
struct bfd _x;
|
||||
};
|
||||
|
||||
#define EMPTY_IMG_FD (-404)
|
||||
|
||||
static inline bool empty_image(struct cr_img *img)
|
||||
{
|
||||
return img && img->_x.fd == EMPTY_IMG_FD;
|
||||
}
|
||||
|
||||
static inline int img_raw_fd(struct cr_img *img)
|
||||
{
|
||||
BUG_ON(bfd_buffered(&img->_x));
|
||||
|
|
|
|||
30
irmap.c
30
irmap.c
|
|
@ -403,23 +403,27 @@ in:
|
|||
if (dir != AT_FDCWD)
|
||||
close(dir);
|
||||
|
||||
if (*img) {
|
||||
pr_info("... done\n");
|
||||
return 1;
|
||||
if (empty_image(*img)) {
|
||||
close_image(*img);
|
||||
if (dir == AT_FDCWD) {
|
||||
pr_info("Searching irmap cache in parent\n");
|
||||
dir = openat(get_service_fd(IMG_FD_OFF),
|
||||
CR_PARENT_LINK, O_RDONLY);
|
||||
if (dir >= 0)
|
||||
goto in;
|
||||
if (errno != ENOENT)
|
||||
return -1;
|
||||
}
|
||||
|
||||
pr_info("No irmap cache\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (errno == ENOENT && dir == AT_FDCWD) {
|
||||
pr_info("Searching irmap cache in parent\n");
|
||||
dir = openat(get_service_fd(IMG_FD_OFF), CR_PARENT_LINK, O_RDONLY);
|
||||
if (dir >= 0)
|
||||
goto in;
|
||||
}
|
||||
|
||||
if (errno != ENOENT)
|
||||
if (!*img)
|
||||
return -1;
|
||||
|
||||
pr_info("No irmap cache\n");
|
||||
return 0;
|
||||
pr_info("... done\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int irmap_load_cache(void)
|
||||
|
|
|
|||
12
mem.c
12
mem.c
|
|
@ -396,17 +396,13 @@ int prepare_mm_pid(struct pstree_item *i)
|
|||
struct rst_info *ri = rsti(i);
|
||||
|
||||
img = open_image(CR_FD_MM, O_RSTR, pid);
|
||||
if (!img) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
if (!img)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = pb_read_one(img, &ri->mm, PB_MM);
|
||||
ret = pb_read_one_eof(img, &ri->mm, PB_MM);
|
||||
close_image(img);
|
||||
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
if (collect_special_file(ri->mm->exe_file_id) == NULL)
|
||||
return -1;
|
||||
|
|
|
|||
6
mount.c
6
mount.c
|
|
@ -937,9 +937,11 @@ static int tmpfs_restore(struct mount_info *pm)
|
|||
struct cr_img *img;
|
||||
|
||||
img = open_image(CR_FD_TMPFS_DEV, O_RSTR, pm->s_dev);
|
||||
if (!img && errno == ENOENT)
|
||||
if (empty_image(img)) {
|
||||
close_image(img);
|
||||
img = open_image(CR_FD_TMPFS_IMG, O_RSTR, pm->mnt_id);
|
||||
if (!img)
|
||||
}
|
||||
if (!img || empty_image(img))
|
||||
return -1;
|
||||
|
||||
ret = cr_system(img_raw_fd(img), -1, -1, "tar",
|
||||
|
|
|
|||
22
page-read.c
22
page-read.c
|
|
@ -256,11 +256,12 @@ int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags)
|
|||
pr->bunch.iov_base = NULL;
|
||||
|
||||
pr->pmi = open_image_at(dfd, i_typ, O_RSTR, (long)pid);
|
||||
if (!pr->pmi) {
|
||||
if (errno == ENOENT)
|
||||
goto open_old;
|
||||
else
|
||||
return -1;
|
||||
if (!pr->pmi)
|
||||
return -1;
|
||||
|
||||
if (empty_image(pr->pmi)) {
|
||||
close_image(pr->pmi);
|
||||
goto open_old;
|
||||
}
|
||||
|
||||
if ((i_typ != CR_FD_SHMEM_PAGEMAP) && try_open_parent(dfd, pid, pr, pr_flags)) {
|
||||
|
|
@ -287,11 +288,12 @@ int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags)
|
|||
|
||||
open_old:
|
||||
pr->pmi = open_image_at(dfd, i_typ_o, flags, pid);
|
||||
if (!pr->pmi) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
if (!pr->pmi)
|
||||
return -1;
|
||||
|
||||
if (empty_image(pr->pmi)) {
|
||||
close_image(pr->pmi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr->get_pagemap = get_page_vaddr;
|
||||
|
|
|
|||
13
protobuf.c
13
protobuf.c
|
|
@ -528,7 +528,10 @@ int do_pb_read_one(struct cr_img *img, void **pobj, int type, bool eof)
|
|||
|
||||
*pobj = NULL;
|
||||
|
||||
ret = bread(&img->_x, &size, sizeof(size));
|
||||
if (unlikely(empty_image(img)))
|
||||
ret = 0;
|
||||
else
|
||||
ret = bread(&img->_x, &size, sizeof(size));
|
||||
if (ret == 0) {
|
||||
if (eof) {
|
||||
return 0;
|
||||
|
|
@ -642,12 +645,8 @@ int collect_image(struct collect_image_info *cinfo)
|
|||
cinfo->fd_type, cinfo->pb_type, cinfo->flags);
|
||||
|
||||
img = open_image(cinfo->fd_type, O_RSTR);
|
||||
if (!img) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if (!img)
|
||||
return -1;
|
||||
|
||||
cinfo->flags |= COLLECT_HAPPENED;
|
||||
if (cinfo->flags & COLLECT_SHARED) {
|
||||
|
|
|
|||
13
pstree.c
13
pstree.c
|
|
@ -427,16 +427,15 @@ static int read_pstree_image(void)
|
|||
struct cr_img *img;
|
||||
|
||||
img = open_image(CR_FD_IDS, O_RSTR, pi->pid.virt);
|
||||
if (!img) {
|
||||
if (errno == ENOENT)
|
||||
continue;
|
||||
if (!img)
|
||||
goto err;
|
||||
}
|
||||
ret = pb_read_one(img, &pi->ids, PB_IDS);
|
||||
ret = pb_read_one_eof(img, &pi->ids, PB_IDS);
|
||||
close_image(img);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != 1)
|
||||
if (ret == 0)
|
||||
continue;
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
if (pi->ids->has_mnt_ns_id) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue