15a67a8d3cfe14170ab3ad7e1dfd263ed00233a5
[handlervirt.git] / node / tender.c
blob15a67a8d3cfe14170ab3ad7e1dfd263ed00233a5
1 #include <stdio.h>
2 #include "node.h"
4 #include <avahi-client/client.h>
5 #include <avahi-client/publish.h>
6 #include <avahi-client/lookup.h>
8 #include <avahi-common/alternative.h>
9 #include <avahi-common/simple-watch.h>
10 #include <avahi-common/malloc.h>
11 #include <avahi-common/error.h>
12 #include <avahi-common/timeval.h>
14 #include <libvirt/libvirt.h>
16 typedef struct offer OFFER;
17 struct offer {
18 char *name;
19 float cost;
20 unsigned long memory;
21 AvahiEntryGroup *group;
22 short int reservate;
23 OFFER *next;
26 OFFER *offers_head = NULL;
27 OFFER *offers_tail = NULL;
29 unsigned long reservate = 0;
31 static int accept_tender(const char *name, unsigned long memory, AvahiClient *c) {
32 OFFER * offer_new;
33 char domain[254];
34 if ((offer_new = (OFFER *) malloc(sizeof(OFFER))) == NULL) {
35 return -1;
37 snprintf(domain, 254, "%s.%s", name, avahi_client_get_host_name_fqdn(c));
38 offer_new->name = strdup(name);
39 offer_new->memory = memory;
40 offer_new->reservate = 1;
41 offer_new->cost = 0.0f;
42 reservate =+ memory;
43 offer_new->group = avahi_entry_group_new(c, entry_group_callback, NULL);
44 offer_new->next = NULL;
46 /* TODO: enable givemetake only after domains are migrated! */
47 avahi_entry_group_add_service(offer_new->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, domain, "_tender._tcp", NULL, NULL, 651, "givemetake=1", NULL, NULL);
48 avahi_entry_group_commit(offer_new->group);
50 if (!offers_head)
51 offers_head = offer_new;
52 else
53 offers_tail->next = offer_new;
55 offers_tail = offer_new;
57 return 0;
60 static int offer_tender(const char *name, unsigned long memory, AvahiClient *c) {
61 OFFER * offer_new;
62 virConnectPtr conn = NULL; /* the hypervisor connection */
64 unsigned long long free_memory;
65 char domain[254], txt[254];
67 /* NULL means connect to local Xen hypervisor */
68 conn = virConnectOpenReadOnly(NULL);
69 if (conn == NULL) {
70 fprintf(stderr, "Failed to connect to hypervisor\n");
71 return -1;
74 free_memory = virNodeGetFreeMemory(conn) - reservate;
75 virConnectClose(conn);
77 if ((offer_new = (OFFER *) malloc(sizeof(OFFER))) == NULL) {
78 return -1;
81 offer_new->cost = (float)memory / (float)free_memory;
82 snprintf(domain, 254, "%s.%s", name, avahi_client_get_host_name_fqdn(c));
83 snprintf(txt, 254, "cost=%f", offer_new->cost);
85 printf("Puts hand up: %f\n", offer_new->cost);
87 /* Here we assume that Avahi will guarantee uniqueness */
88 offer_new->name = strdup(name);
89 offer_new->memory = memory;
90 offer_new->reservate = 0;
91 offer_new->group = avahi_entry_group_new(c, entry_group_callback, NULL);
92 offer_new->next = NULL;
93 avahi_entry_group_add_service(offer_new->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, domain, "_tender._tcp", NULL, NULL, 651, txt, NULL, NULL);
94 avahi_entry_group_commit(offer_new->group);
97 if (!offers_head)
98 offers_head = offer_new;
99 else
100 offers_tail->next = offer_new;
102 offers_tail = offer_new;
104 return 0;
108 int pull_tender(const char *name) {
109 OFFER *offer_prev = NULL;
110 OFFER *offer_find = offers_head;
112 while (offer_find) {
113 if (strcmp(offer_find->name, name) == 0) {
114 if (offer_find->reservate == 1) reservate =- offer_find->memory;
115 free(offer_find->name);
116 avahi_entry_group_free(offer_find->group);
117 if (!offer_prev)
118 offers_head = offer_find->next;
119 else
120 offer_prev->next = offer_find->next;
122 free(offer_find);
123 return 0;
124 } else {
125 offer_prev = offer_find;
126 offer_find = offer_find->next;
129 return -1;
132 void parse_tender(AvahiServiceResolver *r, const char *name, AvahiStringList *txt) {
133 AvahiStringList *needle;
134 if ((needle = avahi_string_list_find (txt, "memory")) != NULL) {
135 unsigned long int amount;
136 char *memory;
137 avahi_string_list_get_pair (needle, NULL, &memory, NULL);
138 amount = strtoul(memory, NULL, 10);
140 if (errno != ERANGE && amount > 0) {
141 if ((needle = avahi_string_list_find (txt, "domain")) != NULL) {
142 char *winner;
143 avahi_string_list_get_pair (needle, NULL, &winner, NULL);
145 if (strcmp(winner, avahi_client_get_host_name_fqdn(avahi_service_resolver_get_client(r))) == 0) {
146 accept_tender(name, amount, avahi_service_resolver_get_client(r));
149 avahi_free(winner);
150 } else {
151 offer_tender(name, amount, avahi_service_resolver_get_client(r));
155 avahi_free(memory);