#include "popen.h"
#include "plugin_tc.h"
#include "main.h"
+#include "../config.h"
#define RRD_TYPE_TC "tc"
#define RRD_TYPE_TC_LEN strlen(RRD_TYPE_TC)
avl_tree tc_device_root_index = {
NULL,
- tc_device_compare,
-#ifdef AVL_LOCK_WITH_MUTEX
- PTHREAD_MUTEX_INITIALIZER
-#else
- PTHREAD_RWLOCK_INITIALIZER
-#endif
+ tc_device_compare
};
#define tc_device_index_add(st) avl_insert(&tc_device_root_index, (avl *)(st))
#define tc_device_index_del(st) avl_remove(&tc_device_root_index, (avl *)(st))
-static struct tc_device *tc_device_index_find(const char *id, uint32_t hash) {
+static inline struct tc_device *tc_device_index_find(const char *id, uint32_t hash) {
struct tc_device *result = NULL, tmp;
tmp.id = (char *)id;
tmp.hash = (hash)?hash:simple_hash(tmp.id);
- avl_search(&(tc_device_root_index), (avl *)&tmp, tc_device_iterator, (avl **)&result);
+ avl_search(&(tc_device_root_index), (avl *) &tmp, tc_device_iterator, (avl **) &result);
return result;
}
#define tc_class_index_add(st, rd) avl_insert(&((st)->classes_index), (avl *)(rd))
#define tc_class_index_del(st, rd) avl_remove(&((st)->classes_index), (avl *)(rd))
-static struct tc_class *tc_class_index_find(struct tc_device *st, const char *id, uint32_t hash) {
+static inline struct tc_class *tc_class_index_find(struct tc_device *st, const char *id, uint32_t hash) {
struct tc_class *result = NULL, tmp;
tmp.id = (char *)id;
tmp.hash = (hash)?hash:simple_hash(tmp.id);
- avl_search(&(st->classes_index), (avl *)&tmp, tc_class_iterator, (avl **)&result);
+ avl_search(&(st->classes_index), (avl *) &tmp, tc_class_iterator, (avl **) &result);
return result;
}
// ----------------------------------------------------------------------------
-static void tc_class_free(struct tc_device *n, struct tc_class *c) {
+static inline void tc_class_free(struct tc_device *n, struct tc_class *c) {
debug(D_TC_LOOP, "Removing from device '%s' class '%s', parentid '%s', leafid '%s', seen=%d", n->id, c->id, c->parentid?c->parentid:"", c->leafid?c->leafid:"", c->seen);
if(c->next) c->next->prev = c->prev;
free(c);
}
-static void tc_device_classes_cleanup(struct tc_device *d) {
+static inline void tc_device_classes_cleanup(struct tc_device *d) {
static int cleanup_every = 999;
if(cleanup_every > 0) {
}
}
-static void tc_device_commit(struct tc_device *d)
+static inline void tc_device_commit(struct tc_device *d)
{
static int enable_new_interfaces = -1;
tc_device_classes_cleanup(d);
}
-static void tc_device_set_class_name(struct tc_device *d, char *id, char *name)
+static inline void tc_device_set_class_name(struct tc_device *d, char *id, char *name)
{
struct tc_class *c = tc_class_index_find(d, id, 0);
if(c) {
}
}
-static void tc_device_set_device_name(struct tc_device *d, char *name) {
+static inline void tc_device_set_device_name(struct tc_device *d, char *name) {
if(d->name) free(d->name);
d->name = NULL;
}
}
-static void tc_device_set_device_family(struct tc_device *d, char *family) {
+static inline void tc_device_set_device_family(struct tc_device *d, char *family) {
if(d->family) free(d->family);
d->family = NULL;
// no need for null termination - it is already null
}
-static struct tc_device *tc_device_create(char *id)
+static inline struct tc_device *tc_device_create(char *id)
{
struct tc_device *d = tc_device_index_find(id, 0);
d->id = strdup(id);
d->hash = simple_hash(d->id);
- d->classes_index.root = NULL;
- d->classes_index.compar = tc_class_compare;
-
- int lock;
-#ifdef AVL_LOCK_WITH_MUTEX
- lock = pthread_mutex_init(&d->classes_index.mutex, NULL);
-#else
- lock = pthread_rwlock_init(&d->classes_index.rwlock, NULL);
-#endif
- if(lock != 0)
- fatal("Failed to initialize plugin_tc mutex/rwlock, return code %d.", lock);
-
+ avl_init(&d->classes_index, tc_class_compare);
tc_device_index_add(d);
if(!tc_device_root) {
return(d);
}
-static struct tc_class *tc_class_add(struct tc_device *n, char *id, char *parentid, char *leafid)
+static inline struct tc_class *tc_class_add(struct tc_device *n, char *id, char *parentid, char *leafid)
{
struct tc_class *c = tc_class_index_find(n, id, 0);
return(c);
}
-static void tc_device_free(struct tc_device *n)
+static inline void tc_device_free(struct tc_device *n)
{
if(n->next) n->next->prev = n->prev;
if(n->prev) n->prev->next = n->next;
free(n);
}
-static void tc_device_free_all()
+static inline void tc_device_free_all()
{
while(tc_device_root)
tc_device_free(tc_device_root);
}
}
-static void tc_split_words(char *str, char **words, int max_words) {
+static inline void tc_split_words(char *str, char **words, int max_words) {
char *s = str;
int i = 0;
// debug(D_TC_LOOP, "IGNORED line");
//}
}
- mypclose(fp, tc_child_pid);
+ // fgets() failed or loop broke
+ int code = mypclose(fp, tc_child_pid);
tc_child_pid = 0;
if(device) {
return NULL;
}
+ if(code == 1 || code == 127) {
+ // 1 = DISABLE
+ // 127 = cannot even run it
+ error("TC: tc-qos-helper.sh exited with code %d. Disabling it.", code);
+
+ tc_device_free_all();
+ pthread_exit(NULL);
+ return NULL;
+ }
+
sleep((unsigned int) rrd_update_every);
}
pthread_exit(NULL);
return NULL;
}
-