Beispiel #1
0
/*
 * 'result_callback' handler for gfs_client_relay().
 */
static gfarm_int32_t
gfs_client_relay_result(void *p, void *arg, size_t size)
{
	gfarm_error_t e, e2;
	struct peer *peer = p;
	struct gfp_xdr *conn = peer_get_conn(peer);
	struct gfs_client_relay_closure *wclosure = arg;
	void *data = NULL;
	size_t data_size;
	int eof;
	static const char diag[] = "gfs_client_relay_result";

	do {
		data = malloc(size);
		if (data == NULL) {
			e = GFARM_ERR_NO_MEMORY;
			(void) gfp_xdr_purge(conn, 0, size);
			break;
		}
		data_size = size;
		e = gfp_xdr_recv(conn, 1, &eof, "r", data_size, &data_size,
		    data);
		if (e != GFARM_ERR_NO_ERROR) {
			(void) gfp_xdr_purge(conn, 0, size);
			break;
		} else if (eof) {
			e = GFARM_ERR_UNEXPECTED_EOF;
		} else if (data_size != 0) {
			e = GFARM_ERR_PROTOCOL;
			gflog_warning(GFARM_MSG_1004036,
			    "%s: <%s> protocol redidual %u",
			    peer_get_hostname(peer), diag, (int)data_size);
		}

	} while (0);

	e2 = wclosure->result_callback(e, wclosure->closure, size, data);
	if (e == GFARM_ERR_NO_ERROR)
		e = e2;

	free(data);
	gfs_client_relay_closure_free(wclosure);
	return (e);
}
Beispiel #2
0
gfarm_error_t
gfj_server_info(struct peer *peer, gfp_xdr_xid_t xid, size_t *sizep,
	int from_client, int skip)
{
	gfarm_error_t e;
	struct gfp_xdr *client = peer_get_conn(peer);
	int i, eof;
	gfarm_int32_t n, *jobs;
	static const char diag[] = "GFJ_PROTO_INFO";

	e = gfj_server_get_request(peer, sizep, diag, "i", &n);
	if (e != GFARM_ERR_NO_ERROR) {
		gflog_debug(GFARM_MSG_1001701,
			"info request failure");
		return (e);
	}

	GFARM_MALLOC_ARRAY(jobs, n);
	if (jobs == NULL) {
		gflog_debug(GFARM_MSG_1001702,
			"allocation of 'jobs' failed");
		return (GFARM_ERR_NO_MEMORY);
	}

	for (i = 0; i < n; i++) {
		e = gfp_xdr_recv(client, 0, &eof, "i", &jobs[i]);
		if (e != GFARM_ERR_NO_ERROR || eof) {
			gflog_debug(GFARM_MSG_1001703,
				"gfp_xdr_recv(jobs[%d]) failed", i);
			if (e == GFARM_ERR_NO_ERROR)
				e = GFARM_ERR_PROTOCOL;
			free(jobs);
			return (e);
		}
	}

	if (skip || !from_client) {
		free(jobs);
		if (skip)
			return (GFARM_ERR_NO_ERROR);
		e = gfj_server_put_reply(peer, xid, sizep, diag,
		    GFARM_ERR_OPERATION_NOT_PERMITTED, "");
		gflog_debug(GFARM_MSG_1001704,
			"operation is not permitted for from_client");
		return (e);
	}

	/* XXX FIXME too long giant lock */
	giant_lock();
	for (i = 0; i < n; i++) {
		if (jobs[i] < 0 || jobs[i] >= job_table_size ||
		    job_table[jobs[i]] == NULL) {
			e = gfj_server_put_reply(peer, xid, sizep, diag,
						 GFARM_ERR_NO_SUCH_OBJECT, "");
			if (e != GFARM_ERR_NO_ERROR) {
				gflog_debug(GFARM_MSG_1001705,
					"gfj_server_put_reply(info) failed");
				giant_unlock();
				free(jobs);
				return (e);
			}
		} else {
			/* XXXRELAY FIXME, reply size is not correct */
			e = gfj_server_put_reply(peer, xid, sizep, diag,
						 GFARM_ERR_NO_ERROR, "");
			if (e != GFARM_ERR_NO_ERROR) {
				gflog_debug(GFARM_MSG_1001706,
					"gfj_server_put_reply(info) failed");
				free(jobs);
				giant_unlock();
				return (e);
			}
			/* XXXRELAY FIXME */
			e = gfj_server_put_info_entry(peer_get_conn(peer),
			      job_table[jobs[i]]->info);
			if (e != GFARM_ERR_NO_ERROR) {
				gflog_debug(GFARM_MSG_1001707,
					"gfj_server_put_info_entry() failed");
				free(jobs);
				giant_unlock();
				return (e);
			}
		}
	}
	free(jobs);
	giant_unlock();
	return (GFARM_ERR_NO_ERROR);
}
Beispiel #3
0
gfarm_error_t
gfj_server_register(struct peer *peer, gfp_xdr_xid_t xid, size_t *sizep,
	int from_client, int skip)
{
	gfarm_error_t e;
	struct gfp_xdr *client = peer_get_conn(peer);
	char *user = peer_get_username(peer);
	int i, eof;
	gfarm_int32_t flags, total_nodes, argc, error, job_id = 0;
	struct gfarm_job_info *info;
	static const char diag[] = "GFJ_PROTO_REGISTER";

	GFARM_MALLOC(info);
	if (info == NULL) {
		gflog_debug(GFARM_MSG_1001685,
			"allocation of gfarm_job_info failed");
		return (GFARM_ERR_NO_MEMORY);
	}
	gfarm_job_info_clear(info, 1);
	e = gfj_server_get_request(peer, sizep, diag, "iisssi",
				   &flags,
				   &total_nodes,
				   &info->job_type,
				   &info->originate_host,
				   &info->gfarm_url_for_scheduling,
				   &argc);
	if (e != GFARM_ERR_NO_ERROR) {
		gflog_debug(GFARM_MSG_1001686,
			"gfj_server_get_request() failed");
		return (e);
	}

	/* XXX - currently `flags' is just igored */
	info->total_nodes = total_nodes;
	info->argc = argc;
	GFARM_MALLOC_ARRAY(info->argv, argc + 1);
	GFARM_MALLOC_ARRAY(info->nodes, total_nodes);
	if (info->argv == NULL || info->nodes == NULL) {
		gflog_debug(GFARM_MSG_1001687,
			"allocation of 'info->argv' or 'info->nodes' failed ");
		free(info->job_type);
		free(info->originate_host);
		free(info->gfarm_url_for_scheduling);
		if (info->argv != NULL)
			free(info->argv);
		if (info->nodes != NULL)
			free(info->nodes);
		free(info);
		return (GFARM_ERR_NO_MEMORY);
	}
	for (i = 0; i < argc; i++) {
		e = gfp_xdr_recv(client, 0, &eof, "s", &info->argv[i]);
		if (e != GFARM_ERR_NO_ERROR || eof) {
			gflog_debug(GFARM_MSG_1001688,
				"gfp_xdr_recv(info->argv[i]) failed");
			if (e == GFARM_ERR_NO_ERROR)
				e = GFARM_ERR_PROTOCOL;
			while (--i >= 0)
				free(info->argv[i]);
			free(info->job_type);
			free(info->originate_host);
			free(info->gfarm_url_for_scheduling);
			free(info->argv);
			free(info->nodes);
			return (e);
		}
	}
	info->argv[i] = NULL;
	info->user = user; /* shared with file_table[].user */
	for (i = 0; i < total_nodes; i++) {
		e = gfp_xdr_recv(client, 0, &eof, "s",
				   &info->nodes[i].hostname);
		if (e != GFARM_ERR_NO_ERROR || eof) {
			gflog_debug(GFARM_MSG_1001689,
				"gfp_xdr_recv(hostname) failed");
			if (e == GFARM_ERR_NO_ERROR)
				e = GFARM_ERR_PROTOCOL;
			while (--i >= 0)
				free(info->nodes[i].hostname);
			for (i = 0; i < argc; i++)
				free(info->argv[i]);
			free(info->job_type);
			free(info->originate_host);
			free(info->gfarm_url_for_scheduling);
			free(info->argv);
			free(info->nodes);
			return (e);
		}
		info->nodes[i].pid = 0;
		info->nodes[i].state = GFJ_NODE_NONE;
	}

	if (skip || !from_client) {
		for (i = 0; i < total_nodes; i++)
			free(info->nodes[i].hostname);
		for (i = 0; i < argc; i++)
			free(info->argv[i]);
		free(info->job_type);
		free(info->originate_host);
		free(info->gfarm_url_for_scheduling);
		free(info->argv);
		free(info->nodes);
		if (skip)
			return (GFARM_ERR_NO_ERROR);
		error = GFARM_ERR_OPERATION_NOT_PERMITTED;
		gflog_debug(GFARM_MSG_1001690,
			"operation is not permitted for from_client");
	} else {
		giant_lock();
		job_id = job_table_add(info, peer_get_jobs_ref(peer));
		giant_unlock();
		if (job_id < JOB_ID_MIN) {
			job_id = 0;
			error = GFARM_ERR_TOO_MANY_JOBS;
			gflog_debug(GFARM_MSG_1001691,
				"too many jobs");
		} else {
			error = GFARM_ERR_NO_ERROR;
		}
	}
	return (gfj_server_put_reply(peer, xid, sizep, diag,
	    error, "i", job_id));
}
Beispiel #4
0
/*
 * Back channel protocol switch for slave gfmd.  It forwards a GFS protocol
 * request from gfsd it a master gmfd and relays its reply in the opposite
 * direction.
 */
static gfarm_error_t
async_back_channel_protocol_switch_slave(struct abstract_host *h,
	struct peer *peer, int request, gfp_xdr_xid_t xid, size_t size,
	int *unknown_request)
{
	gfarm_error_t e = GFARM_ERR_NO_ERROR;
	struct host *host = abstract_host_to_host(h);
	struct gfp_xdr *conn = peer_get_conn(peer);
	struct protocol_switch_slave_closure *closure = NULL;
	size_t data_size;
	int eof;
	static const char diag[] = "async_back_channel_protocol_switch_slave";

	if (debug_mode)
		gflog_info(GFARM_MSG_1004033,
		    "%s: <%s> back_channel start receiving request(%d)",
		    peer_get_hostname(peer), diag, (int)request);

	do {
		/*
		 * We dispose 'closure' in
		 * async_back_channel_protocol_switch_slave_result().
		 */
		closure = protocol_switch_slave_closure_alloc(h,
		    peer_get_private_peer_id(peer), xid, size, NULL);
		if (closure == NULL) {
			e = GFARM_ERR_NO_MEMORY;
			(void) gfp_xdr_purge(conn, 0, size);
			break;
		}

		data_size = size;
		e = gfp_xdr_recv(conn, 1, &eof, "r", data_size, &data_size,
		    closure->data);
		if (e != GFARM_ERR_NO_ERROR) {
			(void) gfp_xdr_purge(conn, 0, size);
			break;
		} else if (eof) {
			e = GFARM_ERR_UNEXPECTED_EOF;
			break;
		} else if (data_size != 0) {
			e = GFARM_ERR_PROTOCOL;
			gflog_warning(GFARM_MSG_1004034,
			    "%s: <%s> protocol redidual %u",
			    peer_get_hostname(peer), diag, (int)data_size);
		}

		e = gfmdc_slave_client_remote_gfs_rpc(peer, closure,
		    async_back_channel_protocol_switch_slave_result,
		    async_back_channel_protocol_switch_slave_disconnect,
		    request, size, closure->data);
	} while (0);

	if (e != GFARM_ERR_NO_ERROR) {
		if (!eof) {
			(void) gfm_async_server_put_reply(host, peer, xid,
			    diag, e, "");
		}
		if (closure != NULL)
			protocol_switch_slave_closure_free(closure);
	}
	return (e);
}
Beispiel #5
0
gfarm_error_t
gfj_server_info(struct peer *peer, int from_client, int skip)
{
	gfarm_error_t e;
	struct gfp_xdr *client = peer_get_conn(peer);
	int i, eof;
	gfarm_int32_t n, *jobs;

	e = gfj_server_get_request(peer, "info", "i", &n);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);

	GFARM_MALLOC_ARRAY(jobs, n);
	if (jobs == NULL)
		return (GFARM_ERR_NO_MEMORY);

	for (i = 0; i < n; i++) {
		e = gfp_xdr_recv(client, 0, &eof, "i", &jobs[i]);
		if (e != GFARM_ERR_NO_ERROR || eof) {
			if (e == GFARM_ERR_NO_ERROR)
				e = GFARM_ERR_PROTOCOL;
			free(jobs);
			return (e);
		}
	}

	if (skip || !from_client) {
		free(jobs);
		if (skip)
			return (GFARM_ERR_NO_ERROR);
		e = gfj_server_put_reply(peer, "info",
		    GFARM_ERR_OPERATION_NOT_PERMITTED, "");
		return (e);
	}

	/* XXX FIXME too long giant lock */
	giant_lock();
	for (i = 0; i < n; i++) {
		if (jobs[i] < 0 || jobs[i] >= job_table_size ||
		    job_table[jobs[i]] == NULL) {
			e = gfj_server_put_reply(peer, "info",
						 GFARM_ERR_NO_SUCH_OBJECT, "");
			if (e != GFARM_ERR_NO_ERROR) {
				giant_unlock();
				free(jobs);
				return (e);
			}
		} else {
			e = gfj_server_put_reply(peer, "info",
						 GFARM_ERR_NO_ERROR, "");
			if (e != GFARM_ERR_NO_ERROR) {
				free(jobs);
				giant_unlock();
				return (e);
			}
			e = gfj_server_put_info_entry(peer_get_conn(peer),
			      job_table[jobs[i]]->info);
			if (e != GFARM_ERR_NO_ERROR) {
				free(jobs);
				giant_unlock();
				return (e);
			}
		}
	}
	free(jobs);
	giant_unlock();
	return (GFARM_ERR_NO_ERROR);
}
Beispiel #6
0
gfarm_error_t
gfj_server_register(struct peer *peer, int from_client, int skip)
{
	gfarm_error_t e;
	struct gfp_xdr *client = peer_get_conn(peer);
	char *user = peer_get_username(peer);
	int i, eof;
	gfarm_int32_t flags, total_nodes, argc, error, job_id = 0;
	struct gfarm_job_info *info;

	GFARM_MALLOC(info);
	if (info == NULL)
		return (GFARM_ERR_NO_MEMORY);
	gfarm_job_info_clear(info, 1);
	e = gfj_server_get_request(peer, "register", "iisssi",
				   &flags,
				   &total_nodes,
				   &info->job_type,
				   &info->originate_host,
				   &info->gfarm_url_for_scheduling,
				   &argc);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);

	/* XXX - currently `flags' is just igored */
	info->total_nodes = total_nodes;
	info->argc = argc;
	GFARM_MALLOC_ARRAY(info->argv, argc + 1);
	GFARM_MALLOC_ARRAY(info->nodes, total_nodes);
	if (info->argv == NULL || info->nodes == NULL) {
		free(info->job_type);
		free(info->originate_host);
		free(info->gfarm_url_for_scheduling);
		if (info->argv != NULL)
			free(info->argv);
		if (info->nodes != NULL)
			free(info->nodes);
		free(info);
		return (GFARM_ERR_NO_MEMORY);
	}
	for (i = 0; i < argc; i++) {
		e = gfp_xdr_recv(client, 0, &eof, "s", &info->argv[i]);
		if (e != GFARM_ERR_NO_ERROR || eof) {
			if (e == GFARM_ERR_NO_ERROR)
				e = GFARM_ERR_PROTOCOL;
			while (--i >= 0)
				free(info->argv[i]);
			free(info->job_type);
			free(info->originate_host);
			free(info->gfarm_url_for_scheduling);
			free(info->argv);
			free(info->nodes);
			return (e);
		}
	}
	info->argv[i] = NULL;
	info->user = user; /* shared with file_table[].user */
	for (i = 0; i < total_nodes; i++) {
		e = gfp_xdr_recv(client, 0, &eof, "s",
				   &info->nodes[i].hostname);
		if (e != GFARM_ERR_NO_ERROR || eof) {
			if (e == GFARM_ERR_NO_ERROR)
				e = GFARM_ERR_PROTOCOL;
			while (--i >= 0)
				free(info->nodes[i].hostname);
			for (i = 0; i < argc; i++)
				free(info->argv[i]);
			free(info->job_type);
			free(info->originate_host);
			free(info->gfarm_url_for_scheduling);
			free(info->argv);
			free(info->nodes);
			return (e);
		}
		info->nodes[i].pid = 0;
		info->nodes[i].state = GFJ_NODE_NONE;
	}

	if (skip || !from_client) {
		for (i = 0; i < total_nodes; i++)
			free(info->nodes[i].hostname);
		for (i = 0; i < argc; i++)
			free(info->argv[i]);
		free(info->job_type);
		free(info->originate_host);
		free(info->gfarm_url_for_scheduling);
		free(info->argv);
		free(info->nodes);
		if (skip)
			return (GFARM_ERR_NO_ERROR);
		error = GFARM_ERR_OPERATION_NOT_PERMITTED;
	} else {
		giant_lock();
		job_id = job_table_add(info, peer_get_jobs_ref(peer));
		giant_unlock();
		if (job_id < JOB_ID_MIN) {
			job_id = 0;
			error = GFARM_ERR_TOO_MANY_JOBS;
		} else {
			error = GFARM_ERR_NO_ERROR;
		}
	}
	return (gfj_server_put_reply(peer, "register",
	    error, "i", job_id));
}