Updates for restoring/save.
[handlervirt.git] / rrdsaver.c
blobd045ac2dd1ede326792ab33cda2f84a69c64e89f
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <errno.h>
6 #include <rrd.h>
7 #include <sys/stat.h>
9 #include <avahi-client/client.h>
10 #include <avahi-client/publish.h>
11 #include <avahi-client/lookup.h>
13 #include <avahi-common/alternative.h>
14 #include <avahi-common/simple-watch.h>
15 #include <avahi-common/malloc.h>
16 #include <avahi-common/error.h>
17 #include <avahi-common/timeval.h>
19 #include <libvirt/libvirt.h>
21 static AvahiSimplePoll *simple_poll = NULL;
23 static void resolve_callback(
24 AvahiServiceResolver *r,
25 AVAHI_GCC_UNUSED AvahiIfIndex interface,
26 AVAHI_GCC_UNUSED AvahiProtocol protocol,
27 AvahiResolverEvent event,
28 const char *name,
29 const char *type,
30 const char *domain,
31 const char *host_name,
32 const AvahiAddress *address,
33 uint16_t port,
34 AvahiStringList *txt,
35 AvahiLookupResultFlags flags,
36 AVAHI_GCC_UNUSED void* userdata) {
38 assert(r);
40 /* Called whenever a service has been resolved successfully or timed out */
42 switch (event) {
43 case AVAHI_RESOLVER_FAILURE:
44 fprintf(stderr, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
45 avahi_service_resolver_free(r);
46 break;
48 case AVAHI_RESOLVER_FOUND: {
49 char a[AVAHI_ADDRESS_STR_MAX], *t;
51 fprintf(stderr, "Service '%s' of type '%s' in domain '%s':\n", name, type, domain);
53 avahi_address_snprint(a, sizeof(a), address);
54 t = avahi_string_list_to_string(txt);
55 fprintf(stderr,
56 "\t%s:%u (%s)\n"
57 "\tTXT=%s\n"
58 "\tcookie is %u\n"
59 "\tis_local: %i\n"
60 "\tour_own: %i\n"
61 "\twide_area: %i\n"
62 "\tmulticast: %i\n"
63 "\tcached: %i\n",
64 host_name, port, a,
66 avahi_string_list_get_service_cookie(txt),
67 !!(flags & AVAHI_LOOKUP_RESULT_LOCAL),
68 !!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN),
69 !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA),
70 !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST),
71 !!(flags & AVAHI_LOOKUP_RESULT_CACHED));
73 char *customer = strdup(name);
74 char *vm = strchr(customer, '_');
75 if (vm != NULL) {
76 AvahiStringList *needle;
77 *vm = '\0';
78 vm++;
80 if ((needle = avahi_string_list_find (txt, "interfaces")) != NULL) {
81 const char *delim = ",";
82 unsigned int no = 0;
83 char *winner, *tok;
84 // char *params[] = { "rxbytes", "rxpackets", "rxerrs", "rxdrop",
85 // "txbytes", "txpackets", "txerrs", "txdrop" };
86 char *params[] = { "rxbytes", "rxpackets",
87 "txbytes", "txpackets" };
89 avahi_string_list_get_pair (needle, NULL, &winner, NULL);
91 tok = strtok (winner, delim);
92 while (tok != NULL) {
93 int i;
94 char rrdfile[1024];
95 char buf[1024];
96 struct stat statbuf;
97 snprintf(rrdfile, 1022, "/mnt/netapp/users/%s/%s/interface_eth%d.rrd", customer, vm, no);
98 rrdfile[1023] = '\0';
100 char *values[4];
102 char *r_update[5] = {"update", rrdfile, "--template", "rxbytes:rxpackets:txbytes:txpackets", buf};
104 if (stat(rrdfile, &statbuf) != 0) {
105 char *r_create[14] = {"create", rrdfile, "-s 30",
106 "DS:rxbytes:DERIVE:1800:0:100000000000",
107 "DS:rxpackets:DERIVE:1800:0:100000000000",
108 "DS:txbytes:DERIVE:1800:0:100000000000",
109 "DS:txpackets:DERIVE:1800:0:100000000000",
110 "RRA:AVERAGE:0.5:1:1200",
111 "RRA:AVERAGE:0.5:10:1200",
112 "RRA:AVERAGE:0.5:120:2400" };
113 rrd_create(10, r_create);
114 if (rrd_test_error()) {
115 fprintf(stderr, "create: %s\n", rrd_get_error());
116 rrd_clear_error();
120 for (i = 0; i < 4; i++) {
121 AvahiStringList *newneedle;
122 char param[256];
123 snprintf(param, 253, "interface_%s_%s", tok, params[i]);
124 param[254] = '\0';
126 if ((newneedle = avahi_string_list_find (txt, param)) != NULL) {
127 avahi_string_list_get_pair (newneedle, NULL, &values[i], NULL);
128 } else {
129 values[i] = NULL;
133 snprintf(buf, 1022, "N:%s:%s:%s:%s",
134 (values[0] == NULL?"U":values[0]),
135 (values[1] == NULL?"U":values[1]),
136 (values[6] == NULL?"U":values[2]),
137 (values[7] == NULL?"U":values[3]));
139 printf("%s\n", buf);
140 rrd_update(5, r_update);
142 for (i = 0; i < 4; i++) {
143 free(values[i]);
146 tok = strtok (NULL, delim);
149 free(winner);
150 no++;
153 if ((needle = avahi_string_list_find (txt, "cpuTime")) != NULL) {
154 char rrdfile[1024];
155 snprintf(rrdfile, 1023, "/mnt/netapp/users/%s/%s/cpuTime.rrd", customer, vm);
156 rrdfile[1023] = '\0';
157 char *winner;
158 avahi_string_list_get_pair (needle, NULL, &winner, NULL);
159 if (winner != NULL) {
160 struct stat statbuf;
161 char buf[128];
162 char *r_update[3] = {"update", rrdfile, buf};
164 if (stat(rrdfile, &statbuf) != 0) {
165 char *r_create[7] = {"create", rrdfile, "-s 30", "DS:cpuTime:DERIVE:1800:0:100000000000", "RRA:AVERAGE:0.5:1:1200", "RRA:AVERAGE:0.5:10:1200", "RRA:AVERAGE:0.5:120:2400" };
166 rrd_create(7, r_create);
167 if (rrd_test_error()) {
168 fprintf(stderr, "create: %s\n", rrd_get_error());
169 rrd_clear_error();
173 snprintf(buf, 127, "N:%s", winner);
174 buf[127] = '\0';
175 avahi_free(winner);
176 rrd_update(3, r_update);
178 if (rrd_test_error()) {
179 fprintf(stderr, "%s\n", rrd_get_error());
180 rrd_clear_error();
185 free(customer);
187 avahi_free(t);
193 static void browse_callback(
194 AvahiServiceBrowser *b,
195 AvahiIfIndex interface,
196 AvahiProtocol protocol,
197 AvahiBrowserEvent event,
198 const char *name,
199 const char *type,
200 const char *domain,
201 AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
202 AVAHI_GCC_UNUSED void* userdata) {
204 assert(b);
206 /* Called whenever a new services becomes available on the LAN or is removed from the LAN */
208 switch (event) {
209 case AVAHI_BROWSER_FAILURE:
210 fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b))));
211 avahi_service_browser_free(b);
212 return;
214 case AVAHI_BROWSER_NEW: {
215 AvahiClient *c = avahi_service_browser_get_client(b);
216 fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
218 /* We ignore the returned resolver object. In the callback
219 function we free it. If the server is terminated before
220 the callback function is called the server will free
221 the resolver for us. */
223 if (!(avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, c)))
224 fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c)));
226 break;
229 case AVAHI_BROWSER_REMOVE:
230 fprintf(stderr, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
231 break;
233 case AVAHI_BROWSER_ALL_FOR_NOW:
234 case AVAHI_BROWSER_CACHE_EXHAUSTED:
235 fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW");
236 break;
240 static void client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata) {
241 // assert(c);
243 /* Called whenever the client or server state changes */
245 switch (state) {
246 case AVAHI_CLIENT_S_RUNNING: {
247 /* The server has startup successfully and registered its host
248 * name on the network, so it's time to create our services */
249 AvahiServiceBrowser *sb = NULL;
251 /* Create the service browser */
252 if (!(sb = avahi_service_browser_new(c, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_domu._tcp", NULL, 0, browse_callback, NULL))) {
253 fprintf(stderr, "Failed to create service browser: %s\n", avahi_strerror(avahi_client_errno(c)));
254 avahi_simple_poll_quit(simple_poll);
256 break;
259 case AVAHI_CLIENT_FAILURE: {
260 int error;
261 AvahiClient *client = NULL;
263 if (c)
264 avahi_client_free(c);
266 /* Allocate a new client */
267 client = avahi_client_new(avahi_simple_poll_get(simple_poll), AVAHI_CLIENT_NO_FAIL, client_callback, NULL, &error);
269 /* Check wether creating the client object succeeded */
270 if (!client) {
271 fprintf(stderr, "Failed to create client: %s\n", avahi_strerror(error));
272 avahi_simple_poll_quit(simple_poll);
275 break;
278 case AVAHI_CLIENT_S_COLLISION:
279 /* Let's drop our registered services. When the server is back
280 * in AVAHI_SERVER_RUNNING state we will register them
281 * again with the new host name. */
283 case AVAHI_CLIENT_S_REGISTERING:
284 /* The server records are now being established. This
285 * might be caused by a host name change. We need to wait
286 * for our own records to register until the host name is
287 * properly esatblished. */
288 break;
290 case AVAHI_CLIENT_CONNECTING:
296 int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char*argv[]) {
297 int ret = 1;
299 /* Allocate main loop object */
300 if (!(simple_poll = avahi_simple_poll_new())) {
301 fprintf(stderr, "Failed to create simple poll object.\n");
302 goto fail;
305 client_callback(NULL, AVAHI_CLIENT_FAILURE, NULL);
307 /* Run the main loop */
308 avahi_simple_poll_loop(simple_poll);
310 ret = 0;
312 fail:
313 if (simple_poll)
314 avahi_simple_poll_free(simple_poll);
316 return ret;