rrd based system stats
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

149 lines
4.4 KiB

  1. /***************************************************************************
  2. * Copyright (C) 06/2006 by Olaf Rempel *
  3. * razzor@kopf-tisch.de *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program; if not, write to the *
  17. * Free Software Foundation, Inc., *
  18. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  19. ***************************************************************************/
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <dlfcn.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <time.h>
  26. #include <limits.h>
  27. #include "configfile.h"
  28. #include "event.h"
  29. #include "logging.h"
  30. #include "network.h"
  31. #include "plugins.h"
  32. #define FLAGS_ACTIVE 0x01
  33. static LIST_HEAD(plugin_list);
  34. static struct event_timeout *probe_event;
  35. static int plugin_init_cb(const char *filename, void *privdata)
  36. {
  37. const char *plugin_dir = (const char *)privdata;
  38. char *fullname = malloc(PATH_MAX);
  39. if (fullname == NULL) {
  40. log_print(LOG_ERROR, "plugin_init_cb(): out of memory");
  41. return -1;
  42. }
  43. int len = snprintf(fullname, PATH_MAX, "%s/%s", plugin_dir, filename);
  44. if (len < 0 || len >= PATH_MAX) {
  45. log_print(LOG_ERROR, "plugin_init_cb(): file name too long: %s/%s", plugin_dir, filename);
  46. free(fullname);
  47. return -1;
  48. }
  49. dlerror();
  50. void *dlhandle = dlopen(fullname, RTLD_NOW);
  51. if (dlhandle == NULL) {
  52. log_print(LOG_ERROR, "plugin_init_cb(): dlopen: %s", dlerror());
  53. free(fullname);
  54. return -1;
  55. }
  56. free(fullname);
  57. struct sammler_plugin *plugin = dlsym(dlhandle, "plugin");
  58. if (plugin == NULL) {
  59. log_print(LOG_ERROR, "plugin_init_cb(): failed to load '%s'", filename);
  60. dlclose(dlhandle);
  61. return -1;
  62. }
  63. if (plugin->init != NULL && (plugin->init() != 0)) {
  64. log_print(LOG_ERROR, "plugin_init_cb(): Plugin '%s': init() failed", plugin->name);
  65. dlclose(dlhandle);
  66. return -1;
  67. }
  68. log_print(LOG_INFO, "Plugin '%s' loaded", plugin->name);
  69. plugin->lastprobe = 0;
  70. plugin->flags = FLAGS_ACTIVE;
  71. plugin->dlhandle = dlhandle;
  72. list_add_tail(&plugin->list, &plugin_list);
  73. return 0;
  74. }
  75. static int plugins_probe(int timerid, void *privdata)
  76. {
  77. time_t now;
  78. time(&now);
  79. struct sammler_plugin *plugin;
  80. list_for_each_entry(plugin, &plugin_list, list) {
  81. if (!(plugin->flags & FLAGS_ACTIVE))
  82. continue;
  83. if (plugin->lastprobe + plugin->interval <= now) {
  84. if (plugin->probe() != 0) {
  85. log_print(LOG_ERROR, "plugin_probe(): plugin '%s' disabled", plugin->name);
  86. plugin->flags &= ~FLAGS_ACTIVE;
  87. }
  88. plugin->lastprobe = now;
  89. }
  90. }
  91. net_submit_flush();
  92. return 0;
  93. }
  94. int plugin_init(void)
  95. {
  96. const char *plugin_dir = config_get_string("global", "plugin_dir", "plugins");
  97. int cnt = config_get_strings("global", "plugin", plugin_init_cb, (void *)plugin_dir);
  98. if (cnt == 0) {
  99. log_print(LOG_ERROR, "plugin_init(): no working plugins");
  100. return -1;
  101. }
  102. probe_event = event_add_timeout_ms(1000, plugins_probe, 0, NULL);
  103. return 0;
  104. }
  105. int plugin_close(void)
  106. {
  107. struct sammler_plugin *plugin, *tmp;
  108. list_for_each_entry_safe(plugin, tmp, &plugin_list, list) {
  109. list_del(&plugin->list);
  110. if (plugin->fini != NULL && plugin->fini() != 0)
  111. log_print(LOG_ERROR, "plugin_close(): Plugin '%s': fini() failed", plugin->name);
  112. dlclose(plugin->dlhandle);
  113. }
  114. event_remove_timeout(probe_event);
  115. return 0;
  116. }
  117. struct sammler_plugin * plugin_lookup(const char *name)
  118. {
  119. struct sammler_plugin *plugin;
  120. list_for_each_entry(plugin, &plugin_list, list) {
  121. if (!strcmp(plugin->name, name))
  122. return plugin;
  123. }
  124. return NULL;
  125. }