[CRIU] [PATCH 09/38] compel: Add simple logging

Cyrill Gorcunov gorcunov at openvz.org
Tue Oct 11 09:03:59 PDT 2016


Took from CRIU but diet it significantly, I need
trivial log engine for now.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 compel/Makefile                 |  1 +
 compel/include/log.h            | 62 +++++++++++++++++++++++++++
 compel/include/uapi/compel.h    |  8 ++++
 compel/include/uapi/loglevels.h |  1 +
 compel/src/lib/log.c            | 93 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 165 insertions(+)
 create mode 100644 compel/include/log.h
 create mode 100644 compel/src/lib/log.c

diff --git a/compel/Makefile b/compel/Makefile
index eb46393f3355..b55b9a5b3f6f 100644
--- a/compel/Makefile
+++ b/compel/Makefile
@@ -16,6 +16,7 @@ lib-y			+= src/lib/handle-elf.o
 host-lib-y		+= src/lib/handle-elf.o
 
 lib-y			+= src/lib/argv.o
+lib-y			+= src/lib/log.o
 
 ifeq ($(ARCH),x86)
 lib-y			+= src/lib/handle-elf-32.o
diff --git a/compel/include/log.h b/compel/include/log.h
new file mode 100644
index 000000000000..5f63d11bbdd4
--- /dev/null
+++ b/compel/include/log.h
@@ -0,0 +1,62 @@
+#ifndef COMPEL_LOG_H__
+#define COMPEL_LOG_H__
+
+#include "uapi/loglevels.h"
+
+#ifndef LOG_PREFIX
+# define LOG_PREFIX
+#endif
+
+extern unsigned int compel_log_get_loglevel(void);
+
+static inline int pr_quelled(unsigned int loglevel)
+{
+	return libcompel_log_get_loglevel() < loglevel && loglevel != LOG_MSG;
+}
+
+extern void print_on_level(unsigned int loglevel, const char *format, ...);
+
+#define pr_msg(fmt, ...)							\
+	print_on_level(LOG_MSG,							\
+		       fmt, ##__VA_ARGS__)
+
+#define pr_info(fmt, ...)							\
+	print_on_level(LOG_INFO,						\
+		       LOG_PREFIX fmt, ##__VA_ARGS__)
+
+#define pr_err(fmt, ...)							\
+	print_on_level(LOG_ERROR,						\
+		       "Error (%s:%d): " LOG_PREFIX fmt,			\
+		       __FILE__, __LINE__, ##__VA_ARGS__)
+
+#define pr_err_once(fmt, ...)							\
+	do {									\
+		static bool __printed;						\
+		if (!__printed) {						\
+			pr_err(fmt, ##__VA_ARGS__);				\
+			__printed = 1;						\
+		}								\
+	} while (0)
+
+#define pr_warn(fmt, ...)							\
+	print_on_level(LOG_WARN,						\
+		       "Warn  (%s:%d): " LOG_PREFIX fmt,			\
+		       __FILE__, __LINE__, ##__VA_ARGS__)
+
+#define pr_warn_once(fmt, ...)							\
+	do {									\
+		static bool __printed;						\
+		if (!__printed) {						\
+			pr_warn(fmt, ##__VA_ARGS__);				\
+			__printed = 1;						\
+		}								\
+	} while (0)
+
+#define pr_debug(fmt, ...)							\
+	print_on_level(LOG_DEBUG,						\
+		       LOG_PREFIX fmt, ##__VA_ARGS__)
+
+#define pr_perror(fmt, ...)							\
+	pr_err(fmt ": %m\n", ##__VA_ARGS__)
+
+#endif /* COMPEL_LOG_H__ */
diff --git a/compel/include/uapi/compel.h b/compel/include/uapi/compel.h
index 9148f94bda45..a39e696d7389 100644
--- a/compel/include/uapi/compel.h
+++ b/compel/include/uapi/compel.h
@@ -18,4 +18,12 @@ extern int libcompel_pack_argv(void *blob, size_t blob_size,
 			       int argc, char **argv,
 			       void **arg_p, size_t *arg_size);
 
+/*
+ * Logging
+ */
+extern int libcompel_log_init(const char *output);
+extern void libcompel_log_fini(void);
+extern void libcompel_log_set_loglevel(unsigned int loglevel);
+extern unsigned int libcompel_log_get_loglevel(void);
+
 #endif /* UAPI_COMPEL_H__ */
diff --git a/compel/include/uapi/loglevels.h b/compel/include/uapi/loglevels.h
index 1f2b665cb4e1..f7cdcc448475 100644
--- a/compel/include/uapi/loglevels.h
+++ b/compel/include/uapi/loglevels.h
@@ -1,6 +1,7 @@
 #ifndef UAPI_COMPEL_LOGLEVELS_H__
 #define UAPI_COMPEL_LOGLEVELS_H__
 
+#define LOG_UNSET		(-1)
 #define LOG_MSG			(0) /* Print message regardless of log level */
 #define LOG_ERROR		(1) /* Errors only, when we're in trouble */
 #define LOG_WARN		(2) /* Warnings, dazen and confused but trying to continue */
diff --git a/compel/src/lib/log.c b/compel/src/lib/log.c
new file mode 100644
index 000000000000..7c2d95c90cbd
--- /dev/null
+++ b/compel/src/lib/log.c
@@ -0,0 +1,93 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <fcntl.h>
+
+#include "uapi/compel.h"
+
+#include "log.h"
+
+static unsigned int current_loglevel = DEFAULT_LOGLEVEL;
+static int logfd = STDOUT_FILENO;
+
+int libcompel_log_init(const char *output)
+{
+	int new_logfd;
+
+	if (output && !strncmp(output, "-", 2)) {
+		new_logfd = dup(STDOUT_FILENO);
+		if (new_logfd < 0) {
+			pr_perror("Cant't dup stdout stream");
+			return -1;
+		}
+	} else if (output) {
+		new_logfd = open(output, O_CREAT|O_TRUNC|O_WRONLY|O_APPEND, 0600);
+		if (new_logfd < 0) {
+			pr_perror("Can't create log file %s", output);
+			return -1;
+		}
+	} else {
+		new_logfd = dup(STDERR_FILENO);
+		if (new_logfd < 0) {
+			pr_perror("Can't dup log file");
+			return -1;
+		}
+	}
+
+	logfd = new_logfd;
+	return 0;
+}
+
+void libcompel_log_fini(void)
+{
+	if (logfd >= 0 && logfd != STDOUT_FILENO) {
+		close(logfd);
+		logfd = STDOUT_FILENO;
+	}
+}
+
+void libcompel_log_set_loglevel(unsigned int level)
+{
+	if (level == LOG_UNSET)
+		current_loglevel = DEFAULT_LOGLEVEL;
+	else
+		current_loglevel = level;
+}
+
+unsigned int libcompel_log_get_loglevel(void)
+{
+	return current_loglevel;
+}
+
+static void __print_on_level(unsigned int loglevel, const char *format, va_list params)
+{
+	size_t size, off = 0;
+	int __errno = errno;
+	char buffer[4096];
+	ssize_t ret;
+
+	if (pr_quelled(loglevel))
+		return;
+
+	size = vsnprintf(buffer, sizeof(buffer), format, params);
+	while (off < size) {
+		ret = write(logfd, buffer + off, size - off);
+		if (ret <= 0)
+			break;
+		off += ret;
+	}
+	errno =  __errno;
+}
+
+void print_on_level(unsigned int loglevel, const char *format, ...)
+{
+	va_list params;
+
+	va_start(params, format);
+	__print_on_level(loglevel, format, params);
+	va_end(params);
+}
-- 
2.7.4



More information about the CRIU mailing list