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>
20 unsigned int domainid
;
21 AvahiEntryGroup
*group
;
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 */
37 case AVAHI_ENTRY_GROUP_ESTABLISHED
:
38 /* The entry group has been established successfully */
39 // fprintf(stderr, "Service '%s' successfully established.\n", name);
42 case AVAHI_ENTRY_GROUP_COLLISION
: {
45 /* A service name collision with a remote service
46 * happened. Let's pick a new name */
47 //n = avahi_alternative_service_name(name);
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));
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
);
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) {
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
++) {
85 domus
[i
].group
= NULL
;
86 domus
[i
].domainid
= ids
[i
+1];
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
);
111 domu_count
= domu_count_new
;
118 static void client_callback(AvahiClient
*c
, AvahiClientState state
, AVAHI_GCC_UNUSED
void * userdata
) {
121 /* Called whenever the client or server state changes */
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 */
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
);
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. */
152 avahi_entry_group_reset(group);*/
156 case AVAHI_CLIENT_CONNECTING
:
163 static void modify_callback(AvahiTimeout
*e
, void *userdata
) {
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
;
184 /* NULL means connect to local Xen hypervisor */
185 conn
= virConnectOpenReadOnly(NULL
);
187 fprintf(stderr
, "Failed to connect to hypervisor\n");
191 /* Allocate main loop object */
192 if (!(simple_poll
= avahi_simple_poll_new())) {
193 fprintf(stderr
, "Failed to create simple poll object.\n");
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 */
202 fprintf(stderr
, "Failed to create client: %s\n", avahi_strerror(error
));
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),
213 /* Run the main loop */
214 avahi_simple_poll_loop(simple_poll
);
223 avahi_client_free(client
);
226 avahi_simple_poll_free(simple_poll
);
229 virConnectClose(conn
);