[PATCH 2/2] logging: rework definition of logging subsystems for libraries

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

pablo at gnumonks.org pablo at gnumonks.org
Sat Jul 2 17:54:59 UTC 2011


From: Pablo Neira Ayuso <pablo at gnumonks.org>

This patchs allow to invoke log_init(...) as many times
as you want. Thus, applications and libraries can register
their own logging subsystems in runtime.

The idea consists of splitting the numberspace for applications
and libraries. From 0 to 64 for applications, from 64 to 255 for
libraries.

#define OSMO_LOG_SS_APPS                0
#define OSMO_LOG_SS_RESERVED            64
#define OSMO_LOG_SS_MAX                 255

The logging subsystem number definitions of the subsystem live
in osmocom/core/logging.h

/* reserved logging subsystems for libraries. */
enum {
        DLLAPDM         = OSMO_LOG_SS_RESERVED,         /* libosmogsm */
        DINP,                                           /* libosmo-abis */
        DMUX,                                           /* libosmo-abis */
        DMI,                                            /* libosmo-abis */
        DMIB,                                           /* libosmo-abis */
        DRSL,                                           /* libosmo-abis */
        DNM,                                            /* libosmo-abis */
};

The full definition (a.k.a. logging categories) is done in the
scope of the applications and libraries.

This patch limits the number of logging subsystems to 256. This
limit is artificial until we provide a different way to define
logging categories. Currently, we do:

struct log_info_cat libosmo_abis_default_categories[] = {
        [DINP] = {
                .name = "DINP",
                .description = "A-bis Intput Subsystem",
                .enabled = 1, .loglevel = LOGL_NOTICE,
        },
        ...
};

Since, with this patch, DINP is 64, we waste 63 positions
in the array defined in libosmo-abis. To avoid this, we
can do it like:

struct log_info_cat libosmo_abis_default_categories[] = {
	{
		.id = DINP,
                .name = "DINP",
                .description = "A-bis Intput Subsystem",
                .enabled = 1, .loglevel = LOGL_NOTICE,
        },
        ...
};

We can introduce this change in the near future and propagate
the changes to existing applications and libraries.
---
 include/osmocom/core/logging.h |   22 ++++++--
 include/osmocom/gsm/gsm.h      |    6 ++
 src/gsm/Makefile.am            |    2 +-
 src/gsm/init.c                 |   22 ++++++++
 src/logging.c                  |  107 ++++++++++++++++++++++-----------------
 5 files changed, 106 insertions(+), 53 deletions(-)
 create mode 100644 include/osmocom/gsm/gsm.h
 create mode 100644 src/gsm/init.c

diff --git a/include/osmocom/core/logging.h b/include/osmocom/core/logging.h
index 4276b3a..fa1e91b 100644
--- a/include/osmocom/core/logging.h
+++ b/include/osmocom/core/logging.h
@@ -5,6 +5,23 @@
 #include <stdint.h>
 #include <osmocom/core/linuxlist.h>
 
+/* subsystem logging numbers: we split the numberspace for applications and
+ * libraries: from 0 to 64 for applications, from 64 to 255 for libraries. */
+#define OSMO_LOG_SS_APPS		0
+#define OSMO_LOG_SS_RESERVED		64
+#define OSMO_LOG_SS_MAX			255
+
+/* reserved logging subsystems for libraries. */
+enum {
+	DLLAPDM		= OSMO_LOG_SS_RESERVED,		/* libosmogsm */
+	DINP,						/* libosmo-abis	*/
+	DMUX,						/* libosmo-abis */
+	DMI,						/* libosmo-abis */
+	DMIB,						/* libosmo-abis */
+	DRSL,						/* libosmo-abis */
+	DNM,						/* libosmo-abis */
+};
+
 #define LOG_MAX_CTX		8
 #define LOG_MAX_FILTERS	8
 
@@ -36,11 +53,6 @@ void logp(int subsys, char *file, int line, int cont, const char *format, ...) _
 
 #define LOG_FILTER_ALL	0x0001
 
