Remove annoying update message
[handlervirt.git] / domumdns.c
blob10dacad03507e37f8243a1d22eda67c34670a958
1 #include <time.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <assert.h>
6 #include <avahi-client/client.h>
7 #include <avahi-client/publish.h>
9 #include <avahi-common/alternative.h>
10 #include <avahi-common/simple-watch.h>
11 #include <avahi-common/malloc.h>
12 #include <avahi-common/error.h>
13 #include <avahi-common/timeval.h>
15 #include <libvirt/libvirt.h>
17 #define POLL 5
19 struct list_el {
20 unsigned int domainid;
21 AvahiEntryGroup *group;
22 unsigned short keep;
25 typedef struct list_el domu;
27 virConnectPtr conn = NULL; /* the hypervisor connection */
28 domu * domus = NULL; /* list of domains */
29 unsigned int domu_count = 0;
30 static AvahiSimplePoll *simple_poll = NULL;
33 static void entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, AVAHI_GCC_UNUSED void *userdata) {
34 /* Called whenever the entry group state changes */
36 switch (state) {
37 case AVAHI_ENTRY_GROUP_ESTABLISHED :
38 /* The entry group has been established successfully */
39 // fprintf(stderr, "Service '%s' successfully established.\n", name);
40 break;
42 case AVAHI_ENTRY_GROUP_COLLISION : {
43 char *n;
45 /* A service name collision with a remote service
46 * happened. Let's pick a new name */
47 //n = avahi_alternative_service_name(name);
48 //avahi_free(name);
49 //name = n;
51 // fprintf(stderr, "Service name collision, renaming service to '%s'\n", name);
53 /* And recreate the services */
54 //create_services(avahi_entry_group_get_client(g));
55 break;
58 case AVAHI_ENTRY_GROUP_FAILURE :
60 fprintf(stderr, "Entry group failure: %s\n", avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))));
62 /* Some kind of failure happened while we were registering our services */
63 avahi_simple_poll_quit(simple_poll);
64 break;
66 case AVAHI_ENTRY_GROUP_UNCOMMITED:
67 case AVAHI_ENTRY_GROUP_REGISTERING:
72 void create_services(AvahiClient *c) {
73 int maxid = virConnectNumOfDomains(conn);
74 if (maxid > 1) { /* ignore dom0 */
75 int *ids = (int *) malloc(sizeof(int) * maxid);
76 if ((maxid = virConnectListDomains(conn, &ids[0], maxid)) < 0) {
77 // error
78 } else {
79 int i;
80 unsigned int domu_count_new = (maxid - 1);
81 domu * domus_old = domus;
82 domus = (domu *) malloc(sizeof(domu) * domu_count_new);
83 for (i = 0; i < domu_count_new; i++) {
84 int j;
85 domus[i].group = NULL;
86 domus[i].domainid = ids[i+1];
87 domus[i].keep = 0;
89 for (j = 0; j < domu_count; j++) {
90 if (ids[i+1] == domus_old[j].domainid) {
91 domus[i].group = domus_old[j].group;
92 domus_old[j].keep = 1;
95 if (i > domu_count || domus[i].group == NULL) {
96 virDomainPtr thisDomain;
97 thisDomain = virDomainLookupByID(conn, ids[i+1]);
98 domus[i].group = avahi_entry_group_new(c, entry_group_callback, NULL);
99 avahi_entry_group_add_service(domus[i].group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, virDomainGetName(thisDomain), "_domu._tcp", NULL, NULL, 651, "test=blah", NULL, NULL);
100 avahi_entry_group_commit(domus[i].group);
104 for (i = 0; i < domu_count; i++) {
105 if (domus_old[i].keep == 0 && domus_old[i].group != NULL) {
106 avahi_entry_group_free(domus_old[i].group);
110 free(domus_old);
111 domu_count = domu_count_new;
113 free(ids);
118 static void client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata) {
119 assert(c);
121 /* Called whenever the client or server state changes */
123 switch (state) {
124 case AVAHI_CLIENT_S_RUNNING:
126 /* The server has startup successfully and registered its host
127 * name on the network, so it's time to create our services */
128 create_services(c);
129 break;
131 case AVAHI_CLIENT_FAILURE:
133 fprintf(stderr, "Client failure: %s\n", avahi_strerror(avahi_client_errno(c)));
134 avahi_simple_poll_quit(simple_poll);
136 break;
138 case AVAHI_CLIENT_S_COLLISION:
140 /* Let's drop our registered services. When the server is back
141 * in AVAHI_SERVER_RUNNING state we will register them
142 * again with the new host name. */
144 case AVAHI_CLIENT_S_REGISTERING:
146 /* The server records are now being established. This
147 * might be caused by a host name change. We need to wait
148 * for our own records to register until the host name is
149 * properly esatblished. */
151 /* if (group)
152 avahi_entry_group_reset(group);*/
154 break;
156 case AVAHI_CLIENT_CONNECTING:
163 static void modify_callback(AvahiTimeout *e, void *userdata) {
164 struct timeval tv;
165 AvahiClient *client = userdata;
167 // fprintf(stderr, "Doing some weird modification\n");
169 /* If the server is currently running, we need to remove our
170 * service and create it anew */
171 if (avahi_client_get_state(client) == AVAHI_CLIENT_S_RUNNING) {
172 /* And create them again with the new name */
173 create_services(client);
175 avahi_simple_poll_get(simple_poll)->timeout_update(e, avahi_elapse_time(&tv, 1000*POLL, 0));
178 int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char*argv[]) {
179 AvahiClient *client = NULL;
180 int error;
181 int ret = 1;
182 struct timeval tv;
184 /* NULL means connect to local Xen hypervisor */
185 conn = virConnectOpenReadOnly(NULL);
186 if (conn == NULL) {
187 fprintf(stderr, "Failed to connect to hypervisor\n");
188 goto fail;
191 /* Allocate main loop object */
192 if (!(simple_poll = avahi_simple_poll_new())) {
193 fprintf(stderr, "Failed to create simple poll object.\n");
194 goto fail;
197 /* Allocate a new client */
198 client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, client_callback, NULL, &error);
200 /* Check wether creating the client object succeeded */
201 if (!client) {
202 fprintf(stderr, "Failed to create client: %s\n", avahi_strerror(error));
203 goto fail;
206 /* After 10s do some weird modification to the service */
207 avahi_simple_poll_get(simple_poll)->timeout_new(
208 avahi_simple_poll_get(simple_poll),
209 avahi_elapse_time(&tv, 1000*POLL, 0),
210 modify_callback,
211 client);
213 /* Run the main loop */
214 avahi_simple_poll_loop(simple_poll);
216 ret = 0;
218 fail:
220 /* Cleanup things */
222 if (client)
223 avahi_client_free(client);
225 if (simple_poll)
226 avahi_simple_poll_free(simple_poll);
228 if (conn)
229 virConnectClose(conn);
231 return ret;