15a67a8d3cfe14170ab3ad7e1dfd263ed00233a5
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
;
21 AvahiEntryGroup
*group
;
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
) {
34 if ((offer_new
= (OFFER
*) malloc(sizeof(OFFER
))) == NULL
) {
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
;
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
);
51 offers_head
= offer_new
;
53 offers_tail
->next
= offer_new
;
55 offers_tail
= offer_new
;
60 static int offer_tender(const char *name
, unsigned long memory
, AvahiClient
*c
) {
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
);
70 fprintf(stderr
, "Failed to connect to hypervisor\n");
74 free_memory
= virNodeGetFreeMemory(conn
) - reservate
;
75 virConnectClose(conn
);
77 if ((offer_new
= (OFFER
*) malloc(sizeof(OFFER
))) == NULL
) {
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
);
98 offers_head
= offer_new
;
100 offers_tail
->next
= offer_new
;
102 offers_tail
= offer_new
;
108 int pull_tender(const char *name
) {
109 OFFER
*offer_prev
= NULL
;
110 OFFER
*offer_find
= offers_head
;
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
);
118 offers_head
= offer_find
->next
;
120 offer_prev
->next
= offer_find
->next
;
125 offer_prev
= offer_find
;
126 offer_find
= offer_find
->next
;
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
;
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
) {
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
));
151 offer_tender(name
, amount
, avahi_service_resolver_get_client(r
));