Update so after migration we will still try to publish the domain.
[handlervirt.git] / node / publish.c
blob5f020ed323775a3a34053cf80ebc6d4de9215295
1 #include <avahi-client/publish.h>
2 #include <avahi-client/lookup.h>
4 #include <avahi-common/alternative.h>
5 #include <avahi-common/simple-watch.h>
6 #include <avahi-common/malloc.h>
7 #include <avahi-common/error.h>
8 #include <avahi-common/timeval.h>
9 #include <avahi-common/strlst.h>
10 #include <avahi-common/thread-watch.h>
12 #include <libvirt/libvirt.h>
14 #include "node.h"
16 struct list_el {
17 unsigned int domainid;
18 AvahiEntryGroup *group;
19 unsigned short keep;
22 typedef struct list_el domu;
24 domu * domus = NULL; /* list of domains */
25 unsigned int domu_count = 0;
28 static AvahiStringList * domainProperties(virDomainPtr thisDomain) {
29 AvahiStringList *new = NULL;
30 // avahi_string_list_new_from_array (NULL, 0);
31 virDomainInfo info;
32 virDomainInterfaceStatsStruct stats;
33 virDomainGetInfo(thisDomain, &info);
34 new = avahi_string_list_add_printf(new, "maxMem=%lu", info.maxMem);
35 new = avahi_string_list_add_printf(new, "memory=%lu", info.memory);
36 new = avahi_string_list_add_printf(new, "cpuTime=%llu", info.cpuTime);
38 /* TODO: multiple network interfaces :( */
39 char vifname[16];
40 snprintf(vifname, 14, "vif%d.0", virDomainGetID(thisDomain));
41 vifname[15] = '\0';
42 unsigned int no = 0;
44 virDomainInterfaceStats(thisDomain, vifname, &stats, sizeof(stats));
46 new = avahi_string_list_add_printf(new, "interfaces=eth%d", no);
47 new = avahi_string_list_add_printf(new, "interface_eth%d_rxbytes=%lld", no, stats.rx_bytes);
48 new = avahi_string_list_add_printf(new, "interface_eth%d_rxpackets=%lld", no, stats.rx_packets);
49 // new = avahi_string_list_add_printf(new, "interface_eth%d_rxerrs=%lld", no, stats.rx_errs);
50 // new = avahi_string_list_add_printf(new, "interface_eth%d_rxdrop=%lld", no, stats.rx_drop);
51 new = avahi_string_list_add_printf(new, "interface_eth%d_txbytes=%lld", no, stats.tx_bytes);
52 new = avahi_string_list_add_printf(new, "interface_eth%d_txpackets=%lld", no, stats.tx_packets);
53 // new = avahi_string_list_add_printf(new, "interface_eth%d_txerrs=%lld", no, stats.tx_errs);
54 // new = avahi_string_list_add_printf(new, "interface_eth%d_txdrop=%lld", no, stats.tx_drop);
56 return new;
59 void remove_everything() {
60 if (domus) {
61 int i;
62 for (i = 0; i < domu_count; i++) {
63 if (domus[i].group) {
64 avahi_entry_group_free(domus[i].group);
65 domus[i].group = NULL;
68 free(domus);
69 domus = NULL;
70 domu_count = 0;
74 void migrate_everything() {
75 if (domus) {
76 virConnectPtr conn;
77 conn = virConnectOpen(NULL);
79 if (conn) {
80 int i;
81 AvahiThreadedPoll *threaded_poll = NULL;
82 AvahiClient *client = NULL;
84 if ((threaded_poll = avahi_threaded_poll_new())) {
85 if ((client = avahi_client_new(avahi_threaded_poll_get(threaded_poll), 0, NULL, NULL, NULL)))
86 avahi_threaded_poll_start(threaded_poll);
89 for (i = 0; i < domu_count; i++) {
90 virDomainPtr dom;
91 dom = virDomainLookupByID (conn, domus[i].domainid);
93 if (dom) {
94 if (client == NULL || migrate_domain(client, threaded_poll, dom) != 0) {
95 virDomainShutdown(dom);
98 virDomainFree(dom);
103 if (threaded_poll) {
104 if (client) {
105 avahi_threaded_poll_stop(threaded_poll);
106 avahi_client_free(client);
109 avahi_threaded_poll_free(threaded_poll);
112 virConnectClose(conn);
117 static void entry_group_callback_publish(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata) {
118 domu *this = userdata;
120 switch (state) {
121 case AVAHI_ENTRY_GROUP_ESTABLISHED:
122 this->group = g;
123 break;
125 case AVAHI_ENTRY_GROUP_FAILURE:
126 case AVAHI_ENTRY_GROUP_COLLISION:
127 fprintf(stderr, "Collision\n");
128 avahi_entry_group_free(g);
129 this->group = NULL;
130 break;
132 default:
133 break;
138 void create_services(AvahiClient *c) {
139 virConnectPtr conn = virConnectOpenReadOnly(NULL);
140 if (conn == NULL)
141 return;
142 int maxid = virConnectNumOfDomains(conn);
143 if (maxid > 1) { /* ignore dom0 */
144 int *ids = (int *) malloc(sizeof(int) * maxid);
145 if ((maxid = virConnectListDomains(conn, &ids[0], maxid)) < 0) {
146 // error
147 } else {
148 int i;
149 unsigned int domu_count_new = (maxid - 1);
150 domu * domus_old = domus;
151 domus = (domu *) malloc(sizeof(domu) * domu_count_new);
152 const char *type = "_domu._tcp";
154 for (i = 0; i < domu_count_new; i++) {
155 int j;
156 domus[i].group = NULL;
157 domus[i].domainid = ids[i+1];
158 domus[i].keep = 0;
160 // fprintf(stderr, "Looking for %d\n", domus[i].domainid);
162 for (j = 0; j < domu_count; j++) {
163 // fprintf(stderr, "--> %d\n", domus_old[j].domainid);
164 if (ids[i+1] == domus_old[j].domainid) {
165 // fprintf(stderr, "got it\n");
166 virDomainPtr thisDomain = virDomainLookupByID(conn, domus[i].domainid);
167 if (thisDomain) {
168 const char *name;
169 name = virDomainGetName(thisDomain);
170 if (name && domus_old[j].group) {
171 domus[i].group = domus_old[j].group;
172 AvahiStringList *domainProps;
173 domainProps = domainProperties(thisDomain);
174 domus_old[j].keep = 1;
175 avahi_entry_group_update_service_txt_strlst(domus[i].group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, type, NULL, domainProps);
176 avahi_string_list_free(domainProps);
178 virDomainFree(thisDomain);
182 if (i > domu_count || domus[i].group == NULL) {
183 const char *name;
184 AvahiStringList *domainProps;
185 virDomainPtr thisDomain = virDomainLookupByID(conn, ids[i+1]);
186 if (thisDomain) {
187 AvahiEntryGroup *group;
188 group = avahi_entry_group_new(c, entry_group_callback_publish, &domus[i]);
189 domainProps = domainProperties(thisDomain);
190 name = virDomainGetName(thisDomain);
192 if (name) {
193 avahi_entry_group_add_service_strlst(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, type, NULL, NULL, 651, domainProps);
194 avahi_entry_group_commit(group);
195 domus[i].keep = 1;
196 } else {
197 domus[i].keep = 0;
200 avahi_string_list_free(domainProps);
201 virDomainFree(thisDomain);
206 for (i = 0; i < domu_count; i++) {
207 // fprintf(stderr, "id: %d, keep: %d\n", domus_old[i].domainid, domus_old[i].keep);
208 if (domus_old[i].keep == 0 && domus_old[i].group != NULL) {
209 avahi_entry_group_free(domus_old[i].group);
210 domus_old[i].group = NULL;
214 free(domus_old);
215 domu_count = domu_count_new;
217 free(ids);
218 } else {
219 remove_everything();
221 virConnectClose(conn);
222 //fprintf(stderr, "exit: %s\n", __func__);