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
;
117 static void client_callback(AvahiClient
*c
, AvahiClientState state
, AVAHI_GCC_UNUSED
void * userdata
) {
120 /* Called whenever the client or server state changes */
123 case AVAHI_CLIENT_S_RUNNING
:
125 /* The server has startup successfully and registered its host
126 * name on the network, so it's time to create our services */
130 case AVAHI_CLIENT_FAILURE
:
132 fprintf(stderr
, "Client failure: %s\n", avahi_strerror(avahi_client_errno(c
)));
133 avahi_simple_poll_quit(simple_poll
);
137 case AVAHI_CLIENT_S_COLLISION
:
139 /* Let's drop our registered services. When the server is back
140 * in AVAHI_SERVER_RUNNING state we will register them
141 * again with the new host name. */
143 case AVAHI_CLIENT_S_REGISTERING
:
145 /* The server records are now being established. This
146 * might be caused by a host name change. We need to wait
147 * for our own records to register until the host name is
148 * properly esatblished. */
151 avahi_entry_group_reset(group);*/
155 case AVAHI_CLIENT_CONNECTING
:
162 static void modify_callback(AvahiTimeout
*e
, void *userdata
) {
164 AvahiClient
*client
= userdata
;
166 fprintf(stderr
, "Doing some weird modification\n");
168 /* If the server is currently running, we need to remove our
169 * service and create it anew */
170 if (avahi_client_get_state(client
) == AVAHI_CLIENT_S_RUNNING
) {
171 /* And create them again with the new name */
172 create_services(client
);
174 avahi_simple_poll_get(simple_poll
)->timeout_update(e
, avahi_elapse_time(&tv
, 1000*POLL
, 0));
177 int main(AVAHI_GCC_UNUSED
int argc
, AVAHI_GCC_UNUSED
char*argv
[]) {
178 AvahiClient
*client
= NULL
;
183 /* NULL means connect to local Xen hypervisor */
184 conn
= virConnectOpenReadOnly(NULL
);
186 fprintf(stderr
, "Failed to connect to hypervisor\n");
190 /* Allocate main loop object */
191 if (!(simple_poll
= avahi_simple_poll_new())) {
192 fprintf(stderr
, "Failed to create simple poll object.\n");
196 /* Allocate a new client */
197 client
= avahi_client_new(avahi_simple_poll_get(simple_poll
), 0, client_callback
, NULL
, &error
);
199 /* Check wether creating the client object succeeded */
201 fprintf(stderr
, "Failed to create client: %s\n", avahi_strerror(error
));
205 /* After 10s do some weird modification to the service */
206 avahi_simple_poll_get(simple_poll
)->timeout_new(
207 avahi_simple_poll_get(simple_poll
),
208 avahi_elapse_time(&tv
, 1000*POLL
, 0),
212 /* Run the main loop */
213 avahi_simple_poll_loop(simple_poll
);
222 avahi_client_free(client
);
225 avahi_simple_poll_free(simple_poll
);
228 virConnectClose(conn
);