/** ========================================================================= * This is the main worker thread. It looks for information comming in the * FIFO and submits the data to the database. This ensures that the PerfMgr * (and therefore OpenSM threads) will not be delayed by DB activity. */ void * db_write_thread(void *pd) { plugin_data_t *plugin_data = (plugin_data_t *)pd; data_entry_t *data = NULL; plugin_log(plugin_data->osmlog, OSM_LOG_INFO, "In DB write thread\n"); plugin_data->exit_flag = 0; if (sql_setup_db_conn(plugin_data)) { thread_signal(plugin_data); return (NULL); } thread_signal(plugin_data); while (1) { if (plugin_data->exit_flag) { return (NULL); } if (!plugin_data->tail) { struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += plugin_data->thread_sleep_s; pthread_mutex_lock(&(plugin_data->sig_lock)); pthread_cond_timedwait(&(plugin_data->signal), &(plugin_data->sig_lock), &ts); pthread_mutex_unlock(&(plugin_data->sig_lock)); continue; } data = pull_from_tail(plugin_data); if (!data) { plugin_log(plugin_data->osmlog, OSM_LOG_ERROR, "plugin_data->tail != NULL but pull returned NULL?"); continue; } switch(data->type) { case OSM_EVENT_ID_PORT_ERRORS: sql_add_port_errors(plugin_data, &(data->data.pe_event)); break; case OSM_EVENT_ID_PORT_DATA_COUNTERS: sql_add_data_counters(plugin_data, &(data->data.dc_event)); break; case OSM_EVENT_ID_PORT_SELECT: sql_add_port_select(plugin_data, &(data->data.ps_event)); break; case OSM_EVENT_ID_TRAP: break; case OSM_EVENT_ID_MAX: break; } free(data); } }
/** ========================================================================= */ static void * create(struct osm_opensm *osm) { struct timespec ts; plugin_data_t *plugin_data = NULL; pthread_attr_t th_attr; int rc = 0; if (!(plugin_data = malloc(sizeof(*plugin_data)))) return (NULL); plugin_data->osmlog = &(osm->log); if (!construct_plugin_data(plugin_data)) { plugin_log(plugin_data->osmlog, OSM_LOG_ERROR, "Failed to read %s\n", DATABASE_CONF); free(plugin_data); return (NULL); } if (pthread_attr_init(&(th_attr))) { free_plugin_data(plugin_data); return (NULL); } pthread_mutex_lock(&(plugin_data->sig_lock)); if (pthread_create(&(plugin_data->thread), &(th_attr), db_write_thread, (void *)plugin_data)) { plugin_log(plugin_data->osmlog, OSM_LOG_INFO, "Failed to create DB write thread\n"); pthread_attr_destroy(&(th_attr)); free_plugin_data(plugin_data); return (NULL); } pthread_attr_destroy(&(th_attr)); clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += 2; /* give 2 sec to start up */ rc = pthread_cond_timedwait(&(plugin_data->signal), &(plugin_data->sig_lock), &ts); pthread_mutex_unlock(&(plugin_data->sig_lock)); if (rc == ETIMEDOUT) { plugin_log(plugin_data->osmlog, OSM_LOG_ERROR, "DB write thread failed to initialize\n"); pthread_join(plugin_data->thread, NULL); free_plugin_data(plugin_data); return (NULL); } plugin_log(plugin_data->osmlog, OSM_LOG_INFO, "DB write thread started\n"); return ((void *)plugin_data); }
/* vcomplain returns 0 if it did not report, 1 else */ __attribute__((format(printf, 3, 0))) static int vcomplain(int level, c_complain_t *c, const char *format, va_list ap) { cdtime_t now; char message[512]; now = cdtime(); if (c->last + c->interval > now) return 0; c->last = now; if (c->interval < plugin_get_interval()) c->interval = plugin_get_interval(); else c->interval *= 2; if (c->interval > TIME_T_TO_CDTIME_T(86400)) c->interval = TIME_T_TO_CDTIME_T(86400); vsnprintf(message, sizeof(message), format, ap); message[sizeof(message) - 1] = '\0'; plugin_log(level, "%s", message); return 1; } /* vcomplain */
/* vcomplain returns 0 if it did not report, 1 else */ static int vcomplain (int level, c_complain_t *c, const char *format, va_list ap) { time_t now; char message[512]; now = time (NULL); if (c->last + c->interval > now) return 0; c->last = now; if (c->interval < interval_g) c->interval = interval_g; else c->interval *= 2; if (c->interval > 86400) c->interval = 86400; vsnprintf (message, sizeof (message), format, ap); message[sizeof (message) - 1] = '\0'; plugin_log (level, "%s", message); return 1; } /* vcomplain */
void c_do_release(int level, c_complain_t *c, const char *format, ...) { char message[512]; va_list ap; if (c->interval == 0) return; c->interval = 0; c->complained_once = 0; va_start(ap, format); vsnprintf(message, sizeof(message), format, ap); message[sizeof(message) - 1] = '\0'; va_end(ap); plugin_log(level, "%s", message); } /* c_release */
static int lua_cb_log_warning(lua_State *L) /* {{{ */ { const char *msg = luaL_checkstring(L, 1); plugin_log(LOG_WARNING, "%s", msg); return 0; } /* }}} int lua_cb_log_warning */
static int lua_cb_log_notice(lua_State *L) /* {{{ */ { const char *msg = luaL_checkstring(L, 1); plugin_log(LOG_NOTICE, "%s", msg); return 0; } /* }}} int lua_cb_log_notice */
static int lua_cb_log_info(lua_State *L) /* {{{ */ { const char *msg = luaL_checkstring(L, 1); plugin_log(LOG_INFO, "%s", msg); return 0; } /* }}} int lua_cb_log_info */
static int lua_cb_log_error(lua_State *L) /* {{{ */ { const char *msg = luaL_checkstring(L, 1); plugin_log(LOG_ERR, "%s", msg); return 0; } /* }}} int lua_cb_log_error */
static int lua_cb_log_debug(lua_State *L) /* {{{ */ { const char *msg = luaL_checkstring(L, 1); plugin_log(LOG_DEBUG, "%s", msg); return 0; } /* }}} int lua_cb_log_debug */
static void kafka_log(const rd_kafka_t *rkt, int level, const char *fac, const char *msg) { plugin_log(level, "%s", msg); }
GkrellmMonitor * install_plugin(gchar *plugin_name) { GList *list; GModule *module; GkrellmMonitor *m, *mm; GkrellmMonitor *(*init_plugin)(); gchar buf[256]; static GkrellmMonitor mon_tmp; if (!g_module_supported()) return NULL; module = g_module_open(plugin_name, 0); plugin_log(plugin_name, "\n", NULL); if (! module) { snprintf(buf, sizeof(buf), _("\tError: %s\n"), g_module_error()); plugin_log(buf, NULL); return NULL; } if (!g_module_symbol(module, "gkrellm_init_plugin", (gpointer) &init_plugin)) { snprintf(buf, sizeof(buf), _("\tError: %s\n"), g_module_error()); plugin_log(buf, NULL); g_module_close(module); return NULL; } _GK.no_messages = TRUE; /* Enforce policy */ mon_tmp.name = g_strdup(plugin_name); gkrellm_record_state(INIT_MONITOR, &mon_tmp); #if defined(WIN32) { win32_plugin_callbacks ** plugin_cb = NULL; if (!g_module_symbol(module, "callbacks", (gpointer) &plugin_cb)) { snprintf(buf, sizeof(buf), _("\tError: %s\n"), g_module_error()); plugin_log(buf, NULL); g_module_close(module); return NULL; } *plugin_cb = &gkrellm_callbacks; } #endif m = (*init_plugin)(); _GK.no_messages = FALSE; g_free(mon_tmp.name); mon_tmp.name = NULL; gkrellm_record_state(INTERNAL, NULL); if (m == NULL) { plugin_log(_("\tOoops! plugin returned NULL, aborting\n"), NULL); g_module_close(module); return NULL; } for (list = gkrellm_monitor_list; list; list = list->next) { mm = (GkrellmMonitor *) list->data; if ( !mm->privat || !mm->privat->style_name || !m->privat || !m->privat->style_name || strcmp(mm->privat->style_name, m->privat->style_name) ) continue; plugin_log(_("\tWarning: style name \""), m->privat->style_name, _("\" already used by:\n\t\t"), mm->path, "\n", NULL); } for (list = gkrellm_monitor_list; list; list = list->next) { mm = (GkrellmMonitor *) list->data; if ( !mm->config_keyword || !m->config_keyword || strcmp(mm->config_keyword, m->config_keyword) ) continue; plugin_log(_("\tWarning: config keyword \""), m->config_keyword, _("\" already used by:\n\t\t"), mm->path, "\n", NULL); } m->handle = module; m->path = plugin_name; if (!m->name) m->name = g_path_get_basename(m->path); if (m->privat == NULL) /* Won't be null if style was added */ m->privat = g_new0(GkrellmMonprivate, 1); m->privat->enabled = TRUE; /* Enforce some id fields. */ m->id &= ~(MON_ID_MASK | MON_CONFIG_MASK); m->id |= MON_PLUGIN; if (PLUGIN_INSERT_BEFORE_ID(m) >= N_BUILTIN_MONITORS) m->insert_before_id = MON_UPTIME; if (!user_placement(m)) { m->privat->insert_before_id = PLUGIN_INSERT_BEFORE_ID(m); m->privat->gravity = PLUGIN_GRAVITY(m); m->privat->insert_after = PLUGIN_INSERT_AFTER(m); } gkrellm_place_plugin(&gkrellm_monitor_list, m); return m; }
void gkrellm_place_plugin(GList **monitor_list, GkrellmMonitor *plugin) { GkrellmMonitor *mon; GList *list, *plist, *waste; gint n, gravity, after_flag; gchar buf[120]; if (plugin->create_monitor && !plugin->privat->main_vbox) { plugin->privat->main_vbox = gtk_vbox_new(FALSE, 0); plugin->privat->top_spacer.vbox = gtk_vbox_new(FALSE, 0); plugin->privat->vbox = gtk_vbox_new(FALSE, 0); plugin->privat->bottom_spacer.vbox = gtk_vbox_new(FALSE, 0); } for (plist = NULL, list = *monitor_list; list; list = list->next) { mon = (GkrellmMonitor *) list->data; /* Save list position as plugins are encountered so we can later | walk through them looking at gravity. */ if (MONITOR_ID(mon) == MON_PLUGIN && plist == NULL) plist = list; if (MONITOR_ID(mon) == plugin->privat->insert_before_id) { after_flag = plugin->privat->insert_after; gravity = plugin->privat->gravity; snprintf(buf, sizeof(buf), _("\t%s: placement is %s %s G:%d\n"), plugin->name, after_flag ? _("after") : _("before"), mon->name, gravity); plugin_log(buf, NULL); if (after_flag) { if ((n = g_list_position(*monitor_list, list)) < 0) n = 0; *monitor_list = g_list_insert(*monitor_list, plugin, n + 1); } else { /* If there are plugins already above this builtin, then place | based on gravity. Insert above the first plugin found that | has greater gravity than the current placing plugin. */ if (plist) { for ( ; plist != list; plist = plist->next) { mon = (GkrellmMonitor *) plist->data; if (mon->privat->gravity > gravity) break; } list = plist; } if (list == *monitor_list) *monitor_list = g_list_prepend(list, plugin); else waste = g_list_prepend(list, plugin); } return; } else if (MONITOR_ID(mon) != MON_PLUGIN) plist = NULL; } if (plugin->privat->insert_before_id != MON_UPTIME) { plugin->privat->insert_before_id = MON_UPTIME; gkrellm_place_plugin(monitor_list, plugin); return; } *monitor_list = g_list_append(*monitor_list, plugin); }
void gkrellm_plugins_load(void) { GkrellmMonitor *m; gchar *path; if (_GK.command_line_plugin) { if ( *_GK.command_line_plugin != '.' && !strchr(_GK.command_line_plugin, G_DIR_SEPARATOR) ) path = g_strconcat(".", G_DIR_SEPARATOR_S, _GK.command_line_plugin, NULL); else path = g_strdup(_GK.command_line_plugin); plugin_log(_("*** Command line plugin:\n"), NULL); if ((m = install_plugin(path)) == NULL) g_free(path); else { m->privat->from_command_line = TRUE; plugins_list = g_list_append(plugins_list, m); } plugin_log("\n", NULL); } load_plugins_enable_file(); load_plugins_placement_file(); path = g_strconcat(gkrellm_homedir(), G_DIR_SEPARATOR_S, GKRELLM_PLUGINS_DIR, NULL); scan_for_plugins(path); g_free(path); #if defined(WIN32) path = NULL; #if GLIB_CHECK_VERSION(2,16,0) gchar *install_path; install_path = g_win32_get_package_installation_directory_of_module(NULL); if (install_path != NULL) { path = g_build_filename(install_path, "lib", "gkrellm2", "plugins", NULL); g_free(install_path); } #else // deprecated since glib 2.16.0 path = g_win32_get_package_installation_subdirectory(NULL, NULL, "lib/gkrellm2/plugins"); #endif if (path) { scan_for_plugins(path); g_free(path); } #endif #if defined(LOCAL_PLUGINS_DIR) scan_for_plugins(LOCAL_PLUGINS_DIR); #endif #if defined(SYSTEM_PLUGINS_DIR) scan_for_plugins(SYSTEM_PLUGINS_DIR); #endif }
static void scan_for_plugins(gchar *path) { GDir *dir; gchar *name, *filename; GList *list; GkrellmMonitor *m = NULL; gchar *s; gboolean exists; if (!path || !*path || (dir = g_dir_open(path, 0, NULL)) == NULL) return; while ((name = (gchar *) g_dir_read_name(dir)) != NULL) { if ( !string_suffix(name, "so") && !string_suffix(name, "la") && !string_suffix(name, "dll") ) continue; /* If there's a libtool .la archive, won't want to load this .so */ if ( !string_suffix(name, "la") && (s = strrchr(name, '.')) != NULL ) { s = g_strndup(name, s - name); filename = g_strconcat(path, G_DIR_SEPARATOR_S, s, ".la", NULL); exists = g_file_test(filename, G_FILE_TEST_EXISTS); g_free(s); g_free(filename); if (exists) continue; } for (list = plugins_list; list; list = list->next) { m = (GkrellmMonitor *) list->data; s = g_path_get_basename(m->path); exists = !strcmp(s, name); g_free(s); if (exists) break; m = NULL; } s = g_strconcat(path, G_DIR_SEPARATOR_S, name, NULL); if (m) { plugin_log(_("Ignoring duplicate plugin "), s, "\n", NULL); g_free(s); continue; } m = install_plugin(s); if (m) /* s is saved for use */ { plugins_list = g_list_append(plugins_list, m); s = g_path_get_basename(m->path); if (! gkrellm_string_in_list(plugins_enable_list, s)) m->privat->enabled = FALSE; } g_free(s); } g_dir_close(dir); }