diff --git a/image-desc.c b/image-desc.c index fc42df760..773f2fa91 100644 --- a/image-desc.c +++ b/image-desc.c @@ -94,11 +94,13 @@ struct cr_fd_desc_tmpl imgset_template[CR_FD_MAX] = { [CR_FD_STATS] = { .fmt = "stats-%s", .magic = STATS_MAGIC, + .oflags = O_SERVICE, }, [CR_FD_IRMAP_CACHE] = { .fmt = "irmap-cache", .magic = IRMAP_CACHE_MAGIC, + .oflags = O_SERVICE, }, [CR_FD_FILE_LOCKS_PID] = { diff --git a/image.c b/image.c index 1f6f15bf3..676a40ebb 100644 --- a/image.c +++ b/image.c @@ -14,6 +14,7 @@ bool fdinfo_per_id = false; bool ns_per_id = false; +bool img_common_magic = false; TaskKobjIdsEntry *root_ids; u32 root_cg_set; @@ -50,10 +51,19 @@ int check_img_inventory(void) root_cg_set = he->root_cg_set; } - if (he->img_version != CRTOOLS_IMAGES_V1) { + switch (he->img_version) { + case CRTOOLS_IMAGES_V1: + /* good old images. OK */ + break; + case CRTOOLS_IMAGES_V1_1: + /* newer images with extra magic in the head */ + img_common_magic = true; + break; + default: pr_err("Not supported images version %u\n", he->img_version); goto out_err; } + ret = 0; out_err: @@ -78,7 +88,8 @@ int write_img_inventory(void) if (!img) return -1; - he.img_version = CRTOOLS_IMAGES_V1; + img_common_magic = true; + he.img_version = CRTOOLS_IMAGES_V1_1; he.fdinfo_per_id = true; he.has_fdinfo_per_id = true; he.ns_per_id = true; @@ -238,6 +249,11 @@ struct cr_img *open_image_at(int dfd, int type, unsigned long flags, ...) return do_open_image(img, dfd, type, oflags, path); } +static inline u32 head_magic(int oflags) +{ + return oflags & O_SERVICE ? IMG_SERVICE_MAGIC : IMG_COMMON_MAGIC; +} + static int img_check_magic(struct cr_img *img, int oflags, int type, char *path) { u32 magic; @@ -245,6 +261,16 @@ static int img_check_magic(struct cr_img *img, int oflags, int type, char *path) if (read_img(img, &magic) < 0) return -1; + if (img_common_magic && (type != CR_FD_INVENTORY)) { + if (magic != head_magic(oflags)) { + pr_err("Head magic doesn't match for %s\n", path); + return -1; + } + + if (read_img(img, &magic) < 0) + return -1; + } + if (magic != imgset_template[type].magic) { pr_err("Magic doesn't match for %s\n", path); return -1; @@ -255,6 +281,14 @@ static int img_check_magic(struct cr_img *img, int oflags, int type, char *path) static int img_write_magic(struct cr_img *img, int oflags, int type) { + if (img_common_magic && (type != CR_FD_INVENTORY)) { + u32 cmagic; + + cmagic = head_magic(oflags); + if (write_img(img, &cmagic)) + return -1; + } + return write_img(img, &imgset_template[type].magic); } @@ -262,7 +296,7 @@ static struct cr_img *do_open_image(struct cr_img *img, int dfd, int type, unsig { int ret, flags; - flags = oflags & ~(O_NOBUF); + flags = oflags & ~(O_NOBUF | O_SERVICE); ret = openat(dfd, path, flags, CR_FD_PERM); if (ret < 0) { diff --git a/include/image.h b/include/image.h index 9ec02383b..55e63dd9c 100644 --- a/include/image.h +++ b/include/image.h @@ -116,12 +116,13 @@ extern bool fdinfo_per_id; extern bool ns_per_id; +extern bool img_common_magic; -#define O_NOBUF (O_DIRECT) - -#define O_DUMP (O_WRONLY | O_CREAT | O_TRUNC) -#define O_SHOW (O_RDONLY | O_NOBUF) -#define O_RSTR (O_RDONLY) +#define O_NOBUF (O_DIRECT) +#define O_SERVICE (O_DIRECTORY) +#define O_DUMP (O_WRONLY | O_CREAT | O_TRUNC) +#define O_SHOW (O_RDONLY | O_NOBUF) +#define O_RSTR (O_RDONLY) struct cr_img { union { diff --git a/include/magic.h b/include/magic.h index 986ba7d12..f739759a1 100644 --- a/include/magic.h +++ b/include/magic.h @@ -6,6 +6,11 @@ */ #define CRTOOLS_IMAGES_V1 1 +/* + * v1.1 has common magic in the head of each image file, + * except for inventory + */ +#define CRTOOLS_IMAGES_V1_1 2 /* * Raw images are images in which data is stored in some @@ -14,6 +19,14 @@ #define RAW_IMAGE_MAGIC 0x0 +/* + * Images have the IMG_COMMON_MAGIC in the head. Service files + * such as stats and irmap-cache have the IMG_SERVICE_MAGIC. + */ + +#define IMG_COMMON_MAGIC 0x54564319 /* Sarov (a.k.a. Arzamas-16) */ +#define IMG_SERVICE_MAGIC 0x55105940 /* Zlatoust */ + /* * The magic-s below correspond to coordinates * of various Russian towns in the NNNNEEEE form. @@ -21,7 +34,6 @@ #define INVENTORY_MAGIC 0x58313116 /* Veliky Novgorod */ #define PSTREE_MAGIC 0x50273030 /* Kyiv */ -#define STATS_MAGIC 0x57093306 /* Ostashkov */ #define FDINFO_MAGIC 0x56213732 /* Dmitrov */ #define PAGEMAP_MAGIC 0x56084025 /* Vladimir */ #define SHMEM_PAGEMAP_MAGIC PAGEMAP_MAGIC @@ -87,6 +99,10 @@ #define PAGES_OLD_MAGIC PAGEMAP_MAGIC #define SHM_PAGES_OLD_MAGIC PAGEMAP_MAGIC +/* + * These are special files, not exactly images + */ +#define STATS_MAGIC 0x57093306 /* Ostashkov */ #define IRMAP_CACHE_MAGIC 0x57004059 /* Ivanovo */ #endif /* __CR_MAGIC_H__ */ diff --git a/pycriu/images/images.py b/pycriu/images/images.py index f0bfe8421..5dde50ca7 100644 --- a/pycriu/images/images.py +++ b/pycriu/images/images.py @@ -287,6 +287,9 @@ def load(f, pretty = False): img_magic, = struct.unpack('i', f.read(4)) + if img_magic in (magic.by_name['IMG_COMMON'], magic.by_name['IMG_SERVICE']): + img_magic, = struct.unpack('i', f.read(4)) + try: m = magic.by_val[img_magic] except: @@ -320,6 +323,12 @@ def dump(img, f): m = img['magic'] magic_val = magic.by_name[img['magic']] + if m != 'INVENTORY': + if m in ('STATS', 'IRMAP_CACHE'): + f.write(struct.pack('i', magic.by_name['IMG_COMMON'])) + else: + f.write(struct.pack('i', magic.by_name['IMG_SERVICE'])) + f.write(struct.pack('i', magic_val)) try: