[CRIU] [PATCH 2/2] img: Introduce v1.1 images (v2)

Pavel Emelyanov xemul at parallels.com
Wed Apr 8 06:37:28 PDT 2015


These images have common magic in front of per-image one. With
this we have 3 "types" of images -- inventory (head), other
images, service files. The latter would be stats (not an image,
just happen to be in PB format) and irmap cache (not an image
again, just auxiliary thing which is in PB for convenience).

Since inventory file is the first one we read on restore it's
OK to set the global "new images" flag there. Dump (write) is
always in new format.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 image-desc.c            |  2 ++
 image.c                 | 40 +++++++++++++++++++++++++++++++++++++---
 include/image.h         | 11 ++++++-----
 include/magic.h         | 18 +++++++++++++++++-
 pycriu/images/images.py |  9 +++++++++
 5 files changed, 71 insertions(+), 9 deletions(-)

diff --git a/image-desc.c b/image-desc.c
index 4be7551..8d74024 100644
--- a/image-desc.c
+++ b/image-desc.c
@@ -93,11 +93,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 1f6f15b..676a40e 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 9ec0238..55e63dd 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 d9af16c..57dd29b 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
@@ -15,13 +20,20 @@
 #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.
  */
 
 #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
@@ -86,6 +98,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 f0bfe84..5dde50c 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:
-- 
1.8.4.2




More information about the CRIU mailing list