Refactor configuration files. 37/67437/22
authorMichal Bloch <m.bloch@samsung.com>
Mon, 30 May 2016 15:02:12 +0000 (17:02 +0200)
committerMichal Bloch <m.bloch@samsung.com>
Wed, 1 Jun 2016 20:12:43 +0000 (22:12 +0200)
There is now a single config file containing everything,
instead of spreading the values over multiple files
and hardcoded definitions.

Change-Id: I0173cf5c41688ccfdfaeeff529394908470a7003
Signed-off-by: Michal Bloch <m.bloch@samsung.com>
Signed-off-by: Kazimierz Krosman <k.krosman@samsung.com>
26 files changed:
Makefile.am
configs/dlog.conf.journal [new file with mode: 0644]
configs/dlog.conf.kmsg [new file with mode: 0644]
configs/dlog.conf.logger [new file with mode: 0644]
configure.ac
include/logcommon.h
include/logconfig.h
include/logprint.h
include/queued_entry.h
packaging/dlog.conf.in [deleted file]
packaging/dlog.spec
packaging/dlog_logger.conf.in [deleted file]
packaging/dlog_logger.path.kmsg
scripts/dlogctrl.in [deleted file]
src/libdlog/log.c
src/libdlog/log_android.c
src/libdlog/log_kmsg.c
src/libdlog/logconfig.c [deleted file]
src/libdlog/loglimiter.c
src/logctrl/logctrl.c [new file with mode: 0644]
src/logger/logger.c
src/loginit/loginit.c
src/logutil/logutil_kmsg_logger.c
src/shared/logcommon.c
src/shared/logconfig.c [new file with mode: 0644]
src/shared/logprint.c

index 7b30c61..5b85867 100755 (executable)
@@ -21,7 +21,7 @@ libdlog_la_SOURCES =  \
        src/shared/logcommon.c \
        include/dlog.h \
        include/dlog-internal.h \
-       src/libdlog/logconfig.c \
+       src/shared/logconfig.c \
        include/logconfig.h \
        src/libdlog/loglimiter.c \
        include/loglimiter.h
@@ -70,6 +70,7 @@ dlogutil_SOURCES = \
        src/shared/logprint.c \
        src/shared/queued_entry.c \
        src/shared/log_file.c \
+       src/shared/logconfig.c \
        include/dlog_ioctl.h \
        include/logcommon.h \
        include/queued_entry.h \
@@ -88,8 +89,6 @@ if WITH_SYSTEMD_JOURNAL
 dlogutil_SOURCES += src/logutil/logutil_journal.c
 endif
 
-sbin_PROGRAMS = dloginit
-
 if !WITH_SYSTEMD_JOURNAL
 
 bin_PROGRAMS += dlog_logger
@@ -105,6 +104,7 @@ dlog_logger_LDFLAGS = \
 dlog_logger_SOURCES = \
        src/shared/dlog_ioctl.c \
        src/shared/logcommon.c \
+       src/shared/logconfig.c \
        src/shared/logprint.c \
        src/logger/logger.c \
        src/shared/queued_entry.c \
@@ -117,6 +117,8 @@ dlog_logger_SOURCES = \
 
 endif
 
+if WITH_KMSG
+sbin_PROGRAMS = dloginit
 dloginit_CFLAGS =  \
        $(AM_CFLAGS) \
        $(LIBUDEV_CFLAGS) \
@@ -129,9 +131,45 @@ dloginit_LDFLAGS = \
 
 dloginit_SOURCES = \
        src/loginit/loginit.c \
+       src/shared/logconfig.c \
+       src/shared/logcommon.c \
        include/logcommon.h \
        include/dlog.h
+endif
+
+bin_PROGRAMS += dlogctrl
+dlogctrl_CFLAGS =  \
+       $(AM_CFLAGS) \
+       -fPIE
+
+dlogctrl_LDFLAGS = \
+       $(AM_LDFLAGS) \
+       -pie
+
+dlogctrl_SOURCES = \
+       src/shared/logconfig.c \
+       src/logctrl/logctrl.c \
+       include/logconfig.h
+
+# conf files
+
+.PHONY: dlog.conf
+
+if WITH_KMSG
+dlog.conf: configs/dlog.conf.kmsg
+       cp configs/dlog.conf.kmsg dlog.conf
+endif
+if WITH_ANDROID_LOGGER
+dlog.conf: configs/dlog.conf.logger
+       cp configs/dlog.conf.logger dlog.conf
+endif
+if WITH_SYSTEMD_JOURNAL
+dlog.conf: configs/dlog.conf.journal
+       cp configs/dlog.conf.journal dlog.conf
+endif
+
+optetcdir = /opt/etc
+optetc_DATA = dlog.conf
 
-# conf file
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = dlog.pc
diff --git a/configs/dlog.conf.journal b/configs/dlog.conf.journal
new file mode 100644 (file)
index 0000000..fade87a
--- /dev/null
@@ -0,0 +1,3 @@
+plog=1
+limiter=0
+limiter|*|*=allow
diff --git a/configs/dlog.conf.kmsg b/configs/dlog.conf.kmsg
new file mode 100644 (file)
index 0000000..1074d7d
--- /dev/null
@@ -0,0 +1,10 @@
+plog=1
+limiter=0
+limiter|*|*=allow
+main_size=1048576
+apps_size=1048576
+system_size=1048576
+radio_size=1048576
+dlog_logger_conf_0=dlogutil -b system -r 5120 -n 1 -f /var/log/dlog/system -v kerneltime *:I
+dlog_logger_conf_1=dlogutil -b main -r 3072 -n 1 -f /var/log/dlog/main -v kerneltime *:W
+dlog_logger_conf_2=dlogutil -b radio -r 1024 -n 1 -f /var/log/dlog/radio -v kerneltime
diff --git a/configs/dlog.conf.logger b/configs/dlog.conf.logger
new file mode 100644 (file)
index 0000000..a00c697
--- /dev/null
@@ -0,0 +1,14 @@
+plog=1
+limiter=0
+limiter|*|*=allow
+main=/dev/log_main
+apps=/dev/log/log_apps
+system=/dev/log_system
+radio=/dev/log_radio
+main_size=1048576
+apps_size=1048576
+system_size=1048576
+radio_size=1048576
+dlog_logger_conf_0=dlogutil -b system -r 5120 -n 1 -f /var/log/dlog/system -v kerneltime *:I
+dlog_logger_conf_1=dlogutil -b main -r 3072 -n 1 -f /var/log/dlog/main -v kerneltime *:W
+dlog_logger_conf_2=dlogutil -b radio -r 1024 -n 1 -f /var/log/dlog/radio -v kerneltime
index 8172eae..921d80b 100755 (executable)
@@ -95,6 +95,5 @@ AC_SUBST(TZ_SYS_ETC)
 
 # output files
 AC_CONFIG_FILES([Makefile dlog.pc]
-                               scripts/dlogctrl
                                )
 AC_OUTPUT
index 5e53104..a80166f 100644 (file)
 #endif
 #define _E(...) fprintf(stderr, __VA_ARGS__)
 
-#define        LOG_MAIN_CONF_PREFIX    "LOG_MAIN="
-#define LOG_RADIO_CONF_PREFIX   "LOG_RADIO="
-#define LOG_SYSTEM_CONF_PREFIX  "LOG_SYSTEM="
-#define LOG_APPS_CONF_PREFIX    "LOG_APPS="
-#define LOG_TYPE_CONF_PREFIX   "LOG_TYPE="
-
 /*
  * LOG_ATOMIC_SIZE is calculated according to kernel value
  * 976 = 1024(size of log line) - 48(size of max prefix length)
 #define LOG_BUF_SIZE    1024
 #define LOG_MAX_SIZE    4076
 
-#define LOG_CONFIG_FILE TZ_SYS_ETC"/dlog.conf"
-
 #define gettid() syscall(SYS_gettid)
 
-int get_log_dev_names(char devs[LOG_ID_MAX][PATH_MAX]);
-
-log_id_t log_id_by_name(const char *name);
-
+char * log_name_by_id (log_id_t id);
+log_id_t log_id_by_name (const char *name);
+void syslog_critical_failure (const char * message);
 #endif /* _LOGCOMMON_H */
index c675622..4533630 100755 (executable)
 #ifndef _LOGCONFIG_H_
 #define _LOGCONFIG_H_
 
