262acd40f3e4539d34a73f9a77f90f0b84f8d9c6
[handlervirt.git] / node / tender.c
blob262acd40f3e4539d34a73f9a77f90f0b84f8d9c6
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>
15 #include <libvirt/libvirt.h>
17 static int accept_tender(const char *name, unsigned long memory, AvahiClient *c) {
18 OFFER * offer_new;
19 char domain[254];
20 if ((offer_new = (OFFER *) malloc(sizeof(OFFER))) == NULL) {
21 return -1;
23 snprintf(domain, 254, "%s.%s", name, avahi_client_get_host_name_fqdn(c));
24 offer_new->name = strdup(name);
25 offer_new->memory = memory;
26 offer_new->reservate = 1;
27 offer_new->cost = 0.0f;
28 reservate =+ memory;
29 offer_new->group = avahi_entry_group_new(c, entry_group_callback, NULL);
30 offer_new->next = NULL;
32 /* TODO: enable givemetake only after domains are migrated! */
33 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);
34 avahi_entry_group_commit(offer_new->group);
36 if (!offers_head)
37 offers_head = offer_new;
38 else
39 offers_tail->next = offer_new;
41 offers_tail = offer_new;
43 return 0;
46 static int offer_tender(const char *name, unsigned long memory, AvahiClient *c) {
47 OFFER * offer_new;
48 virConnectPtr conn = NULL; /* the hypervisor connection */
50 unsigned long long free_memory;
51 char domain[254], txt[254];
53 /* NULL means connect to local Xen hypervisor */
54 conn = virConnectOpenReadOnly(NULL);
55 if (conn == NULL) {
56 fprintf(stderr, "Failed to connect to hypervisor\n");
57 return -1;
60 free_memory = virNodeGetFreeMemory(conn) - reservate;
61 virConnectClose(conn);
63 if ((offer_new = (OFFER *) malloc(sizeof(OFFER))) == NULL) {
64 return -1;
67 offer_new->cost = (float)memory / (float)free_memory;
68 snprintf(domain, 254, "%s.%s", name, avahi_client_get_host_name_fqdn(c));
69 snprintf(txt, 254, "cost=%f", offer_new->cost);
71 printf("Puts hand up: %f\n", offer_new->cost);
73 /* Here we assume that Avahi will guarantee uniqueness */
74 offer_new->name = strdup(name);
75 offer_new->memory = memory;
76 offer_new->reservate = 0;
77 offer_new->group = avahi_entry_group_new(c, entry_group_callback, NULL);
78 offer_new->next = NULL;
79 avahi_entry_group_add_service(offer_new->group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, domain, "_tender._tcp", NULL, NULL, 651, txt, NULL, NULL);
80 avahi_entry_group_commit(offer_new->group);
83 if (!offers_head)
84 offers_head = offer_new;
85 else
86 offers_tail->next = offer_new;
88 offers_tail = offer_new;
90 return 0;
94 int pull_tender(const char *name) {
95 OFFER *offer_prev = NULL;
96 OFFER *offer_find = offers_head;
98 while (offer_find) {
99 if (strcmp(offer_find->name, name) == 0) {
100 if (offer_find->reservate == 1) reservate =- offer_find->memory;
101 free(offer_find->name);
102 avahi_entry_group_free(offer_find->group);
103 if (!offer_prev)
104 offers_head = offer_find->next;
105 else
106 offer_prev->next = offer_find->next;
108 free(offer_find);
109 return 0;
110 } else {
111 offer_prev = offer_find;
112 offer_find = offer_find->next;
115 return -1;
118 void parse_tender(AvahiServiceResolver *r, const char *name, AvahiStringList *txt) {
119 AvahiStringList *needle;
120 if ((needle = avahi_string_list_find (txt, "memory")) != NULL) {
121 unsigned long int amount;
122 char *memory;
123 avahi_string_list_get_pair (needle, NULL, &memory, NULL);
124 amount = strtoul(memory, NULL, 10);
126 if (errno != ERANGE && amount > 0) {
127 if ((needle = avahi_string_list_find (txt, "domain")) != NULL) {
128 char *winner;
129 avahi_string_list_get_pair (needle, NULL, &winner, NULL);
131 if (strcmp(winner, avahi_client_get_host_name_fqdn(avahi_service_resolver_get_client(r))) == 0) {
132 accept_tender(name, amount, avahi_service_resolver_get_client(r));
135 avahi_free(winner);
136 } else {
137 offer_tender(name, amount, avahi_service_resolver_get_client(r));
141 avahi_free(memory);