Commit 8ce37e67 authored by Pavel Emelyanov's avatar Pavel Emelyanov

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: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 7ede4697
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment