Esempio n. 1
0
int master_workers_capacity(struct jx *j) {
	int capacity_tasks   = jx_lookup_integer(j, "capacity_tasks");
	int capacity_cores   = jx_lookup_integer(j, "capacity_cores");
	int capacity_memory  = jx_lookup_integer(j, "capacity_memory");
	int capacity_disk    = jx_lookup_integer(j, "capacity_disk");

	const int cores = resources->cores;
	const int memory = resources->memory;
	const int disk = resources->disk;

	// first, assume one task per worker
	int capacity = capacity_tasks;

	// then, enforce tasks per worker
	if(tasks_per_worker > 0) {
		capacity = DIV_INT_ROUND_UP(capacity, tasks_per_worker);
	}

	// then, enforce capacity per resource
	if(cores > 0 && capacity_cores > 0) {
		capacity = MIN(capacity, DIV_INT_ROUND_UP(capacity_cores, cores));
	}

	if(memory > 0 && capacity_memory > 0) {
		capacity = MIN(capacity, DIV_INT_ROUND_UP(capacity_memory, memory));
	}

	if(disk > 0 && capacity_disk > 0) {
		capacity = MIN(capacity, DIV_INT_ROUND_UP(capacity_disk, disk));
	}

	return capacity;
}
Esempio n. 2
0
int master_workers_needed_by_resource(struct jx *j) {
	int tasks_total_cores  = jx_lookup_integer(j, "tasks_total_cores");
	int tasks_total_memory = jx_lookup_integer(j, "tasks_total_memory");
	int tasks_total_disk   = jx_lookup_integer(j, "tasks_total_disk");

	const int cores = resources->cores;
	const int memory = resources->memory;
	const int disk = resources->disk;

	int needed = 0;

	if(cores  > 0  && tasks_total_cores > 0) {
		needed = MAX(needed, DIV_INT_ROUND_UP(tasks_total_cores, cores));
	}

	if(memory > 0  && tasks_total_memory > 0) {
		needed = MAX(needed, DIV_INT_ROUND_UP(tasks_total_memory, memory));
	}

	if(disk > 0  && tasks_total_disk > 0) {
		needed = MAX(needed, DIV_INT_ROUND_UP(tasks_total_disk, disk));
	}

	return needed;
}
Esempio n. 3
0
static void remove_expired_records()
{
	struct jx *j;
	char *key;

	time_t current = time(0);

	// Only clean every clean_interval seconds.
	if((current-last_clean_time)<clean_interval) return;

	// After restarting, all records will have appear to be stale.
	// Run for a minimum of lifetime seconds before cleaning anything up.
	if((current-starttime)<lifetime ) return;

	jx_database_firstkey(table);
	while(jx_database_nextkey(table, &key, &j)) {
		time_t lastheardfrom = jx_lookup_integer(j,"lastheardfrom");

		int this_lifetime = jx_lookup_integer(j,"lifetime");
		if(this_lifetime>0) {
			this_lifetime = MIN(lifetime,this_lifetime);
		} else {
			this_lifetime = lifetime;
		}

		if( (current-lastheardfrom) > this_lifetime ) {
				j = jx_database_remove(table,key);
			if(j) jx_delete(j);
		}
	}

	last_clean_time = current;
}
Esempio n. 4
0
static void chirp_jx_to_stat(struct jx *j, struct chirp_stat *info)
{
	memset(info, 0, sizeof(*info));
	info->cst_atime = info->cst_mtime = info->cst_ctime = jx_lookup_integer(j, "lastheardfrom");
	info->cst_size = jx_lookup_integer(j, "total") - jx_lookup_integer(j, "avail");
	info->cst_size /= 1024 * 1024;
	info->cst_mode = S_IFDIR | 0555;
}
Esempio n. 5
0
static int count_workers_needed( struct list *masters_list, int only_waiting )
{
	int needed_workers=0;
	int masters=0;
	struct jx *j;

	if(!masters_list) {
		return needed_workers;
	}

	list_first_item(masters_list);
	while((j=list_next_item(masters_list))) {

		const char *project =jx_lookup_string(j,"project");
		const char *host =   jx_lookup_string(j,"name");
		const int  port =    jx_lookup_integer(j,"port");
		const char *owner =  jx_lookup_string(j,"owner");
		const int tr =       jx_lookup_integer(j,"tasks_on_workers");
		const int tw =       jx_lookup_integer(j,"tasks_waiting");
		const int tl =       jx_lookup_integer(j,"tasks_left");

		int tasks = tr+tw+tl;

		// first assume one task per worker
		int need;
		if(only_waiting) {
			need = tw;
		} else {
			need = tasks;
		}

		// enforce many tasks per worker
		if(tasks_per_worker > 0) {
			need = DIV_INT_ROUND_UP(need, tasks_per_worker);
		}

		// consider if tasks declared resources...
		need = MAX(need, master_workers_needed_by_resource(j));

		int capacity = master_workers_capacity(j);
		if(consider_capacity && capacity > 0) {
			need = MIN(need, capacity);
		}

		debug(D_WQ,"%s %s:%d %s %d %d %d",project,host,port,owner,tasks,capacity,need);

		needed_workers += need;
		masters++;
	}

	return needed_workers;
}
Esempio n. 6
0
static int server_table_load(time_t stoptime)
{
	struct catalog_query *q;
	struct jx *j;
	char *key;
	void *item;

	if((last_update + update_interval) > time(0)) {
		return 1;
	}

	if(!server_table) {
		server_table = hash_table_create(0, 0);
		if(!server_table)
			return 0;
	}

	if(inhibit_catalog_queries) {
		debug(D_CHIRP, "catalog queries disabled\n");
		return 1;
	}

	hash_table_firstkey(server_table);
	while(hash_table_nextkey(server_table, &key, &item)) {
		hash_table_remove(server_table, key);
		jx_delete(item);
	}

	debug(D_CHIRP, "querying catalog at %s:%d", CATALOG_HOST, CATALOG_PORT);

	q = catalog_query_create(CATALOG_HOST, CATALOG_PORT, stoptime);
	if(!q)
		return 0;

	while((j = catalog_query_read(q, stoptime))) {
		char name[CHIRP_PATH_MAX];
		const char *type, *hname;
		int port;

		type = jx_lookup_string(j, "type");
		if(type && !strcmp(type, "chirp")) {
			hname = jx_lookup_string(j, "name");
			if(hname) {
				port = jx_lookup_integer(j, "port");
				if(!port)
					port = CHIRP_PORT;
				sprintf(name, "%s:%d", hname, port);
				hash_table_insert(server_table, name, j);
			} else {
				jx_delete(j);
			}
		} else {
			jx_delete(j);
		}
	}
	catalog_query_delete(q);
	last_update = time(0);

	return 1;
}
Esempio n. 7
0
static int describe_aws_job(char* aws_jobid, char* env_var){
	char* cmd = string_format("aws batch describe-jobs --jobs %s",aws_jobid);
	struct jx* jx = run_command(cmd);
	free(cmd);
	int succeed = DESCRIBE_AWS_JOB_NON_FINAL; //default status
	struct jx* jobs_array = jx_lookup(jx,"jobs");
	if(!jobs_array){
		debug(D_BATCH,"Problem with given aws_jobid: %s",aws_jobid);
		return DESCRIBE_AWS_JOB_NON_EXIST;
	}
	struct jx* first_item = jx_array_index(jobs_array,0);
	if(!first_item){
		debug(D_BATCH,"Problem with given aws_jobid: %s",aws_jobid);
		return DESCRIBE_AWS_JOB_NON_EXIST;
	}
	if(strstr((char*)jx_lookup_string(first_item,"status"),"SUCCEEDED")){
		succeed = DESCRIBE_AWS_JOB_SUCCESS;
	}
	if(strstr((char*)jx_lookup_string(first_item,"status"),"FAILED")){
		succeed = DESCRIBE_AWS_JOB_FAILED;
	}

	//start and stop
	if(succeed == DESCRIBE_AWS_JOB_SUCCESS || succeed == DESCRIBE_AWS_JOB_FAILED){	
		int64_t created_string = (int64_t) jx_lookup_integer(first_item,"createdAt");
		int64_t start_string = (int64_t)jx_lookup_integer(first_item,"startedAt");
		int64_t end_string = (int64_t)jx_lookup_integer(first_item,"stoppedAt");
		if(created_string != 0 ){
			debug(D_BATCH,"Job %s was created at: %"PRIi64"",aws_jobid,created_string);
		}
		if(start_string != 0 ){
			debug(D_BATCH,"Job %s started at: %"PRIi64"",aws_jobid,start_string);
		}
		if(end_string != 0 ){
			debug(D_BATCH,"Job %s ended at: %"PRIi64"",aws_jobid,end_string);
		}
	}
	jx_delete(jx);
	return succeed;
}
Esempio n. 8
0
static int count_workers_connected( struct list *masters_list )
{
	int connected_workers=0;
	struct jx *j;

	if(!masters_list) {
		return connected_workers;
	}

	list_first_item(masters_list);
	while((j=list_next_item(masters_list))) {
		const int workers = jx_lookup_integer(j,"workers");
		connected_workers += workers;
	}

	return connected_workers;
}
Esempio n. 9
0
static void make_hash_key(struct jx *j, char *key)
{
	const char *name, *addr;
	int port;

	addr = jx_lookup_string(j, "address");
	if(!addr)
		addr = "unknown";

	port = jx_lookup_integer(j, "port");

	name = jx_lookup_string(j, "name");
	if(!name)
		name = "unknown";

	sprintf(key, "%s:%d:%s", addr, port, name);
}
Esempio n. 10
0
static int finished_aws_job_exit_code(char* aws_jobid, char* env_var){
	char* cmd = string_format("aws batch describe-jobs --jobs %s",aws_jobid);
	struct jx* jx = run_command(cmd);
	free(cmd);
	struct jx* jobs_array = jx_lookup(jx,"jobs");
	if(!jobs_array){
		debug(D_BATCH,"Problem with given aws_jobid: %s",aws_jobid);
		return DESCRIBE_AWS_JOB_NON_EXIST;
	}
	struct jx* first_item = jx_array_index(jobs_array,0);
	if(!first_item){
		debug(D_BATCH,"Problem with given aws_jobid: %s",aws_jobid);
		return DESCRIBE_AWS_JOB_NON_EXIST;
	}
	int ret = (int)jx_lookup_integer(first_item,"exitCode");
	jx_delete(jx);
	return ret;
}
Esempio n. 11
0
int main( int argc, char *argv[] )
{
	int count =0;
	int first = 0;

	printf("{\n");

	while(1) {
		struct nvpair *nv = nvpair_create();
		int r = nvpair_parse_stream(nv,stdin);
		if(r) {
			struct jx *j = nvpair_to_jx(nv);
			const char *name = jx_lookup_string(j,"name");
			const char *host = jx_lookup_string(j,"host");
			int port = jx_lookup_integer(j,"port");

			if(first) {
				first = 0;
			} else {
				printf(",\n");
			}
			printf("\"%s:%s:%d\":",name,host,port);

			jx_print_stream(j,stdout);
			count++;
		} else if(r<0) {
			fprintf(stderr,"nvpair conversion error!\n");
		} else {
			break;
		}

	}

	printf("\n}\n");

	fprintf(stderr,"%d records converted.\n",count);
	return 0;
}
Esempio n. 12
0
int main(int argc, char *argv[])
{
	enum {
		LONGOPT_SERVER_LASTHEARDFROM = INT_MAX-0,
		LONGOPT_SERVER_PROJECT       = INT_MAX-1,
		LONGOPT_WHERE = INT_MAX-2,
	};

	static const struct option long_options[] = {
		{"all", no_argument, 0, 'a'},
		{"brief", no_argument, 0, 's'},
		{"catalog", required_argument, 0, 'c'},
		{"debug", required_argument, 0, 'd'},
		{"debug-file", required_argument, 0, 'o'},
		{"debug-rotate-max", required_argument, 0, 'O'},
		{"help", no_argument, 0, 'h'},
		{"server-lastheardfrom", required_argument, 0, LONGOPT_SERVER_LASTHEARDFROM},
		{"server-project", required_argument, 0, LONGOPT_SERVER_PROJECT},
		{"server-space", required_argument, 0, 'A'},
		{"timeout", required_argument, 0, 't'},
		{"totals", no_argument, 0, 'T'},
		{"verbose", no_argument, 0, 'l'},
		{"version", no_argument, 0, 'v'},
		{"where", required_argument, 0, LONGOPT_WHERE },
		{0, 0, 0, 0}
	};

	struct catalog_query *q;
	struct jx *j;
	time_t timeout = 60, stoptime;
	const char *catalog_host = 0;
	int i;
	int c;
	int count = 0;
	int mode = MODE_TABLE;
	INT64_T sum_total = 0, sum_avail = 0;
	const char *filter_name = 0;
	const char *filter_value = 0;
	const char *where_expr = "true";
	int show_all_types = 0;

	const char *server_project = NULL;
	time_t      server_lastheardfrom = 0;
	uint64_t    server_avail = 0;

	debug_config(argv[0]);

	while((c = getopt_long(argc, argv, "aA:c:d:t:o:O:sTlvh", long_options, NULL)) > -1) {
		switch (c) {
		case 'a':
			show_all_types = 1;
			break;
		case 'c':
			catalog_host = optarg;
			break;
		case 'd':
			debug_flags_set(optarg);
			break;
		case 't':
			timeout = string_time_parse(optarg);
			break;
		case 'A':
			server_avail = string_metric_parse(optarg);
			break;
		case 'o':
			debug_config_file(optarg);
			break;
		case 'O':
			debug_config_file_size(string_metric_parse(optarg));
			break;
		case 'v':
			cctools_version_print(stdout, argv[0]);
			return 1;
		case 's':
			mode = MODE_SHORT;
			break;
		case 'l':
			mode = MODE_LONG;
			break;
		case 'T':
			mode = MODE_TOTAL;
			break;
		case LONGOPT_SERVER_LASTHEARDFROM:
			server_lastheardfrom = time(0)-string_time_parse(optarg);
			break;
		case LONGOPT_SERVER_PROJECT:
			server_project = xxstrdup(optarg);
			break;
		case LONGOPT_WHERE:
			where_expr = optarg;
			break;
		case 'h':
		default:
			show_help(argv[0]);
			return 1;
		}
	}

	cctools_version_debug(D_DEBUG, argv[0]);

	if(argc - optind == 0) {
		// fine, keep going
	} else if((argc - optind) == 1) {
		filter_name = "name";
		filter_value = argv[optind];
	} else if((argc - optind) == 2) {
		filter_name = argv[optind];
		filter_value = argv[optind + 1];
	} else {
		show_help(argv[0]);
		return 1;
	}

	stoptime = time(0) + timeout;

	const char *query_expr;

	if(show_all_types) {
		query_expr = where_expr;
	} else {
		query_expr = string_format("%s && (type==\"chirp\" || type==\"catalog\")",where_expr);
	}

	struct jx *jexpr = jx_parse_string(query_expr);
	if(!jexpr) {
		fprintf(stderr,"invalid expression: %s\n",query_expr);
		return 1;
	}

	q = catalog_query_create(catalog_host, 0, jexpr, stoptime);
	if(!q) {
		fprintf(stderr, "couldn't query catalog: %s\n", strerror(errno));
		return 1;
	}

	if(mode == MODE_TABLE) {
		jx_table_print_header(headers,stdout);
	} else if(mode==MODE_LONG) {
		printf("[\n");
	}

	while((j = catalog_query_read(q, stoptime))) {
		table[count++] = j;
	}

	catalog_query_delete(q);

	qsort(table, count, sizeof(*table), (int (*)(const void *, const void *)) compare_entries);

	for(i = 0; i < count; i++) {
		const char *lastheardfrom = jx_lookup_string(table[i], "lastheardfrom");
		if (lastheardfrom && (time_t)strtoul(lastheardfrom, NULL, 10) < server_lastheardfrom)
			continue;

		const char *avail = jx_lookup_string(table[i], "avail");
		if (avail && strtoul(avail, NULL, 10) < server_avail)
			continue;

		const char *project = jx_lookup_string(table[i], "project");
		if (server_project && (project == NULL || !(strcmp(project, server_project) == 0)))
			continue;

		if(filter_name) {
			const char *v = jx_lookup_string(table[i], filter_name);
			if(!v || strcmp(filter_value, v))
				continue;
		}

		if(mode == MODE_SHORT) {
			const char *t = jx_lookup_string(table[i], "type");
			if(t && !strcmp(t, "chirp")) {
				printf("%s:%d\n", jx_lookup_string(table[i], "name"), (int) jx_lookup_integer(table[i], "port"));
			}
		} else if(mode == MODE_LONG) {
			if(i!=0) printf(",\n");
			jx_print_stream(table[i],stdout);
		} else if(mode == MODE_TABLE) {
			jx_table_print(headers, table[i], stdout);
		} else if(mode == MODE_TOTAL) {
			sum_avail += jx_lookup_integer(table[i], "avail");
			sum_total += jx_lookup_integer(table[i], "total");
		}
	}

	for(i=0;i<count;i++) {
		jx_delete(table[i]);
	}

	if(mode == MODE_TOTAL) {
		printf("NODES: %4d\n", count);
		printf("TOTAL: %6sB\n", string_metric(sum_total, -1, 0));
		printf("AVAIL: %6sB\n", string_metric(sum_avail, -1, 0));
		printf("INUSE: %6sB\n", string_metric(sum_total - sum_avail, -1, 0));
	} else if(mode == MODE_TABLE) {
		jx_table_print_footer(headers,stdout);
	} else if(mode==MODE_LONG) {
		printf("\n]\n");
	}

	return 0;
}
Esempio n. 13
0
static void handle_query(struct link *query_link)
{
	FILE *stream;
	char line[LINE_MAX];
	char url[LINE_MAX];
	char path[LINE_MAX];
	char action[LINE_MAX];
	char version[LINE_MAX];
	char hostport[LINE_MAX];
	char addr[LINK_ADDRESS_MAX];
	char key[LINE_MAX];
	int port;
	time_t current;

	char *hkey;
	struct jx *j;
	int i, n;

	link_address_remote(query_link, addr, &port);
	debug(D_DEBUG, "www query from %s:%d", addr, port);

	if(link_readline(query_link, line, LINE_MAX, time(0) + HANDLE_QUERY_TIMEOUT)) {
		string_chomp(line);
		if(sscanf(line, "%s %s %s", action, url, version) != 3) {
			return;
		}

		// Consume the rest of the query
		while(1) {
			if(!link_readline(query_link, line, LINE_MAX, time(0) + HANDLE_QUERY_TIMEOUT)) {
				return;
			}

			if(line[0] == 0) {
				break;
			}
		}
	} else {
		return;
	}

	// Output response
	stream = fdopen(link_fd(query_link), "w");
	if(!stream) {
		return;
	}
	link_nonblocking(query_link, 0);

	current = time(0);
	fprintf(stream, "HTTP/1.1 200 OK\n");
	fprintf(stream, "Date: %s", ctime(&current));
	fprintf(stream, "Server: catalog_server\n");
	fprintf(stream, "Connection: close\n");
	fprintf(stream, "Access-Control-Allow-Origin: *\n");

	if(sscanf(url, "http://%[^/]%s", hostport, path) == 2) {
		// continue on
	} else {
		strcpy(path, url);
	}

	/* load the hash table entries into one big array */

	n = 0;
	jx_database_firstkey(table);
	while(jx_database_nextkey(table, &hkey, &j)) {
		array[n] = j;
		n++;
	}

	/* sort the array by name before displaying */

	qsort(array, n, sizeof(struct jx *), compare_jx);

	if(!strcmp(path, "/query.text")) {
		fprintf(stream, "Content-type: text/plain\n\n");
		for(i = 0; i < n; i++)
			jx_export_nvpair(array[i], stream);
	} else if(!strcmp(path, "/query.json")) {
		fprintf(stream, "Content-type: text/plain\n\n");
		fprintf(stream,"[\n");
		for(i = 0; i < n; i++) {
			jx_print_stream(array[i],stream);
			if(i<(n-1)) fprintf(stream,",\n");
		}
		fprintf(stream,"\n]\n");
	} else if(!strcmp(path, "/query.oldclassads")) {
		fprintf(stream, "Content-type: text/plain\n\n");
		for(i = 0; i < n; i++)
			jx_export_old_classads(array[i], stream);
	} else if(!strcmp(path, "/query.newclassads")) {
		fprintf(stream, "Content-type: text/plain\n\n");
		for(i = 0; i < n; i++)
			jx_export_new_classads(array[i], stream);
	} else if(!strcmp(path, "/query.xml")) {
		fprintf(stream, "Content-type: text/xml\n\n");
		fprintf(stream, "<?xml version=\"1.0\" standalone=\"yes\"?>\n");
		fprintf(stream, "<catalog>\n");
		for(i = 0; i < n; i++)
			jx_export_xml(array[i], stream);
		fprintf(stream, "</catalog>\n");
	} else if(sscanf(path, "/detail/%s", key) == 1) {
		struct jx *j;
		fprintf(stream, "Content-type: text/html\n\n");
		j = jx_database_lookup(table, key);
		if(j) {
			const char *name = jx_lookup_string(j, "name");
			if(!name)
				name = "unknown";
			fprintf(stream, "<title>%s catalog server: %s</title>\n", preferred_hostname, name);
			fprintf(stream, "<center>\n");
			fprintf(stream, "<h1>%s catalog server</h1>\n", preferred_hostname);
			fprintf(stream, "<h2>%s</h2>\n", name);
			fprintf(stream, "<p><a href=/>return to catalog view</a><p>\n");
			jx_export_html_solo(j, stream);
			fprintf(stream, "</center>\n");
		} else {
			fprintf(stream, "<title>%s catalog server</title>\n", preferred_hostname);
			fprintf(stream, "<center>\n");
			fprintf(stream, "<h1>%s catalog server</h1>\n", preferred_hostname);
			fprintf(stream, "<h2>Unknown Item!</h2>\n");
			fprintf(stream, "</center>\n");
		}
	} else {
		char avail_line[LINE_MAX];
		char total_line[LINE_MAX];
		INT64_T sum_total = 0;
		INT64_T sum_avail = 0;
		INT64_T sum_devices = 0;

		fprintf(stream, "Content-type: text/html\n\n");
		fprintf(stream, "<title>%s catalog server</title>\n", preferred_hostname);
		fprintf(stream, "<center>\n");
		fprintf(stream, "<h1>%s catalog server</h1>\n", preferred_hostname);
		fprintf(stream, "<a href=/query.text>text</a> - ");
		fprintf(stream, "<a href=/query.html>html</a> - ");
		fprintf(stream, "<a href=/query.xml>xml</a> - ");
		fprintf(stream, "<a href=/query.json>json</a> - ");
		fprintf(stream, "<a href=/query.oldclassads>oldclassads</a> - ");
		fprintf(stream, "<a href=/query.newclassads>newclassads</a>");
		fprintf(stream, "<p>\n");

		for(i = 0; i < n; i++) {
			j = array[i];
			sum_total += jx_lookup_integer(j, "total");
			sum_avail += jx_lookup_integer(j, "avail");
			sum_devices++;
		}

		string_metric(sum_avail, -1, avail_line);
		string_metric(sum_total, -1, total_line);
		fprintf(stream, "<b>%sB available out of %sB on %d devices</b><p>\n", avail_line, total_line, (int) sum_devices);

		jx_export_html_header(stream, html_headers);
		for(i = 0; i < n; i++) {
			j = array[i];
			make_hash_key(j, key);
			sprintf(url, "/detail/%s", key);
			jx_export_html_with_link(j, stream, html_headers, "name", url);
		}
		jx_export_html_footer(stream, html_headers);
		fprintf(stream, "</center>\n");
	}
	fclose(stream);
}
Esempio n. 14
0
static void handle_update( const char *addr, int port, const char *raw_data, int raw_data_length, const char *protocol )
{
	char key[LINE_MAX];
	unsigned long data_length;
	struct jx *j;

		// If the packet starts with Control-Z (0x1A), it is compressed,
		// so uncompress it to data[].  Otherwise just copy to data[];.

		if(raw_data[0]==0x1A) {
			data_length = sizeof(data);
			int success = uncompress((Bytef*)data,&data_length,(const Bytef*)&raw_data[1],raw_data_length-1);
			if(success!=Z_OK) {
				debug(D_DEBUG,"warning: %s:%d sent invalid compressed data (ignoring it)\n",addr,port);
				return;
			}
		} else {
			memcpy(data,raw_data,raw_data_length);
			data_length = raw_data_length;
		}

		// Make sure the string data is null terminated.
		data[data_length] = 0;

		// Once uncompressed, if it starts with a bracket,
		// then it is JX/JSON, otherwise it is the legacy nvpair format.

		if(data[0]=='{') {
			j = jx_parse_string(data);
			if(!j) {
				debug(D_DEBUG,"warning: %s:%d sent invalid JSON data (ignoring it)\n%s\n",addr,port,data);
				return;
			}
			if(!jx_is_constant(j)) {
				debug(D_DEBUG,"warning: %s:%d sent non-constant JX data (ignoring it)\n%s\n",addr,port,data);
				jx_delete(j);
				return;
			}
		} else {
			struct nvpair *nv = nvpair_create();
			if(!nv) return;
			nvpair_parse(nv, data);
			j = nvpair_to_jx(nv);
			nvpair_delete(nv);
		}

		jx_insert_string(j, "address", addr);
		jx_insert_integer(j, "lastheardfrom", time(0));

		/* If the server reports unbelievable numbers, simply reset them */

		if(max_server_size > 0) {
			INT64_T total = jx_lookup_integer(j, "total");
			INT64_T avail = jx_lookup_integer(j, "avail");

			if(total > max_server_size || avail > max_server_size) {
				jx_insert_integer(j, "total", max_server_size);
				jx_insert_integer(j, "avail", max_server_size);
			}
		}

		/* Do not believe the server's reported name, just resolve it backwards. */

		char name[DOMAIN_NAME_MAX];
		if(domain_name_cache_lookup_reverse(addr, name)) {
			/*
			Special case: Prior bug resulted in multiple name
			entries in logged data.  When removing the name property,
			keep looking until all items are removed.
			*/
			struct jx *jname = jx_string("name");
			struct jx *n;
			while((n=jx_remove(j,jname))) {
				jx_delete(n);
			}
			jx_delete(jname);

			jx_insert_string(j,"name",name);
	
		} else if (jx_lookup_string(j, "name") == NULL) {
			/* If rDNS is unsuccessful, then we use the name reported if given.
			 * This allows for hostnames that are only valid in the subnet of
			 * the reporting server.  Here we set the "name" field to the IP
			 * Address, addr, because it was not set by the reporting server.
			 */
			jx_insert_string(j, "name", addr);
		}

		make_hash_key(j, key);

		if(logfile) {
			if(!jx_database_lookup(table,key)) {
				jx_print_stream(j,logfile);
				fprintf(logfile,"\n");
				fflush(logfile);
			}
		}

		jx_database_insert(table, key, j);

		debug(D_DEBUG, "received %s update from %s",protocol,key);
}
Esempio n. 15
0
/*
 * Obtains information from the Catalog, format it, and make return it to user.
 */
