From 338a4d8033c1e4a9d9777c550a5e307f86e2f409 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 4 Oct 2008 00:06:46 +0200 Subject: [PATCH] Updates for restoring/save. --- Makefile | 2 +- handler_virt.c | 275 ++++++++++++--------------------------------------------- node/Makefile | 4 +- node/publish.c | 46 +++++----- 4 files changed, 83 insertions(+), 244 deletions(-) diff --git a/Makefile b/Makefile index 4cc79c7..904e1d7 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ all: handler_example.c # gcc -g -lavahi-client -L/opt/libvirt/lib -lvirt -o offer offer.c # gcc -g -fPIC -shared -I/opt/cherokee/include -o libplugin_example.so handler_example.c # gcc -g -fPIC -shared -I/opt/cherokee/include -lavahi-client -o libplugin_avahi.so handler_avahi.c - gcc -DTRACE_ENABLED -D_GNU_SOURCE -I/usr/include/libxml2 -g -fPIC -shared -I/opt/cherokee/include -lrrd -lavahi-client -L/opt/domu/lib -lvirt -o libplugin_virt.so handler_clusterstats.c handler_virt.c experiment5.c handler_virt_domains.c + gcc -DTRACE_ENABLED -D_GNU_SOURCE -I/usr/include/libxml2 -g -fPIC -shared -I/opt/cherokee/include -lrrd -lavahi-client -L/opt/domu/lib -lvirt -o libplugin_virt.so handler_clusterstats.c handler_virt.c experiment5.c handler_virt_domains.c handler_virt_tender.c # gcc -g -fPIC -shared -I/opt/cherokee/include -lavahi-client -o libplugin_clusterstats.so handler_clusterstats.c install: diff --git a/handler_virt.c b/handler_virt.c index ec3e2d4..3909405 100644 --- a/handler_virt.c +++ b/handler_virt.c @@ -81,6 +81,7 @@ #include "handler_virt.h" #include "handler_clusterstats.h" +#include "handler_virt_tender.h" #include #include #include @@ -97,6 +98,7 @@ #include + /* Plug-in initialization * * In this function you can use any of these: @@ -173,157 +175,6 @@ cherokee_handler_virt_configure (cherokee_config_node_t *conf, cherokee_server_t return cherokee_handler_clusterstats_configure (conf, srv, _props); } -static void entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, AVAHI_GCC_UNUSED void *userdata) { - switch (state) { - case AVAHI_ENTRY_GROUP_ESTABLISHED : - /* The entry group has been established successfully */ - break; - - case AVAHI_ENTRY_GROUP_COLLISION : { - /* A service name collision with a remote service - * happened. */ - break; - } - - case AVAHI_ENTRY_GROUP_FAILURE : - /* Some kind of failure happened while we were registering our services */ - break; - - case AVAHI_ENTRY_GROUP_UNCOMMITED: - case AVAHI_ENTRY_GROUP_REGISTERING: - ; - } -} - -static void tender_resolve_callback( - AvahiServiceResolver *r, - AVAHI_GCC_UNUSED AvahiIfIndex interface, - AVAHI_GCC_UNUSED AvahiProtocol protocol, - AvahiResolverEvent event, - const char *name, - const char *type, - const char *domain, - const char *host_name, - const AvahiAddress *address, - uint16_t port, - AvahiStringList *txt, - AvahiLookupResultFlags flags, - void* userdata) { - - tender_t *tender = userdata; - - assert(r); - - /* Called whenever a service has been resolved successfully or timed out */ - - switch (event) { - case AVAHI_RESOLVER_FAILURE: - fprintf(stderr, "(Resolver) FAILURE!\n"); - avahi_service_resolver_free(r); - break; - - case AVAHI_RESOLVER_FOUND: { - char a[AVAHI_ADDRESS_STR_MAX], *t; - AvahiStringList *needle; - - fprintf(stderr, "(Resolver) Service '%s' of type '%s' in domain '%s':\n", name, type, domain); - - avahi_address_snprint(a, sizeof(a), address); - t = avahi_string_list_to_string(txt); - fprintf(stderr, - "\t%s:%u (%s)\n" - "\tTXT=%s\n" - "\tcookie is %u\n" - "\tis_local: %i\n" - "\tour_own: %i\n" - "\twide_area: %i\n" - "\tmulticast: %i\n" - "\tcached: %i\n", - host_name, port, a, - t, - avahi_string_list_get_service_cookie(txt), - !!(flags & AVAHI_LOOKUP_RESULT_LOCAL), - !!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN), - !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA), - !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST), - !!(flags & AVAHI_LOOKUP_RESULT_CACHED)); - - - avahi_free(t); - - unsigned int len = strlen(tender->name); - - if (strlen(name) > len && name[len] == '.' && strncmp(tender->name, name, len) == 0) { - if ((needle = avahi_string_list_find (txt, "cost")) != NULL) { - - float amount; - char *cost; - avahi_string_list_get_pair (needle, NULL, &cost, NULL); - amount = atof(cost); - - TRACE("tender", "%s will run %s for the cost of L$W %f\n", host_name, tender->name, amount); - if (amount < tender->cost) { - /* TODO: LOCK */ - tender->cost = amount; - tender->dom = strdup(host_name); - TRACE("tender", "We will consider his offer!"); - } - - avahi_free(cost); - } - break; - } - } - } -} - - -static void tender_browse_callback( - AvahiServiceBrowser *b, - AvahiIfIndex interface, - AvahiProtocol protocol, - AvahiBrowserEvent event, - const char *name, - const char *type, - const char *domain, - AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, - void* userdata) { - AvahiClient *c; - assert(b); - - c = avahi_service_browser_get_client(b); - - /* Called whenever a new services becomes available on the LAN or is removed from the LAN */ - - switch (event) { - case AVAHI_BROWSER_FAILURE: - fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_client_errno(c))); - return; - - case AVAHI_BROWSER_NEW: - fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain); - - /* We ignore the returned resolver object. In the callback - function we free it. If the server is terminated before - the callback function is called the server will free - the resolver for us. */ - - if (!(avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, tender_resolve_callback, userdata))) - fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c))); - - break; - - case AVAHI_BROWSER_REMOVE: - fprintf(stderr, "%s, (Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", __func__, name, type, domain); - break; - - case AVAHI_BROWSER_ALL_FOR_NOW: - case AVAHI_BROWSER_CACHE_EXHAUSTED: - fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW"); - break; - } -} - ret_t cherokee_handler_virt_init (cherokee_handler_virt_t *hdl) { @@ -716,20 +567,43 @@ virt_virt_function(cherokee_handler_virt_t *hdl, virDomainPtr dom, virConnectPtr cherokee_buffer_add_va (&path, "/mnt/netapp/users/%s/%s/memory", hdl->user.buf, hdl->vm.buf); if (stat(path.buf, &statbuf) == 0) { - int result; - if ((result = virDomainRestore(virConn, path.buf)) != 0) { - TRACE("virt", "Restoring of %s/%s failed", hdl->user.buf, hdl->vm.buf); - conn->error_code = http_internal_error; - ret = ret_error; + char *destination = create_tender(hdl, virDomainGetName(dom), virDomainGetMaxMemory(dom)); + + if (destination == NULL) { + TRACE("virt", "Nobody wants %s, poor vm!\n", destination); + cherokee_buffer_add_long10(buf, -1); + } else { + virConnectPtr virConnNew; + cherokee_buffer_t uri = CHEROKEE_BUF_INIT; + + if (virDomainUndefine(dom) != 0) { + TRACE("virt", "Can't undefine %s, some idiot run it already?\n", destination); + cherokee_buffer_add_long10(buf, -1); + } else { + cherokee_buffer_add_va (&uri, "xen://%s/", destination); + virConnNew = virConnectOpen (uri.buf); + + if (virConnNew == NULL) { + TRACE("virt", "Can't connect to %s\n", uri.buf); + cherokee_buffer_add_long10(buf, -1); + } else { + cherokee_buffer_add_long10(buf, virDomainRestore(virConn, path.buf)); + virConnectClose(virConn); + virConn = virConnNew; + /* TODO: Here I actually want virConnNew to be virConn */ + } + } + cherokee_buffer_mrproper(&uri); + free(destination); } - cherokee_buffer_add_long10(buf, result); } else { TRACE("virt", "Memory file for %s/%s does not exist", hdl->user.buf, hdl->vm.buf); conn->error_code = http_not_found; ret = ret_error; } - + cherokee_buffer_mrproper(&path); + return ret; break; } @@ -934,75 +808,40 @@ virt_virt_function(cherokee_handler_virt_t *hdl, virDomainPtr dom, virConnectPtr } case domainCreate: { + char *destination; cherokee_buffer_t xmlDesc = CHEROKEE_BUF_INIT; - char txt[254]; save_xml(hdl, dom, &xmlDesc); - tender_t best_tender; - snprintf(txt, 252, "memory=%lu", virDomainGetMaxMemory(dom)); - txt[253] = '\0'; - best_tender.name = virDomainGetName(dom); - best_tender.cost = FLT_MAX; - best_tender.dom = NULL; - - avahi_threaded_poll_lock(HDL_CLUSTERSTATS_PROPS(hdl)->threaded_poll); - AvahiServiceBrowser *sb = avahi_service_browser_new(HDL_CLUSTERSTATS_PROPS(hdl)->client, AVAHI_IF_UNSPEC, - AVAHI_PROTO_UNSPEC, "_tender._tcp", - NULL, 0, tender_browse_callback, &best_tender); + destination = create_tender(hdl, virDomainGetName(dom), virDomainGetMaxMemory(dom)); - if (sb == NULL) { - TRACE("avahi", "For whatever reason the sb is NULL\n"); + if (destination == NULL) { + TRACE("virt", "Nobody wants %s, poor vm!\n", destination); + cherokee_buffer_add_long10(buf, -1); } else { - AvahiEntryGroup *group = avahi_entry_group_new(HDL_CLUSTERSTATS_PROPS(hdl)->client, entry_group_callback, NULL); - - if (group == NULL) { - TRACE("avahi", "For whatever reason the group is NULL\n"); - } else { - avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, - best_tender.name, "_offer._tcp", NULL, NULL, 651, txt, NULL, NULL); - avahi_entry_group_commit(group); - avahi_threaded_poll_unlock(HDL_CLUSTERSTATS_PROPS(hdl)->threaded_poll); - - sleep(3); /* we are for quick bidding ;) */ - - avahi_threaded_poll_lock(HDL_CLUSTERSTATS_PROPS(hdl)->threaded_poll); - avahi_entry_group_free(group); + virConnectPtr virConnNew; + cherokee_buffer_t uri = CHEROKEE_BUF_INIT; + + if (virDomainUndefine(dom) != 0) { + TRACE("virt", "Can't undefine %s, some idiot run it already?\n", destination); } - - avahi_service_browser_free(sb); - avahi_threaded_poll_unlock(HDL_CLUSTERSTATS_PROPS(hdl)->threaded_poll); - - if (best_tender.dom == NULL) { - TRACE("virt", "Nobody wants %s, poor vm!\n", best_tender.name); + + cherokee_buffer_add_va (&uri, "xen://%s/", destination); + virConnNew = virConnectOpen (uri.buf); + + if (virConnNew == NULL) { + TRACE("virt", "Can't connect to %s\n", uri.buf); cherokee_buffer_add_long10(buf, -1); } else { - if (virDomainUndefine(dom) != 0) { - TRACE("virt", "Can't undefine %s, some idiot run it already?\n", best_tender.name); - cherokee_buffer_add_long10(buf, -1); - } else { - virConnectPtr virConnNew; - cherokee_buffer_t uri = CHEROKEE_BUF_INIT; - // virConnectClose(virConn); - cherokee_buffer_add_va (&uri, "xen://%s/", best_tender.dom); - virConnNew = virConnectOpen (uri.buf); - if (virConnNew == NULL) { - TRACE("virt", "Can't connect to %s\n", uri.buf); - cherokee_buffer_add_long10(buf, -1); - } else { - cherokee_buffer_add_long10(buf, - (virDomainCreateLinux(virConnNew, xmlDesc.buf, 0) != NULL ? - 0 : -1 )); - virConnectClose(virConn); - - virConn = virConnNew; - /* TODO: Here I actually want virConnNew to be virConn */ - } - cherokee_buffer_mrproper(&uri); - } - TRACE("virt", "going to free\n"); - free(best_tender.dom); - } + cherokee_buffer_add_long10(buf, + (virDomainCreateLinux(virConnNew, xmlDesc.buf, 0) != NULL ? + 0 : -1 )); + virConnectClose(virConn); + virConn = virConnNew; + /* TODO: Here I actually want virConnNew to be virConn */ + } + cherokee_buffer_mrproper(&uri); + free(destination); } cherokee_buffer_mrproper(&xmlDesc); diff --git a/node/Makefile b/node/Makefile index 035045d..427aa11 100644 --- a/node/Makefile +++ b/node/Makefile @@ -1,2 +1,2 @@ -node: - gcc -I/usr/include/avahi -I/usr/include/libvirt -lvirt -lavahi-client -Wall avahi.c main.c publish.c tender.c -o $@ +all: + gcc -g -I/usr/include/avahi -I/usr/include/libvirt -lvirt -lavahi-client -Wall avahi.c main.c publish.c tender.c -o node diff --git a/node/publish.c b/node/publish.c index e3da488..f949bc7 100644 --- a/node/publish.c +++ b/node/publish.c @@ -60,6 +60,7 @@ void remove_everything() { int i; for (i = 0; i < domu_count; i++) { avahi_entry_group_free(domus[i].group); + domus[i].group = NULL; } free(domus); domus = NULL; @@ -90,49 +91,47 @@ void create_services(AvahiClient *c) { domus[i].domainid = ids[i+1]; domus[i].keep = 0; - fprintf(stderr, "Looking for %d\n", domus[i].domainid); +// fprintf(stderr, "Looking for %d\n", domus[i].domainid); for (j = 0; j < domu_count; j++) { - fprintf(stderr, "--> %d\n", domus_old[j].domainid); +// fprintf(stderr, "--> %d\n", domus_old[j].domainid); if (ids[i+1] == domus_old[j].domainid) { - fprintf(stderr, "got it\n"); +// fprintf(stderr, "got it\n"); virDomainPtr thisDomain = virDomainLookupByID(conn, domus[i].domainid); - domus[i].group = domus_old[j].group; if (thisDomain) { - const char *name = virDomainGetName(thisDomain); + const char *name; + name = virDomainGetName(thisDomain); if (name) { + domus[i].group = domus_old[j].group; AvahiStringList *domainProps; domainProps = domainProperties(thisDomain); domus_old[j].keep = 1; avahi_entry_group_update_service_txt_strlst(domus[i].group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, type, NULL, domainProps); avahi_string_list_free(domainProps); - } else { - // domus_old[j].keep = 0; } - } else { - // domus_old[j].keep = 0; + virDomainFree(thisDomain); } - virDomainFree(thisDomain); } } if (i > domu_count || domus[i].group == NULL) { const char *name; AvahiStringList *domainProps; virDomainPtr thisDomain = virDomainLookupByID(conn, ids[i+1]); - domus[i].group = avahi_entry_group_new(c, entry_group_callback, NULL); - domainProps = domainProperties(thisDomain); - name = virDomainGetName(thisDomain); - - if (name) { - avahi_entry_group_add_service_strlst(domus[i].group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, type, NULL, NULL, 651, domainProps); - avahi_entry_group_commit(domus[i].group); - } else { - domus[i].keep = 0; - } - - avahi_string_list_free(domainProps); - virDomainFree(thisDomain); + if (thisDomain) { + domus[i].group = avahi_entry_group_new(c, entry_group_callback, NULL); + domainProps = domainProperties(thisDomain); + name = virDomainGetName(thisDomain); + + if (name) { + avahi_entry_group_add_service_strlst(domus[i].group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, type, NULL, NULL, 651, domainProps); + avahi_entry_group_commit(domus[i].group); + } else { + domus[i].keep = 0; + } + avahi_string_list_free(domainProps); + virDomainFree(thisDomain); + } } } @@ -140,6 +139,7 @@ void create_services(AvahiClient *c) { // fprintf(stderr, "id: %d, keep: %d\n", domus_old[i].domainid, domus_old[i].keep); if (domus_old[i].keep == 0 && domus_old[i].group != NULL) { avahi_entry_group_free(domus_old[i].group); + domus_old[i].group = NULL; } } -- 2.11.4.GIT