-/* logging levels defined by the library itself */
-#define DLGLOBAL	-1
-#define DLLAPDM		-2
-#define OSMO_NUM_DLIB	2
-
 struct log_category {
 	uint8_t loglevel;
 	uint8_t enabled;
diff --git a/include/osmocom/gsm/gsm.h b/include/osmocom/gsm/gsm.h
new file mode 100644
index 0000000..9d3f418
--- /dev/null
+++ b/include/osmocom/gsm/gsm.h
@@ -0,0 +1,6 @@
+#ifndef _GSM_H_
+#define _GSM_H_
+
+void libosmo_gsm_init(void *ctx);
+
+#endif
diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am
index 88b2d9a..5e1d36c 100644
--- a/src/gsm/Makefile.am
+++ b/src/gsm/Makefile.am
@@ -10,6 +10,6 @@ lib_LTLIBRARIES = libosmogsm.la
 libosmogsm_la_SOURCES = a5.c rxlev_stat.c tlv_parser.c comp128.c gsm_utils.c \
                         rsl.c gsm48.c gsm48_ie.c gsm0808.c sysinfo.c \
 			gprs_cipher_core.c gsm0480.c abis_nm.c gsm0502.c \
-			lapdm.c
+			lapdm.c init.c
 libosmogsm_la_LDFLAGS = -version-info $(LIBVERSION)
 libosmogsm_la_LIBADD = $(top_builddir)/src/libosmocore.la
diff --git a/src/gsm/init.c b/src/gsm/init.c
new file mode 100644
index 0000000..00e6b30
--- /dev/null
+++ b/src/gsm/init.c
@@ -0,0 +1,22 @@
+#include <osmocom/core/utils.h>
+#include <osmocom/core/logging.h>
+
+struct log_info_cat libosmo_gsm_default_categories[] = {
+	[DLLAPDM] = {
+		.name = "DLLAPDM",
+		.description = "LAPDm in libosmogsm",
+		.loglevel = LOGL_NOTICE,
+		.enabled = 1,
+	},
+};
+
+const struct log_info libosmo_gsm_log = {
+	.filter_fn = NULL,	/* the application should set this. */
+	.cat = libosmo_gsm_default_categories,
+	.num_cat = ARRAY_SIZE(libosmo_gsm_default_categories),
+};
+
+void libosmo_gsm_init(void *ctx)
+{
+	log_init(&libosmo_gsm_log, ctx);
+}
diff --git a/src/logging.c b/src/logging.c
index 24b310b..ffd81c6 100644
--- a/src/logging.c
+++ b/src/logging.c
@@ -58,22 +58,6 @@ static const struct value_string loglevel_strs[LOGLEVEL_DEFS+1] = {
 	{ 0, NULL },
 };
 
-#define INT2IDX(x)	(-1*(x)-1)
-static const struct log_info_cat internal_cat[OSMO_NUM_DLIB] = {
-	[INT2IDX(DLGLOBAL)] = {	/* -1 becomes 0 */
-		.name = "DLGLOBAL",
-		.description = "Library-internal global log family",
-		.loglevel = LOGL_NOTICE,
-		.enabled = 1,
-	},
-	[INT2IDX(DLLAPDM)] = {	/* -2 becomes 1 */
-		.name = "DLLAPDM",
-		.description = "LAPDm in libosmogsm",
-		.loglevel = LOGL_NOTICE,
-		.enabled = 1,
-	},
-};
-
 /* You have to keep this in sync with the structure loglevel_strs. */
 const char *loglevel_descriptions[LOGLEVEL_DEFS+1] = {
 	"Log simply everything",
@@ -85,12 +69,6 @@ const char *loglevel_descriptions[LOGLEVEL_DEFS+1] = {
 	NULL,
 };
 
-/* special magic for negative (library-internal) log subsystem numbers */
-static int subsys_lib2index(int subsys)
-{
-	return (subsys * -1) + (osmo_log_info->num_cat_user-1);
-}
-
 int log_parse_level(const char *lvl)
 {
 	return get_string_value(loglevel_strs, lvl);
@@ -142,7 +120,8 @@ void log_parse_category_mask(struct log_target* target, const char *_mask)
 			if (colon)
 			    length = colon - category_token;
 
-			if (strncasecmp(osmo_log_info->cat[i].name,
+			if (osmo_log_info->cat[i].name != NULL &&
+			    strncasecmp(osmo_log_info->cat[i].name,
 					category_token, length) == 0) {
 				int level = 0;
 
@@ -221,12 +200,6 @@ static void _logp(int subsys, int level, char *file, int line,
 {
 	struct log_target *tar;
 
-	if (subsys < 0)
-		subsys = subsys_lib2index(subsys);
-
-	if (subsys > osmo_log_info->num_cat)
-		subsys = DLGLOBAL;
-
 	llist_for_each_entry(tar, &osmo_log_target_list, entry) {
 		struct log_category *category;
 		int output = 0;
@@ -607,8 +580,19 @@ err:
 	return str;
 }
 
-int log_init(const struct log_info *inf, void *ctx)
+static void log_info_set(struct log_info_cat *lic1, struct log_info_cat *lic2)
 {
+	lic1->name = talloc_strdup(tall_log_ctx, lic2->name);
+	lic1->color = talloc_strdup(tall_log_ctx, lic2->color);
+	lic1->description = talloc_strdup(tall_log_ctx, lic2->description);
+	lic1->loglevel = lic2->loglevel;
+	lic1->enabled = lic2->enabled;
+}
+
+static int log_info_init(const struct log_info *inf, void *ctx)
+{
+	/* keep this easy, allocate maximum number of categories. */
+	size_t size = sizeof(struct log_info_cat) * OSMO_LOG_SS_MAX;
 	int i;
 
 	tall_log_ctx = talloc_named_const(ctx, 1, "logging");
@@ -619,31 +603,60 @@ int log_init(const struct log_info *inf, void *ctx)
 	if (!osmo_log_info)
 		return -ENOMEM;
 
-	osmo_log_info->num_cat_user = inf->num_cat;
-	/* total number = number of user cat + library cat */
-	osmo_log_info->num_cat = inf->num_cat + ARRAY_SIZE(internal_cat);
+	osmo_log_info->filter_fn = inf->filter_fn;
+	osmo_log_info->num_cat = inf->num_cat;
 
-	osmo_log_info->cat = talloc_zero_array(osmo_log_info,
-					struct log_info_cat,
-					osmo_log_info->num_cat);
-	if (!osmo_log_info->cat) {
+	osmo_log_info->cat = talloc_zero_size(tall_log_ctx, size);
+	if (osmo_log_info->cat == NULL) {
 		talloc_free(osmo_log_info);
 		osmo_log_info = NULL;
 		return -ENOMEM;
 	}
-
-	/* copy over the user part */
-	for (i = 0; i < inf->num_cat; i++) {
-		memcpy(&osmo_log_info->cat[i], &inf->cat[i],
-			sizeof(struct log_info_cat));
+	for (i=0; i<inf->num_cat; i++) {
+		if (inf->cat[i].name == NULL)
+			continue;
+		log_info_set(&osmo_log_info->cat[i], &inf->cat[i]);
 	}
+	return 0;
+}
 
-	/* copy over the library part */
-	for (i = 0; i < ARRAY_SIZE(internal_cat); i++) {
-		unsigned int cn = osmo_log_info->num_cat_user + i;
-		memcpy(&osmo_log_info->cat[cn],
-			&internal_cat[i], sizeof(struct log_info_cat));
+static int log_info_add(const struct log_info *log_info)
+{
+	int i, limit = osmo_log_info->num_cat;
+
+	if (osmo_log_info->filter_fn == NULL) {
+		osmo_log_info->filter_fn = log_info->filter_fn;
+	} else {
+		fprintf(stderr, "sorry, you cannot override filter "
+				"function in logging infrastructure\n");
 	}
+	if (log_info->num_cat > osmo_log_info->num_cat)
+		limit = osmo_log_info->num_cat;
 
+	osmo_log_info->num_cat = limit;
+	for (i=0; i<log_info->num_cat; i++) {
+		if (log_info->cat[i].name == NULL)
+			continue;
+		if (osmo_log_info->cat[i].name == NULL)
+			log_info_set(&osmo_log_info->cat[i], &log_info->cat[i]);
+	}
 	return 0;
 }
+
+int log_init(const struct log_info *inf, void *ctx)
+{
+	int ret;
+
+	/* Artificially limit the maximum number of logging subsystems to
+	 * avoid too big arrays with logging definitions. We can fix this by
+	 * adding some ID field in the logging definition structure, later. */
+	if (inf->num_cat > OSMO_LOG_SS_MAX)
+		return -EINVAL;
+
+	if (tall_log_ctx == NULL)
+		ret = log_info_init(inf, ctx);
+	else
+		ret = log_info_add(inf);
+
+	return ret;
+}
-- 
1.7.2.5





More information about the OpenBSC mailing list