summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-11-25 16:54:47 +0100
committerMarcel Holtmann <marcel@holtmann.org>2009-11-25 16:54:47 +0100
commit8d304343818090c3ae76b8c812e101aca3ca262d (patch)
treec7a7da6d26fcf65e1f212cee15f315391e5a2d51
parent4ca114eed5a1b092fb0e585de877a9db6281bb62 (diff)
downloadconnman-8d304343818090c3ae76b8c812e101aca3ca262d.tar.gz
connman-8d304343818090c3ae76b8c812e101aca3ca262d.tar.bz2
connman-8d304343818090c3ae76b8c812e101aca3ca262d.zip
Add support for dynamic debug framework
-rw-r--r--include/log.h25
-rw-r--r--src/connman.h6
-rw-r--r--src/log.c93
-rw-r--r--src/main.c16
-rw-r--r--src/manager.c51
-rwxr-xr-xtest/test-manager3
6 files changed, 154 insertions, 40 deletions
diff --git a/include/log.h b/include/log.h
index 0ed8ee27..c48ad9d1 100644
--- a/include/log.h
+++ b/include/log.h
@@ -41,6 +41,21 @@ void connman_error(const char *format, ...)
void connman_debug(const char *format, ...)
__attribute__((format(printf, 1, 2)));
+struct connman_debug_desc {
+ const char *name;
+ const char *file;
+#define CONNMAN_DEBUG_FLAG_DEFAULT (0)
+#define CONNMAN_DEBUG_FLAG_PRINT (1 << 0)
+#define CONNMAN_DEBUG_FLAG_ALIAS (1 << 1)
+ unsigned int flags;
+} __attribute__((aligned(8)));
+
+#define CONNMAN_DEBUG_DEFINE(name) \
+ static struct connman_debug_desc __debug_alias_ ## name \
+ __attribute__((used, section("__debug"), aligned(8))) = { \
+ #name, __FILE__, CONNMAN_DEBUG_FLAG_ALIAS \
+ };
+
/**
* DBG:
* @fmt: format string
@@ -49,7 +64,15 @@ void connman_debug(const char *format, ...)
* Simple macro around connman_debug() which also include the function
* name it is called in.
*/
-#define DBG(fmt, arg...) connman_debug("%s:%s() " fmt, __FILE__, __FUNCTION__ , ## arg)
+#define DBG(fmt, arg...) do { \
+ static struct connman_debug_desc desc \
+ __attribute__((used, section("__debug"), aligned(8))) = { \
+ .file = __FILE__, .flags = CONNMAN_DEBUG_FLAG_DEFAULT, \
+ }; \
+ if (desc.flags & CONNMAN_DEBUG_FLAG_PRINT) \
+ connman_debug("%s:%s() " fmt, \
+ __FILE__, __FUNCTION__ , ## arg); \
+} while (0)
#ifdef __cplusplus
}
diff --git a/src/connman.h b/src/connman.h
index 36a4e46c..098bed51 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -75,11 +75,11 @@ int __connman_agent_request_passphrase(struct connman_service *service,
#include <connman/log.h>
-int __connman_log_init(gboolean detach, gboolean debug);
+int __connman_log_init(const char *debug, connman_bool_t detach);
void __connman_log_cleanup(void);
-void __connman_toggle_debug(void);
-gboolean __connman_debug_enabled(void);
+void __connman_debug_list_available(DBusMessageIter *iter);
+void __connman_debug_list_enabled(DBusMessageIter *iter);
#include <connman/option.h>
diff --git a/src/log.c b/src/log.c
index dbc3f7c6..5b5f82ca 100644
--- a/src/log.c
+++ b/src/log.c
@@ -28,8 +28,6 @@
#include "connman.h"
-static volatile gboolean debug_enabled = FALSE;
-
/**
* connman_info:
* @format: format string
@@ -90,17 +88,11 @@ void connman_error(const char *format, ...)
* @varargs: list of arguments
*
* Output debug message
- *
- * The actual output of the debug message is controlled via a command line
- * switch. If not enabled, these messages will be ignored.
*/
void connman_debug(const char *format, ...)
{
va_list ap;
- if (debug_enabled == FALSE)
- return;
-
va_start(ap, format);
vsyslog(LOG_DEBUG, format, ap);
@@ -108,20 +100,81 @@ void connman_debug(const char *format, ...)
va_end(ap);
}
-void __connman_toggle_debug(void)
+extern struct connman_debug_desc __start___debug[];
+extern struct connman_debug_desc __stop___debug[];
+
+void __connman_debug_list_available(DBusMessageIter *iter)
+{
+ struct connman_debug_desc *desc;
+
+ for (desc = __start___debug; desc < __stop___debug; desc++) {
+ if ((desc->flags & CONNMAN_DEBUG_FLAG_ALIAS) &&
+ desc->name != NULL)
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &desc->name);
+ }
+}
+
+static gchar **enabled = NULL;
+
+void __connman_debug_list_enabled(DBusMessageIter *iter)
+{
+ int i;
+
+ if (enabled == NULL)
+ return;
+
+ for (i = 0; enabled[i] != NULL; i++)
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &enabled[i]);
+}
+
+static connman_bool_t is_enabled(struct connman_debug_desc *desc)
{
- if (debug_enabled == TRUE) {
- connman_info("Disabling debug output");
- debug_enabled = FALSE;
- } else {
- connman_info("Enabling debug output");
- debug_enabled = TRUE;
+ int i;
+
+ if (enabled == NULL)
+ return FALSE;
+
+ for (i = 0; enabled[i] != NULL; i++) {
+ if (desc->name != NULL && g_pattern_match_simple(enabled[i],
+ desc->name) == TRUE)
+ return TRUE;
+ if (desc->file != NULL && g_pattern_match_simple(enabled[i],
+ desc->file) == TRUE)
+ return TRUE;
}
+
+ return FALSE;
}
-int __connman_log_init(gboolean detach, gboolean debug)
+int __connman_log_init(const char *debug, connman_bool_t detach)
{
int option = LOG_NDELAY | LOG_PID;
+ struct connman_debug_desc *desc;
+ const char *name = NULL, *file = NULL;
+
+ if (debug != NULL)
+ enabled = g_strsplit_set(debug, ":, ", 0);
+
+ for (desc = __start___debug; desc < __stop___debug; desc++) {
+ if (desc->flags & CONNMAN_DEBUG_FLAG_ALIAS) {
+ file = desc->file;
+ name = desc->name;
+ continue;
+ }
+
+ if (file != NULL || name != NULL) {
+ if (g_strcmp0(desc->file, file) == 0) {
+ if (desc->name == NULL)
+ desc->name = name;
+ } else
+ file = NULL;
+ }
+
+ if (is_enabled(desc) == TRUE)
+ desc->flags |= CONNMAN_DEBUG_FLAG_PRINT;
+ }
if (detach == FALSE)
option |= LOG_PERROR;
@@ -130,9 +183,6 @@ int __connman_log_init(gboolean detach, gboolean debug)
syslog(LOG_INFO, "Connection Manager version %s", VERSION);
- if (debug == TRUE)
- __connman_toggle_debug();
-
return 0;
}
@@ -141,9 +191,6 @@ void __connman_log_cleanup(void)
syslog(LOG_INFO, "Exit");
closelog();
-}
-gboolean __connman_debug_enabled(void)
-{
- return debug_enabled;
+ g_strfreev(enabled);
}
diff --git a/src/main.c b/src/main.c
index ef9b017a..312b823f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -45,11 +45,6 @@ static void sig_term(int sig)
g_main_loop_quit(main_loop);
}
-static void sig_debug(int sig)
-{
- __connman_toggle_debug();
-}
-
static void disconnect_callback(DBusConnection *conn, void *user_data)
{
connman_error("D-Bus disconnect");
@@ -57,6 +52,7 @@ static void disconnect_callback(DBusConnection *conn, void *user_data)
g_main_loop_quit(main_loop);
}
+static gchar *option_debug = NULL;
static gchar *option_device = NULL;
static gchar *option_plugin = NULL;
static gchar *option_nodevice = NULL;
@@ -64,11 +60,12 @@ static gchar *option_noplugin = NULL;
static gchar *option_wifi = NULL;
static gboolean option_detach = TRUE;
static gboolean option_compat = FALSE;
-static gboolean option_debug = FALSE;
static gboolean option_selftest = FALSE;
static gboolean option_version = FALSE;
static GOptionEntry options[] = {
+ { "debug", 'd', 0, G_OPTION_ARG_STRING, &option_debug,
+ "Specify debug options to enable", "DEBUG" },
{ "device", 'i', 0, G_OPTION_ARG_STRING, &option_device,
"Specify networking device or interface", "DEV" },
{ "nodevice", 'I', 0, G_OPTION_ARG_STRING, &option_nodevice,
@@ -84,8 +81,6 @@ static GOptionEntry options[] = {
"Don't fork daemon to background" },
{ "compat", 'c', 0, G_OPTION_ARG_NONE, &option_compat,
"Enable Network Manager compatibility" },
- { "debug", 'd', 0, G_OPTION_ARG_NONE, &option_debug,
- "Enable debug information output" },
{ "selftest", 't', 0, G_OPTION_ARG_NONE, &option_selftest,
"Run self testing routines" },
{ "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
@@ -189,7 +184,7 @@ int main(int argc, char *argv[])
}
}
- __connman_log_init(option_detach, option_debug);
+ __connman_log_init(option_debug, option_detach);
if (option_selftest == TRUE) {
if (__connman_selftest() < 0) {
@@ -227,9 +222,6 @@ int main(int argc, char *argv[])
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
- sa.sa_handler = sig_debug;
- sigaction(SIGUSR2, &sa, NULL);
-
g_main_loop_run(main_loop);
__connman_element_stop();
diff --git a/src/manager.c b/src/manager.c
index e761ce8c..1a114a41 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -195,6 +195,54 @@ static void append_connected_technologies(DBusMessageIter *dict)
dbus_message_iter_close_container(dict, &entry);
}
+static void append_available_debugs(DBusMessageIter *dict)
+{
+ DBusMessageIter entry, value, iter;
+ const char *key = "AvailableDebugs";
+
+ dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
+ NULL, &entry);
+
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+
+ dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
+ DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
+ &value);
+
+ dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING, &iter);
+ __connman_debug_list_available(&iter);
+ dbus_message_iter_close_container(&value, &iter);
+
+ dbus_message_iter_close_container(&entry, &value);
+
+ dbus_message_iter_close_container(dict, &entry);
+}
+
+static void append_enabled_debugs(DBusMessageIter *dict)
+{
+ DBusMessageIter entry, value, iter;
+ const char *key = "EnabledDebugs";
+
+ dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
+ NULL, &entry);
+
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+
+ dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
+ DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
+ &value);
+
+ dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING, &iter);
+ __connman_debug_list_enabled(&iter);
+ dbus_message_iter_close_container(&value, &iter);
+
+ dbus_message_iter_close_container(&entry, &value);
+
+ dbus_message_iter_close_container(dict, &entry);
+}
+
static DBusMessage *get_properties(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -252,6 +300,9 @@ static DBusMessage *get_properties(DBusConnection *conn,
connman_dbus_dict_append_variant(&dict, "DefaultTechnology",
DBUS_TYPE_STRING, &str);
+ append_available_debugs(&dict);
+ append_enabled_debugs(&dict);
+
dbus_message_iter_close_container(&array, &dict);
return reply;
diff --git a/test/test-manager b/test/test-manager
index db9c12af..07e3d853 100755
--- a/test/test-manager
+++ b/test/test-manager
@@ -63,7 +63,8 @@ for key in properties.keys():
if key in ["Profiles", "Devices", "Connections", "Services"]:
print_properties(key, properties[key])
elif key in ["AvailableTechnologies", "EnabledTechnologies",
- "ConnectedTechnologies"]:
+ "ConnectedTechnologies",
+ "AvailableDebugs", "EnabledDebugs"]:
print "%s" % (key)
list = ""
for val in properties[key]: