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
,
31 const char *host_name
,
32 const AvahiAddress
*address
,
35 AvahiLookupResultFlags flags
,
36 AVAHI_GCC_UNUSED
void* userdata
) {
40 /* Called whenever a service has been resolved successfully or timed out */
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
);
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
);
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
, '_');
76 AvahiStringList
*needle
;
80 if ((needle
= avahi_string_list_find (txt
, "interfaces")) != NULL
) {
81 const char *delim
= ",";
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
);
97 snprintf(rrdfile
, 1022, "/mnt/netapp/users/%s/%s/interface_eth%d.rrd", customer
, vm
, no
);
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());
120 for (i
= 0; i
< 4; i
++) {
121 AvahiStringList
*newneedle
;
123 snprintf(param
, 253, "interface_%s_%s", tok
, params
[i
]);
126 if ((newneedle
= avahi_string_list_find (txt
, param
)) != NULL
) {
127 avahi_string_list_get_pair (newneedle
, NULL
, &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]));
140 rrd_update(5, r_update
);
142 for (i
= 0; i
< 4; i
++) {
146 tok
= strtok (NULL
, delim
);
153 if ((needle
= avahi_string_list_find (txt
, "cpuTime")) != NULL
) {
155 snprintf(rrdfile
, 1023, "/mnt/netapp/users/%s/%s/cpuTime.rrd", customer
, vm
);
156 rrdfile
[1023] = '\0';
158 avahi_string_list_get_pair (needle
, NULL
, &winner
, NULL
);
159 if (winner
!= NULL
) {
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());
173 snprintf(buf
, 127, "N:%s", winner
);
176 rrd_update(3, r_update
);
178 if (rrd_test_error()) {
179 fprintf(stderr
, "%s\n", rrd_get_error());
193 static void browse_callback(
194 AvahiServiceBrowser
*b
,
195 AvahiIfIndex interface
,
196 AvahiProtocol protocol
,
197 AvahiBrowserEvent event
,
201 AVAHI_GCC_UNUSED AvahiLookupResultFlags flags
,
202 AVAHI_GCC_UNUSED
void* userdata
) {
206 /* Called whenever a new services becomes available on the LAN or is removed from the LAN */
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
);
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
)));
229 case AVAHI_BROWSER_REMOVE
:
230 fprintf(stderr
, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name
, type
, domain
);
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");
240 static void client_callback(AvahiClient
*c
, AvahiClientState state
, AVAHI_GCC_UNUSED
void * userdata
) {
243 /* Called whenever the client or server state changes */
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
);
259 case AVAHI_CLIENT_FAILURE
: {
261 AvahiClient
*client
= NULL
;
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 */
271 fprintf(stderr
, "Failed to create client: %s\n", avahi_strerror(error
));
272 avahi_simple_poll_quit(simple_poll
);
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. */
290 case AVAHI_CLIENT_CONNECTING
:
296 int main(AVAHI_GCC_UNUSED
int argc
, AVAHI_GCC_UNUSED
char*argv
[]) {
299 /* Allocate main loop object */
300 if (!(simple_poll
= avahi_simple_poll_new())) {
301 fprintf(stderr
, "Failed to create simple poll object.\n");
305 client_callback(NULL
, AVAHI_CLIENT_FAILURE
, NULL
);
307 /* Run the main loop */
308 avahi_simple_poll_loop(simple_poll
);
314 avahi_simple_poll_free(simple_poll
);