From 9e84bd10830d384eea8a703da7c58e5dd62d9f43 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Tue, 7 Aug 2012 02:00:39 +0400 Subject: [PATCH] pb: Introduce pb message types and cr-descriptors The protobuf-c generate plain routines for entries manipulations, but we want to have some "generic" way of working with messages. Collect them all in an array of descriptors (similar to image files descriptions) and do full typechecking while this. Such thing will allow to simplfy code later. Signed-off-by: Pavel Emelyanov --- crtools.c | 2 + include/protobuf.h | 40 +++++++++++++++++++ protobuf.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+) diff --git a/crtools.c b/crtools.c index 69fe2c373..59c165dd2 100644 --- a/crtools.c +++ b/crtools.c @@ -63,6 +63,8 @@ int main(int argc, char *argv[]) BUILD_BUG_ON(PAGE_SIZE != PAGE_IMAGE_SIZE); + cr_pb_init(); + if (argc < 2) goto usage; diff --git a/include/protobuf.h b/include/protobuf.h index e13c3e44c..5fa89baa0 100644 --- a/include/protobuf.h +++ b/include/protobuf.h @@ -5,6 +5,44 @@ #include "compiler.h" #include "util.h" +enum { + PB_INVENTORY, + PB_FDINFO, + PB_CORE, + PB_MM, + PB_VMAS, + PB_SIGACT, + PB_ITIMERS, + PB_CREDS, + PB_FS, + PB_UTSNS, + PB_IPCNS_VAR, + PB_IPCNS_SHM, + PB_IPCNS_MSG, + PB_IPCNS_MSG_ENT, + PB_IPCNS_SEM, + PB_MOUNTPOINTS, + PB_NETDEV, + PB_PSTREE, + PB_GHOST_FILE, + PB_TCP_STREAM, + PB_SK_QUEUES, + PB_REG_FILES, + PB_INETSK, + PB_UNIXSK, + PB_PIPES, + PB_FIFO, + PB_PIPES_DATA, + PB_REMAP_FPATH, + PB_EVENTFD, + PB_EVENTPOLL, + PB_EVENTPOLL_TFD, + PB_SIGNALFD, + PB_INOTIFY, + PB_INOTIFY_WD, + + PB_MAX +}; /* * ATTENTION * @@ -33,6 +71,8 @@ extern int pb_read_object_with_header(int fd, void **pobj, #define PB_GPS_TYPECHECK(__o, __fn) ({ if (0) __fn##__get_packed_size(__o); (pb_getpksize_t)&__fn##__get_packed_size; }) #define PB_FREE_TYPECHECK(__o, __fn) ({ if (0) __fn##__free_unpacked(__o, NULL); (pb_free_t)&__fn##__free_unpacked; }) +void cr_pb_init(void); + #define pb_read(__fd, __obj_pptr, __proto_message_name) \ pb_read_object_with_header(__fd, (void **)__obj_pptr, \ PB_UNPACK_TYPECHECK(__obj_pptr, __proto_message_name), false) diff --git a/protobuf.c b/protobuf.c index 4a5d861d6..9f6f441ac 100644 --- a/protobuf.c +++ b/protobuf.c @@ -6,12 +6,107 @@ #include +#include "crtools.h" #include "compiler.h" #include "types.h" #include "log.h" #include "util.h" #include "protobuf.h" +#include "protobuf/inventory.pb-c.h" +#include "protobuf/regfile.pb-c.h" +#include "protobuf/eventfd.pb-c.h" +#include "protobuf/eventpoll.pb-c.h" +#include "protobuf/signalfd.pb-c.h" +#include "protobuf/inotify.pb-c.h" +#include "protobuf/core.pb-c.h" +#include "protobuf/mm.pb-c.h" +#include "protobuf/pipe.pb-c.h" +#include "protobuf/fifo.pb-c.h" +#include "protobuf/fdinfo.pb-c.h" +#include "protobuf/pipe-data.pb-c.h" +#include "protobuf/pstree.pb-c.h" +#include "protobuf/sa.pb-c.h" +#include "protobuf/sk-unix.pb-c.h" +#include "protobuf/sk-inet.pb-c.h" +#include "protobuf/sk-packet.pb-c.h" +#include "protobuf/creds.pb-c.h" +#include "protobuf/itimer.pb-c.h" +#include "protobuf/utsns.pb-c.h" +#include "protobuf/ipc-var.pb-c.h" +#include "protobuf/ipc-shm.pb-c.h" +#include "protobuf/ipc-msg.pb-c.h" +#include "protobuf/ipc-sem.pb-c.h" +#include "protobuf/fs.pb-c.h" +#include "protobuf/remap-file-path.pb-c.h" +#include "protobuf/ghost-file.pb-c.h" +#include "protobuf/mnt.pb-c.h" +#include "protobuf/netdev.pb-c.h" +#include "protobuf/tcp-stream.pb-c.h" + +struct cr_pb_message_desc { + pb_getpksize_t getpksize; + pb_pack_t pack; + pb_unpack_t unpack; + pb_free_t free; + const ProtobufCMessageDescriptor *pb_desc; +}; + +/* + * This should be explicitly "called" to do type-checking + */ + +#define CR_PB_MDESC_INIT(__var, __type, __name) do { \ + __var.getpksize = PB_GPS_TYPECHECK((__type *)NULL, __name); \ + __var.pack = PB_PACK_TYPECHECK((__type *)NULL, __name); \ + __var.unpack = PB_UNPACK_TYPECHECK((__type **)NULL, __name); \ + __var.free = PB_FREE_TYPECHECK((__type *)NULL, __name); \ + __var.pb_desc = &__name##__descriptor; \ + } while (0) + +static struct cr_pb_message_desc cr_pb_descs[PB_MAX]; + +#define CR_PB_DESC(__type, __vtype, __ftype) \ + CR_PB_MDESC_INIT(cr_pb_descs[PB_##__type], __vtype##Entry, __ftype##_entry) + +void cr_pb_init(void) +{ + CR_PB_DESC(INVENTORY, Inventory, inventory); + CR_PB_DESC(FDINFO, Fdinfo, fdinfo); + CR_PB_DESC(REG_FILES, RegFile, reg_file); + CR_PB_DESC(EVENTFD, EventfdFile, eventfd_file); + CR_PB_DESC(EVENTPOLL, EventpollFile, eventpoll_file); + CR_PB_DESC(EVENTPOLL_TFD, EventpollTfd, eventpoll_tfd); + CR_PB_DESC(SIGNALFD, Signalfd, signalfd); + CR_PB_DESC(INOTIFY, InotifyFile, inotify_file); + CR_PB_DESC(INOTIFY_WD, InotifyWd, inotify_wd); + CR_PB_DESC(CORE, Core, core); + CR_PB_DESC(MM, Mm, mm); + CR_PB_DESC(VMAS, Vma, vma); + CR_PB_DESC(PIPES, Pipe, pipe); + CR_PB_DESC(PIPES_DATA, PipeData, pipe_data); + CR_PB_DESC(FIFO, Fifo, fifo); + CR_PB_DESC(PSTREE, Pstree, pstree); + CR_PB_DESC(SIGACT, Sa, sa); + CR_PB_DESC(UNIXSK, UnixSk, unix_sk); + CR_PB_DESC(INETSK, InetSk, inet_sk); + CR_PB_DESC(SK_QUEUES, SkPacket, sk_packet); + CR_PB_DESC(ITIMERS, Itimer, itimer); + CR_PB_DESC(CREDS, Creds, creds); + CR_PB_DESC(UTSNS, Utsns, utsns); + CR_PB_DESC(IPCNS_VAR, IpcVar, ipc_var); + CR_PB_DESC(IPCNS_SHM, IpcShm, ipc_shm); + /* There's no _entry suffix in this one :( */ + CR_PB_MDESC_INIT(cr_pb_descs[PB_IPCNS_MSG], IpcMsg, ipc_msg); + CR_PB_DESC(IPCNS_MSG_ENT, IpcMsg, ipc_msg); + CR_PB_DESC(IPCNS_SEM, IpcSem, ipc_sem); + CR_PB_DESC(FS, Fs, fs); + CR_PB_DESC(REMAP_FPATH, RemapFilePath, remap_file_path); + CR_PB_DESC(GHOST_FILE, GhostFile, ghost_file); + CR_PB_DESC(TCP_STREAM, TcpStream, tcp_stream); + CR_PB_DESC(MOUNTPOINTS, Mnt, mnt); + CR_PB_DESC(NETDEV, NetDevice, net_device); +} /* * To speed up reading of packed objects