Add flog to CRIU

Change made through this commit:
- Include copy of flog as a seperate tree.
- Modify the makefile to add and compile flog code.

Signed-off-by: prakritigoyal19 <prakritigoyal19@gmail.com>
This commit is contained in:
prakritigoyal19 2020-06-07 09:22:53 +05:30 committed by Andrei Vagin
parent 4f8f295e57
commit 6f8d5435bb
13 changed files with 755 additions and 1 deletions

View file

@ -147,7 +147,7 @@ HOSTCFLAGS += $(WARNINGS) $(DEFINES) -iquote include/
export AFLAGS CFLAGS USERCLFAGS HOSTCFLAGS
# Default target
all: criu lib crit
all: flog criu lib crit
.PHONY: all
#
@ -233,6 +233,15 @@ soccr/built-in.o: $(CONFIG_HEADER) .FORCE
$(SOCCR_A): |soccr/built-in.o
criu-deps += $(SOCCR_A)
#flog gets used by criu, build it earlier
flogMakefile: ;
flog%:
$(Q) $(MAKE) $(build)=flog $@
flog:
$(Q) $(MAKE) $(build)=flog all
.PHONY: flog
#
# CRIU building done in own directory
# with slightly different rules so we
@ -275,6 +284,7 @@ lib: crit
clean mrproper:
$(Q) $(MAKE) $(build)=images $@
$(Q) $(MAKE) $(build)=flog $@
$(Q) $(MAKE) $(build)=criu $@
$(Q) $(MAKE) $(build)=soccr $@
$(Q) $(MAKE) $(build)=lib $@

29
flog/Makefile Normal file
View file

@ -0,0 +1,29 @@
OPTS=-ggdb3 -Wall -Werror
export OPTS
CFLAGS += -iquote include
CFLAGS += -iquote flog/include
CFLAGS += -iquote flog/include/uapi
include $(__nmk_dir)msg.mk
$(eval $(call gen-built-in,src))
flog:
$(Q) $(MAKE) $(build)=$(obj)/src all
.PHONY: flog
clean-flog:
$(call msg-gen, $@)
$(Q) $(MAKE) $(build)=$(obj)/src clean
$(Q) $(RM) built-in.o
.PHONY: clean-flog
clean: clean-flog
mrproper: clean
test:
./tests/test00
all-y += flog

4
flog/built-in.S Normal file
View file

@ -0,0 +1,4 @@
SECTIONS
{
.rodata : { _rodata_start = . ; *(.rodata*) ; _rodata_end = . ;}
}

71
flog/include/compiler.h Normal file
View file

@ -0,0 +1,71 @@
#ifndef __COMPILER_H__
#define __COMPILER_H__
/*
* Various definitions for success build,
* picked from various places, mostly from
* the linux kernel.
*/
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)
#define NORETURN __attribute__((__noreturn__))
#define __packed __attribute__((__packed__))
#define __used __attribute__((__used__))
#define __maybe_unused __attribute__((unused))
#define __always_unused __attribute__((unused))
#define __section(S) __attribute__ ((__section__(#S)))
#ifndef __always_inline
# define __always_inline inline __attribute__((always_inline))
#endif
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#ifndef always_inline
# define always_inline __always_inline
#endif
#ifndef noinline
# define noinline __attribute__((noinline))
#endif
#define __aligned(x) __attribute__((aligned(x)))
#ifndef offsetof
# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
#define barrier() asm volatile("" ::: "memory")
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
#define __round_mask(x, y) ((__typeof__(x))((y) - 1))
#define round_up(x, y) ((((x) - 1) | __round_mask(x, y)) + 1)
#define round_down(x, y) ((x) & ~__round_mask(x, y))
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
#define max(x, y) ({ \
typeof(x) _max1 = (x); \
typeof(y) _max2 = (y); \
(void) (&_max1 == &_max2); \
_max1 > _max2 ? _max1 : _max2; })
#define is_log2(v) (((v) & ((v) - 1)) == 0)
#endif /* __COMPILER_H__ */

