262acd40f3e4539d34a73f9a77f90f0b84f8d9c6
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
) {
20 if ((offer_new
= (OFFER
*) malloc(sizeof(OFFER
))) == NULL
) {
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
;
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
);
37 offers_head
= offer_new
;
39 offers_tail
->next
= offer_new
;
41 offers_tail
= offer_new
;
46 static int offer_tender(const char *name
, unsigned long memory
, AvahiClient
*c
) {
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
);
56 fprintf(stderr
, "Failed to connect to hypervisor\n");
60 free_memory
= virNodeGetFreeMemory(conn
) - reservate
;
61 virConnectClose(conn
);
63 if ((offer_new
= (OFFER
*) malloc(sizeof(OFFER
))) == NULL
) {
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
);
84 offers_head
= offer_new
;
86 offers_tail
->next
= offer_new
;
88 offers_tail
= offer_new
;
94 int pull_tender(const char *name
) {
95 OFFER
*offer_prev
= NULL
;
96 OFFER
*offer_find
= offers_head
;
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
);
104 offers_head
= offer_find
->next
;
106 offer_prev
->next
= offer_find
->next
;
111 offer_prev
= offer_find
;
112 offer_find
= offer_find
->next
;
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
;
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
) {
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
));
137 offer_tender(name
, amount
, avahi_service_resolver_get_client(r
));