+#define MAX_CONF_KEY_LEN   32
+#define MAX_CONF_VAL_LEN   256
+#define MAX_CONF_ENTRY_LEN (MAX_CONF_KEY_LEN + MAX_CONF_VAL_LEN + 2) // +2 for the delimiter and newline
+
+typedef enum {
+       CONFIG_TYPE_KMSG,
+       CONFIG_TYPE_COMMON,
+       CONFIG_TYPE_MAX
+} config_type;
+
+struct log_conf_entry;
+
 struct log_config {
-       int lc_plog;        /* Platform logging enable/disable */
-       int lc_limiter;     /* Log limiter enable/disable */
+       struct log_conf_entry *begin;
+       struct log_conf_entry *last;
 };
 
-int __log_config_read(const char* config_file, struct log_config* config);
+const char * get_config_filename (config_type type);
+
+int log_config_set (struct log_config* config, const char* key, const char* value);
+const char* log_config_get (struct log_config* config, const char* key);
+int log_config_read (struct log_config* config);
+int log_config_read_file (struct log_config* config, char const* filename);
+int log_config_write(struct log_config* config, char const* filename);
+void log_config_free (struct log_config* config);
+
+void log_config_print_out (struct log_config* config);
+int log_config_print_key (struct log_config* config, const char* key);
+void log_config_push (struct log_config* config, const char* key, const char* value);
+int log_config_remove (struct log_config* config, const char* key);
+int log_config_foreach (struct log_config* config, int (*func)(const char* key, const char* value));
 
-#endif /* _LOGCONFIG_H_ */
\ No newline at end of file
+#endif /* _LOGCONFIG_H_ */
index 2b866ce..fbf97da 100755 (executable)
@@ -64,6 +64,11 @@ void log_set_print_format(log_format *p_format,
         log_print_format format);
 
 /**
+ * Returns a deep copy of the passed object.
+ */
+log_format *log_format_from_format(log_format *p_format);
+
+/**
  * Returns FORMAT_OFF on invalid string
  */
 log_print_format log_format_from_string(const char *s);
index 6738bd5..c48b0ba 100644 (file)
@@ -55,12 +55,12 @@ int cmp(struct queued_entry_t* a, struct queued_entry_t* b);
 
 struct logger_entry {
     uint16_t    len;    /* length of the payload */
-    uint16_t    __pad;  /* no matter what, we get 2 bytes of padding */
+    uint16_t    buf_id; /* ID of the log buffer */
     int32_t     pid;    /* generating process's pid */
     int32_t     tid;    /* generating process's tid */
     int32_t     sec;    /* seconds since Epoch */
     int32_t     nsec;   /* nanoseconds */
-    char        msg[]; /* the entry's payload */
+    char        msg[];  /* the entry's payload */
 };
 
 struct queued_entry_t {
diff --git a/packaging/dlog.conf.in b/packaging/dlog.conf.in
deleted file mode 100755 (executable)
index ea201a5..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-#
-# Dlog configuration file.
-#
-# Lines beginning with '#' are comments.
-#
-# Following file configures dlog library.
-# First section contains global configuration for library.
-# It allows to disable or enable platform logs and log limiter features.
-
-PlatformLogs                   on        # Possible values are 'on' and 'off'
-LogLimiter                     off
-
-# Second section controls filtering rules for dlog limiter.
-# Each line represent a rule for a filter. Filtering is done
-# at runtime, but configuration is read only at the boot time.
-# Log lines filtered out are not written to log buffers.
-# Filtering is done for "TAG"|priority pair, where TAG is string defined by application.
-# Which should be quoted with '"' character. It may contain spaces but not TABs.
-# Priority is one character from the following values:
-#
-#     V or v or 1 - Verbose messages,
-#     D or d or 2 - Debug messages,
-#     I or i or 3 - Informational messages,
-#     W or w or 4 - Warning messages,
-#     E or e or 5 - Error messages,
-#     F or f or 6 - Fatal messages.
-#
-# Limiter can define rules 'for all' by using an '*' character.
-# It's a wildcard replacing all TAGs not mentioned in this file.
-# '*' could be used also as wildcard for priority.
-# An asterisk is not evaluated, which means rules like "WOR*" are threated as a TAGs.
-# Log filter works according to rules presented below:
-#
-# case 1) The "TAG"|priority pair is not presented on the list.
-#       - Use "TAG"|* rule to decide what to do.
-#       - If "TAG"|* is not defined, use "*"|priority rule to decide what to do.
-#       - If "*"|priority pair is not present, use "*"|* rule.
-#       - If rule "*"|* is not present, then allow logging.
-#
-# case 2) The "TAG"|priority pair is on the list (applies to
-#         "*" |priority and "*"|* rules).
-#       - If policy = ALLOW, then log speed is unlimited.
-#       - If policy = <number> then limit to <number> logs per minute.
-#       - If policy = DENY then forbid logging.
-#
-# Maximum <number> is 10000, which gives 10000 log line per minute.
-# Please keep in mind that dlog uses constant size log storage, thus
-# when the application writes many logs, it may cause older entries overwriting.
-#
-# The configuration file has following format:
-# Lines beginning with # are threated as comments.
-# TAG can contain any ASCII letter or digit and spaces, but
-# not a TAB character. TAG has to be quoted using '"' character.
-# TAG is separated from priority with pipe '|' character.
-# Priority is one character long, the possible values are presented above.
-# Policy is separated from the "TAG"|priority pair with TAB character.
-# Policy is expressed as ALLOW, DENY or number from 0 to 10000 (not case sensitive).
-# Setting policy as 0 is the same as DENY.
-# Setting policy to more than 10000 is threated as allow.
-
-
-
-
-# TAG|priority POLICY
-"*"|*                          ALLOW
index f903cd0..b844ecc 100755 (executable)
@@ -7,14 +7,12 @@ License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
 Source101:  packaging/dlogutil.manifest
 Source102:  packaging/libdlog.manifest
-Source201:  packaging/dlog.conf.in
-Source202:  packaging/dlog_logger.conf.in
 Source301:  packaging/dlog_logger.service
 Source302:  packaging/dlog_logger.path.kmsg
-Source303:     packaging/dlog_logger.path.logger
+Source303:  packaging/dlog_logger.path.logger
 Source401:  packaging/dloginit.service
 Source501:  packaging/01-dlog.rules.kmsg
-Source502:     packaging/01-dlog.rules.logger
+Source502:  packaging/01-dlog.rules.logger
 
 # Choose dlog backend log device
 # Warning : MUST be only one "ON" in below three switches
@@ -100,7 +98,6 @@ cp %{SOURCE102} .
                        --enable-debug_mode \
                        TZ_SYS_ETC=%{TZ_SYS_ETC}
 make %{?jobs:-j%jobs} \
-       CFLAGS+=-DKMSG_DEV_CONFIG_FILE=\\\"/run/dloginit.conf\\\" \
        CFLAGS+=-DTZ_SYS_ETC=\\\"%{TZ_SYS_ETC}\\\" \
 %if %{?backend_journal} == ON
        CFLAGS+=-DDLOG_BACKEND_JOURNAL
@@ -118,10 +115,8 @@ rm -rf %{buildroot}
 
 %make_install
 mkdir -p %{buildroot}/usr/bin/
-cp %{_builddir}/%{name}-%{version}/scripts/dlogctrl %{buildroot}/usr/bin/dlogctrl
 
 mkdir -p %{buildroot}%{TZ_SYS_ETC}
-cp %SOURCE201 %{buildroot}%{TZ_SYS_ETC}/dlog.conf
 
 %if %{?backend_journal} == OFF
 
@@ -136,14 +131,13 @@ install -m 0644 %SOURCE303 %{buildroot}%{_unitdir}/dlog_logger.path
 
 ln -s ../dlog_logger.path %{buildroot}%{_unitdir}/multi-user.target.wants/dlog_logger.path
 
-# default set log output to external files
-cp %SOURCE202 %{buildroot}%{TZ_SYS_ETC}/dlog_logger.conf
-
 %endif
 
+%if %{?backend_kmsg} == ON
 mkdir -p %{buildroot}%{_unitdir}/sysinit.target.wants/
 install -m 0644 %SOURCE401 %{buildroot}%{_unitdir}
 ln -s ../dloginit.service %{buildroot}%{_unitdir}/sysinit.target.wants/dloginit.service
+%endif
 
 mkdir -p %{buildroot}%{_udevrulesdir}
 
@@ -186,7 +180,6 @@ systemctl daemon-reload
 %if %{?backend_journal} == OFF
 %{_udevrulesdir}/01-dlog.rules
 %attr(750,log,log) %{_bindir}/dlog_logger
-%attr(664,log,log) %{TZ_SYS_ETC}/dlog_logger.conf
 %{_unitdir}/dlog_logger.service
 %{_unitdir}/dlog_logger.path
 %{_unitdir}/multi-user.target.wants/dlog_logger.path
@@ -199,9 +192,11 @@ systemctl daemon-reload
 %{_libdir}/libdlog.so.0.0.0
 %attr(664,log,log) %{TZ_SYS_ETC}/dlog.conf
 /usr/share/license/%{name}
+%if %{?backend_kmsg} == ON
 %attr(700,log,log) %{_sbindir}/dloginit
 %attr(-,log,log) %{_unitdir}/dloginit.service
 %{_unitdir}/sysinit.target.wants/dloginit.service
+%endif
 
 %files -n libdlog-devel
 %{_includedir}/dlog/dlog.h
diff --git a/packaging/dlog_logger.conf.in b/packaging/dlog_logger.conf.in
deleted file mode 100755 (executable)
index a3eecd1..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-dlogutil -b system -r 5120 -n 1 -f /var/log/dlog/system -v threadtime *:I
-dlogutil -b main -r 3072 -n 1 -f /var/log/dlog/main -v threadtime *:W
-dlogutil -b radio -r 1024 -n 1 -f /var/log/dlog/radio -v threadtime
index e9cb000..3ed654c 100644 (file)
@@ -2,4 +2,4 @@
 Description=Path activation for dlog_logger
 
 [Path]
-PathExists=/run/dloginit.conf
+PathExists=/run/dlog.conf
diff --git a/scripts/dlogctrl.in b/scripts/dlogctrl.in
deleted file mode 100755 (executable)
index 9cac6f0..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/bin/sh
-
-MODE=none
-OBJ=none
-VAL=none
-CONFIG_PATH=@TZ_SYS_ETC@
-
-function Usage()
-{
-       /bin/echo "Usage: dlogctrl {get|set} {platformlog | loglimiter } {on|off}"
-       exit 1
-}
-
-case "$1" in
-get)
-       MODE=get
-;;
-set)
-       MODE=set
-;;
-*)
-       Usage
-esac
-
-case "$2" in
-platformlog)
-       OBJ=PlatformLogs
-;;
-loglimiter)
-       OBJ=LogLimiter
-;;
-*)
-       Usage
-esac
-
-if [ "$MODE" = "set" ]; then
-       case "$3" in
-       1|on)
-               VAL=on
-       ;;
-       0|off)
-               VAL=off
-       ;;
-       *)
-               Usage
-       esac
-
-       echo "Setting $OBJ=$VAL"
-       /bin/sed "s/$OBJ[\t ]*[onf]*/$OBJ $VAL/" < "$CONFIG_PATH/dlog.conf" > /tmp/dlog.conf.new
-       /bin/cp /tmp/dlog.conf.new "$CONFIG_PATH/dlog.conf"
-       /bin/sync
-       echo "You must reboot this target to apply the change!"
-else
-       case "$(grep "$OBJ" "$CONFIG_PATH/dlog.conf" | awk '{ print $2 }')" in
-       on)
-               /bin/echo "1"
-       ;;
-       off)
-               /bin/echo "0"
-       ;;
-       esac
-fi
-
-exit 0
index e866ec3..d62e456 100755 (executable)
@@ -17,6 +17,7 @@
  */
 
 #include <pthread.h>