int main(int argc, char** argv) {

    static const struct option long_options[] = {
        {"help", no_argument, 0, 'h'},
        {"project", required_argument, 0, 'N'},
        {"server", required_argument, 0, 's'},
        {"timeout", required_argument, 0, 't'},
        {"username", required_argument, 0, 'u'},
        {0, 0, 0, 0}
    };

    struct catalog_query *q;
    struct jx *j;
    int c;
    unsigned int i;
    time_t timeout = 60;
    char* catalog_host = NULL;
    
    char* username = NULL;
    char* project = NULL;
    
    char* server = NULL;
    
    while ((c = getopt_long(argc, argv, "N:t:u:w:s:h", long_options, NULL)) > -1) {
        switch (c) {
            case 'N':
                project = xxstrdup(optarg);
                break;
            case 't':
                timeout = string_time_parse(optarg);
                break;
            case 'u':
                username = xxstrdup(optarg);
                break;
            case 's':
                server = xxstrdup(optarg);
                break;
            case 'h':
            default:
                show_help(argv[0]);
                return 1;
        }
    }
    
    //setup address
    if(server==NULL){
        catalog_host = CATALOG_HOST;
    }

    //make query
    struct jx *jexpr = jx_operator(
        JX_OP_EQ,
        jx_symbol("type"),
        jx_string("makeflow")
    );

    if (project) {
        jexpr = jx_operator(
            JX_OP_AND,
            jexpr,
            jx_operator(
                JX_OP_EQ,
                jx_symbol("project"),
                jx_string(project)
            )
        );
    }

    if (username) {
        jexpr = jx_operator(
            JX_OP_AND,
            jexpr,
            jx_operator(
                JX_OP_EQ,
                jx_symbol("username"),
                jx_string(username)
            )
        );
    }

    time_t stoptime = time(0) + timeout;
    unsigned int count = 0;
    
    //create catalog_query from jx
    q = catalog_query_create(catalog_host, jexpr, stoptime);
    if (!q) {
        fprintf(stderr, "couldn't query catalog: %s\n", strerror(errno));
        return 1;
    }


    while ((j = catalog_query_read(q, stoptime))) {
        table[count++] = j;
    }
    
    catalog_query_delete(q);//all done with connection

    //sort
    qsort(table, count, sizeof(*table), (int (*)(const void *, const void *)) compare_entries);
    
    //print them out
    printf("%-10s %-18s %6s %6s %6s %6s %6s %6s %6s\n",
	   "OWNER", "PROJECT", "JOBS", "WAIT", "RUN", "COMP", "ABRT", "FAIL", "TYPE");
    for(i=0; i<count; i++){
        printf("%-10s %-18s %6" PRId64 " %6" PRId64 " %6" PRId64 " %6" PRId64 " %6" PRId64 " %6" PRId64 " %6s\n",
		jx_lookup_string(table[i], "owner"),
		jx_lookup_string(table[i], "project"),
		jx_lookup_integer(table[i], "total"),
		jx_lookup_integer(table[i], "waiting"),
		jx_lookup_integer(table[i], "running"),
		jx_lookup_integer(table[i], "completed"),
		jx_lookup_integer(table[i], "aborted"),
		jx_lookup_integer(table[i], "failed"),
		jx_lookup_string(table[i], "batch_type")
	);
    }
    printf("\n");//be polite
    
    //cleanup
    for(i=0;i<count;i++) {
	jx_delete(table[i]);
    }

    //done
    return (EXIT_SUCCESS);
}