Prevent CDR backends from unregistering while billing data is in flight
[asterisk/asterisk.git] / cdr / cdr_syslog.c
index 9455c7b..de8cae4 100644 (file)
  * at the top of the source tree.
  */
 
-/*! \file cdr_syslog.c
- *
+/*!
+ * \file
  * \brief syslog CDR logger
+ *
  * \author Sean Bright <sean@malleable.com>
  *
  * See also
  * \ingroup cdr_drivers
  */
 
+/*! \li \ref cdr_syslog.c uses the configuration file \ref cdr_syslog.conf
+ * \addtogroup configuration_file Configuration Files
+ */
+
+/*!
+ * \page cdr_syslog.conf cdr_syslog.conf
+ * \verbinclude cdr_syslog.conf.sample
+ */
+
 /*** MODULEINFO
-        <depend>syslog</depend>
+       <depend>syslog</depend>
+       <support_level>core</support_level>
 ***/
 
 #include "asterisk.h"
@@ -49,7 +60,7 @@ AST_THREADSTORAGE(syslog_buf);
 
 static const char name[] = "cdr-syslog";
 
-struct cdr_config {
+struct cdr_syslog_config {
        AST_DECLARE_STRING_FIELDS(
                AST_STRING_FIELD(ident);
                AST_STRING_FIELD(format);
@@ -57,14 +68,14 @@ struct cdr_config {
        int facility;
        int priority;
        ast_mutex_t lock;
-       AST_LIST_ENTRY(cdr_config) list;
+       AST_LIST_ENTRY(cdr_syslog_config) list;
 };
 
-static AST_RWLIST_HEAD_STATIC(sinks, cdr_config);
+static AST_RWLIST_HEAD_STATIC(sinks, cdr_syslog_config);
 
 static void free_config(void)
 {
-       struct cdr_config *sink;
+       struct cdr_syslog_config *sink;
        while ((sink = AST_RWLIST_REMOVE_HEAD(&sinks, list))) {
                ast_mutex_destroy(&sink->lock);
                ast_free(sink);
@@ -75,7 +86,7 @@ static int syslog_log(struct ast_cdr *cdr)
 {
        struct ast_channel *dummy;
        struct ast_str *str;
-       struct cdr_config *sink;
+       struct cdr_syslog_config *sink;
 
        /* Batching saves memory management here.  Otherwise, it's the same as doing an
           allocation and free each time. */
@@ -91,7 +102,7 @@ static int syslog_log(struct ast_cdr *cdr)
        /* We need to dup here since the cdr actually belongs to the other channel,
           so when we release this channel we don't want the CDR getting cleaned
           up prematurely. */
-       dummy->cdr = ast_cdr_dup(cdr);
+       ast_channel_cdr_set(dummy, ast_cdr_dup(cdr));
 
        AST_RWLIST_RDLOCK(&sinks);
 
@@ -114,7 +125,7 @@ static int syslog_log(struct ast_cdr *cdr)
 
        AST_RWLIST_UNLOCK(&sinks);
 
-       ast_channel_release(dummy);
+       ast_channel_unref(dummy);
 
        return 0;
 }
@@ -163,7 +174,7 @@ static int load_config(int reload)
        }
 
        while ((catg = ast_category_browse(cfg, catg))) {
-               struct cdr_config *sink;
+               struct cdr_syslog_config *sink;
 
                if (!strcasecmp(catg, "general")) {
                        continue;
@@ -175,7 +186,7 @@ static int load_config(int reload)
                        continue;
                }
 
-               sink = ast_calloc_with_stringfields(1, struct cdr_config, 1024);
+               sink = ast_calloc_with_stringfields(1, struct cdr_syslog_config, 1024);
 
                if (!sink) {
                        ast_log(AST_LOG_ERROR,
@@ -224,7 +235,9 @@ static int load_config(int reload)
 
 static int unload_module(void)
 {
-       ast_cdr_unregister(name);
+       if (ast_cdr_unregister(name)) {
+               return -1;
+       }
 
        if (AST_RWLIST_WRLOCK(&sinks)) {
                ast_cdr_register(name, ast_module_info->description, syslog_log);
@@ -263,15 +276,18 @@ static int reload(void)
                return AST_MODULE_LOAD_DECLINE;
        }
 
-       free_config();
-       res = load_config(1);
+       if ((res = load_config(1))) {
+               free_config();
+       }
+
        AST_RWLIST_UNLOCK(&sinks);
 
        return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
 }
 
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Customizable syslog CDR Backend",
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Customizable syslog CDR Backend",
        .load = load_module,
        .unload = unload_module,
        .reload = reload,
+       .load_pri = AST_MODPRI_CDR_DRIVER,
 );