}
dbport = 0;
- ast_cdr_unregister(name);
-
- return 0;
+ if (reload) {
+ return ast_cdr_backend_suspend(name);
+ } else {
+ return ast_cdr_unregister(name);
+ }
}
static int my_load_config_string(struct ast_config *cfg, const char *category, const char *variable, struct ast_str **field, const char *def)
return AST_MODULE_LOAD_FAILURE;
}
- res = ast_cdr_register(name, desc, mysql_log);
+ if (!reload) {
+ res = ast_cdr_register(name, desc, mysql_log);
+ } else {
+ res = ast_cdr_backend_unsuspend(name);
+ }
if (res) {
ast_log(LOG_ERROR, "Unable to register MySQL CDR handling\n");
} else {
static int unload_module(void)
{
- ast_cdr_unregister(name);
+ if (ast_cdr_unregister(name)) {
+ return -1;
+ }
+
if (AST_RWLIST_WRLOCK(&odbc_tables)) {
ast_cdr_register(name, ast_module_info->description, odbc_log);
ast_log(LOG_ERROR, "Unable to lock column list. Unload failed.\n");
static int unload_module(void)
{
- ast_cdr_unregister(name);
+ if (ast_cdr_unregister(name)) {
+ return -1;
+ }
+
loaded = 0;
return 0;
}
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, custom_log);
if (!cfg) {
/* Standard configuration */
ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n");
- if (enablecdr)
- ast_cdr_unregister(name);
+ if (enablecdr) {
+ ast_cdr_backend_suspend(name);
+ }
enablecdr = 0;
return -1;
}
ast_config_destroy(cfg);
- if (enablecdr && !newenablecdr)
- ast_cdr_unregister(name);
- else if (!enablecdr && newenablecdr)
- ast_cdr_register(name, "Asterisk Manager Interface CDR Backend", manager_log);
+ if (!newenablecdr) {
+ ast_cdr_backend_suspend(name);
+ } else if (newenablecdr) {
+ ast_cdr_backend_unsuspend(name);
+ }
enablecdr = newenablecdr;
return 0;
static int unload_module(void)
{
- ast_cdr_unregister(name);
+ if (ast_cdr_unregister(name)) {
+ return -1;
+ }
+
if (customfields)
ast_free(customfields);
static int load_module(void)
{
+ if (ast_cdr_register(name, "Asterisk Manager Interface CDR Backend", manager_log)) {
+ return AST_MODULE_LOAD_DECLINE;
+ }
+
if (load_config(0)) {
+ ast_cdr_unregister(name);
return AST_MODULE_LOAD_DECLINE;
}
} while (0);
if (ast_test_flag(&config, CONFIG_REGISTERED) && (!cfg || dsn == NULL || table == NULL)) {
- ast_cdr_unregister(name);
+ ast_cdr_backend_suspend(name);
ast_clear_flag(&config, CONFIG_REGISTERED);
+ } else {
+ ast_cdr_backend_unsuspend(name);
}
if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg != CONFIG_STATUS_FILEINVALID) {
static int unload_module(void)
{
- ast_cdr_unregister(name);
+ if (ast_cdr_unregister(name)) {
+ return -1;
+ }
if (dsn) {
ast_verb(11, "cdr_odbc: free dsn\n");
static int unload_module(void)
{
- ast_cdr_unregister(name);
+ if (ast_cdr_unregister(name)) {
+ return -1;
+ }
+
ast_cli_unregister_multiple(cdr_pgsql_status_cli, ARRAY_LEN(cdr_pgsql_status_cli));
PQfinish(conn);
static int unload_module(void)
{
- ast_cdr_unregister(name);
+ if (ast_cdr_unregister(name)) {
+ return -1;
+ }
+
if (rh) {
rc_destroy(rh);
rh = NULL;
static int unload_module(void)
{
- ast_cdr_unregister(name);
+ if (ast_cdr_unregister(name)) {
+ return -1;
+ }
+
if (db) {
sqlite_close(db);
}
static int unload_module(void)
{
- ast_cdr_unregister(name);
+ if (ast_cdr_unregister(name)) {
+ return -1;
+ }
free_config(0);
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);
static int tds_unload_module(void)
{
+ if (ast_cdr_unregister(name)) {
+ return -1;
+ }
+
if (settings) {
ast_mutex_lock(&tds_lock);
mssql_disconnect();
ast_free(settings);
}
- ast_cdr_unregister(name);
-
dbexit();
return 0;
* \brief Unregister a CDR handling engine
* \param name name of CDR handler to unregister
* Unregisters a CDR by it's name
+ *
+ * \retval 0 The backend unregistered successfully
+ * \retval -1 The backend could not be unregistered at this time
+ */
+int ast_cdr_unregister(const char *name);
+
+/*!
+ * \brief Suspend a CDR backend temporarily
+ *
+ * \retval 0 The backend is suspdended
+ * \retval -1 The backend could not be suspended
+ */
+int ast_cdr_backend_suspend(const char *name);
+
+/*!
+ * \brief Unsuspend a CDR backend
+ *
+ * \retval 0 The backend was unsuspended
+ * \retval -1 The back could not be unsuspended
*/
-void ast_cdr_unregister(const char *name);
+int ast_cdr_backend_unsuspend(const char *name);
/*!
* \brief Disposition to a string
char desc[80];
ast_cdrbe be;
AST_RWLIST_ENTRY(cdr_beitem) list;
+ int suspended:1;
};
/*! \brief List of registered backends */
return ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED);
}
+int ast_cdr_backend_suspend(const char *name)
+{
+ int success = -1;
+ struct cdr_beitem *i = NULL;
+
+ AST_RWLIST_WRLOCK(&be_list);
+ AST_RWLIST_TRAVERSE(&be_list, i, list) {
+ if (!strcasecmp(name, i->name)) {
+ ast_debug(3, "Suspending CDR backend %s\n", i->name);
+ i->suspended = 1;
+ success = 0;
+ }
+ }
+ AST_RWLIST_UNLOCK(&be_list);
+
+ return success;
+}
+
+int ast_cdr_backend_unsuspend(const char *name)
+{
+ int success = -1;
+ struct cdr_beitem *i = NULL;
+
+ AST_RWLIST_WRLOCK(&be_list);
+ AST_RWLIST_TRAVERSE(&be_list, i, list) {
+ if (!strcasecmp(name, i->name)) {
+ ast_debug(3, "Unsuspending CDR backend %s\n", i->name);
+ i->suspended = 0;
+ success = 0;
+ }
+ }
+ AST_RWLIST_UNLOCK(&be_list);
+
+ return success;
+}
+
int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
{
struct cdr_beitem *i = NULL;
return 0;
}
-void ast_cdr_unregister(const char *name)
+int ast_cdr_unregister(const char *name)
{
- struct cdr_beitem *i = NULL;
+ struct cdr_beitem *match = NULL;
+ int active_count;
AST_RWLIST_WRLOCK(&be_list);
- AST_RWLIST_TRAVERSE_SAFE_BEGIN(&be_list, i, list) {
- if (!strcasecmp(name, i->name)) {
- AST_RWLIST_REMOVE_CURRENT(list);
+ AST_RWLIST_TRAVERSE(&be_list, match, list) {
+ if (!strcasecmp(name, match->name)) {
break;
}
}
- AST_RWLIST_TRAVERSE_SAFE_END;
- AST_RWLIST_UNLOCK(&be_list);
- if (i) {
- ast_verb(2, "Unregistered '%s' CDR backend\n", name);
- ast_free(i);
+ if (!match) {
+ AST_RWLIST_UNLOCK(&be_list);
+ return 0;
+ }
+
+ active_count = ao2_container_count(active_cdrs_by_channel);
+
+ if (!match->suspended && active_count != 0) {
+ AST_RWLIST_UNLOCK(&be_list);
+ ast_log(AST_LOG_WARNING, "Unable to unregister CDR backend %s; %d CDRs are still active\n",
+ name, active_count);
+ return -1;
}
+
+ AST_RWLIST_REMOVE(&be_list, match, list);
+ AST_RWLIST_UNLOCK(&be_list);
+
+ ast_verb(2, "Unregistered '%s' CDR backend\n", name);
+ ast_free(match);
+
+ return 0;
}
struct ast_cdr *ast_cdr_dup(struct ast_cdr *cdr)
}
AST_RWLIST_RDLOCK(&be_list);
AST_RWLIST_TRAVERSE(&be_list, i, list) {
- i->be(cdr);
+ if (!i->suspended) {
+ i->be(cdr);
+ }
}
AST_RWLIST_UNLOCK(&be_list);
}
ast_cli(a->fd, " (none)\n");
} else {
AST_RWLIST_TRAVERSE(&be_list, beitem, list) {
- ast_cli(a->fd, " %s\n", beitem->name);
+ ast_cli(a->fd, " %s%s\n", beitem->name, beitem->suspended ? " (suspended) " : "");
}
}
AST_RWLIST_UNLOCK(&be_list);