9
flog/include/flog.h Normal file
View file

@ -0,0 +1,9 @@
#ifndef __FLOG_H__
#define __FLOG_H__
#include <string.h>
#include <errno.h>
#include "uapi/flog.h"
#endif /* __FLOG_H__ */

17
flog/include/log.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef __LOG_H__
#define __LOG_H__
#include <stdio.h>
#define pr_out(fmt, ...) fprintf(stdout, fmt, ##__VA_ARGS__)
#if 1
# define pr_debug(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
#else
# define pr_debug(fmt, ...)
#endif
#define pr_err(fmt, ...) fprintf(stderr, "Error (%s:%d): "fmt, __FILE__, __LINE__, ##__VA_ARGS__)
#define pr_perror(fmt, ...) fprintf(stderr, "Error (%s:%d): "fmt "%m\n", __FILE__, __LINE__, ##__VA_ARGS__)
#endif /* __LOG_H__ */

16
flog/include/types.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef __FLOG_TYPES_H__
#define __FLOG_TYPES_H__
#include <stdint.h>
#include <stdbool.h>
typedef uint64_t u64;
typedef int64_t s64;
typedef uint32_t u32;
typedef int32_t s32;
typedef uint16_t u16;
typedef int16_t s16;
typedef uint8_t u8;
typedef int8_t s8;
#endif /* __FLOG_TYPES_H__ */

149
flog/include/uapi/flog.h Normal file
View file

