/** * \brief Remove data manager from list, close it and free templates * * \param[in] output_manager Output Manager structure * \param[in] old_manager Data Manager to remove and close */ void output_manager_remove(struct output_manager_config *output_manager, struct data_manager_config *old_manager) { struct data_manager_config *aux_conf = output_manager->data_managers; if (aux_conf == old_manager) { output_manager->data_managers = old_manager->next; } while (aux_conf->next) { if (aux_conf->next == old_manager) { aux_conf->next = old_manager->next; if (output_manager->last == old_manager) { output_manager->last = aux_conf; } break; } else { aux_conf = aux_conf->next; } } if (output_manager->data_managers == NULL) { output_manager->last = NULL; } uint32_t odid = old_manager->observation_domain_id; data_manager_close(&old_manager); tm_remove_all_odid_templates(template_mgr, odid); }
/** * \brief Remove data manager from list, close it and free templates * * \param[in] output_manager Output Manager structure * \param[in] old_manager Data Manager to remove and close */ void output_manager_remove(struct output_manager_config *output_manager, struct data_manager_config *old_manager) { struct data_manager_config *aux_conf = output_manager->data_managers; if (aux_conf == old_manager) { output_manager->data_managers = old_manager->next; } while (aux_conf->next) { if (aux_conf->next == old_manager) { aux_conf->next = old_manager->next; if (output_manager->last == old_manager) { output_manager->last = aux_conf; } break; } else { aux_conf = aux_conf->next; } } if (output_manager->data_managers == NULL) { output_manager->last = NULL; } uint32_t odid = old_manager->observation_domain_id; data_manager_close(&old_manager); if (!output_manager->perman_odid_merge && output_manager->manager_mode != OM_SINGLE) { tm_remove_all_odid_templates(template_mgr, odid); } else { // Single manager -> remove all templates tm_remove_all_templates(template_mgr); } }
/** * \brief Change mode of output manager * * Allow to change mode from single mode to multi mode and vice versa. * If new mode is different from current mode, all data managers are removed. * If the manager thread is running, it will be stopped and restarted later. * * \param[in] mode New mode of output manager * \return 0 on successs */ int output_manager_set_mode(enum om_mode mode) { if (conf->perman_odid_merge) { /* Nothing can be changed, permanent single manager mode enabled */ if (mode == OM_MULTIPLE) { MSG_WARNING(msg_module, "Unable to change Output Manager mode. " "Single manager mode permanently enabled ('-M' argument)"); } return 0; } if (conf->manager_mode == mode) { /* Mode is still the same */ return 0; } if (conf->running) { MSG_DEBUG(msg_module, "Stopping Output Manager thread"); rbuffer_write(conf->in_queue, NULL, 1); pthread_join(conf->thread_id, NULL); } /* Delete data managers */ struct data_manager_config *aux_config = conf->data_managers; while (aux_config) { struct data_manager_config *tmp = aux_config; aux_config = aux_config->next; data_manager_close(&tmp); } conf->data_managers = NULL; conf->last = NULL; conf->manager_mode = mode; if (mode == OM_SINGLE) { MSG_INFO(msg_module, "Switching Output Manager to single manager mode"); } else if (mode == OM_MULTIPLE) { MSG_INFO(msg_module, "Switching Output Manager to multiple manager mode"); } else { /* Unknown mode */ } if (conf->running) { /* Restart thread */ int retval; MSG_DEBUG(msg_module, "Restarting Output Manager thread"); retval = pthread_create(&(conf->thread_id), NULL, &output_manager_plugin_thread, (void *) conf); if (retval != 0) { MSG_ERROR(msg_module, "Unable to create Output Manager thread"); free(conf); return -1; } } return 0; }
/** * \brief Close Ouput Manager and all Data Managers */ void output_manager_close(void *config) { struct output_manager_config *manager = (struct output_manager_config *) config; struct data_manager_config *aux_config = NULL, *tmp = NULL; struct stat_thread *aux_thread = NULL, *tmp_thread = NULL; /* Stop Output Manager thread and free input buffer */ if (manager->running) { rbuffer_write(manager->in_queue, NULL, 1); pthread_join(manager->thread_id, NULL); rbuffer_free(manager->in_queue); /* Close statistics thread */ if (manager->stat_interval > 0) { manager->stats.done = 1; pthread_kill(manager->stat_thread, SIGUSR1); pthread_join(manager->stat_thread, NULL); } aux_config = manager->data_managers; /* Close all data managers */ while (aux_config) { tmp = aux_config; aux_config = aux_config->next; data_manager_close(&tmp); } /* Free input_info_list */ if (input_info_list) { struct input_info_node *aux_node = input_info_list; while (aux_node) { struct input_info_node *aux_node_rm = aux_node; aux_node = aux_node->next; free(aux_node_rm); } } /* Free all thread structures for statistics */ aux_thread = manager->stats.threads; while (aux_thread) { tmp_thread = aux_thread; aux_thread = aux_thread->next; free(tmp_thread); } } free(manager); }