static void follow_location(domain_t * domain, const char *location, size_t len) { debug("-- follow location %.*s", (int) len, location); __sync_fetch_and_add(&domain->options->counters.follow, 1); char *host; char c; size_t host_len; if (phr_parse_host(location, len, (const char **)&host, &host_len) > 0) { free(domain->domain); c = host[host_len]; host[host_len] = 0; domain->domain = strdup(host); host[host_len] = c; if (false == is_valid_location(domain, location, len)) { free_domain(domain); return; } http_request(domain); } }
static void send_request(struct ev_loop *loop, domain_t * domain) { debug("send_request %s, search = %s", domain->domain, search_path[domain->index_search]); char buf[MAXLINE]; ev_io_set(&domain->io, domain->io.fd, EV_READ); ev_set_cb(&domain->io, recv_handler); ev_timer_set(&domain->tw, MAXRECVTIME, 0); size_t len = snprintf(buf, sizeof (buf), http_get, search_path[domain->index_search], domain->domain); /* this is safe */ if (len == writen(domain->io.fd, buf, len)) { //bzero(domain->data.buffer, sizeof(domain->data.buffer)); domain->data.len = 0; ev_io_start(loop, &domain->io); ev_timer_start(loop, &domain->tw); } else { free_domain(domain); } }
/* * Release all memory allocated for entire domain list */ void free_domain_list(domain_t* list) { domain_t* ptr; if (!list) return; while(list) { ptr = list; list = list->next; free_domain(ptr); } }
static void add_domain (virDomainPtr dom) { struct domain *domain; domains = realloc (domains, (nr_domains + 1) * sizeof (struct domain)); if (domains == NULL) { perror ("realloc"); exit (EXIT_FAILURE); } domain = &domains[nr_domains]; nr_domains++; domain->name = strdup (virDomainGetName (dom)); if (domain->name == NULL) { perror ("strdup"); exit (EXIT_FAILURE); } char uuid[VIR_UUID_STRING_BUFLEN]; if (virDomainGetUUIDString (dom, uuid) == 0) { domain->uuid = strdup (uuid); if (domain->uuid == NULL) { perror ("strdup"); exit (EXIT_FAILURE); } } else domain->uuid = NULL; domain->disks = NULL; int n = guestfs___for_each_disk (g, dom, add_disk, domain); if (n == -1) exit (EXIT_FAILURE); domain->nr_disks = n; if (domain->nr_disks > MAX_DISKS) { fprintf (stderr, _("%s: ignoring %s, it has too many disks (%zu > %d)"), program_name, domain->name, domain->nr_disks, MAX_DISKS); free_domain (domain); nr_domains--; return; } }
static void connect_handler(struct ev_loop *loop, struct ev_io *watcher, int events) { domain_t * domain = (domain_t *) watcher; ev_io_stop(loop, &domain->io); ev_timer_stop(loop, &domain->tw); debug("-- connected %s", domain->domain); int error; socklen_t len = sizeof (error); if (getsockopt(domain->io.fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0 || error) { free_domain(domain); errno = error; } else { send_request(loop, domain); } }
/* * Create a new domain structure which will initialy have * one domain name */ static domain_t* new_domain(str* did, str* domain, unsigned int flags) { domain_t* d; int_str name, val; str name_s = STR_STATIC_INIT(AVP_DID); d = (domain_t*)shm_malloc(sizeof(domain_t)); if (!d) goto error; memset(d, 0, sizeof(domain_t)); d->did.s = shm_malloc(did->len); if (!d->did.s) goto error; memcpy(d->did.s, did->s, did->len); d->did.len = did->len; d->domain = (str*)shm_malloc(sizeof(str)); if (!d->domain) goto error; d->domain[0].s = shm_malloc(domain->len); if (!d->domain[0].s) goto error; memcpy(d->domain[0].s, domain->s, domain->len); d->domain[0].len = domain->len; strlower(d->domain); d->flags = (unsigned int*)shm_malloc(sizeof(unsigned int)); if (!d->flags) goto error; d->flags[0] = flags; d->n = 1; /* Create an attribute containing did of the domain */ name.s = name_s; val.s = *did; if (add_avp_list(&d->attrs, AVP_CLASS_DOMAIN | AVP_NAME_STR | AVP_VAL_STR, name, val) < 0) goto error; return d; error: ERR("Unable to create new domain structure\n"); free_domain(d); return 0; }
struct domain *domain_create(domid_t dom_id, unsigned int cpu) { struct domain *d, **pd; struct vcpu *v; if ( (d = alloc_domain()) == NULL ) return NULL; d->domain_id = dom_id; atomic_set(&d->refcnt, 1); spin_lock_init(&d->big_lock); spin_lock_init(&d->page_alloc_lock); INIT_LIST_HEAD(&d->page_list); INIT_LIST_HEAD(&d->xenpage_list); rangeset_domain_initialise(d); if ( !is_idle_domain(d) ) { set_bit(_DOMF_ctrl_pause, &d->domain_flags); if ( evtchn_init(d) != 0 ) goto fail1; if ( grant_table_create(d) != 0 ) goto fail2; } if ( arch_domain_create(d) != 0 ) goto fail3; if ( (v = alloc_vcpu(d, 0, cpu)) == NULL ) goto fail4; d->iomem_caps = rangeset_new(d, "I/O Memory", RANGESETF_prettyprint_hex); d->irq_caps = rangeset_new(d, "Interrupts", 0); if ( (d->iomem_caps == NULL) || (d->irq_caps == NULL) ) goto fail4; /* NB. alloc_vcpu() is undone in free_domain() */ #if 0 if ( sched_init_domain(d) != 0 ) goto fail4; #endif if ( !is_idle_domain(d) ) { write_lock(&domlist_lock); pd = &domain_list; /* NB. domain_list maintained in order of dom_id. */ for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) if ( (*pd)->domain_id > d->domain_id ) break; d->next_in_list = *pd; *pd = d; d->next_in_hashbucket = domain_hash[DOMAIN_HASH(dom_id)]; domain_hash[DOMAIN_HASH(dom_id)] = d; write_unlock(&domlist_lock); } return d; fail4: arch_domain_destroy(d); fail3: if ( !is_idle_domain(d) ) grant_table_destroy(d); fail2: if ( !is_idle_domain(d) ) evtchn_destroy(d); fail1: rangeset_domain_destroy(d); free_domain(d); return NULL; }
static void recv_handler(struct ev_loop *loop, struct ev_io *watcher, int events) { //debug("recv_handler"); size_t i; domain_t *domain = (domain_t *) watcher; ev_io_stop(loop, &domain->io); ev_timer_stop(loop, &domain->tw); //debug("recv_header %s -- data buffer:%p; data len: %d", domain->domain, domain->data.buffer + domain->data.len, domain->data.len); ssize_t len = readn(domain->io.fd, domain->data.buffer + domain->data.len, sizeof (domain->data.buffer) - domain->data.len); if (len <= 0) { if (EAGAIN == errno) { // сокет занят буфер кончился и прочее //err_ret("error read socket %s: ", domain->domain); ev_io_start(loop, &domain->io); ev_timer_start(loop, &domain->tw); return; } else { // жесткая ошибка err_ret("error read socket %s: ", domain->domain); free_domain(domain); return; } } else { domain->data.len += len; int pret = parse_response(domain); debug("parse_response %s:%d", domain->domain, pret); if (pret > 0) { switch (domain->http.status) { case 301: case 302: { for (i = 0; i != domain->http.num_headers; ++i) { if (NULL != memmem(domain->http.headers[i].name, domain->http.headers[i].name_len, "Location", 8)) { follow_location(domain, domain->http.headers[i].value, domain->http.headers[i].value_len); return; //break; } } break; } case 200: { if (true == parse_body(&domain->data.buffer[pret], domain->data.len - pret)) { success_checked(domain); } else { if (++domain->index_search < (sizeof (search_path) / sizeof (search_path[0]))) { //ares_gethostbyname(domain->options->ares.channel, domain->domain, AF_INET, ev_ares_dns_callback, (void *) domain); http_request(domain); return; } } break; } } } else { error_parse(domain); } } debug("-- %s %d checked", domain->domain, domain->http.status); free_domain(domain); }
void get_domains_from_libvirt (void) { virErrorPtr err; virConnectPtr conn; int n; size_t i, j, nr_disks_added; nr_domains = 0; domains = NULL; /* Get the list of all domains. */ conn = virConnectOpenReadOnly (libvirt_uri); if (!conn) { err = virGetLastError (); fprintf (stderr, _("%s: could not connect to libvirt (code %d, domain %d): %s"), program_name, err->code, err->domain, err->message); exit (EXIT_FAILURE); } n = virConnectNumOfDomains (conn); if (n == -1) { err = virGetLastError (); fprintf (stderr, _("%s: could not get number of running domains (code %d, domain %d): %s"), program_name, err->code, err->domain, err->message); exit (EXIT_FAILURE); } int ids[n]; n = virConnectListDomains (conn, ids, n); if (n == -1) { err = virGetLastError (); fprintf (stderr, _("%s: could not list running domains (code %d, domain %d): %s"), program_name, err->code, err->domain, err->message); exit (EXIT_FAILURE); } add_domains_by_id (conn, ids, n); n = virConnectNumOfDefinedDomains (conn); if (n == -1) { err = virGetLastError (); fprintf (stderr, _("%s: could not get number of inactive domains (code %d, domain %d): %s"), program_name, err->code, err->domain, err->message); exit (EXIT_FAILURE); } char *names[n]; n = virConnectListDefinedDomains (conn, names, n); if (n == -1) { err = virGetLastError (); fprintf (stderr, _("%s: could not list inactive domains (code %d, domain %d): %s"), program_name, err->code, err->domain, err->message); exit (EXIT_FAILURE); } add_domains_by_name (conn, names, n); /* You must free these even though the libvirt documentation doesn't * mention it. */ for (i = 0; i < (size_t) n; ++i) free (names[i]); virConnectClose (conn); /* No domains? */ if (nr_domains == 0) return; /* Sort the domains alphabetically by name for display. */ qsort (domains, nr_domains, sizeof (struct domain), compare_domain_names); print_title (); /* To minimize the number of times we have to launch the appliance, * shuffle as many domains together as we can, but not exceeding * MAX_DISKS per request. If --one-per-guest was requested then only * request disks from a single guest each time. * Interesting application for NP-complete knapsack problem here. */ if (one_per_guest) { for (i = 0; i < nr_domains; ++i) multi_df (&domains[i], 1); } else { for (i = 0; i < nr_domains; /**/) { nr_disks_added = 0; /* Make a request with domains [i..j-1]. */ for (j = i; j < nr_domains; ++j) { if (nr_disks_added + domains[j].nr_disks > MAX_DISKS) break; nr_disks_added += domains[j].nr_disks; } multi_df (&domains[i], j-i); i = j; } } /* Free up domains structure. */ for (i = 0; i < nr_domains; ++i) free_domain (&domains[i]); free (domains); }