]> arthur.barton.de Git - netdata.git/blob - src/rrdhost.c
6ec171b15cf1b10053cbdff1f06d6e2ca55a9b2d
[netdata.git] / src / rrdhost.c
1 #define NETDATA_RRD_INTERNALS 1
2 #include "common.h"
3
4 // ----------------------------------------------------------------------------
5 // RRDHOST
6
7 RRDHOST localhost = {
8         .hostname = "localhost",
9         .machine_guid = "",
10         .rrdset_root = NULL,
11         .rrdset_root_rwlock = PTHREAD_RWLOCK_INITIALIZER,
12         .rrdset_root_index = {
13                 { NULL, rrdset_compare },
14                 AVL_LOCK_INITIALIZER
15         },
16         .rrdset_root_index_name = {
17                 { NULL, rrdset_compare_name },
18                 AVL_LOCK_INITIALIZER
19         },
20         .rrdfamily_root_index = {
21                 { NULL, rrdfamily_compare },
22                 AVL_LOCK_INITIALIZER
23         },
24         .variables_root_index = {
25                 { NULL, rrdvar_compare },
26                 AVL_LOCK_INITIALIZER
27         },
28         .health_log = {
29                 .next_log_id = 1,
30                 .next_alarm_id = 1,
31                 .count = 0,
32                 .max = 1000,
33                 .alarms = NULL,
34                 .alarm_log_rwlock = PTHREAD_RWLOCK_INITIALIZER
35         },
36         .next = NULL
37 };
38
39 void rrdhost_init(char *hostname) {
40     localhost.hostname = hostname;
41     localhost.health_log.next_log_id =
42         localhost.health_log.next_alarm_id = (uint32_t)now_realtime_sec();
43 }
44
45 void rrdhost_rwlock(RRDHOST *host) {
46     pthread_rwlock_wrlock(&host->rrdset_root_rwlock);
47 }
48
49 void rrdhost_rdlock(RRDHOST *host) {
50     pthread_rwlock_rdlock(&host->rrdset_root_rwlock);
51 }
52
53 void rrdhost_unlock(RRDHOST *host) {
54     pthread_rwlock_unlock(&host->rrdset_root_rwlock);
55 }
56
57 void rrdhost_check_rdlock_int(RRDHOST *host, const char *file, const char *function, const unsigned long line) {
58     int ret = pthread_rwlock_trywrlock(&host->rrdset_root_rwlock);
59
60     if(ret == 0)
61         fatal("RRDHOST '%s' should be read-locked, but it is not, at function %s() at line %lu of file '%s'", host->hostname, function, line, file);
62 }
63
64 void rrdhost_check_wrlock_int(RRDHOST *host, const char *file, const char *function, const unsigned long line) {
65     int ret = pthread_rwlock_tryrdlock(&host->rrdset_root_rwlock);
66
67     if(ret == 0)
68         fatal("RRDHOST '%s' should be write-locked, but it is not, at function %s() at line %lu of file '%s'", host->hostname, function, line, file);
69 }
70
71 void rrdhost_free(RRDHOST *host) {
72     info("Freeing all memory...");
73
74     rrdhost_rwlock(host);
75
76     RRDSET *st;
77     for(st = host->rrdset_root; st ;) {
78         RRDSET *next = st->next;
79
80         pthread_rwlock_wrlock(&st->rwlock);
81
82         while(st->variables)
83             rrdsetvar_free(st->variables);
84
85         while(st->alarms)
86             rrdsetcalc_unlink(st->alarms);
87
88         while(st->dimensions)
89             rrddim_free(st, st->dimensions);
90
91         if(unlikely(rrdset_index_del(host, st) != st))
92             error("RRDSET: INTERNAL ERROR: attempt to remove from index chart '%s', removed a different chart.", st->id);
93
94         rrdset_index_del_name(host, st);
95
96         st->rrdfamily->use_count--;
97         if(!st->rrdfamily->use_count)
98             rrdfamily_free(host, st->rrdfamily);
99
100         pthread_rwlock_unlock(&st->rwlock);
101
102         if(st->mapped == RRD_MEMORY_MODE_SAVE || st->mapped == RRD_MEMORY_MODE_MAP) {
103             debug(D_RRD_CALLS, "Unmapping stats '%s'.", st->name);
104             munmap(st, st->memsize);
105         }
106         else
107             freez(st);
108
109         st = next;
110     }
111     host->rrdset_root = NULL;
112
113     rrdhost_unlock(host);
114
115     info("Memory cleanup completed...");
116 }
117
118 void rrdhost_save(RRDHOST *host) {
119     info("Saving database...");
120
121     RRDSET *st;
122     RRDDIM *rd;
123
124     // we get an write lock
125     // to ensure only one thread is saving the database
126     rrdhost_rwlock(host);
127
128     for(st = host->rrdset_root; st ; st = st->next) {
129         pthread_rwlock_rdlock(&st->rwlock);
130
131         if(st->mapped == RRD_MEMORY_MODE_SAVE) {
132             debug(D_RRD_CALLS, "Saving stats '%s' to '%s'.", st->name, st->cache_filename);
133             savememory(st->cache_filename, st, st->memsize);
134         }
135
136         for(rd = st->dimensions; rd ; rd = rd->next) {
137             if(likely(rd->memory_mode == RRD_MEMORY_MODE_SAVE)) {
138                 debug(D_RRD_CALLS, "Saving dimension '%s' to '%s'.", rd->name, rd->cache_filename);
139                 savememory(rd->cache_filename, rd, rd->memsize);
140             }
141         }
142
143         pthread_rwlock_unlock(&st->rwlock);
144     }
145
146     rrdhost_unlock(host);
147 }
148
149 void rrdhost_free_all(void) {
150     RRDHOST *host;
151
152     // FIXME: lock all hosts
153
154     for(host = &localhost; host ;) {
155         RRDHOST *next = host = host->next;
156         rrdhost_free(host);
157         host = next;
158     }
159
160     // FIXME: unlock all hosts
161 }
162
163 void rrdhost_save_all(void) {
164     RRDHOST *host;
165     for(host = &localhost; host ; host = host->next)
166         rrdhost_save(host);
167 }