[CRIU] Re: [PATCH 3/5] protobuf: Add protobuf engine
Stanislav Kinsbursky
skinsbursky at parallels.com
Thu Jul 5 01:52:42 EDT 2012
04.07.2012 22:05, Cyrill Gorcunov пишет:
> Since protobuf is not that simple to deal with we provide
> helpers to work with it
>
> - pbimg_write_obj to write PB objects
> - pbimg_read_obj_eof to read PB objects
>
> Note the plural case of "objects" here. While in previous commit
> descibes the ability to use pretty flexible structure of objects
> which can be stored on disk, at moment most simple way is used
> to not crash overall crtools code but make a transition to new
> format via small steps.
>
> So at moment the img files with PB objects do have the following
> structure
>
> | 4 bytes magic number as a header
> +---
> | 24 bytes message obj_hdr
> +---
> | X bytes protobuf-object
> +---
> ...
>
> and so on
>
> Ie it's not that efficient but enough for this stage.
>
> Because messages obj_hdr and img_hdr and fixed in size
> and immutable we provide a fast way to encode/decode them
> via pbimg_write_img_hdr/pbimg_write_obj_hdr helpers. The
> read speed up achieved via img_hrd_t and obj_hdr_t structures
> which are 1:1 binary representation of PB ABI and will never
> change.
>
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
> Makefile | 1 +
> include/protobuf.h | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> protobuf.c | 38 ++++++++++++++++++++++++
> 3 files changed, 122 insertions(+), 0 deletions(-)
> create mode 100644 include/protobuf.h
> create mode 100644 protobuf.c
>
> diff --git a/Makefile b/Makefile
> index db2e6f7..9905c3d 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -59,6 +59,7 @@ OBJS += eventpoll.o
> OBJS += mount.o
> OBJS += inotify.o
> OBJS += pstree.o
> +OBJS += protobuf.o
>
> PROTOBUF-LIB := protobuf/protobuf-lib.o
>
> diff --git a/include/protobuf.h b/include/protobuf.h
> new file mode 100644
> index 0000000..74b1bb1
> --- /dev/null
> +++ b/include/protobuf.h
> @@ -0,0 +1,83 @@
> +#ifndef PROTOBUF_H__
> +#define PROTOBUF_H__
> +
> +#include "types.h"
> +#include "compiler.h"
> +
> +#include "syscall.h"
> +
> +typedef struct {
> + u8 ___tag_pad1;
> + u64 magic;
> + u8 ___tag_pad2;
> + u64 version;
> + u8 ___tag_pad3;
> + u64 flags;
> +} __packed img_hrd_t;
> +
Could you, please, explain, what for are these ____tag_pad's are required?
> +typedef struct {
> + u8 ___tag_pad1;
> + u32 type;
> + u8 ___tag_pad2;
> + u64 pksize;
> +} __packed obj_hdr_t;
> +
> +#define pbimg_read_img_hdr(fd, h) read_img(fd, h)
> +#define pbimg_read_obj_hdr(fd, h) read_img(fd, h)
> +
> +#define pbimg_read_img_hdr_eof(fd, h) read_img_eof(fd, h)
> +#define pbimg_read_obj_hdr_eof(fd, h) read_img_eof(fd, h)
> +
> +extern int pbimg_write_img_hdr(int fd, img_hrd_t *h);
> +extern int pbimg_write_obj_hdr(int fd, obj_hdr_t *h);
> +
> +#define pbimg_write_obj(__fd, __object, __type, __get_packed_size, __pack) \
> +({ \
> + u8 ___buf[KILO(16)]; \
> + u32 ___size = __get_packed_size(__object); \
> + int ___ret = -1; \
> + \
> + if (___size <= sizeof(___buf)) { \
> + obj_hdr_t ___ohdr = { .type = __type, .pksize = ___size }; \
> + ___ret = pbimg_write_obj_hdr(__fd, &___ohdr); \
> + if (!___ret) { \
> + __pack(__object, ___buf); \
> + ___ret = write_img(__fd, &___size); \
> + if (!___ret) \
> + ___ret = write_img_buf(__fd, ___buf, ___size); \
> + } \
> + } else \
> + pr_err("Protobuf entry passed is too big (%dK)", \
> + (int)KBYTES(___size)); \
> + ___ret; \
> +})
> +
> +/* Don't forget to free unpacked data on return */
> +#define pbimg_read_obj_eof(__fd, __object, __type, __unpack) \
> +({ \
> + u8 ___buf[KILO(16)]; \
> + obj_hdr_t ___ohdr; \
> + u32 ___size; \
> + int ___ret; \
> + \
> + *(__object) = NULL; \
> + ___ret = pbimg_read_obj_hdr_eof(__fd, &___ohdr); \
> + if (___ret > 0) { \
> + if (__type == ___ohdr.type) { \
> + ___ret = read_img_eof(__fd, &___size); \
> + if (___ret > 0) { \
> + if (___size <= sizeof(___buf)) \
> + ___ret = read_img_buf(__fd, ___buf, ___size); \
> + if (___ret == 1) \
> + *(__object) = __unpack(NULL, ___size, ___buf); \
> + } \
> + } else { \
> + pr_err("Corrupted image, type mismatch (%x %x)\n", \
> + (int)__type, (int)___ohdr.type); \
> + ___ret = -1; \
> + } \
> + } \
> + ___ret; \
> +})
> +
> +#endif /* PROTOBUF_H__ */
> diff --git a/protobuf.c b/protobuf.c
> new file mode 100644
> index 0000000..17b2052
> --- /dev/null
> +++ b/protobuf.c
> @@ -0,0 +1,38 @@
> +#include <unistd.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
> +#include <stdlib.h>
> +
> +#include "compiler.h"
> +#include "types.h"
> +#include "log.h"
> +#include "util.h"
> +
> +#include "protobuf.h"
> +
> +enum {
> + CR_PROTOBUF_C_WIRE_TYPE_VARINT,
> + CR_PROTOBUF_C_WIRE_TYPE_64BIT,
> + CR_PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED,
> + CR_PROTOBUF_C_WIRE_TYPE_START_GROUP,
> + CR_PROTOBUF_C_WIRE_TYPE_END_GROUP,
> + CR_PROTOBUF_C_WIRE_TYPE_32BIT
> +};
> +
> +int pbimg_write_img_hdr(int fd, img_hrd_t *h)
> +{
> + h->___tag_pad1 = (1 << 3) | CR_PROTOBUF_C_WIRE_TYPE_64BIT;
> + h->___tag_pad2 = (2 << 3) | CR_PROTOBUF_C_WIRE_TYPE_64BIT;
> + h->___tag_pad3 = (3 << 3) | CR_PROTOBUF_C_WIRE_TYPE_64BIT;
> +
> + return write_img(fd, h);
> +}
> +
> +int pbimg_write_obj_hdr(int fd, obj_hdr_t *h)
> +{
> + h->___tag_pad1 = (1 << 3) | CR_PROTOBUF_C_WIRE_TYPE_32BIT;
> + h->___tag_pad2 = (2 << 3) | CR_PROTOBUF_C_WIRE_TYPE_64BIT;
> +
> + return write_img(fd, h);
> +}
More information about the CRIU
mailing list