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
,
204 AvahiClient
*c
= userdata
;
207 /* Called whenever a new services becomes available on the LAN or is removed from the LAN */
210 case AVAHI_BROWSER_FAILURE
:
212 fprintf(stderr
, "(Browser) %s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b
))));
213 avahi_simple_poll_quit(simple_poll
);
216 case AVAHI_BROWSER_NEW
:
217 fprintf(stderr
, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name
, type
, domain
);
219 /* We ignore the returned resolver object. In the callback
220 function we free it. If the server is terminated before
221 the callback function is called the server will free
222 the resolver for us. */
224 if (!(avahi_service_resolver_new(c
, interface
, protocol
, name
, type
, domain
, AVAHI_PROTO_UNSPEC
, 0, resolve_callback
, c
)))
225 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 */
251 case AVAHI_CLIENT_FAILURE
:
252 fprintf(stderr
, "Client failure: %s\n", avahi_strerror(avahi_client_errno(c
)));
253 avahi_simple_poll_quit(simple_poll
);
256 case AVAHI_CLIENT_S_COLLISION
:
257 /* Let's drop our registered services. When the server is back
258 * in AVAHI_SERVER_RUNNING state we will register them
259 * again with the new host name. */
261 case AVAHI_CLIENT_S_REGISTERING
:
262 /* The server records are now being established. This
263 * might be caused by a host name change. We need to wait
264 * for our own records to register until the host name is
265 * properly esatblished. */
268 case AVAHI_CLIENT_CONNECTING
:
274 int main(AVAHI_GCC_UNUSED
int argc
, AVAHI_GCC_UNUSED
char*argv
[]) {
275 AvahiClient
*client
= NULL
;
276 AvahiServiceBrowser
*sb
= NULL
;
280 /* Allocate main loop object */
281 if (!(simple_poll
= avahi_simple_poll_new())) {
282 fprintf(stderr
, "Failed to create simple poll object.\n");
286 /* Allocate a new client */
287 client
= avahi_client_new(avahi_simple_poll_get(simple_poll
), 0, client_callback
, NULL
, &error
);
289 /* Check wether creating the client object succeeded */
291 fprintf(stderr
, "Failed to create client: %s\n", avahi_strerror(error
));
295 /* Create the service browser */
296 if (!(sb
= avahi_service_browser_new(client
, AVAHI_IF_UNSPEC
, AVAHI_PROTO_UNSPEC
, "_domu._tcp", NULL
, 0, browse_callback
, client
))) {
297 fprintf(stderr
, "Failed to create service browser: %s\n", avahi_strerror(avahi_client_errno(client
)));
302 /* Run the main loop */
303 avahi_simple_poll_loop(simple_poll
);
311 avahi_service_browser_free(sb
);
314 avahi_client_free(client
);
317 avahi_simple_poll_free(simple_poll
);