@ -0,0 +1,149 @@
#ifndef __UAPI_FLOG_H__
#define __UAPI_FLOG_H__
#include <stdbool.h>
#include <string.h>
#include <errno.h>
/*
* We work with up to 32 arguments in macros here.
* If more provided -- behaviour is undefined.
*/
/*
* By Laurent Deniau at https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s
*/
#define FLOG_PP_NARG_(...) FLOG_PP_ARG_N(__VA_ARGS__)
#define FLOG_PP_NARG(...) FLOG_PP_NARG_(1, ##__VA_ARGS__, FLOG_PP_RSEQ_N())
#define FLOG_PP_ARG_N( _0, _1, _2, _3, _4, \
_5, _6, _7, _8, _9, \
_10,_11,_12,_13,_14, \
_15,_16,_17,_18,_19, \
_20,_21,_22,_23,_24, \
_25,_26,_27,_28,_29, \
_30,_31, N, ...) N
#define FLOG_PP_RSEQ_N() \
31, 30, 29, 28, 27, \
26, 25, 24, 23, 22, \
21, 20, 19, 18, 17, \
16, 15, 14, 13, 12, \
11, 10, 9, 8, 7, \
6, 5, 4, 3, 2, \
1, 0
#define FLOG_GENMASK_0(N, x) 0
#define FLOG_GENMASK_1(N, op, x, ...) (op(N, 0, x))
#define FLOG_GENMASK_2(N, op, x, ...) ((op(N, 1, x)) | FLOG_GENMASK_1(N, op, __VA_ARGS__))
#define FLOG_GENMASK_3(N, op, x, ...) ((op(N, 2, x)) | FLOG_GENMASK_2(N, op, __VA_ARGS__))
#define FLOG_GENMASK_4(N, op, x, ...) ((op(N, 3, x)) | FLOG_GENMASK_3(N, op, __VA_ARGS__))
#define FLOG_GENMASK_5(N, op, x, ...) ((op(N, 4, x)) | FLOG_GENMASK_4(N, op, __VA_ARGS__))
#define FLOG_GENMASK_6(N, op, x, ...) ((op(N, 5, x)) | FLOG_GENMASK_5(N, op, __VA_ARGS__))
#define FLOG_GENMASK_7(N, op, x, ...) ((op(N, 6, x)) | FLOG_GENMASK_6(N, op, __VA_ARGS__))
#define FLOG_GENMASK_8(N, op, x, ...) ((op(N, 7, x)) | FLOG_GENMASK_7(N, op, __VA_ARGS__))
#define FLOG_GENMASK_9(N, op, x, ...) ((op(N, 8, x)) | FLOG_GENMASK_8(N, op, __VA_ARGS__))
#define FLOG_GENMASK_10(N, op, x, ...) ((op(N, 9, x)) | FLOG_GENMASK_9(N, op, __VA_ARGS__))
#define FLOG_GENMASK_11(N, op, x, ...) ((op(N, 10, x)) | FLOG_GENMASK_10(N, op, __VA_ARGS__))
#define FLOG_GENMASK_12(N, op, x, ...) ((op(N, 11, x)) | FLOG_GENMASK_11(N, op, __VA_ARGS__))
#define FLOG_GENMASK_13(N, op, x, ...) ((op(N, 12, x)) | FLOG_GENMASK_12(N, op, __VA_ARGS__))
#define FLOG_GENMASK_14(N, op, x, ...) ((op(N, 13, x)) | FLOG_GENMASK_13(N, op, __VA_ARGS__))
#define FLOG_GENMASK_15(N, op, x, ...) ((op(N, 14, x)) | FLOG_GENMASK_14(N, op, __VA_ARGS__))
#define FLOG_GENMASK_16(N, op, x, ...) ((op(N, 15, x)) | FLOG_GENMASK_15(N, op, __VA_ARGS__))
#define FLOG_GENMASK_17(N, op, x, ...) ((op(N, 16, x)) | FLOG_GENMASK_16(N, op, __VA_ARGS__))
#define FLOG_GENMASK_18(N, op, x, ...) ((op(N, 17, x)) | FLOG_GENMASK_17(N, op, __VA_ARGS__))
#define FLOG_GENMASK_19(N, op, x, ...) ((op(N, 18, x)) | FLOG_GENMASK_18(N, op, __VA_ARGS__))
#define FLOG_GENMASK_20(N, op, x, ...) ((op(N, 19, x)) | FLOG_GENMASK_19(N, op, __VA_ARGS__))
#define FLOG_GENMASK_21(N, op, x, ...) ((op(N, 20, x)) | FLOG_GENMASK_20(N, op, __VA_ARGS__))
#define FLOG_GENMASK_22(N, op, x, ...) ((op(N, 21, x)) | FLOG_GENMASK_21(N, op, __VA_ARGS__))
#define FLOG_GENMASK_23(N, op, x, ...) ((op(N, 22, x)) | FLOG_GENMASK_22(N, op, __VA_ARGS__))
#define FLOG_GENMASK_24(N, op, x, ...) ((op(N, 23, x)) | FLOG_GENMASK_23(N, op, __VA_ARGS__))
#define FLOG_GENMASK_25(N, op, x, ...) ((op(N, 24, x)) | FLOG_GENMASK_24(N, op, __VA_ARGS__))
#define FLOG_GENMASK_26(N, op, x, ...) ((op(N, 25, x)) | FLOG_GENMASK_25(N, op, __VA_ARGS__))
#define FLOG_GENMASK_27(N, op, x, ...) ((op(N, 26, x)) | FLOG_GENMASK_26(N, op, __VA_ARGS__))
#define FLOG_GENMASK_28(N, op, x, ...) ((op(N, 27, x)) | FLOG_GENMASK_27(N, op, __VA_ARGS__))
#define FLOG_GENMASK_29(N, op, x, ...) ((op(N, 28, x)) | FLOG_GENMASK_28(N, op, __VA_ARGS__))
#define FLOG_GENMASK_30(N, op, x, ...) ((op(N, 29, x)) | FLOG_GENMASK_29(N, op, __VA_ARGS__))
#define FLOG_GENMASK_31(N, op, x, ...) ((op(N, 30, x)) | FLOG_GENMASK_30(N, op, __VA_ARGS__))
#define FLOG_GENMASK_32(N, op, x, ...) ((op(N, 31, x)) | FLOG_GENMASK_31(N, op, __VA_ARGS__))
#define FLOG_CONCAT(arg1, arg2) FLOG_CONCAT1(arg1, arg2)
#define FLOG_CONCAT1(arg1, arg2) FLOG_CONCAT2(arg1, arg2)
#define FLOG_CONCAT2(arg1, arg2) arg1##arg2
#define FLOG_GENMASK_(N, op, ...) FLOG_CONCAT(FLOG_GENMASK_, N)(N, op, ##__VA_ARGS__)
#define FLOG_GENMASK(op, ...) FLOG_GENMASK_(FLOG_PP_NARG(__VA_ARGS__), op, ##__VA_ARGS__)
#define flog_genbit(ord, n, v, ...) \
_Generic((v), \
\
/* Basic types */ \
char: 0, \
signed char: 0, \
unsigned char: 0, \
signed short int: 0, \
unsigned short int: 0, \
signed int: 0, \
unsigned int: 0, \
signed long: 0, \
unsigned long: 0, \
signed long long: 0, \
unsigned long long: 0, \
\
/* Not used for a while */ \
/* float: 12, */ \
/* double: 13, */ \
/* long double: 14, */ \
\
/* Basic poniters */ \
char *: (1u << (ord - n - 1)), \
signed char *: (1u << (ord - n - 1)), \
unsigned char *: (1u << (ord - n - 1)), \
signed short int *: 0, \
unsigned short int *: 0, \
signed int *: 0, \
unsigned int *: 0, \
signed long *: 0, \
unsigned long *: 0, \
signed long long *: 0, \
unsigned long long *: 0, \
void *: 0, \
\
/* Const basic pointers */ \
const char *: (1u << (ord - n - 1)), \
const signed char *: (1u << (ord - n - 1)), \
const unsigned char *: (1u << (ord - n - 1)), \
const signed short int *: 0, \
const unsigned short int *: 0, \
const signed int *: 0, \
const unsigned int *: 0, \
const signed long *: 0, \
const unsigned long *: 0, \
const signed long long *: 0, \
const unsigned long long *: 0, \
const void *: 0, \
\
/* Systypes and pointers */ \
default: -1)
typedef struct {
unsigned int magic;
unsigned int size;
unsigned int nargs;
unsigned int mask;
long fmt;
long args[0];
} flog_msg_t;
extern int flog_encode_msg(int fdout, unsigned int nargs, unsigned int mask, const char *format, ...);
void flog_decode_msg(int fdout, const char *format, ...);
extern int flog_decode_all(int fdin, int fdout);
#define flog_encode(fdout, fmt, ...) \
flog_encode_msg(fdout, FLOG_PP_NARG(__VA_ARGS__), \
FLOG_GENMASK(flog_genbit, ##__VA_ARGS__), fmt, ##__VA_ARGS__)
int flog_map_buf(int fdout);
int flog_close(int fdout);
#endif /* __UAPI_FLOG_H__ */

37
flog/include/util.h Normal file
View file

@ -0,0 +1,37 @@
#ifndef __UTIL_H__
#define __UTIL_H__
#include <string.h>
#include <errno.h>
#include "log.h"
#include "types.h"
#define __xalloc(op, size, ...) \
({ \
void *___p = op(__VA_ARGS__); \
___p; \
})
#define xstrdup(str) __xalloc(strdup, strlen(str) + 1, str)
#define xmalloc(size) __xalloc(malloc, size, size)
#define xzalloc(size) __xalloc(calloc, size, 1, size)
#define xrealloc(p, size) __xalloc(realloc, size, p, size)
#define xfree(p) do { if (p) free(p); } while (0)
#define xrealloc_safe(pptr, size) \
({ \
int __ret = -ENOMEM; \
void *new = xrealloc(*pptr, size); \
if (new) { \
*pptr = new; \
__ret = 0; \
} \
__ret; \
})
#define memzero_p(p) memset(p, 0, sizeof(*p))
#define memzero(p, size) memset(p, 0, size)
#endif /* __UTIL_H__ */

5
flog/src/Makefile Normal file
View file

@ -0,0 +1,5 @@
ccflags-y += -DCONFIG_X86_64 -iquote ./include $(OPTS)
ldflags-y += -r
#obj-y += main.o
obj-y += flog.o

215
flog/src/flog.c Normal file
View file

@ -0,0 +1,215 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/param.h>
#include <sys/mman.h>
//#include <ffi.h>
#include "uapi/flog.h"
#include "util.h"
#define MAGIC 0xABCDABCD
#define BUF_SIZE (1<<20)
static char _mbuf[BUF_SIZE];
static char *mbuf = _mbuf;
static char *fbuf;
static uint64_t fsize;
static uint64_t mbuf_size = sizeof(_mbuf);
/*int flog_decode_all(int fdin, int fdout)
{
flog_msg_t *m = (void *)mbuf;
ffi_type *args[34] = {
[0] = &ffi_type_sint,
[1] = &ffi_type_pointer,
[2 ... 33] = &ffi_type_slong
};
void *values[34];
ffi_cif cif;
ffi_arg rc;
size_t i, ret;
char *fmt;
values[0] = (void *)&fdout;
while (1) {
ret = read(fdin, mbuf, sizeof(m));
if (ret == 0)
break;
if (ret < 0) {
fprintf(stderr, "Unable to read a message: %m");
return -1;
}
if (m->magic != MAGIC) {
fprintf(stderr, "The log file was not properly closed\n");
break;
}
ret = m->size - sizeof(m);
if (m->size > mbuf_size) {
fprintf(stderr, "The buffer is too small");
return -1;
}
if (read(fdin, mbuf + sizeof(m), ret) != ret) {
fprintf(stderr, "Unable to read a message: %m");
return -1;
}
fmt = mbuf + m->fmt;
values[1] = &fmt;
for (i = 0; i < m->nargs; i++) {
values[i + 2] = (void *)&m->args[i];
if (m->mask & (1u << i)) {
m->args[i] = (long)(mbuf + m->args[i]);
}
}
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, m->nargs + 2,
&ffi_type_sint, args) == FFI_OK)
ffi_call(&cif, FFI_FN(dprintf), &rc, values);
}
return 0;
}*/
static int flog_enqueue(flog_msg_t *m)
{
if (write(1, m, m->size) != m->size) {
fprintf(stderr, "Unable to write a message\n");
return -1;
}
return 0;
}
/*extern char *rodata_start;
extern char *rodata_end;
*/
/* Pre-allocate a buffer in a file and map it into memory. */
int flog_map_buf(int fdout)
{
uint64_t off = 0;
void *addr;
/*
* Two buffers are mmaped into memory. A new one is mapped when a first
* one is completly filled.
*/
if (fbuf && (mbuf - fbuf < BUF_SIZE))
return 0;
if (fbuf) {
if (munmap(fbuf, BUF_SIZE * 2)) {
fprintf(stderr, "Unable to unmap a buffer: %m");
return -1;
}
off = mbuf - fbuf - BUF_SIZE;
fbuf = NULL;
}
if (fsize == 0)
fsize += BUF_SIZE;
fsize += BUF_SIZE;
if (ftruncate(fdout, fsize)) {
fprintf(stderr, "Unable to truncate a file: %m");
return -1;
}
if (!fbuf)
addr = mmap(NULL, BUF_SIZE * 2, PROT_WRITE | PROT_READ,
MAP_FILE | MAP_SHARED, fdout, fsize - 2 * BUF_SIZE);
else
addr = mremap(fbuf + BUF_SIZE, BUF_SIZE,
BUF_SIZE * 2, MREMAP_FIXED, fbuf);
if (addr == MAP_FAILED) {
fprintf(stderr, "Unable to map a buffer: %m");
return -1;
}
fbuf = addr;
mbuf = fbuf + off;
mbuf_size = 2 * BUF_SIZE;
return 0;
}
int flog_close(int fdout)
{
if (mbuf == _mbuf)
return 0;
munmap(fbuf, BUF_SIZE * 2);
if (ftruncate(fdout, fsize - 2 * BUF_SIZE + mbuf - fbuf)) {
fprintf(stderr, "Unable to truncate a file: %m");
return -1;
}
return 0;
}
int flog_encode_msg(int fdout, unsigned int nargs, unsigned int mask, const char *format, ...)
{
flog_msg_t *m;
va_list argptr;
char *str_start, *p;
size_t i;
if (mbuf != _mbuf && flog_map_buf(fdout))
return -1;
m = (void *) mbuf;
m->nargs = nargs;
m->mask = mask;
str_start = (void *)m->args + sizeof(m->args[0]) * nargs;
p = memccpy(str_start, format, 0, mbuf_size - (str_start - mbuf));
if (p == NULL) {
fprintf(stderr, "No memory for string argument\n");
return -1;
}
m->fmt = str_start - mbuf;
str_start = p;
va_start(argptr, format);
for (i = 0; i < nargs; i++) {
m->args[i] = (long)va_arg(argptr, long);
/*
* If we got a string, we should either
* reference it when in rodata, or make
* a copy (FIXME implement rodata refs).
*/
if (mask & (1u << i)) {
p = memccpy(str_start, (void *)m->args[i], 0, mbuf_size - (str_start - mbuf));
if (p == NULL) {
fprintf(stderr, "No memory for string argument\n");
return -1;
}
m->args[i] = str_start - mbuf;
str_start = p;
}
}
va_end(argptr);
m->size = str_start - mbuf;
/*
* A magic is required to know where we stop writing into a log file,
* if it was not properly closed. The file is mapped into memory, so a
* space in the file is allocated in advance and at the end it can have
* some unused tail.
*/
m->magic = MAGIC;
m->size = roundup(m->size, 8);
if (mbuf == _mbuf) {
if (flog_enqueue(m))
return -1;
} else {
mbuf += m->size;
mbuf_size -= m->size;
}
return 0;
}

170
flog/src/main.c Normal file
View file

@ -0,0 +1,170 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "flog.h"
extern char _rodata_start, _rodata_end;
char *rodata_start = &_rodata_start;
char *rodata_end = &_rodata_end;
enum {
MODE_BINARY,
MODE_FPRINTF,
MODE_SPRINTF,
MODE_DPRINTF,
};
int main(int argc, char *argv[])
{
static const char str1[] = "String1 String1";
static const char str2[] = "string2 string2 string2";
int fdout = STDOUT_FILENO;
bool use_decoder = false;
int mode = MODE_BINARY;
size_t niter = 100;
int opt, idx;
size_t i;
static const char short_opts[] = "m:o:di:h";
static struct option long_opts[] = {
{ "mode", required_argument, 0, 'm' },
{ "output", required_argument, 0, 'o' },
{ "decode", no_argument, 0, 'd' },
{ "iter", required_argument, 0, 'i' },
{ "help", no_argument, 0, 'h' },
{ },
};
while (1) {
idx = -1;
opt = getopt_long(argc, argv, short_opts, long_opts, &idx);
if (opt == -1)
break;
switch (opt) {
case 'm':
if (strcmp(optarg, "binary") == 0) {
mode = MODE_BINARY;
} else if (strcmp(optarg, "fprintf") == 0) {
mode = MODE_FPRINTF;
} else if (strcmp(optarg, "sprintf") == 0) {
mode = MODE_SPRINTF;
} else if (strcmp(optarg, "dprintf") == 0) {
mode = MODE_DPRINTF;
} else
goto usage;
break;
case 'o':
if (strcmp(optarg, "stdout") == 0) {
fdout = fileno(stdout);
} else if (strcmp(optarg, "stderr") == 0) {
fdout = fileno(stderr);
} else {
fdout = open(optarg, O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fdout < 0) {
fprintf(stderr, "Can't open %s: %s\n",
optarg, strerror(errno));
exit(1);
}
}
break;
case 'i':
niter = atoi(optarg);
break;
case 'd':
use_decoder = true;
break;
case 'h':
default:
goto usage;
}
}
switch (mode) {
case MODE_BINARY:
if (use_decoder)
return flog_decode_all(STDIN_FILENO, fdout);
if (fdout != STDOUT_FILENO && flog_map_buf(fdout))
return 1;
for (i = 0; i < niter; i++)
if (flog_encode(fdout, "Some message %s %s %c %li %d %lu\n",
str1, str2, 'c', (long)-4, (short)2,
(unsigned long)2))
return 1;
if (flog_close(fdout))
return 1;
break;
case MODE_DPRINTF:
{
for (i = 0; i < niter; i++) {
dprintf(fdout, "Some message %s %s %c %li %d %lu\n",
str1, str2, 'c', (long)-4, (short)2,
(unsigned long)2);
}
break;
}
case MODE_FPRINTF:
{
FILE *f = fdopen(fdout, "w");
for (i = 0; i < niter; i++) {
fprintf(f, "Some message %s %s %c %li %d %lu\n",
str1, str2, 'c', (long)-4, (short)2,
(unsigned long)2);
fflush(f);
}
fclose(f);
break;
}
case MODE_SPRINTF:
{
static char buf[4096];
for (i = 0; i < niter; i++) {
sprintf(buf, "Some message %s %s %c %li %d %lu\n",
str1, str2, 'c', (long)-4, (short)2,
(unsigned long)2);
}
break;
}
default:
return 1;
}
return 0;
usage:
fprintf(stderr,
"flog [--mode binary|dprintf] [--output stdout|stderr|filename] [--decode] [--iter number]\n"
"\n"
"Examples:\n"
"\n"
" - run 100000 iterations of instant message processing (immediate dprintf calls)\n"
"\n"
" flog -m dprintf -i 100000\n"
"\n"
" - run 100000 iterations in binary mode without processing (queue messages only)\n"
"\n"
" flog -i 100000\n"
"\n"
" - run 100000 iterations in binary mode with decoding after\n"
"\n"
" flog -i 100000 -d\n"
"\n"
" - run 100000 iterations in binary mode with decoding after, writting results into 'out' file\n"
"\n"
" flog -i 100000 -d -o out\n"
"\n");
return 1;
}

22
flog/tests/test00 Executable file
View file

@ -0,0 +1,22 @@
#!/bin/sh
set -e -x
echo Map a log file into memory
time ./flog run -i 1000000 -o /tmp/flog.raw.map
echo Write into a log file
time ./flog run -i 1000000 > /tmp/flog.raw
echo Use fprintf
time ./flog run -m fprintf -i 1000000 -o /tmp/flog.fprintf.txt
echo Use dprintf
time ./flog run -m dprintf -i 1000000 -o /tmp/flog.dprintf.txt
echo Use sprintf
time ./flog run -m sprintf -i 1000000
time ./flog run -d < /tmp/flog.raw > /tmp/flog.raw.txt
cmp /tmp/flog.raw.txt /tmp/flog.fprintf.txt
time ./flog run -d < /tmp/flog.raw.map > /tmp/flog.raw.map.txt
cmp /tmp/flog.raw.map.txt /tmp/flog.fprintf.txt
cmp /tmp/flog.dprintf.txt /tmp/flog.fprintf.txt