Example #1
0
int ofi_mr_insert(struct ofi_util_mr * in_mr_h, const struct fi_mr_attr *in_attr,
                                uint64_t * out_key, void * in_prov_mr)
{
    struct fi_mr_attr * item;

    if (!in_attr || in_attr->iov_count <= 0 || !in_prov_mr) {
        return -FI_EINVAL;
    }

    item = create_mr_attr_copy(in_attr, in_prov_mr);
    if (!item)
        return -FI_ENOMEM;

    /* Scalable MR handling: use requested key and offset */
    if (in_mr_h->mr_type == FI_MR_SCALABLE) {
        item->offset = (uintptr_t) in_attr->mr_iov[0].iov_base + in_attr->offset;
        /* verify key doesn't already exist */
        if (rbtFind(in_mr_h->map_handle, &item->requested_key)) {
                free((void *)item->mr_iov);
                free(item);
                return -FI_EINVAL;
        }
    } else {
        item->requested_key = get_mr_key(in_mr_h);
        item->offset = (uintptr_t) in_attr->mr_iov[0].iov_base;
    }

    rbtInsert(in_mr_h->map_handle, &item->requested_key, item);
    *out_key = item->requested_key;

    return 0;
}
Example #2
0
int ofi_mr_insert(struct ofi_mr_map *map, const struct fi_mr_attr *attr,
		  uint64_t *key, void *context)
{
	struct fi_mr_attr *item;

	item = dup_mr_attr(attr);
	if (!item)
		return -FI_ENOMEM;

	if (!(map->mode & FI_MR_VIRT_ADDR))
		item->offset = (uintptr_t) attr->mr_iov[0].iov_base;

	if (!(map->mode & FI_MR_PROV_KEY)) {
		if (rbtFind(map->rbtree, &item->requested_key)) {
			free(item);
			return -FI_ENOKEY;
		}
	} else {
		item->requested_key = map->key++;
	}

	rbtInsert(map->rbtree, &item->requested_key, item);
	*key = item->requested_key;
	item->context = context;

	return 0;
}
Example #3
0
static void locator_updatecache(enum locator_servicetype_t svc, char *key, char *resp)
{
	RbtIterator handle;
	cacheitm_t *newitm;

	if (!havecache[svc]) return;

	handle = rbtFind(locatorcache[svc], key);
	if (handle == rbtEnd(locatorcache[svc])) {
		newitm = (cacheitm_t *)calloc(1, sizeof(cacheitm_t));
		newitm->key = strdup(key);
		newitm->resp = strdup(resp);
		if (rbtInsert(locatorcache[svc], newitm->key, newitm) != RBT_STATUS_OK) {
			xfree(newitm->key);
			xfree(newitm->resp);
			xfree(newitm);
		}
	}
	else {
		newitm = (cacheitm_t *)gettreeitem(locatorcache[svc], handle);
		if (newitm->resp) xfree(newitm->resp);
		newitm->resp = strdup(resp);
		newitm->tstamp = getcurrenttime(NULL);
	}
}
Example #4
0
static void load_links(char *directory, char *urlprefix)
{
	DIR		*linkdir;
	struct dirent 	*d;
	char		fn[PATH_MAX];

	dbgprintf("load_links(%s, %s)\n", textornull(directory), textornull(urlprefix));

	linkdir = opendir(directory);
	if (!linkdir) {
		errprintf("Cannot read links in directory %s\n", directory);
		return;
	}

	MEMDEFINE(fn);

	while ((d = readdir(linkdir))) {
		link_t *newlink;

		if (*(d->d_name) == '.') continue;

		strcpy(fn, d->d_name);
		newlink = init_link(fn, urlprefix);
		rbtInsert(linkstree, newlink->key, newlink);
	}
	closedir(linkdir);

	MEMUNDEFINE(fn);
}
Example #5
0
void addnetpeer(char *peername)
{
	xymon_peer_t *newpeer;
	struct in_addr addr;
	char *oneip;
	int peerport = 0;
	char *delim;

	dbgprintf("Adding network peer %s\n", peername);

	oneip = strdup(peername);

	delim = strchr(oneip, ':');
	if (delim) {
		*delim = '\0';
		peerport = atoi(delim+1);
	}

	if (inet_aton(oneip, &addr) == 0) {
		/* peer is not an IP - do DNS lookup */

		struct hostent *hent;

		hent = gethostbyname(oneip);
		if (hent) {
			char *realip;

			memcpy(&addr, *(hent->h_addr_list), sizeof(struct in_addr));
			realip = inet_ntoa(addr);
			if (inet_aton(realip, &addr) == 0) {
				errprintf("Invalid IP address for %s (%s)\n", oneip, realip);
				goto done;
			}
		}
		else {
			errprintf("Cannot determine IP address of peer %s\n", oneip);
			goto done;
		}
	}

	if (peerport == 0) peerport = atoi(xgetenv("XYMONDPORT"));

	newpeer = calloc(1, sizeof(xymon_peer_t));
	newpeer->peername = strdup(peername);
	newpeer->peerstatus = P_DOWN;
	newpeer->peertype = P_NET;
	newpeer->peeraddr.sin_family = AF_INET;
	newpeer->peeraddr.sin_addr.s_addr = addr.s_addr;
	newpeer->peeraddr.sin_port = htons(peerport);

	rbtInsert(peers, newpeer->peername, newpeer);

done:
	xfree(oneip);
}
Example #6
0
void addclone_nkconfig(char *origin, char *newclone)
{
	char *newkey;
	RbtHandle handle;

	newkey = (char *)malloc(strlen(newclone) + 2);
	sprintf(newkey, "%s=", newclone);
	handle = rbtFind(rbconf, newkey);
	if (handle != rbtEnd(rbconf)) dropclone_nkconfig(newclone);
	rbtInsert(rbconf, newkey, strdup(origin));
}
Example #7
0
static void build_hosttree(void)
{
	static int hosttree_exists = 0;
	namelist_t *walk;
	RbtStatus status;
	char *tstr;

	if (hosttree_exists) {
		rbtDelete(rbhosts);
		rbtDelete(rbclients);
	}
	rbhosts = rbtNew(name_compare);
	rbclients = rbtNew(name_compare);
	hosttree_exists = 1;

	for (walk = namehead; (walk); walk = walk->next) {
		status = rbtInsert(rbhosts, walk->bbhostname, walk);
		if (walk->clientname) rbtInsert(rbclients, walk->clientname, walk);

		switch (status) {
		  case RBT_STATUS_OK:
		  case RBT_STATUS_DUPLICATE_KEY:
			break;
		  case RBT_STATUS_MEM_EXHAUSTED:
			errprintf("loadhosts:build_hosttree - insert into tree failed (out of memory)\n");
			break;
		  default:
			errprintf("loadhosts:build_hosttree - insert into tree failed code %d\n", status);
			break;
		}

		tstr = bbh_item(walk, BBH_NOTBEFORE);
		walk->notbefore = (tstr ? timestr2timet(tstr) : 0);
		if (walk->notbefore == -1) walk->notbefore = 0;

		tstr = bbh_item(walk, BBH_NOTAFTER);
		walk->notafter = (tstr ? timestr2timet(tstr) : INT_MAX);
		if (walk->notafter == -1) walk->notafter = INT_MAX;
	}
}
Example #8
0
static int psmx_ns_map_add(int service, psm_epid_t name)
{
	if (rbtFind(psmx_ns_map, (void *)(uintptr_t)service)) {
		FI_WARN(&psmx_prov, FI_LOG_CORE,
			"failed to add address: service %u already in use.\n", service);
		return -FI_EBUSY;
	}

	if (rbtInsert(psmx_ns_map, (void *)(uintptr_t)service, (void *)name)) {
		FI_WARN(&psmx_prov, FI_LOG_CORE,
			"failed to add address for service %u: out of memory.\n", service);
		return -FI_ENOMEM;
	}

	return 0;
}
Example #9
0
static int ofi_mr_rbt_storage_insert(struct ofi_mr_storage *storage,
				     struct iovec *key,
				     struct ofi_mr_entry *entry)
{
	int ret = rbtInsert((RbtHandle)storage->storage,
			    (void *)&entry->iov, (void *)entry);
	if (ret != RBT_STATUS_OK) {
		switch (ret) {
		case RBT_STATUS_MEM_EXHAUSTED:
			return -FI_ENOMEM;
		case RBT_STATUS_DUPLICATE_KEY:
			return -FI_EALREADY;
		default:
			return -FI_EAVAIL;
		}
	}
	return ret;
}
Example #10
0
void addlocalpeer(char *childcmd, char **childargs)
{
	xymon_peer_t *newpeer;
	int i, count;

	dbgprintf("Adding local peer using command %s\n", childcmd);

	for (count=0; (childargs[count]); count++) ;

	newpeer = (xymon_peer_t *)calloc(1, sizeof(xymon_peer_t));
	newpeer->peername = strdup("");
	newpeer->peerstatus = P_DOWN;
	newpeer->peertype = P_LOCAL;
	newpeer->childcmd = strdup(childcmd);
	newpeer->childargs = (char **)calloc(count+1, sizeof(char *));
	for (i=0; (i<count); i++) newpeer->childargs[i] = strdup(childargs[i]);

	rbtInsert(peers, newpeer->peername, newpeer);
}
Example #11
0
RbtHandle columnlist(RbtHandle statetree)
{
	RbtHandle rbcolumns;
	RbtIterator hhandle;

	rbcolumns = rbtNew(name_compare);
	for (hhandle = rbtBegin(statetree); (hhandle != rbtEnd(statetree)); hhandle = rbtNext(statetree, hhandle)) {
		void *k1, *k2;
		hstatus_t *itm;
		RbtStatus status;

	        rbtKeyValue(statetree, hhandle, &k1, &k2);
		itm = (hstatus_t *)k2;

		status = rbtInsert(rbcolumns, itm->testname, NULL);
	}

	return rbcolumns;
}
Example #12
0
static int util_ns_map_add(struct util_ns *ns, void *service_in,
			   void *name_in)
{
	void *name, *service;
	int ret;

	service = calloc(ns->service_len, 1);
	if (!service) {
		ret = -FI_ENOMEM;
		goto err1;
	}
	memcpy(service, service_in, ns->service_len);

	name = calloc(ns->name_len, 1);
	if (!name) {
		ret = -FI_ENOMEM;
		goto err2;
	}
	memcpy(name, name_in, ns->name_len);

	if (rbtFind(ns->ns_map, service)) {
		ret = -FI_EADDRINUSE;
		goto err3;
	}

	if (rbtInsert(ns->ns_map, service, name)) {
		ret = -FI_ENOMEM;
		goto err3;
	}
	return FI_SUCCESS;

err3:
	free(name);
err2:
	free(service);
err1:
	return ret;
}
Example #13
0
static int psmx2_mr_reserve_key(struct psmx2_fid_domain *domain,
				uint64_t requested_key,
				uint64_t *assigned_key,
				void *mr)
{
	uint64_t key;
	int i;
	int try_count;
	int err = -FI_ENOKEY;

	fastlock_acquire(&domain->mr_lock);

	if (domain->mr_mode == FI_MR_SCALABLE) {
		key = requested_key;
		try_count = 1;
	}
	else {
		key = domain->mr_reserved_key;
		try_count = 10000; /* large enough */
	}

	for (i=0; i<try_count; i++, key++) {
		if (!rbtFind(domain->mr_map, (void *)key)) {
			if (!rbtInsert(domain->mr_map, (void *)key, mr)) {
				if (domain->mr_mode != FI_MR_SCALABLE)
					domain->mr_reserved_key = key + 1;
				*assigned_key = key;
				err = 0;
			}
			break;
		}
	}

	fastlock_release(&domain->mr_lock);

	return err;
}
Example #14
0
int  tex_cache_getid(int imgid,int* cacheid)
{
	KeyType key = imgid;
	RbtStatus status;
	NodeType *p;
	int ret = 0;

	if ((p = rbtFind(rb,key)) != NULL) {
		*cacheid = ((tex_node_p)(p->val.node))->texid;
		ret = 1;
	} else {
		ValType val;
		val.stuff = imgid;
		val.node  = get_free_node();
		key = imgid;
		status = rbtInsert(rb,key, val);
		if (status) {
			printf("fail: status = %d\n", status);
		}
		*cacheid  = ((tex_node_p)(val.node))->texid;
	}

	return ret;
}
Example #15
0
static int sock_regattr(struct fid *fid, const struct fi_mr_attr *attr,
		uint64_t flags, struct fid_mr **mr)
{
	struct fi_eq_entry eq_entry;
	struct sock_domain *dom;
	struct sock_mr *_mr;
	uint64_t key;
	struct fid_domain *domain;
	RbtStatus res;
	int ret = 0;

	if (fid->fclass != FI_CLASS_DOMAIN || !attr || attr->iov_count <= 0) {
		return -FI_EINVAL;
	}

	domain = container_of(fid, struct fid_domain, fid);
	dom = container_of(domain, struct sock_domain, dom_fid);

	_mr = calloc(1, sizeof(*_mr) +
		     sizeof(_mr->mr_iov) * (attr->iov_count - 1));
	if (!_mr)
		return -FI_ENOMEM;

	fastlock_acquire(&dom->lock);
	if (dom->attr.mr_mode == FI_MR_SCALABLE &&
	    sock_mr_get_entry(dom, attr->requested_key) != NULL) {
		ret = -FI_ENOKEY;
		goto err;
	}

	_mr->mr_fid.fid.fclass = FI_CLASS_MR;
	_mr->mr_fid.fid.context = attr->context;
	_mr->mr_fid.fid.ops = &sock_mr_fi_ops;

	_mr->domain = dom;
	_mr->access = attr->access;
	_mr->flags = flags;
	_mr->offset = (dom->attr.mr_mode == FI_MR_SCALABLE) ?
		(uintptr_t) attr->mr_iov[0].iov_base + attr->offset :
		(uintptr_t) attr->mr_iov[0].iov_base;

	key = (dom->attr.mr_mode == FI_MR_BASIC) ?
		sock_get_mr_key(dom) : attr->requested_key;

	_mr->key = key;
	res = rbtInsert(dom->mr_heap, &_mr->key, _mr);
	if (res != RBT_STATUS_OK) {
		ret = -FI_ENOMEM;
		goto err;
	}

	_mr->mr_fid.key = key;
	_mr->mr_fid.mem_desc = (void *) (uintptr_t) key;
	fastlock_release(&dom->lock);

	_mr->iov_count = attr->iov_count;
	memcpy(&_mr->mr_iov, attr->mr_iov, sizeof(_mr->mr_iov) * attr->iov_count);

	*mr = &_mr->mr_fid;
	atomic_inc(&dom->ref);

	if (dom->mr_eq) {
		eq_entry.fid = &domain->fid;
		eq_entry.context = attr->context;
		return sock_eq_report_event(dom->mr_eq, FI_MR_COMPLETE,
					    &eq_entry, sizeof(eq_entry), 0);
	}

	return 0;

err:
	fastlock_release(&dom->lock);
	free(_mr);
	return ret;
}
Example #16
0
int load_hostnames(char *bbhostsfn, char *extrainclude, int fqdn)
{
	/* Return value: 0 for load OK, 1 for "No files changed since last load", -1 for error (file not found) */
	static void *bbhfiles = NULL;
	FILE *bbhosts;
	int ip1, ip2, ip3, ip4, groupid, pageidx;
	char hostname[4096];
	strbuffer_t *inbuf;
	pagelist_t *curtoppage, *curpage, *pgtail;
	namelist_t *nametail = NULL;
	RbtHandle htree;

	/* First check if there were no modifications at all */
	if (bbhfiles) {
		if (!stackfmodified(bbhfiles)){
			dbgprintf("No files modified, skipping reload of %s\n", bbhostsfn);
			return 1;
		}
		else {
			stackfclist(&bbhfiles);
			bbhfiles = NULL;
		}
	}

	MEMDEFINE(hostname);
	MEMDEFINE(l);

	configloaded = 1;
	initialize_hostlist();
	curpage = curtoppage = pgtail = pghead;
	pageidx = groupid = 0;

	bbhosts = stackfopen(bbhostsfn, "r", &bbhfiles);
	if (bbhosts == NULL) return -1;

	inbuf = newstrbuffer(0);
	htree = rbtNew(name_compare);
	while (stackfgets(inbuf, extrainclude)) {
		sanitize_input(inbuf, 0, 0);

		if (strncmp(STRBUF(inbuf), "page", 4) == 0) {
			pagelist_t *newp;
			char *name, *title;

			pageidx = groupid = 0;
			if (get_page_name_title(STRBUF(inbuf), "page", &name, &title) == 0) {
				newp = (pagelist_t *)malloc(sizeof(pagelist_t));
				newp->pagepath = strdup(name);
				newp->pagetitle = (title ? strdup(title) : NULL);
				newp->next = NULL;

				pgtail->next = newp;
				pgtail = newp;

				curpage = curtoppage = newp;
			}
		}
		else if (strncmp(STRBUF(inbuf), "subpage", 7) == 0) {
			pagelist_t *newp;
			char *name, *title;

			pageidx = groupid = 0;
			if (get_page_name_title(STRBUF(inbuf), "subpage", &name, &title) == 0) {
				newp = (pagelist_t *)malloc(sizeof(pagelist_t));
				newp->pagepath = malloc(strlen(curtoppage->pagepath) + strlen(name) + 2);
				sprintf(newp->pagepath, "%s/%s", curtoppage->pagepath, name);
				newp->pagetitle = malloc(strlen(curtoppage->pagetitle) + strlen(title) + 2);
				sprintf(newp->pagetitle, "%s/%s", curtoppage->pagetitle, title);
				newp->next = NULL;

				pgtail->next = newp;
				pgtail = newp;

				curpage = newp;
			}
		}
		else if (strncmp(STRBUF(inbuf), "subparent", 9) == 0) {
			pagelist_t *newp, *parent;
			char *pname, *name, *title;

			pageidx = groupid = 0;
			parent = NULL;
			if (get_page_name_title(STRBUF(inbuf), "subparent", &pname, &title) == 0) {
				for (parent = pghead; (parent && !pagematch(parent, pname)); parent = parent->next);
			}

			if (parent && (get_page_name_title(title, "", &name, &title) == 0)) {
				newp = (pagelist_t *)malloc(sizeof(pagelist_t));
				newp->pagepath = malloc(strlen(parent->pagepath) + strlen(name) + 2);
				sprintf(newp->pagepath, "%s/%s", parent->pagepath, name);
				newp->pagetitle = malloc(strlen(parent->pagetitle) + strlen(title) + 2);
				sprintf(newp->pagetitle, "%s/%s", parent->pagetitle, title);
				newp->next = NULL;

				pgtail->next = newp;
				pgtail = newp;

				curpage = newp;
			}
		}
		else if (strncmp(STRBUF(inbuf), "group", 5) == 0) {
			groupid++;
		}
		else if (sscanf(STRBUF(inbuf), "%d.%d.%d.%d %s", &ip1, &ip2, &ip3, &ip4, hostname) == 5) {
			char *startoftags, *tag, *delim;
			int elemidx, elemsize;
			char clientname[4096];
			char downtime[4096];
			char groupidstr[10];
			RbtIterator handle;

			namelist_t *newitem = calloc(1, sizeof(namelist_t));
			namelist_t *iwalk, *iprev;

			MEMDEFINE(clientname);
			MEMDEFINE(downtime);

			/* Hostname beginning with '@' are "no-display" hosts. But we still want them. */
			if (*hostname == '@') memmove(hostname, hostname+1, strlen(hostname));

			if (!fqdn) {
				/* Strip any domain from the hostname */
				char *p = strchr(hostname, '.');
				if (p) *p = '\0';
			}

			sprintf(newitem->ip, "%d.%d.%d.%d", ip1, ip2, ip3, ip4);
			sprintf(groupidstr, "%d", groupid);
			newitem->groupid = strdup(groupidstr);
			newitem->pageindex = pageidx++;

			newitem->bbhostname = strdup(hostname);
			if (ip1 || ip2 || ip3 || ip4) newitem->preference = 1; else newitem->preference = 0;
			newitem->logname = strdup(newitem->bbhostname);
			{ char *p = newitem->logname; while ((p = strchr(p, '.')) != NULL) { *p = '_'; } }
			newitem->page = curpage;
			newitem->defaulthost = defaulthost;

			clientname[0] = downtime[0] = '\0';
			startoftags = strchr(STRBUF(inbuf), '#');
			if (startoftags == NULL) startoftags = ""; else startoftags++;
			startoftags += strspn(startoftags, " \t\r\n");
			newitem->allelems = strdup(startoftags);
			elemsize = 5;
			newitem->elems = (char **)malloc((elemsize+1)*sizeof(char *));

			tag = newitem->allelems; elemidx = 0;
			while (tag && *tag) {
				if (elemidx == elemsize) {
					elemsize += 5;
					newitem->elems = (char **)realloc(newitem->elems, (elemsize+1)*sizeof(char *));
				}
				newitem->elems[elemidx] = tag;

				/* Skip until we hit a whitespace or a quote */
				tag += strcspn(tag, " \t\r\n\"");
				if (*tag == '"') {
					delim = tag;

					/* Hit a quote - skip until the next matching quote */
					tag = strchr(tag+1, '"');
					if (tag != NULL) { 
						/* Found end-quote, NULL the item here and move on */
						*tag = '\0'; tag++; 
					}

					/* Now move quoted data one byte down (including the NUL) to kill quotechar */
					memmove(delim, delim+1, strlen(delim));
				}
				else if (*tag) {
					/* Normal end of item, NULL it and move on */
					*tag = '\0'; tag++;
				}
				else {
					/* End of line - no more to do. */
					tag = NULL;
				}

				/* 
				 * If we find a "noconn", drop preference value to 0.
				 * If we find a "prefer", up reference value to 2.
				 */
				if ((newitem->preference == 1) && (strcmp(newitem->elems[elemidx], "noconn") == 0))
					newitem->preference = 0;
				else if (strcmp(newitem->elems[elemidx], "prefer") == 0)
					newitem->preference = 2;

				/* Skip whitespace until start of next tag */
				if (tag) tag += strspn(tag, " \t\r\n");
				elemidx++;
			}

			newitem->elems[elemidx] = NULL;

			/* See if this host is defined before */
			handle = rbtFind(htree, newitem->bbhostname);
			if (strcasecmp(newitem->bbhostname, ".default.") == 0) {
				/* The pseudo DEFAULT host */
				newitem->next = NULL;
				defaulthost = newitem;
			}
			else if (handle == rbtEnd(htree)) {
				/* New item, so add to end of list */
				newitem->next = NULL;
				if (namehead == NULL) 
					namehead = nametail = newitem;
				else {
					nametail->next = newitem;
					nametail = newitem;
				}
				rbtInsert(htree, newitem->bbhostname, newitem);
			}
			else {
				/* Find the existing record - compare the record pointer instead of the name */
				namelist_t *existingrec = (namelist_t *)gettreeitem(htree, handle);
				for (iwalk = namehead, iprev = NULL; ((iwalk != existingrec) && iwalk); iprev = iwalk, iwalk = iwalk->next) ;
 				if (newitem->preference <= iwalk->preference) {
					/* Add after the existing (more preferred) entry */
					newitem->next = iwalk->next;
					iwalk->next = newitem;
				}
				else {
					/* New item has higher preference, so add before the iwalk item (i.e. after iprev) */
					if (iprev == NULL) {
						newitem->next = namehead;
						namehead = newitem;
					}
					else {
						newitem->next = iprev->next;
						iprev->next = newitem;
					}
				}
			}

			newitem->clientname = bbh_find_item(newitem, BBH_CLIENTALIAS);
			if (newitem->clientname == NULL) newitem->clientname = newitem->bbhostname;
			newitem->downtime = bbh_find_item(newitem, BBH_DOWNTIME);

			MEMUNDEFINE(clientname);
			MEMUNDEFINE(downtime);
		}
	}
	stackfclose(bbhosts);
	freestrbuffer(inbuf);
	rbtDelete(htree);

	MEMUNDEFINE(hostname);
	MEMUNDEFINE(l);

	build_hosttree();

	return 0;
}
Example #17
0
int main(int argc, char *argv[])
{
	int argi;
	struct sigaction sa;
	namelist_t *hostwalk;
	time_t nexttimeout;

	for (argi=1; (argi < argc); argi++) {
		if (argnmatch(argv[argi], "--server=")) {
			char *p = strchr(argv[argi], '=');
			serverip = strdup(p+1);
		}
		else if (argnmatch(argv[argi], "--interval=")) {
			char *p = strchr(argv[argi], '=');
			pollinterval = atoi(p+1);
		}
		else if (argnmatch(argv[argi], "--log-interval=")) {
			char *p = strchr(argv[argi], '=');
			errorloginterval = atoi(p+1);
		}
		else if (argnmatch(argv[argi], "--id=")) {
			char *p = strchr(argv[argi], '=');
			serverid = atoi(p+1);
		}
		else if (strcmp(argv[argi], "--debug") == 0) {
			debug = 1;
		}
	}

	setup_signalhandler("hobbitfetch");
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = sigmisc_handler;
	sigaction(SIGHUP, &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);
	sigaction(SIGUSR1, &sa, NULL);	/* SIGUSR1 triggers logging of active requests */

	clients = rbtNew(name_compare);
	nexttimeout = time(NULL) + 60;

	{
		/* Seed the random number generator */
		struct timeval tv;
		struct timezone tz;

		gettimeofday(&tv, &tz);
		srandom(tv.tv_usec);
	}

	do {
		RbtIterator handle;
		conn_t *connwalk, *cprev;
		fd_set fdread, fdwrite;
		int n, maxfd;
		struct timeval tmo;
		time_t now;
		
		now = time(NULL);
		if (now > reloadtime) {
			/* Time to reload the bb-hosts file */
			reloadtime = now + 600;

			load_hostnames(xgetenv("BBHOSTS"), NULL, get_fqdn());
			for (hostwalk = first_host(); (hostwalk); hostwalk = hostwalk->next) {
				char *hname;
				clients_t *newclient;

				if (!bbh_item(hostwalk, BBH_FLAG_PULLDATA)) continue;

				hname = bbh_item(hostwalk, BBH_HOSTNAME);
				handle = rbtFind(clients, hname);
				if (handle == rbtEnd(clients)) {
					newclient = (clients_t *)calloc(1, sizeof(clients_t));
					newclient->hostname = strdup(hname);
					rbtInsert(clients, newclient->hostname, newclient);
					whentoqueue = now;
				}
			}
		}

		now = time(NULL);
		if (now > nexttimeout) {
			/* Check for connections that have timed out */
			nexttimeout = now + 60;

			for (connwalk = chead; (connwalk); connwalk = connwalk->next) {
				if ((connwalk->tstamp + 60) < now) {
					if (debug || (connwalk->client->nexterrortxt < now)) {
						errprintf("Timeout while talking to %s (req %lu): Aborting session\n",
							  addrstring(&connwalk->caddr), connwalk->seq);
						connwalk->client->nexterrortxt = now + errorloginterval;
					}
					flag_cleanup(connwalk);
				}
			}
		}

		if (needcleanup) {
			/* Remove any finished requests */
			needcleanup = 0;
			connwalk = chead; cprev = NULL;
			dbgprintf("Doing cleanup\n");

			while (connwalk) {
				conn_t *zombie;

				if ((connwalk->action == C_READING) || (connwalk->action == C_WRITING)) {
					/* Active connection - skip to the next conn_t record */
					cprev = connwalk;
					connwalk = connwalk->next;
					continue;
				}

				if (connwalk->action == C_CLEANUP) {
					if (connwalk->ctype == C_CLIENT) {
						/* 
						 * Finished getting data from a client, 
						 * flag idle and set next poll time.
						 */
						connwalk->client->busy = 0;
						set_polltime(connwalk->client);
					}
					else if (connwalk->ctype == C_SERVER) {
						/* Nothing needed for server cleanups */
					}
				}

				/* Unlink the request from the list of active connections */
				zombie = connwalk;
				if (cprev == NULL) {
					chead = zombie->next;
					connwalk = chead;
					cprev = NULL;
				}
				else {
					cprev->next = zombie->next;
					connwalk = zombie->next;
				}

				/* Purge the zombie */
				dbgprintf("Request completed: req %lu, peer %s, action was %d, type was %d\n", 
					zombie->seq, addrstring(&zombie->caddr), 
					zombie->action, zombie->ctype);
				close(zombie->sockfd);
				freestrbuffer(zombie->msgbuf);
				xfree(zombie);
			}

			/* Set the tail pointer correctly */
			ctail = chead;
			if (ctail) { while (ctail->next) ctail = ctail->next; }
		}

		if (dumpsessions) {
			/* Set by SIGUSR1 - dump the list of active requests */
			dumpsessions = 0;
			for (connwalk = chead; (connwalk); connwalk = connwalk->next) {
				char *ctypestr, *actionstr;
				char timestr[30];

				switch (connwalk->ctype) {
				  case C_CLIENT: ctypestr = "client"; break;
				  case C_SERVER: ctypestr = "server"; break;
				}

				switch (connwalk->action) {
				  case C_READING: actionstr = "reading"; break;
				  case C_WRITING: actionstr = "writing"; break;
				  case C_CLEANUP: actionstr = "cleanup"; break;
				}

				strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S",
					 localtime(&connwalk->tstamp));

				errprintf("Request %lu: state %s/%s, peer %s, started %s (%lu secs ago)\n",
					  connwalk->seq, ctypestr, actionstr, addrstring(&connwalk->caddr),
					  timestr, (now - connwalk->tstamp));
			}
		}

		now = time(NULL);
		if (now >= whentoqueue) {
			/* Scan host-tree for clients we need to contact */
			for (handle = rbtBegin(clients); (handle != rbtEnd(clients)); handle = rbtNext(clients, handle)) {
				clients_t *clientwalk;
				char msgline[100];
				strbuffer_t *request;
				char *pullstr, *ip;
				int port;

				clientwalk = (clients_t *)gettreeitem(clients, handle);
				if (clientwalk->busy) continue;
				if (clientwalk->nextpoll > now) continue;

				/* Deleted hosts stay in our tree - but should disappear from the known hosts */
				hostwalk = hostinfo(clientwalk->hostname); if (!hostwalk) continue;
				pullstr = bbh_item(hostwalk, BBH_FLAG_PULLDATA); if (!pullstr) continue;

				ip = strchr(pullstr, '=');
				port = atoi(xgetenv("BBPORT"));

				if (!ip) {
					ip = strdup(bbh_item(hostwalk, BBH_IP));
				}
				else {
					/* There is an explicit IP setting in the pulldata tag */
					char *p;

					ip++; /* Skip the '=' */
					ip = strdup(ip);
					p = strchr(ip, ':');
					if (p) { *p = '\0'; port = atoi(p+1); }

					if (*ip == '\0') {
						/* No IP given, just a port number */
						xfree(ip);
						ip = strdup(bbh_item(hostwalk, BBH_IP));
					}
				}

				if (strcmp(ip, "0.0.0.0") == 0) {
					struct hostent *hent;

					xfree(ip); ip = NULL;
					hent = gethostbyname(clientwalk->hostname);
					if (hent) {
						struct in_addr addr;

						memcpy(&addr, *(hent->h_addr_list), sizeof(addr));
						ip = strdup(inet_ntoa(addr));
					}
				}

				if (!ip) continue;

				/* 
				 * Build the "pullclient" request, which includes the latest
				 * clientdata config we got from the server. Keep the clientdata
				 * here - we send "pullclient" requests more often that we actually
				 * contact the server, but we should provide the config data always.
				 */
				request = newstrbuffer(0);
				sprintf(msgline, "pullclient %d\n", serverid);
				addtobuffer(request, msgline);
				if (clientwalk->clientdata) addtobuffer(request, clientwalk->clientdata);

				/* Put the request on the connection queue */
				addrequest(C_CLIENT, ip, port, request, clientwalk);
				clientwalk->busy = 1;

				xfree(ip);
			}
		}

		/* Handle request queue */
		FD_ZERO(&fdread);
		FD_ZERO(&fdwrite);
		maxfd = -1;
		for (connwalk = chead; (connwalk); connwalk = connwalk->next) {
			switch (connwalk->action) {
			  case C_READING: 
				FD_SET(connwalk->sockfd, &fdread);
				if (connwalk->sockfd > maxfd) maxfd = connwalk->sockfd;
				break;

			  case C_WRITING: 
				FD_SET(connwalk->sockfd, &fdwrite);
				if (connwalk->sockfd > maxfd) maxfd = connwalk->sockfd;
				break;

			  case C_CLEANUP:
				break;
			}
		}

		/* Do select with a 1 second timeout */
		tmo.tv_sec = 1;
		tmo.tv_usec = 0;
		n = select(maxfd+1, &fdread, &fdwrite, NULL, &tmo);

		if (n == -1) {
			if (errno == EINTR) continue;	/* Interrupted, e.g. a SIGHUP */

			/* This is a "cannot-happen" failure. Bail out */
			errprintf("select failure: %s\n", strerror(errno));
			return 0;
		}

		if (n == 0) continue;	/* Timeout */

		for (connwalk = chead; (connwalk); connwalk = connwalk->next) {
			switch (connwalk->action) {
			  case C_READING: 
				if (FD_ISSET(connwalk->sockfd, &fdread)) grabdata(connwalk);
				break;

			  case C_WRITING: 
				if (FD_ISSET(connwalk->sockfd, &fdwrite)) senddata(connwalk);
				break;

			  case C_CLEANUP:
				break;
			}
		}

	} while (running);

	return 0;
}
Example #18
0
int update_nkconfig(nkconf_t *rec)
{
	char *bakfn;
	FILE *bakfd;
	unsigned char buf[8192];
	int n;
	struct stat st;
	struct utimbuf ut;

	RbtHandle handle;
	FILE *fd;
	int result = 0;

	/* First, copy the old file */
	bakfn = (char *)malloc(strlen(configfn) + 5);
	sprintf(bakfn, "%s.bak", configfn);
	if (stat(configfn, &st) == 0) {
		ut.actime = st.st_atime;
		ut.modtime = st.st_mtime;
	}
	else ut.actime = ut.modtime = getcurrenttime(NULL);
	fd = fopen(configfn, "r");
	if (fd) {
		bakfd = fopen(bakfn, "w");
		if (bakfd) {
			while ((n = fread(buf, 1, sizeof(buf), fd)) > 0) fwrite(buf, 1, n, bakfd);
			fclose(bakfd);
			utime(bakfn, &ut);
		}
		fclose(fd);
	}
	xfree(bakfn);

	fd = fopen(configfn, "w");
	if (fd == NULL) {
		errprintf("Cannot open output file %s\n", configfn);
		return 1;
	}

	if (rec) {
		handle = rbtFind(rbconf, rec->key);
		if (handle == rbtEnd(rbconf)) rbtInsert(rbconf, rec->key, rec);
	}

	handle = rbtBegin(rbconf);
	while (handle != rbtEnd(rbconf)) {
		void *k1, *k2;
		char *onekey;

		rbtKeyValue(rbconf, handle, &k1, &k2);
		onekey = (char *)k1;

		if (*(onekey + strlen(onekey) - 1) == '=') {
			char *pointsto = (char *)k2;
			char *hostname;
			
			hostname = strdup(onekey);
			*(hostname + strlen(hostname) - 1) = '\0';
			fprintf(fd, "%s|=%s\n", hostname, pointsto);
		}
		else {
			nkconf_t *onerec = (nkconf_t *)k2;
			char startstr[20], endstr[20];

			*startstr = *endstr = '\0';
			if (onerec->starttime > 0) sprintf(startstr, "%d", (int)onerec->starttime);
			if (onerec->endtime > 0) sprintf(endstr, "%d", (int)onerec->endtime);

			fprintf(fd, "%s|%s|%s|%s|%d|%s|%s|%s\n",
				onekey, 
				startstr, endstr,
				(onerec->nktime ? onerec->nktime : ""),
				onerec->priority, 
				(onerec->ttgroup ? onerec->ttgroup : ""), 
				(onerec->ttextra ? onerec->ttextra : ""),
				(onerec->updinfo ? onerec->updinfo : ""));
		}

		handle = rbtNext(rbconf, handle);
	}

	fclose(fd);

	return result;
}
Example #19
0
int loadstatus(int maxprio, time_t maxage, int mincolor, int wantacked)
{
	int xymondresult;
	char *board = NULL;
	char *bol, *eol;
	time_t now;
	char msg[1024];
	int i;
	sendreturn_t *sres;

	sprintf(msg, "xymondboard acklevel=%d fields=hostname,testname,color,lastchange,logtime,validtime,acklist color=%s", critacklevel,colorname(mincolor));
	for (i=mincolor+1; (i < COL_COUNT); i++) sprintf(msg+strlen(msg), ",%s", colorname(i));

	sres = newsendreturnbuf(1, NULL);
	xymondresult = sendmessage(msg, NULL, XYMON_TIMEOUT, sres);
	if (xymondresult != XYMONSEND_OK) {
		freesendreturnbuf(sres);
		errormsg("Unable to fetch current status\n");
		return 1;
	}
	else {
		board = getsendreturnstr(sres, 1);
		freesendreturnbuf(sres);
	}

	now = getcurrenttime(NULL);
	rbstate = rbtNew(name_compare);

	bol = board;
	while (bol && (*bol)) {
		char *endkey;
		RbtStatus status;

		eol = strchr(bol, '\n'); if (eol) *eol = '\0';

		/* Find the config entry */
		endkey = strchr(bol, '|'); if (endkey) endkey = strchr(endkey+1, '|'); 
		if (endkey) {
			critconf_t *cfg;
			char *ackstr, *ackrtimestr, *ackvtimestr, *acklevelstr, *ackbystr, *ackmsgstr;

			*endkey = '\0';
			cfg = get_critconfig(bol, CRITCONF_TIMEFILTER, NULL);
			*endkey = '|';

			if (cfg) {
				hstatus_t *newitem = (hstatus_t *)calloc(1, sizeof(hstatus_t));
				newitem->config     = cfg;
				newitem->hostname   = gettok(bol, "|");
				newitem->testname   = gettok(NULL, "|");
				newitem->color      = parse_color(gettok(NULL, "|"));
				newitem->lastchange = atoi(gettok(NULL, "|"));
				newitem->logtime    = atoi(gettok(NULL, "|"));
				newitem->validtime  = atoi(gettok(NULL, "|"));
				ackstr              = gettok(NULL, "|");
				ackrtimestr = ackvtimestr = acklevelstr = ackbystr = ackmsgstr = NULL;

				if (ackstr) {
					nldecode(ackstr);
					ackrtimestr = strtok(ackstr, ":");
					if (ackrtimestr) ackvtimestr = strtok(NULL, ":");
					if (ackvtimestr) acklevelstr = strtok(NULL, ":");
					if (acklevelstr) ackbystr = strtok(NULL, ":");
					if (ackbystr)    ackmsgstr = strtok(NULL, ":");
				}

				if ( (hostinfo(newitem->hostname) == NULL)  ||
				     (newitem->config->priority > maxprio)  ||
				     ((now - newitem->lastchange) > maxage) ||
				     (newitem->color < mincolor)            ||
				     (ackmsgstr && !wantacked)              ) {
					xfree(newitem);
				}
				else {
					if (ackvtimestr && ackbystr && ackmsgstr) {
						newitem->acktime = atoi(ackvtimestr);
						newitem->ackedby = strdup(ackbystr);
						newitem->ackmsg  = strdup(ackmsgstr);
					}

					newitem->key = (char *)malloc(strlen(newitem->hostname) + strlen(newitem->testname) + 2);
					sprintf(newitem->key, "%s|%s", newitem->hostname, newitem->testname);
					status = rbtInsert(rbstate, newitem->key, newitem);
				}
			}
		}

		bol = (eol ? (eol+1) : NULL);
	}

	return 0;
}
Example #20
0
int load_nkconfig(char *fn)
{
	static void *configfiles = NULL;
	static int firsttime = 1;
	FILE *fd;
	strbuffer_t *inbuf;

	/* Setup the default configuration filename */
	if (!fn) {
		if (!defaultfn) {
			char *bbhome = xgetenv("BBHOME");
			defaultfn = (char *)malloc(strlen(bbhome) + strlen(DEFAULTCONFIG) + 2);
			sprintf(defaultfn, "%s/%s", bbhome, DEFAULTCONFIG);
		}
		fn = defaultfn;
	}

	if (configfn) xfree(configfn);
	configfn = strdup(fn);

	/* First check if there were no modifications at all */
	if (configfiles) {
		if (!stackfmodified(configfiles)){
			dbgprintf("No files modified, skipping reload of %s\n", fn);
			return 0;
		}
		else {
			stackfclist(&configfiles);
			configfiles = NULL;
		}
	}

	if (!firsttime) {
		/* Clean up existing datatree */
		RbtHandle handle;
		void *k1, *k2;

		for (handle = rbtBegin(rbconf); (handle != rbtEnd(rbconf)); handle = rbtNext(rbconf, handle)) {
			rbtKeyValue(rbconf, handle, &k1, &k2);
			flushrec(k1, k2);
		}

		rbtDelete(rbconf);
	}

	firsttime = 0;
	rbconf = rbtNew(name_compare);

	fd = stackfopen(fn, "r", &configfiles);
	if (fd == NULL) return 1;

	inbuf = newstrbuffer(0);
	while (stackfgets(inbuf, NULL)) {
		/* Full record : Host  service  START  END  TIMESPEC  TTPrio TTGroup TTExtra */
		/* Clone record: Host  =HOST */
		char *ehost, *eservice, *estart, *eend, *etime, *ttgroup, *ttextra, *updinfo;
		int ttprio = 0;
		nkconf_t *newitem;
		RbtStatus status;
		int idx = 0;

		ehost = gettok(STRBUF(inbuf), "|\n"); if (!ehost) continue;
		eservice = gettok(NULL, "|\n"); if (!eservice) continue;

		if (*eservice == '=') {
			char *key = (char *)malloc(strlen(ehost) + 2);
			char *pointsto = strdup(eservice+1);

			sprintf(key, "%s=", ehost);
			status = rbtInsert(rbconf, key, pointsto);
		}
		else {
			estart = gettok(NULL, "|\n"); if (!estart) continue;
			eend = gettok(NULL, "|\n"); if (!eend) continue;
			etime = gettok(NULL, "|\n"); if (!etime) continue;
			ttprio = atoi(gettok(NULL, "|\n")); if (ttprio == 0) continue;
			ttgroup = gettok(NULL, "|\n");
			ttextra = gettok(NULL, "|\n");
			updinfo = gettok(NULL, "|\n");

			newitem = (nkconf_t *)malloc(sizeof(nkconf_t));
			newitem->key = (char *)malloc(strlen(ehost) + strlen(eservice) + 15);
			sprintf(newitem->key, "%s|%s", ehost, eservice);
			newitem->starttime= ((estart && *estart) ? atoi(estart) : 0);
			newitem->endtime  = ((eend && *eend) ? atoi(eend) : 0);
			newitem->nktime   = ((etime && *etime) ? strdup(etime) : NULL);
			newitem->priority = ttprio;
			newitem->ttgroup  = strdup(ttgroup);
			newitem->ttextra  = strdup(ttextra);
			newitem->updinfo  = strdup(updinfo);

			status = rbtInsert(rbconf, newitem->key, newitem);
			while (status == RBT_STATUS_DUPLICATE_KEY) {
				idx++;
				sprintf(newitem->key, "%s|%s|%d", ehost, eservice, idx);
				status = rbtInsert(rbconf, newitem->key, newitem);
			}
		}
	}

	stackfclose(fd);
	freestrbuffer(inbuf);

	if (debug) {
		RbtHandle handle;

		handle = rbtBegin(rbconf);
		while (handle != rbtEnd(rbconf)) {
			void *k1, *k2;
			rbtKeyValue(rbconf, handle, &k1, &k2);
			printf("%s\n", (char *)k1);
			handle = rbtNext(rbconf, handle);
		}
	}

	return 0;
}