+#include <stdlib.h>
 
 #include <dlog.h>
 #include <logcommon.h>
@@ -29,7 +30,7 @@
 /*
  * @brief Points to a function which writes a log message
  * @details The function pointed to depends on the backend used
- * @param log_id ID of the buffer to log to. Belongs to [0, LOG_ID_MAX)
+ * @param log_id ID of the buffer to log to. Belongs to (LOG_ID_INVALID, LOG_ID_MAX) non-inclusive
  * @param prio Priority of the message.
  * @param tag The message tag, identifies the sender.
  * @param msg The contents of the message.
  * @seealso __dlog_init_backend
  */
 int (*write_to_log)(log_id_t log_id, log_priority prio, const char *tag, const char *msg);
-
-static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
-static struct log_config config;
+pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
 extern void __dlog_init_backend();
 
+static int limiter;
+static int plog;
+
 static int __write_to_log_null(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
 {
        return DLOG_ERROR_NOT_PERMITTED;
 }
 
+static int __config_iteration(const char* key, const char* value)
+{
+       const int prefix_len = strlen("limiter|");
+       char * delimiter_pos;
+       char limiter_tag [MAX_CONF_KEY_LEN];
+       int limit;
+
+       if (!strcmp(key, "limiter|"))
+               return 1;
+
+       delimiter_pos = strchr(key + prefix_len + 1, '|');
+       if (!delimiter_pos || (delimiter_pos + 1 == key + strlen(key)))
+               return 1;
+
+       snprintf(limiter_tag, delimiter_pos - (key + prefix_len), "%s", key + prefix_len);
+
+       if (!strcmp(value, "allow"))
+               limit = __LOG_LIMITER_LIMIT_MAX + 1;
+       else if (!strcmp(value, "deny" ))
+               limit = 0;
+       else
+               limit = atoi(value);
+
+       __log_limiter_add_rule(limiter_tag, *(delimiter_pos + 1), limit);
+       return 0;
+}
+
 static void __configure(void)
 {
-       if (0 > __log_config_read(LOG_CONFIG_FILE, &config)) {
-               config.lc_limiter = 0;
-               config.lc_plog = 0;
-       }
+       struct log_config conf;
+       const char * conf_value;
 
-       if (config.lc_limiter) {
-               if (0 > __log_limiter_initialize())
-                       config.lc_limiter = 0;
-       }
+       limiter = 0;
+       plog = 0;
+
+       if (!log_config_read(&conf))
+               return;
+
+       conf_value = log_config_get (&conf, "plog");
+       if (!conf_value)
+               return;
+       plog = atoi (conf_value);
+
+       conf_value = log_config_get (&conf, "limiter");
+       if (!conf_value)
+               return;
+       limiter = atoi (conf_value);
+
+       log_config_foreach(&conf, __config_iteration);
+       log_config_free (&conf);
+
+       if (limiter && (0 > __log_limiter_initialize()))
+               limiter = 0;
 }
 
 static void __dlog_init(void)
@@ -90,10 +134,10 @@ static int dlog_should_log(log_id_t log_id, const char* tag, int prio)
        if (log_id == LOG_ID_INVALID || LOG_ID_MAX <= log_id)
                return DLOG_ERROR_INVALID_PARAMETER;
 
-       if (log_id != LOG_ID_APPS && !config.lc_plog)
+       if (log_id != LOG_ID_APPS && !plog)
                return DLOG_ERROR_NOT_PERMITTED;
 
-       if (config.lc_limiter) {
+       if (limiter) {
                should_log = __log_limiter_pass_log(tag, prio);
 
                if (!should_log) {
index 4df1921..ec393ca 100644 (file)
@@ -3,11 +3,11 @@
 
 #include <dlog.h>
 #include <logcommon.h>
+#include <logconfig.h>
 
 extern int (*write_to_log)(log_id_t, log_priority, const char *tag, const char *msg);
 
 static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1 };
-static char log_devs[LOG_ID_MAX][PATH_MAX];
 
 static int __write_to_log_android(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
 {
@@ -45,20 +45,36 @@ static int __write_to_log_android(log_id_t log_id, log_priority prio, const char
 
 void __dlog_init_backend()
 {
-       if (0 == get_log_dev_names(log_devs)) {
-               log_fds[LOG_ID_MAIN]   = open(log_devs[LOG_ID_MAIN],   O_WRONLY);
-               log_fds[LOG_ID_SYSTEM] = open(log_devs[LOG_ID_SYSTEM], O_WRONLY);
-               log_fds[LOG_ID_RADIO]  = open(log_devs[LOG_ID_RADIO],  O_WRONLY);
-               log_fds[LOG_ID_APPS]   = open(log_devs[LOG_ID_APPS],   O_WRONLY);
+       struct log_config conf;
+       log_id_t buf_id;
+
+       if (!log_config_read (&conf))
+               return;
+
+       for (buf_id = 0; buf_id < LOG_ID_MAX; ++buf_id) {
+               const char * const buffer_name = log_config_get(&conf, log_name_by_id(buf_id));
+
+               if (!buffer_name) {
+                       char err_message [MAX_CONF_VAL_LEN + 64];
+                       snprintf (err_message, MAX_CONF_VAL_LEN + 64, "LOG BUFFER #%d %s HAS NO PATH SET IN CONFIG", buf_id, buffer_name);
+                       syslog_critical_failure (err_message);
+                       return;
+               }
+
+               log_fds[buf_id] = open(buffer_name, O_WRONLY);
        }
-       if (log_fds[LOG_ID_MAIN] >= 0)
-               write_to_log = __write_to_log_android;
-
-       if (log_fds[LOG_ID_RADIO]  < 0)
-               log_fds[LOG_ID_RADIO]  = log_fds[LOG_ID_MAIN];
-       if (log_fds[LOG_ID_SYSTEM] < 0)
-               log_fds[LOG_ID_SYSTEM] = log_fds[LOG_ID_MAIN];
-       if (log_fds[LOG_ID_APPS]   < 0)
-               log_fds[LOG_ID_APPS]   = log_fds[LOG_ID_MAIN];
+
+       log_config_free (&conf);
+
+       if (log_fds[LOG_ID_MAIN] < 0) {
+               syslog_critical_failure ("COULD NOT OPEN MAIN LOG");
+               return;
+       }
+
+       write_to_log = __write_to_log_android;
+
+       for (buf_id = 0; buf_id < LOG_ID_MAX; ++buf_id)
+               if ((buf_id != LOG_ID_MAIN) && (log_fds[buf_id] < 0))
+                       log_fds[buf_id] = log_fds[LOG_ID_MAIN];
 }
 
index afe3712..4e9f249 100644 (file)
@@ -3,11 +3,11 @@
 
 #include <dlog.h>
 #include <logcommon.h>
+#include <logconfig.h>
 
 extern int (*write_to_log)(log_id_t, log_priority, const char *tag, const char *msg);
 
 static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1 };
-static char log_devs[LOG_ID_MAX][PATH_MAX];
 
 static int __write_to_log_kmsg(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
 {
@@ -53,20 +53,36 @@ static int __write_to_log_kmsg(log_id_t log_id, log_priority prio, const char *t
 
 void __dlog_init_backend()
 {
-       if (0 == get_log_dev_names(log_devs)) {
-               log_fds[LOG_ID_MAIN]   = open(log_devs[LOG_ID_MAIN],   O_WRONLY);
-               log_fds[LOG_ID_SYSTEM] = open(log_devs[LOG_ID_SYSTEM], O_WRONLY);
-               log_fds[LOG_ID_RADIO]  = open(log_devs[LOG_ID_RADIO],  O_WRONLY);
-               log_fds[LOG_ID_APPS]   = open(log_devs[LOG_ID_APPS],   O_WRONLY);
+       struct log_config conf;
+       log_id_t buf_id;
+
+       if (!log_config_read (&conf))
+               return;
+
+       for (buf_id = 0; buf_id < LOG_ID_MAX; ++buf_id) {
+               const char * const buffer_name = log_config_get(&conf, log_name_by_id(buf_id));
+
+               if (!buffer_name) {
+                       char err_message [MAX_CONF_VAL_LEN + 64];
+                       snprintf (err_message, MAX_CONF_VAL_LEN + 64, "LOG BUFFER #%d %s HAS NO PATH SET IN CONFIG", buf_id, buffer_name);
+                       syslog_critical_failure (err_message);
+                       return;
+               }
+
+               log_fds[buf_id] = open(buffer_name, O_WRONLY);
        }
-       if (log_fds[LOG_ID_MAIN] >= 0)
-               write_to_log = __write_to_log_kmsg;
-
-       if (log_fds[LOG_ID_RADIO]  < 0)
-               log_fds[LOG_ID_RADIO]  = log_fds[LOG_ID_MAIN];
-       if (log_fds[LOG_ID_SYSTEM] < 0)
-               log_fds[LOG_ID_SYSTEM] = log_fds[LOG_ID_MAIN];
-       if (log_fds[LOG_ID_APPS]   < 0)
-               log_fds[LOG_ID_APPS]   = log_fds[LOG_ID_MAIN];
+
+       log_config_free (&conf);
+
+       if (log_fds[LOG_ID_MAIN] < 0) {
+               syslog_critical_failure ("COULD NOT OPEN MAIN LOG");
+               return;
+       }
+
+       write_to_log = __write_to_log_kmsg;
+
+       for (buf_id = 0; buf_id < LOG_ID_MAX; ++buf_id)
+               if ((buf_id != LOG_ID_MAIN) && (log_fds[buf_id] < 0))
+                       log_fds[buf_id] = log_fds[LOG_ID_MAIN];
 }
 
diff --git a/src/libdlog/logconfig.c b/src/libdlog/logconfig.c
deleted file mode 100755 (executable)
index fabac0d..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * DLOG
- * Copyright (c) 2013 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "logconfig.h"
-#include "loglimiter.h"
-
-/* Functions possible return value */
-#define RET_ERROR                      (-1)
-#define RET_SUCCESS                    0
-
-#define CONFIG_LINE_MAX_LEN            256
-#define CONFIG_OPTION_MAX_LEN          64
-
-/* Shortcut macros */
-#define isCOMMENT(c)                   ('#' == c)
-#define isNEWLINE(c)                   ('\n' == c || '\r' == c)
-
-/* Dlog options definition */
-#define LOG_PLATFORM_STRING            "PlatformLogs"
-#define LOG_LIMITER_STRING             "LogLimiter"
-
-/* Define options possible values */
-#define ALLOW_STRING                   "allow"
-#define DENY_STRING                    "deny"
-#define ON_STRING                      "on"
-#define OFF_STRING                     "off"
-#define isYES(c)                       (c == '1')
-#define isNO(c)                        (c == '0')
-
-
-static int log_config_multiplex_opt(char* opt_str, char* val_str, int prio,
-               struct log_config* config)
-{
-       int value = 0;
-
-       /* There are only two ways to interpret the lines, so make here a short circuit */
-       if (0 < prio) { /* Is it a rule or an option  ? */
-               /* For the filtering rule ... */
-
-               if (!strncasecmp(ALLOW_STRING, val_str, sizeof(ALLOW_STRING))) {
-                       value = __LOG_LIMITER_LIMIT_MAX + 1;
-               } else if (!strncasecmp(DENY_STRING, val_str, sizeof(DENY_STRING))) {
-                       value = 0;
-               } else {
-                       char* endptr = NULL;
-
-                       value = strtoul(val_str, &endptr, 0);
-                       if (*endptr != '\0')
-                               return RET_ERROR;
-               }
-
-               return __log_limiter_add_rule(opt_str, prio, value);
-
-       } else { /* It's an option then */
-               if (isYES(*val_str)) {
-                       value = 1;
-               } else if (isNO(*val_str)) {
-                       value = 0;
-               } else if (!strncasecmp(ON_STRING, val_str, sizeof(ON_STRING))) {
-                       value = 1;
-               } else if (!strncasecmp(OFF_STRING, val_str, sizeof(OFF_STRING))) {
-                       value = 0;
-               } else {
-                       return RET_ERROR;
-               }
-
-               if (!strncasecmp(LOG_PLATFORM_STRING, opt_str,
-                                       sizeof(LOG_PLATFORM_STRING))) {
-                       config->lc_plog = value;
-               } else if (!strncasecmp(LOG_LIMITER_STRING, opt_str,
-                                       sizeof(LOG_LIMITER_STRING))) {
-                       config->lc_limiter = value;
-               } else {
-                       return RET_ERROR;
-               }
-       }
-
-       return RET_SUCCESS;
-}
-
-/* Function returns 0 for success or -1 when error occurred */
-int __log_config_read(const char* config_file, struct log_config* config)
-{
-       FILE* fconfig = NULL;
-       char buf[CONFIG_LINE_MAX_LEN];
-       char opt[CONFIG_OPTION_MAX_LEN];
-       char opt_value[CONFIG_OPTION_MAX_LEN];
-       int prio = (-1);
-       int ret = 0;
-
-       /* Check input */
-       if (NULL == config_file || NULL == config) {
-               return RET_ERROR;
-       }
-
-       if (NULL == (fconfig = fopen(config_file, "r"))) {
-               return RET_ERROR;
-       }
-
-       while (1) {
-               memset(buf, 0, CONFIG_LINE_MAX_LEN);
-               errno = 0;
-               if (NULL == fgets(buf, CONFIG_LINE_MAX_LEN, fconfig)) {
-                       if (!errno) {
-                               break;
-                       }
-                       goto bailout;
-               }
-
-               /* We ignore comments and blank lines */
-               if (isCOMMENT(*buf) || isNEWLINE(*buf)) {
-                       continue;
-               }
-
-               memset(opt, 0, sizeof(opt));
-               memset(opt_value, 0, sizeof(opt_value));
-               prio = (-1);
-               /* Read configure line, sscanf() should return two tokens,
-                * even for tag filtering rule */
-               ret = sscanf(buf, "%[A-z0-9-]\t%[A-z0-9]", opt, opt_value);
-               if (ret != 2) { /* The line is malformed ? */
-                       char c = 0;
-                       /* This could be rule with space inside TAG */
-                       ret = sscanf(buf, "\"%[]A-z0-9*\x20_+:;/-]\"\t|\t%c\t%[A-z0-9]",
-                                       opt, &c, opt_value);
-                       if (ret != 3) {
-                               goto bailout;
-                       }
-                       prio = (int)c;
-               }
-
-
-               if (0 > log_config_multiplex_opt(opt, opt_value, prio, config)) {
-                       goto bailout;
-               }
-       }
-
-       fclose(fconfig);
-       return RET_SUCCESS;
-
-bailout:
-       /* These actions should warranty that
-          we cleanly handle initialization errors */
-       fclose(fconfig);
-       /* Clean rules list to prevent log limiter initialization,
-          if configuration error occured. */
-       __log_limiter_rules_purge();
-
-       return RET_ERROR;
-}
index 85c1c51..627982c 100755 (executable)
@@ -33,9 +33,7 @@
 /* Included for priorities level */
 #include <dlog.h>
 #include "loglimiter.h"
-
-/* Defines maximal meaningful tag length */
-#define TAG_REASONABLE_LEN        32
+#include <logconfig.h>
 
 /* Some random big odd number to make hash more diverse */
 #define HASH_MAGIC_THINGY         5237231
@@ -52,7 +50,7 @@ struct rule {
        int limit;
        int hit;
        time_t start;
-       char tag[TAG_REASONABLE_LEN];
+       char tag[MAX_CONF_KEY_LEN];
 };
 
 typedef int (*hash_cmp_func_t)(struct rule*, struct rule*);
@@ -314,7 +312,7 @@ int __log_limiter_add_rule(const char* tag, int prio, int limit)
 
        memset(r, 0, sizeof(struct rule));
 
-       snprintf(r->tag, TAG_REASONABLE_LEN, "%s", tag);
+       snprintf(r->tag, MAX_CONF_KEY_LEN, "%s", tag);
        r->prio = util_prio_to_char(prio);
        r->hash = util_hash_key(tag, r->prio);
        r->limit = limit;
diff --git a/src/logctrl/logctrl.c b/src/logctrl/logctrl.c
new file mode 100644 (file)
index 0000000..9e6a76a
--- /dev/null
@@ -0,0 +1,134 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <logconfig.h>
+
+void print_help ()
+{
+       printf ("dlogctrl - provides control over dlog configuration. Options:\n"
+               "\t-p        Precludes -k. Prints all entries in the config.\n"
+               "\t-k key    Precludes -p and requires one of -gs.  Specifies a config key.\n"
+               "\t-g        Requires -k, precludes -cs. Gets and prints the value of the entry assigned to the key.\n"
+               "\t-s value  Requires -k, precludes -cg. Sets the value of the entry associated with the key.\n"
+               "\t-c        Requires -k, precludes -gs. Clears the entry.\n"
+               "Having either -p or -k is mandatory.\n"
+       );
+}
+
+struct options {
+       int print_all;
+       int has_key;
+       int should_get;
+       int should_set;
+       int should_clear;
+};
+
+int validate (struct options o) {
+       int valid = 1;
+
+       if (!o.has_key && !o.print_all) {
+               printf ("Having either -p or -k is mandatory!\n");
+               valid = 0;
+       }
+       if (o.has_key && !(o.should_get || o.should_set || o.should_clear)) {
+               printf ("-k requires either -c, -g, or -s!\n");
+               valid = 0;
+       }
+       if (o.has_key && o.print_all) {
+               printf ("-p and -k preclude each other!\n");
+               valid = 0;
+       }
+       if (o.should_set + o.should_get + o.should_clear > 1) {
+               printf ("-c, -g and -s preclude each other!\n");
+               valid = 0;
+       }
+       if (!o.has_key && (o.should_set || o.should_get || o.should_clear)) {
+               printf ("-c, -g and -s require -k!\n");
+               valid = 0;
+       }
+
+       return valid;
+}
+
+int main (int argc, char ** argv)
+{
+       struct log_config conf;
+       char key [MAX_CONF_KEY_LEN];
+       char val [MAX_CONF_VAL_LEN];
+       struct options opt = {0,0,0,0,0};
+       const char * filename = getenv ("DLOG_CONFIG_PATH") ?: get_config_filename (CONFIG_TYPE_COMMON);
+
+       if (argc == 1) {
+               print_help (argv[0]);
+               return 0;
+       }
+
+       for (;;) {
+               int ret = getopt(argc, argv, "pt:k:gs:c");
+
+               if (ret < 0)
+                       break;
+
+               switch (ret) {
+               case 'p':
+                       opt.print_all = 1;
+                       break;
+               case 'k':
+                       snprintf (key, MAX_CONF_KEY_LEN, "%s", optarg);
+                       opt.has_key = 1;
+                       break;
+               case 'g':
+                       opt.should_get = 1;
+                       break;
+               case 'c':
+                       opt.should_clear = 1;
+                       break;
+               case 's':
+                       opt.should_set = 1;
+                       snprintf(val, MAX_CONF_VAL_LEN, "%s", optarg);
+                       break;
+               }
+       }
+
+       if (!validate(opt)) {
+               print_help (argv[0]);
+               return 1;
+       }
+
+       if (!log_config_read (&conf)) {
+               printf ("Error: cannot open the config file!\n");
+               return 1;
+       }
+
+       if (opt.print_all) {
+               log_config_print_out (&conf);
+       } else if (opt.should_get) {
+               if (!log_config_print_key (&conf, key))
+                       goto err_entry;
+       } else if (opt.should_clear) {
+               if (!log_config_remove(&conf, key))
+                       goto err_entry;
+               if (!log_config_write (&conf, filename))
+                       goto err_save;
+       } else if (opt.should_set) {
+               if (!log_config_set(&conf, key, val))
+                       log_config_push(&conf, key, val);
+               if (!log_config_write (&conf, filename))
+                       goto err_save;
+       } else {
+               printf ("Error: invalid options\n");
+               return 1;
+       }
+
+       return 0;
+
+err_save:
+       printf("Cannot save file\n");
+       return 1;
+
+err_entry:
+       printf ("Entry not found\n");
+       return 1;
+}
index 9f97e02..bd38c41 100755 (executable)
@@ -37,6 +37,7 @@
 #include <log_file.h>
 #include <logprint.h>
 #include <dlog_ioctl.h>
+#include <logconfig.h>
 
 #define COMMAND_MAX 5
 #define DELIMITER " "
@@ -46,8 +47,6 @@
 #define BUFFER_MAX 100
 #define INTERVAL_MAX 60*60
 
-#define CONFIG_FILE TZ_SYS_ETC"/dlog_logger.conf"
-
 #define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
 
 struct log_command {
@@ -80,7 +79,7 @@ struct log_device {
        struct log_device *next;
 };
 
-static char device_path_table[LOG_ID_MAX][PATH_MAX];
+static struct log_config conf;
 
 static struct log_work *works;
 static struct log_device *devices;
@@ -186,7 +185,7 @@ static void maybe_print_start(struct log_device *dev)
                        logwork->printed = true;
                        snprintf(buf, sizeof(buf),
                                        "--------- beginning of %s\n",
-                                       device_path_table[dev->id]);
+                                       log_config_get(&conf, log_name_by_id(dev->id)));
                        if (write(logwork->file.fd, buf, strlen(buf)) < 0) {
                                _E("maybe work error");
                                exit(EXIT_FAILURE);
@@ -463,10 +462,10 @@ static struct log_device *device_new(int id)
                return NULL;
        }
        dev->id = id;
-       dev->fd = open(device_path_table[id], O_RDONLY);
+       dev->fd = open(log_config_get(&conf, log_name_by_id(id)), O_RDONLY);
        if (dev->fd < 0) {
                _E("Unable to open log device %s (%d)",
-                               device_path_table[id],
+                               log_config_get(&conf, log_name_by_id(id)),
                                errno);
                free(dev);
                return NULL;
@@ -478,7 +477,7 @@ static struct log_device *device_new(int id)
 
        get_log_read_size_max(dev->fd, &dev->log_read_size_max);
        _D("device %s log read size max %u\n",
-          device_path_table[id], dev->log_read_size_max);
+          log_config_get(&conf, log_name_by_id(id)), dev->log_read_size_max);
 
 #if DLOG_BACKEND_KMSG
        off_t off;
@@ -486,7 +485,7 @@ static struct log_device *device_new(int id)
        off = lseek(dev->fd, 0, SEEK_DATA);
        if (off == -1) {
                _E("Unable to lseek device %s. %d\n",
-                  device_path_table[id], errno);
+                  log_config_get(&conf, log_name_by_id(id)), errno);
                exit(EXIT_FAILURE);
        }
 #endif
@@ -523,13 +522,13 @@ static void device_add(int id)
                        devices = device_new(id);
                        if (devices == NULL) {
                                _E("failed to device_new: %s\n",
-                                               device_path_table[id]);
+                                               log_config_get(&conf, log_name_by_id(id)));
                                exit(EXIT_FAILURE);
                        }
        } else {
                if (device_add_to_tail(devices, device_new(id)) < 0) {
                        _E("failed to device_add_to_tail: %s\n",
-                                       device_path_table[id]);
+                                       log_config_get(&conf, log_name_by_id(id)));
                        exit(EXIT_FAILURE);
                }
        }
@@ -582,7 +581,7 @@ static void device_chain_free(struct log_device *dev)
  * parse command line
  * using getopt function
  */
-static int parse_command_line(char *linebuffer, struct log_command *cmd)
+static int parse_command_line(char const *linebuffer, struct log_command *cmd)
 {
        int i, ret, id, argc;
        char *argv[MAX_ARGS];
@@ -720,32 +719,29 @@ exit_free:
  */
 static int parse_command(struct log_command *command_list)
 {
-       FILE *fp;
+       struct log_config conf;
+       char conf_key [MAX_CONF_KEY_LEN];
+       const char * conf_val;
        int ncmd;
-       char *line_p;
-       char linebuffer[1024];
 
-       fp = fopen(CONFIG_FILE, "re");
-       if (!fp) {
-               _E("no config file\n");
-               goto exit;
-       }
+       if (!log_config_read (&conf))
+               return 0;
+
        ncmd = 0;
-       while (fgets(linebuffer, sizeof(linebuffer), fp) != NULL) {
-               line_p = strchr(linebuffer, '\n');
-               if (line_p != NULL)
-                       *line_p = '\0';
-               if (parse_command_line(linebuffer, &command_list[ncmd]) == 0)
+       while (1) {
+               sprintf (conf_key, "dlog_logger_conf_%d", ncmd);
+               conf_val = log_config_get (&conf, conf_key);
+               if (!conf_val)
+                       break;
+               if (parse_command_line(conf_val, &command_list[ncmd]) == 0)
                        ncmd++;
                if (COMMAND_MAX <= ncmd)
                        break;
        }
-       fclose(fp);
 
-       return ncmd;
+       log_config_free (&conf);
 
-exit:
-       return 0;
+       return ncmd;
 }
 
 /*
@@ -864,7 +860,7 @@ int main(int argc, char **argv)
        if (!ncmd)
                goto exit;
 
-       if (0 != get_log_dev_names(device_path_table))
+       if (!log_config_read (&conf))
                goto exit;
 
        /* create log device */
index 401ff27..cd1e326 100755 (executable)
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 #include <libudev.h>
 
 #include <logcommon.h>
+#include <logconfig.h>
 #include <dlog.h>
 
-#ifdef DLOG_BACKEND_KMSG
-
-#define DEV_KMSG       "/dev/kmsg"
+#define DEV_KMSG    "/dev/kmsg"
+#define BACKUP_SIZE 1048576
 
 int g_minors[LOG_ID_MAX] = {-1, -1, -1, -1};
 
-static int create_kmsg_devs(int fd)
+static int create_kmsg_devs(int fd, struct log_config *conf)
 {
        int i;
        struct kmsg_cmd_buffer_add cmd = {
-               .size = 1024*256,
                .mode = 0662,
        };
 
        for (i = 0; i < LOG_ID_MAX; i++) {
+               char key [MAX_CONF_KEY_LEN];
+               const char *size_str;
+               char *size_str_end;
+
+               snprintf (key, MAX_CONF_KEY_LEN, "%s_size", log_name_by_id(i));
+               size_str = log_config_get (conf, key);
+               errno = 0;
+
+               if (!size_str) {
+                       cmd.size = BACKUP_SIZE;
+               } else {
+                       cmd.size = strtol(size_str, &size_str_end, 10);
+                       if (errno || (cmd.size <= 0) || (*size_str_end != '\0'))
+                               cmd.size = BACKUP_SIZE;
+               }
+
                if (0 > ioctl(fd, KMSG_CMD_BUFFER_ADD, &cmd)) {
                        _E("ioctl KMSG_CMD_BUFFER_ADD failed. (%d)\n", errno);
                        return -1;
@@ -66,58 +82,14 @@ static void remove_kmsg_devs(int fd)
        }
 }
 
-static int write_config_kmsg(FILE *config_file)
-{
-       return fprintf(config_file,
-                       "%s%s\n"
-                       "%s%s%d\n"
-                       "%s%s%d\n"
-                       "%s%s%d\n"
-                       "%s%s%d",
-                       LOG_TYPE_CONF_PREFIX, "kmsg",
-                       LOG_MAIN_CONF_PREFIX, DEV_KMSG, g_minors[LOG_ID_MAIN],
-                       LOG_RADIO_CONF_PREFIX, DEV_KMSG, g_minors[LOG_ID_RADIO],
-                       LOG_SYSTEM_CONF_PREFIX, DEV_KMSG, g_minors[LOG_ID_SYSTEM],
-                       LOG_APPS_CONF_PREFIX, DEV_KMSG, g_minors[LOG_ID_APPS]);
-}
-
-#elif DLOG_BACKEND_LOGGER
-
-static void write_config_logger(FILE *config_file)
-{
-       fprintf(config_file,
-                       "%s%s\n"
-                       "%s%s\n"
-                       "%s%s\n"
-                       "%s%s\n"
-                       "%s%s",
-                       LOG_TYPE_CONF_PREFIX,   "logger",
-                       LOG_MAIN_CONF_PREFIX,   "/dev/log_main",
-                       LOG_RADIO_CONF_PREFIX,  "/dev/log_radio",
-                       LOG_SYSTEM_CONF_PREFIX, "/dev/log_system",
-                       LOG_APPS_CONF_PREFIX,   "/dev/log_apps");
-}
-
-#elif DLOG_BACKEND_JOURNAL
-
-static void write_config_journal(FILE *config_file)
-{
-       fprintf(config_file, "%s%s",
-                       LOG_TYPE_CONF_PREFIX, "journal");
-}
-
-#endif
-
 int main()
 {
-       FILE *config_file = fopen(KMSG_DEV_CONFIG_FILE, "w");
-       if (!config_file) {
-               _E("Unable to open %s config file\n", KMSG_DEV_CONFIG_FILE);
-               exit(EXIT_FAILURE);
-       }
+       int kmsg_fd, i;
+       struct log_config conf_in;
+       struct log_config conf_out;
 
-#ifdef DLOG_BACKEND_KMSG
-       int kmsg_fd;
+       log_config_read (&conf_in);
+       memset (&conf_out, 0, sizeof(struct log_config));
 
        kmsg_fd = open(DEV_KMSG, O_RDWR);
        if (kmsg_fd < 0) {
@@ -125,25 +97,26 @@ int main()
                exit(EXIT_FAILURE);
        }
 
-       if (0 > create_kmsg_devs(kmsg_fd))
+       if (0 > create_kmsg_devs(kmsg_fd, &conf_in))
                goto error;
 
-       if (0 > write_config_kmsg(config_file))
-               goto error;
+       for (i = 0; i < LOG_ID_MAX; ++i) {
+               char key [MAX_CONF_KEY_LEN];
+               char val [MAX_CONF_VAL_LEN];
 
-       return 0;
+               snprintf(key, MAX_CONF_KEY_LEN, "%s_size", log_name_by_id(i));
+               snprintf(val, MAX_CONF_VAL_LEN, "%s", log_config_get (&conf_in, key));
+               log_config_push (&conf_out, key, val);
 
-error:
-       remove_kmsg_devs(kmsg_fd);
-       exit(EXIT_FAILURE);
+               snprintf(val, MAX_CONF_VAL_LEN, "%s%d", DEV_KMSG, g_minors[i]);
+               log_config_push (&conf_out, log_name_by_id(i), val);
+       }
 
-#elif DLOG_BACKEND_LOGGER
-       write_config_logger(config_file);
-       return 0;
+       log_config_write (&conf_out, get_config_filename (CONFIG_TYPE_KMSG));
 
-#elif DLOG_BACKEND_JOURNAL
-       write_config_journal(config_file);
        return 0;
 
-#endif
+error:
+       remove_kmsg_devs(kmsg_fd);
+       exit(EXIT_FAILURE);
 }
index 0c84b53..4a4591f 100755 (executable)
@@ -30,6 +30,7 @@
 #include <log_file.h>
 #include <logprint.h>
 #include <dlog_ioctl.h>
+#include <logconfig.h>
 
 #define DEFAULT_LOG_ROTATE_SIZE_KBYTES 16
 #define DEFAULT_MAX_ROTATED_LOGS 4
@@ -58,7 +59,7 @@ struct log_device_t {
        struct log_device_t* next;
 };
 
-static char g_devs[LOG_ID_MAX][PATH_MAX];
+static struct log_config conf;
 
 static void processBuffer(struct log_device_t* dev, struct logger_entry *buf)
 {
@@ -403,7 +404,7 @@ static int log_devices_add_to_tail(struct log_device_t *devices, struct log_devi
        return 0;
 }
 
-int main (int argc, char **argv)
+int main(int argc, char **argv)
 {
        int err;
        int has_set_log_format = 0;
@@ -428,8 +429,7 @@ int main (int argc, char **argv)
                show_help(argv[0]);
                exit(0);
        }
-
-       if (0 != get_log_dev_names(g_devs)) {
+       if (!log_config_read(&conf)) {
                _E("Unable to read initial configuration\n");
                exit(-1);
        }
@@ -474,14 +474,14 @@ int main (int argc, char **argv)
                                                  exit(-1);
                                          }
 
-                                         dev = log_devices_new(g_devs[id]);
+                                         dev = log_devices_new(log_config_get(&conf, log_name_by_id(id)));
                                          if (dev == NULL) {
-                                                 _E("Can't add log device: %s\n", g_devs[id]);
+                                                 _E("Can't add log device: %s\n", log_config_get(&conf, log_name_by_id(id)));
                                                  exit(-1);
                                          }
                                          if (devices) {
                                                  if (log_devices_add_to_tail(devices, dev)) {
-                                                         _E("Open log device %s failed\n", g_devs[id]);
+                                                         _E("Open log device %s failed\n", log_config_get(&conf, log_name_by_id(id)));
                                                          exit(-1);
                                                  }
                                          } else {
@@ -543,9 +543,9 @@ int main (int argc, char **argv)
        }
 
        if (!devices) {
-               devices = log_devices_new(g_devs[LOG_ID_MAIN]);
+               devices = log_devices_new(log_config_get(&conf, log_name_by_id(LOG_ID_MAIN)));
                if (devices == NULL) {
-                       _E("Can't add log device: %s\n", g_devs[LOG_ID_MAIN]);
+                       _E("Can't add log device: %s\n", log_config_get(&conf, log_name_by_id(LOG_ID_MAIN)));
                        exit(-1);
                }
                g_dev_count = 1;
@@ -554,15 +554,15 @@ int main (int argc, char **argv)
                        accessmode = W_OK;
 
                /* only add this if it's available */
-               if (0 == access(g_devs[LOG_ID_SYSTEM], accessmode)) {
-                       if (log_devices_add_to_tail(devices, log_devices_new(g_devs[LOG_ID_SYSTEM]))) {
-                               _E("Can't add log device: %s\n", g_devs[LOG_ID_SYSTEM]);
+               if (0 == access(log_config_get(&conf, log_name_by_id(LOG_ID_SYSTEM)), accessmode)) {
+                       if (log_devices_add_to_tail(devices, log_devices_new(log_config_get(&conf, log_name_by_id(LOG_ID_SYSTEM))))) {
+                               _E("Can't add log device: %s\n", log_config_get(&conf, log_name_by_id(LOG_ID_SYSTEM)));
                                exit(-1);
                        }
                }
-               if (0 == access(g_devs[LOG_ID_APPS], accessmode)) {
-                       if (log_devices_add_to_tail(devices, log_devices_new(g_devs[LOG_ID_APPS]))) {
-                               _E("Can't add log device: %s\n", g_devs[LOG_ID_APPS]);
+               if (0 == access(log_config_get(&conf, log_name_by_id(LOG_ID_APPS)), accessmode)) {
+                       if (log_devices_add_to_tail(devices, log_devices_new(log_config_get(&conf, log_name_by_id(LOG_ID_APPS))))) {
+                               _E("Can't add log device: %s\n", log_config_get(&conf, log_name_by_id(LOG_ID_APPS)));
                                exit(-1);
                        }
                }
index 109c809..6d27af5 100644 (file)
  */
 
 #include <string.h>
+#include <syslog.h>
 
 #include <logcommon.h>
 
 #define MAX_PREFIX_SIZE 32
 #define LINE_MAX        (MAX_PREFIX_SIZE+PATH_MAX)
 
-static char* get_dev_from_line(char *line, char *prefix)
-{
-       size_t len = strlen(prefix);
-       if (strncmp(line, prefix, len))
-               return NULL;
-       return line + len;
-}
+static struct {
+       log_id_t id;
+       char * name;
+} logid_map [] = {
+       { .id = LOG_ID_MAIN,   .name = "main" },
+       { .id = LOG_ID_RADIO,  .name = "radio" },
+       { .id = LOG_ID_SYSTEM, .name = "system" },
+       { .id = LOG_ID_APPS,   .name = "apps" },
+};
 
-int get_log_dev_names(char devs[LOG_ID_MAX][PATH_MAX])
+log_id_t log_id_by_name(const char *name)
 {
-       int i;
-       FILE *config_file;
-       char line[LINE_MAX];
-
-       for (i = 0; i < LOG_ID_MAX; i++)
-               devs[i][0] = '\0';
-
-       config_file = fopen(KMSG_DEV_CONFIG_FILE, "r");
-       if (!config_file)
-               return -1;
-
-       while (fgets(line, LINE_MAX, config_file)) {
-               char *dev;
-               int len = strlen(line);
+       log_id_t i;
 
-               if (line[0] == '\n' || line[0] == '#')
-                       continue;
+       for (i = 0; i < LOG_ID_MAX; ++i)
+               if (!strcmp (name, logid_map[i].name))
+                       return logid_map[i].id;
 
-               if (line[len-1] == '\n')
-                       line[len-1] = '\0';
-
-               dev = get_dev_from_line(line, LOG_TYPE_CONF_PREFIX);
-               if (dev)
-                       continue;
-
-               dev = get_dev_from_line(line, LOG_MAIN_CONF_PREFIX);
-               if (dev) {
-                       strncpy(devs[LOG_ID_MAIN], dev, PATH_MAX);
-                       continue;
-               }
-               dev = get_dev_from_line(line, LOG_RADIO_CONF_PREFIX);
-               if (dev) {
-                       strncpy(devs[LOG_ID_RADIO], dev, PATH_MAX);
-                       continue;
-               }
-               dev = get_dev_from_line(line, LOG_SYSTEM_CONF_PREFIX);
-               if (dev) {
-                       strncpy(devs[LOG_ID_SYSTEM], dev, PATH_MAX);
-                       continue;
-               }
-               dev = get_dev_from_line(line, LOG_APPS_CONF_PREFIX);
-               if (dev) {
-                       strncpy(devs[LOG_ID_APPS], dev, PATH_MAX);
-                       continue;
-               }
-
-               goto error;
-       }
+       return LOG_ID_INVALID;
+}
 
-       for (i = 0; i < LOG_ID_MAX; i++) {
-               if (devs[i][0] == '\0')
-                       goto error;
-       }
+char * log_name_by_id (log_id_t id)
+{
+       log_id_t i;
 
-       fclose(config_file);
-       return 0;
+       for (i = 0; i < LOG_ID_MAX; ++i)
+               if (id == logid_map[i].id)
+                       return logid_map[i].name;
 
-error:
-       fclose(config_file);
-       return -1;
+       return "";
 }
 
-log_id_t log_id_by_name(const char *name)
+/* Sends a message to syslog in case dlog has a critical failure and cannot make its own log */
+void syslog_critical_failure (const char * message)
 {
-       if (0 == strcmp(name, "main"))
-               return LOG_ID_MAIN;
-       else if (0 == strcmp(name, "radio"))
-               return LOG_ID_RADIO;
-       else if (0 == strcmp(name, "system"))
-               return LOG_ID_SYSTEM;
-       else if (0 == strcmp(name, "apps"))
-               return LOG_ID_APPS;
-       else
-               return LOG_ID_INVALID;
+       openlog (NULL, LOG_PERROR | LOG_CONS | LOG_PID | LOG_NDELAY, 0);
+       syslog (LOG_CRIT, "DLOG CRITIAL FAILURE: %s", message);
+       closelog ();
 }
diff --git a/src/shared/logconfig.c b/src/shared/logconfig.c
new file mode 100644 (file)
index 0000000..1fbfe86
--- /dev/null
@@ -0,0 +1,234 @@
+#include <logconfig.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef TZ_SYS_ETC
+#define TZ_SYS_ETC "/opt/etc"
+#endif
+
+const char * get_config_filename (config_type type)
+{
+       switch (type) {
+       case CONFIG_TYPE_COMMON:
+               return TZ_SYS_ETC "/dlog.conf";
+       case CONFIG_TYPE_KMSG:
+               return "/run/dlog.conf";
+       default:
+               return NULL;
+       }
+}
+
+struct log_conf_entry {
+       char key [MAX_CONF_KEY_LEN];
+       char value [MAX_CONF_VAL_LEN];
+       struct log_conf_entry * next;
+};
+
+const char * log_config_get (struct log_config* c, const char* key)
+{
+       struct log_conf_entry * e;
+
+       if (!c)
+               return NULL;
+
+       e = c->begin;
+       while (e)
+               if (!strcmp (e->key, key))
+                       return e->value;
+               else
+                       e = e->next;
+
+       return NULL;
+}
+
+int log_config_set (struct log_config* c, const char* key, const char* value)
+{
+       struct log_conf_entry * e;
+
+       if (!c || !key || !value)
+               return 0;
+
+       e = c->begin;
+       while (e) {
+               if (!strcmp (e->key, key)) {
+                       strncpy (e->value, value, MAX_CONF_VAL_LEN);
+                       return 1;
+               }
+               e = e->next;
+       }
+       return 0;
+}
+
+int log_config_read (struct log_config* config)
+{
+       int i;
+       int ret = 0;
+       char const * override;
+
+       if (!config)
+               return 0;
+
+       config->begin = config->last = NULL;
+
+       override = getenv ("DLOG_CONFIG_PATH");
+       if (override)
+               return log_config_read_file (config, override);
+#ifdef DLOG_BACKEND_KMSG
+       ret |= log_config_read_file (config, get_config_filename (CONFIG_TYPE_KMSG)); // fixme: ugly
+#endif
+       ret |= log_config_read_file (config, get_config_filename (CONFIG_TYPE_COMMON));
+
+       return ret;
+}
+
+int log_config_read_file (struct log_config* config, const char* filename)
+{
+       FILE * file;
+       char line [MAX_CONF_ENTRY_LEN];
+       char * tok;
+
+       if (!config)
+               return 0;
+
+       file = fopen (filename, "r");
+       if (!file)
+               return 0;
+
+       while (fgets(line, MAX_CONF_ENTRY_LEN, file)) {
+               int len = strlen (line);
+               char key [MAX_CONF_KEY_LEN];
+
+               if (len <= 1 || line[0] == '#')
+                       continue;
+
+               if (line[len - 1] == '\n')
+                       line [len - 1] = '\0';
+
+               tok = strchr (line, '=');
+               if (!tok || (tok - line > MAX_CONF_KEY_LEN))
+                       continue;
+               ++tok;
+
+               snprintf (key, tok - line, "%s", line);
+               if (!log_config_get (config, key))
+                       log_config_push (config, key, tok);
+       }
+
+       fclose (file);
+       return 1;
+}
+
+void log_config_free (struct log_config* config)
+{
+       struct log_conf_entry * current = config->begin, * prev;
+
+       while (current) {
+               prev = current;
+               current = current->next;
+               free (prev);
+       }
+}
+
+int log_config_write (struct log_config* config, char const * filename)
+{
+       FILE * file;
+       int r;
+       struct log_conf_entry * e;
+
+       if (!config)
+               return 0;
+
+       file = fopen (filename, "w");
+       if (!file)
+               return 0;
+
+       e = config->begin;
+
+       while (e) {
+               r = fprintf (file, "%s=%s\n", e->key, e->value);
+               if (r < 0)
+                       return 0;
+
+               e = e->next;
+       }
+
+       fclose (file);
+       return 1;
+}
+
+void log_config_print_out (struct log_config* config)
+{
+       struct log_conf_entry* e = config->begin;
+       while (e) {
+               printf ("[%s] = %s\n", e->key, e->value);
+               e = e->next;
+       }
+}
+
+int log_config_print_key (struct log_config* config, const char* key)
+{
+       struct log_conf_entry* e = config->begin;
+       while (e) {
+               if (!strcmp(key, e->key)) {
+                       printf ("%s\n", e->value);
+                       return 1;
+               }
+               e = e->next;
+       }
+       return 0;
+}
+
+void log_config_push (struct log_config* config, const char* key, const char* value)
+{
+       struct log_conf_entry* e = calloc (1, sizeof(struct log_conf_entry));
+       snprintf(e->key, MAX_CONF_KEY_LEN, "%s", key);
+       snprintf(e->value, MAX_CONF_VAL_LEN, "%s", value);
+
+       if (!config->last) {
+               config->begin = config->last = e;
+               return;
+       }
+
+       config->last->next = e;
+       config->last = e;
+}
+
+int log_config_remove (struct log_config* config, const char* key)
+{
+       struct log_conf_entry* prev;
+       struct log_conf_entry* e = config->begin;
+       prev = NULL;
+       while (e) {
+               if (!strcmp(key, e->key)) {
+                       if (prev)
+                               prev->next = e->next;
+                       else
+                               config->begin = e->next;
+
+                       if (e == config->last)
+                               config->last = prev;
+
+                       free (e);
+                       return 1;
+               }
+               prev = e;
+               e = e->next;
+
+       }
+       return 0;
+}
+
+int log_config_foreach (struct log_config* config, int (*func)(const char* key, const char* value))
+{
+       int r = -1;
+       struct log_conf_entry* e = config->begin;
+       while (e)
+       {
+               if (!(r = func(e->key, e->value)))
+                       break;
+
+               e = e->next;
+       }
+       return r;
+}
index 42f7d12..657188c 100755 (executable)
@@ -177,6 +177,38 @@ log_format *log_format_new(void)
        return p_ret;
 }
 
+log_format *log_format_from_format(log_format *p_format)
+{
+       log_format *p_ret;
+       FilterInfo *p_info, *p_info_old = NULL;
+
+       if (!(p_ret = log_format_new()))
+               return NULL;
+
+       *p_ret = *p_format;
+
+       p_info = p_format->filters;
+
+       while (p_info != NULL) {
+               FilterInfo *p_tmp;
+               p_tmp = filterinfo_new(p_info->mTag, p_info->mPri);
+               if (!p_tmp)
+               {
+                       log_format_free(p_ret);
+                       return NULL;
+               }
+
+               if (!p_info_old)
+                       p_format->filters = p_tmp;
+               else
+                       p_info_old->p_next = p_tmp;
+
+               p_info_old = p_tmp;
+               p_info = p_info->p_next;
+       }
+       return p_ret;
+}
+
 void log_format_free(log_format *p_format)
 {
        FilterInfo *p_info, *p_info_old;