mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-22 01:51:51 +00:00
img: Don't create empty images
Currently on dump we generate too many image files, effectively all the stuff from the GLOB set is created. The thing is that sometimes some of created images can be empty (just contain the magic number at the head). Thos images are useless and just waste the space. When applied after the "empty images" set, this introduces the lazy images -- when we call open_image() the actual file is only created (and the magic number is written into it) when the very first object goes into it. For example for the simplest test we have, then static/env00 one, the created image files are core-7290.img creds-7290.img fdinfo-2.img fs-7290.img ids-7290.img inventory.img mm-7290.img pagemap-7290.img pages-1.img pstree.img reg-files.img sigacts-7290.img Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
parent
7ede4697cf
commit
8ce37e676a
52
image.c
52
image.c
@ -202,28 +202,48 @@ struct cr_imgset *cr_glob_imgset_open(int mode)
|
||||
return cr_imgset_open(-1 /* ignored */, GLOB, mode);
|
||||
}
|
||||
|
||||
static struct cr_img *do_open_image(struct cr_img *img, int dfd, int type, unsigned long flags, char *path);
|
||||
|
||||
struct cr_img *open_image_at(int dfd, int type, unsigned long flags, ...)
|
||||
{
|
||||
struct cr_img *img;
|
||||
unsigned long oflags = flags;
|
||||
unsigned long oflags;
|
||||
char path[PATH_MAX];
|
||||
va_list args;
|
||||
int ret;
|
||||
bool lazy = false;
|
||||
|
||||
if (dfd == -1)
|
||||
if (dfd == -1) {
|
||||
dfd = get_service_fd(IMG_FD_OFF);
|
||||
lazy = (flags & O_CREAT);
|
||||
}
|
||||
|
||||
img = xmalloc(sizeof(*img));
|
||||
if (!img)
|
||||
goto errn;
|
||||
return NULL;
|
||||
|
||||
oflags |= imgset_template[type].oflags;
|
||||
flags &= ~(O_NOBUF);
|
||||
oflags = flags | imgset_template[type].oflags;
|
||||
|
||||
va_start(args, flags);
|
||||
vsnprintf(path, PATH_MAX, imgset_template[type].fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (lazy) {
|
||||
img->fd = LAZY_IMG_FD;
|
||||
img->type = type;
|
||||
img->oflags = oflags;
|
||||
img->path = xstrdup(path);
|
||||
return img;
|
||||
}
|
||||
|
||||
return do_open_image(img, dfd, type, oflags, path);
|
||||
}
|
||||
|
||||
static struct cr_img *do_open_image(struct cr_img *img, int dfd, int type, unsigned long oflags, char *path)
|
||||
{
|
||||
int ret, flags;
|
||||
|
||||
flags = oflags & ~(O_NOBUF);
|
||||
|
||||
ret = openat(dfd, path, flags, CR_FD_PERM);
|
||||
if (ret < 0) {
|
||||
if (!(flags & O_CREAT) && (errno == ENOENT)) {
|
||||
@ -271,17 +291,33 @@ skip_magic:
|
||||
|
||||
err:
|
||||
xfree(img);
|
||||
errn:
|
||||
return NULL;
|
||||
|
||||
err_close:
|
||||
close_image(img);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int open_image_lazy(struct cr_img *img)
|
||||
{
|
||||
int dfd;
|
||||
char *path = img->path;
|
||||
|
||||
dfd = get_service_fd(IMG_FD_OFF);
|
||||
if (do_open_image(img, dfd, img->type, img->oflags, path) == NULL)
|
||||
return -1;
|
||||
|
||||
xfree(path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void close_image(struct cr_img *img)
|
||||
{
|
||||
if (!empty_image(img))
|
||||
if (lazy_image(img))
|
||||
xfree(img->path);
|
||||
else if (!empty_image(img))
|
||||
bclose(&img->_x);
|
||||
|
||||
xfree(img);
|
||||
}
|
||||
|
||||
|
@ -124,16 +124,30 @@ extern bool ns_per_id;
|
||||
#define O_RSTR (O_RDONLY)
|
||||
|
||||
struct cr_img {
|
||||
struct bfd _x;
|
||||
union {
|
||||
struct bfd _x;
|
||||
struct {
|
||||
int fd; /* should be first to coincide with _x.fd */
|
||||
int type;
|
||||
unsigned long oflags;
|
||||
char *path;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#define EMPTY_IMG_FD (-404)
|
||||
#define LAZY_IMG_FD (-505)
|
||||
|
||||
static inline bool empty_image(struct cr_img *img)
|
||||
{
|
||||
return img && img->_x.fd == EMPTY_IMG_FD;
|
||||
}
|
||||
|
||||
static inline bool lazy_image(struct cr_img *img)
|
||||
{
|
||||
return img->_x.fd == LAZY_IMG_FD;
|
||||
}
|
||||
|
||||
static inline int img_raw_fd(struct cr_img *img)
|
||||
{
|
||||
BUG_ON(bfd_buffered(&img->_x));
|
||||
@ -145,6 +159,7 @@ extern void close_image_dir(void);
|
||||
|
||||
extern struct cr_img *open_image_at(int dfd, int type, unsigned long flags, ...);
|
||||
#define open_image(typ, flags, ...) open_image_at(-1, typ, flags, ##__VA_ARGS__)
|
||||
extern int open_image_lazy(struct cr_img *img);
|
||||
extern struct cr_img *open_pages_image(unsigned long flags, struct cr_img *pmi);
|
||||
extern struct cr_img *open_pages_image_at(int dfd, unsigned long flags, struct cr_img *pmi);
|
||||
extern void up_page_ids_base(void);
|
||||
|
@ -603,6 +603,9 @@ int pb_write_one(struct cr_img *img, void *obj, int type)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lazy_image(img) && open_image_lazy(img))
|
||||
return -1;
|
||||
|
||||
size = cr_pb_descs[type].getpksize(obj);
|
||||
if (size > (u32)sizeof(local)) {
|
||||
buf = xmalloc(size);
|
||||
|
Loading…
x
Reference in New Issue
Block a user