63750f6eb7cacf44f35b323eeebd6053f861455a
[handlervirt.git] / node / publish.c
blob63750f6eb7cacf44f35b323eeebd6053f861455a
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>
11 #include <libvirt/libvirt.h>
13 #include "node.h"
15 struct list_el {
16 unsigned int domainid;
17 AvahiEntryGroup *group;
18 unsigned short keep;
21 typedef struct list_el domu;
23 domu * domus = NULL; /* list of domains */
24 unsigned int domu_count = 0;
27 static AvahiStringList * domainProperties(virDomainPtr thisDomain) {
28 AvahiStringList *new = NULL;
29 // avahi_string_list_new_from_array (NULL, 0);
30 virDomainInfo info;
31 virDomainInterfaceStatsStruct stats;
32 virDomainGetInfo(thisDomain, &info);
33 new = avahi_string_list_add_printf(new, "maxMem=%lu", info.maxMem);
34 new = avahi_string_list_add_printf(new, "memory=%lu", info.memory);
35 new = avahi_string_list_add_printf(new, "cpuTime=%llu", info.cpuTime);
37 /* TODO: multiple network interfaces :( */
38 char vifname[16];
39 snprintf(vifname, 14, "vif%d.0", virDomainGetID(thisDomain));
40 vifname[15] = '\0';
41 unsigned int no = 0;
43 virDomainInterfaceStats(thisDomain, vifname, &stats, sizeof(stats));
45 new = avahi_string_list_add_printf(new, "interfaces=eth%d", no);
46 new = avahi_string_list_add_printf(new, "interface_eth%d_rxbytes=%lld", no, stats.rx_bytes);
47 new = avahi_string_list_add_printf(new, "interface_eth%d_rxpackets=%lld", no, stats.rx_packets);
48 // new = avahi_string_list_add_printf(new, "interface_eth%d_rxerrs=%lld", no, stats.rx_errs);
49 // new = avahi_string_list_add_printf(new, "interface_eth%d_rxdrop=%lld", no, stats.rx_drop);
50 new = avahi_string_list_add_printf(new, "interface_eth%d_txbytes=%lld", no, stats.tx_bytes);
51 new = avahi_string_list_add_printf(new, "interface_eth%d_txpackets=%lld", no, stats.tx_packets);
52 // new = avahi_string_list_add_printf(new, "interface_eth%d_txerrs=%lld", no, stats.tx_errs);
53 // new = avahi_string_list_add_printf(new, "interface_eth%d_txdrop=%lld", no, stats.tx_drop);
55 return new;
58 void remove_everything() {
59 if (domus) {
60 int i;
61 for (i = 0; i < domu_count; i++) {
62 avahi_entry_group_free(domus[i].group);
63 domus[i].group = NULL;
65 free(domus);
66 domus = NULL;
67 domu_count = 0;
71 void migrate_everything(AvahiClient *c) {
72 if (domus) {
73 virConnectPtr conn;
74 conn = virConnectOpen(NULL);
76 if (conn) {
77 int i;
78 for (i = 0; i < domu_count; i++) {
79 virDomainPtr dom;
80 dom = virDomainLookupByID (conn, domus[i].domainid);
82 if (dom) {
83 if (migrate_domain(c, dom) != 0) {
84 virDomainShutdown(dom);
87 virDomainFree(dom);
91 virConnectClose(conn);
97 void create_services(AvahiClient *c) {
98 virConnectPtr conn = virConnectOpenReadOnly(NULL);
99 if (conn == NULL)
100 return;
101 int maxid = virConnectNumOfDomains(conn);
102 if (maxid > 1) { /* ignore dom0 */
103 int *ids = (int *) malloc(sizeof(int) * maxid);
104 if ((maxid = virConnectListDomains(conn, &ids[0], maxid)) < 0) {
105 // error
106 } else {
107 int i;
108 unsigned int domu_count_new = (maxid - 1);
109 domu * domus_old = domus;
110 domus = (domu *) malloc(sizeof(domu) * domu_count_new);
111 const char *type = "_domu._tcp";
113 for (i = 0; i < domu_count_new; i++) {
114 int j;
115 domus[i].group = NULL;
116 domus[i].domainid = ids[i+1];
117 domus[i].keep = 0;
119 // fprintf(stderr, "Looking for %d\n", domus[i].domainid);
121 for (j = 0; j < domu_count; j++) {
122 // fprintf(stderr, "--> %d\n", domus_old[j].domainid);
123 if (ids[i+1] == domus_old[j].domainid) {
124 // fprintf(stderr, "got it\n");
125 virDomainPtr thisDomain = virDomainLookupByID(conn, domus[i].domainid);
126 if (thisDomain) {
127 const char *name;
128 name = virDomainGetName(thisDomain);
129 if (name) {
130 domus[i].group = domus_old[j].group;
131 AvahiStringList *domainProps;
132 domainProps = domainProperties(thisDomain);
133 domus_old[j].keep = 1;
134 avahi_entry_group_update_service_txt_strlst(domus[i].group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, type, NULL, domainProps);
135 avahi_string_list_free(domainProps);
137 virDomainFree(thisDomain);
141 if (i > domu_count || domus[i].group == NULL) {
142 const char *name;
143 AvahiStringList *domainProps;
144 virDomainPtr thisDomain = virDomainLookupByID(conn, ids[i+1]);
145 if (thisDomain) {
146 domus[i].group = avahi_entry_group_new(c, entry_group_callback, NULL);
147 domainProps = domainProperties(thisDomain);
148 name = virDomainGetName(thisDomain);
150 if (name) {
151 avahi_entry_group_add_service_strlst(domus[i].group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, type, NULL, NULL, 651, domainProps);
152 avahi_entry_group_commit(domus[i].group);
153 } else {
154 domus[i].keep = 0;
157 avahi_string_list_free(domainProps);
158 virDomainFree(thisDomain);
163 for (i = 0; i < domu_count; i++) {
164 // fprintf(stderr, "id: %d, keep: %d\n", domus_old[i].domainid, domus_old[i].keep);
165 if (domus_old[i].keep == 0 && domus_old[i].group != NULL) {
166 avahi_entry_group_free(domus_old[i].group);
167 domus_old[i].group = NULL;
171 free(domus_old);
172 domu_count = domu_count_new;
174 free(ids);
175 } else {
176 remove_everything();
178 virConnectClose(conn);
179 //fprintf(stderr, "exit: %s\n", __func__);