Exemplo n.º 1
0
gfarm_error_t
gfj_server_list(struct peer *peer, int from_client, int skip)
{
	gfarm_error_t e;
	struct gfp_xdr *client = peer_get_conn(peer);
	char *user;
	int i;
	gfarm_int32_t n;

	e = gfj_server_get_request(peer, "list", "s", &user);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);
	if (skip) {
		free(user);
		return (GFARM_ERR_NO_ERROR);
	}

	if (!from_client) {
		e = gfj_server_put_reply(peer, "list",
		    GFARM_ERR_OPERATION_NOT_PERMITTED, "");
		if (e != GFARM_ERR_NO_ERROR)
			return (e);
	} else {
		/* XXX FIXME too long giant lock */
		giant_lock();

		n = 0;
		for (i = 0; i < job_table_size; i++) {
			if (job_table[i] != NULL &&
			    (*user == '\0' ||
			     strcmp(user, job_table[i]->info->user) == 0))
				n++;
		}

		e = gfj_server_put_reply(peer, "register",
		    GFARM_ERR_NO_ERROR, "i", n);
		if (e != GFARM_ERR_NO_ERROR) {
			giant_unlock();
			return (e);
		}

		for (i = 0; i < job_table_size; i++) {
			if (job_table[i] != NULL &&
			    (*user == '\0' ||
			     strcmp(user, job_table[i]->info->user) == 0)) {
				e = gfp_xdr_send(client, "i",
				    (gfarm_int32_t)i);
				if (e != GFARM_ERR_NO_ERROR) {
					giant_unlock();
					return (e);
				}
			}
		}
		giant_unlock();
	}
	free(user);
	return (GFARM_ERR_NO_ERROR);
}
Exemplo n.º 2
0
Arquivo: job.c Projeto: ddk50/gfarm_v2
gfarm_error_t
gfj_server_unregister(struct peer *peer, gfp_xdr_xid_t xid, size_t *sizep,
	int from_client, int skip)
{
	char *user = peer_get_username(peer);
	gfarm_error_t e;
	gfarm_int32_t error;
	gfarm_int32_t job_id;
	static const char diag[] = "GFJ_PROTO_UNREGISTER";

	e = gfj_server_get_request(peer, sizep, diag, "i", &job_id);
	if (e != GFARM_ERR_NO_ERROR) {
		gflog_debug(GFARM_MSG_1001692,
			"unregister request failure");
		return (e);
	}
	if (skip)
		return (GFARM_ERR_NO_ERROR);
	if (!from_client) {
		error = GFARM_ERR_OPERATION_NOT_PERMITTED;
		gflog_debug(GFARM_MSG_1001693,
			"operation is not permitted for from_client");
	} else {
		giant_lock();
		error = job_table_remove(job_id, user,
		    peer_get_jobs_ref(peer));
		giant_unlock();
	}
	return (gfj_server_put_reply(peer, xid, sizep, diag, error, ""));
}
Exemplo n.º 3
0
gfarm_error_t
gfm_server_inherit_fd(struct peer *peer, int from_client, int skip)
{
	gfarm_int32_t e;
	gfarm_int32_t parent_fd, fd;
	struct host *spool_host;
	struct process *process;

	e = gfm_server_get_request(peer, "inherit_fd", "i", &parent_fd);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);
	if (skip)
		return (GFARM_ERR_NO_ERROR);
	giant_lock();

	if (!from_client && (spool_host = peer_get_host(peer)) == NULL)
		e = GFARM_ERR_OPERATION_NOT_PERMITTED;
	else if ((process = peer_get_process(peer)) == NULL)
		e = GFARM_ERR_OPERATION_NOT_PERMITTED;
	else if ((e = process_inherit_fd(process, parent_fd, peer, NULL,
	    &fd)) != GFARM_ERR_NO_ERROR)
		;
	else
		peer_fdpair_set_current(peer, fd);

	giant_unlock();
	return (gfm_server_put_reply(peer, "inherit_fd", e, ""));
}
Exemplo n.º 4
0
gfarm_error_t
gfm_server_bequeath_fd(struct peer *peer, int from_client, int skip)
{
	gfarm_int32_t e;
	struct host *spool_host;
	struct process *process;
	gfarm_int32_t fd;

	if (skip)
		return (GFARM_ERR_NO_ERROR);
	giant_lock();

	if (!from_client && (spool_host = peer_get_host(peer)) == NULL)
		e = GFARM_ERR_OPERATION_NOT_PERMITTED;
	else if ((process = peer_get_process(peer)) == NULL)
		e = GFARM_ERR_OPERATION_NOT_PERMITTED;
	else if ((e = peer_fdpair_get_current(peer, &fd)) !=
	    GFARM_ERR_NO_ERROR)
		;
	else
		e = process_bequeath_fd(process, fd);

	giant_unlock();
	return (gfm_server_put_reply(peer, "bequeath_fd", e, ""));
}
Exemplo n.º 5
0
gfarm_error_t
gfm_server_process_set(struct peer *peer, int from_client, int skip)
{
	gfarm_int32_t e;
	gfarm_pid_t pid;
	gfarm_int32_t keytype;
	size_t keylen;
	char sharedkey[GFM_PROTO_PROCESS_KEY_LEN_SHAREDSECRET];
	struct process *process;

	e = gfm_server_get_request(peer, "process_set",
	    "ibl", &keytype, sizeof(sharedkey), &keylen, sharedkey, &pid);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);
	if (skip)
		return (GFARM_ERR_NO_ERROR);

	giant_lock();
	if (peer_get_process(peer) != NULL) {
		e = GFARM_ERR_ALREADY_EXISTS;
	} else if (keytype != GFM_PROTO_PROCESS_KEY_TYPE_SHAREDSECRET ||
	    keylen != GFM_PROTO_PROCESS_KEY_LEN_SHAREDSECRET) {
		e = GFARM_ERR_INVALID_ARGUMENT;
	} else if ((e = process_does_match(pid, keytype, keylen, sharedkey,
	    &process)) == GFARM_ERR_NO_ERROR) {
		peer_set_process(peer, process);
		if (!from_client)
			peer_set_user(peer, process_get_user(process));
	}
	giant_unlock();
	return (gfm_server_put_reply(peer, "process_set", e, ""));
}
Exemplo n.º 6
0
gfarm_error_t
gfm_server_process_alloc(struct peer *peer, int from_client, int skip)
{
	gfarm_int32_t e;
	struct user *user;
	gfarm_int32_t keytype;
	size_t keylen;
	char sharedkey[GFM_PROTO_PROCESS_KEY_LEN_SHAREDSECRET];
	struct process *process;
	gfarm_pid_t pid;

	e = gfm_server_get_request(peer, "process_alloc",
	    "ib", &keytype, sizeof(sharedkey), &keylen, sharedkey);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);
	if (skip)
		return (GFARM_ERR_NO_ERROR);

	giant_lock();
	if (peer_get_process(peer) != NULL) {
		e = GFARM_ERR_ALREADY_EXISTS;
	} else if (!from_client || (user = peer_get_user(peer)) == NULL) {
		e = GFARM_ERR_OPERATION_NOT_PERMITTED;
	} else if ((e = process_alloc(user, keytype, keylen, sharedkey,
	    &process, &pid)) == GFARM_ERR_NO_ERROR) {
		peer_set_process(peer, process);
	}
	giant_unlock();
	return (gfm_server_put_reply(peer, "process_alloc", e, "l", pid));
}
Exemplo n.º 7
0
gfarm_error_t
gfm_server_process_free(struct peer *peer, int from_client, int skip)
{
	gfarm_error_t e;

	if (skip)
		return (GFARM_ERR_NO_ERROR);
	
	giant_lock();
	if (peer_get_process(peer) == NULL)
		e = GFARM_ERR_NO_SUCH_PROCESS;
	else {
		peer_unset_process(peer);
		e = GFARM_ERR_NO_ERROR;
	}

	giant_unlock();
	return (gfm_server_put_reply(peer, "process_free", e, ""));
}
Exemplo n.º 8
0
gfarm_error_t
gfm_server_process_alloc_child(struct peer *peer, int from_client, int skip)
{
	gfarm_int32_t e;
	struct user *user;
	gfarm_int32_t parent_keytype, keytype;
	size_t parent_keylen, keylen;
	char parent_sharedkey[GFM_PROTO_PROCESS_KEY_LEN_SHAREDSECRET];
	char sharedkey[GFM_PROTO_PROCESS_KEY_LEN_SHAREDSECRET];
	struct process *parent_process, *process;
	gfarm_pid_t parent_pid, pid;

	e = gfm_server_get_request(peer, "process_alloc_child", "iblib",
	    &parent_keytype,
	    sizeof(parent_sharedkey), &parent_keylen, parent_sharedkey,
	    &parent_pid,
	    &keytype, sizeof(sharedkey), &keylen, sharedkey);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);
	if (skip)
		return (GFARM_ERR_NO_ERROR);

	giant_lock();
	if (peer_get_process(peer) != NULL) {
		e = GFARM_ERR_ALREADY_EXISTS;
	} else if (!from_client || (user = peer_get_user(peer)) == NULL) {
		e = GFARM_ERR_OPERATION_NOT_PERMITTED;
	} else if (parent_keytype != GFM_PROTO_PROCESS_KEY_TYPE_SHAREDSECRET ||
	    parent_keylen != GFM_PROTO_PROCESS_KEY_LEN_SHAREDSECRET) {
		e = GFARM_ERR_INVALID_ARGUMENT;
	} else if ((e = process_does_match(parent_pid,
	    parent_keytype, parent_keylen, parent_sharedkey,
	    &parent_process)) != GFARM_ERR_NO_ERROR) {
		/* error */
	} else if ((e = process_alloc(user, keytype, keylen, sharedkey,
	    &process, &pid)) == GFARM_ERR_NO_ERROR) {
		peer_set_process(peer, process);
		process_add_child(parent_process, process);
	}
	giant_unlock();
	return (gfm_server_put_reply(peer, "process_alloc_child", e, "l",
	    pid));
}
Exemplo n.º 9
0
gfarm_error_t
gfj_server_unregister(struct peer *peer, int from_client, int skip)
{
	char *user = peer_get_username(peer);
	gfarm_error_t e;
	gfarm_int32_t error;
	gfarm_int32_t job_id;

	e = gfj_server_get_request(peer, "unregister", "i", &job_id);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);
	if (skip)
		return (GFARM_ERR_NO_ERROR);
	if (!from_client) {
		error = GFARM_ERR_OPERATION_NOT_PERMITTED;
	} else {
		giant_lock();
		error = job_table_remove(job_id, user,
		    peer_get_jobs_ref(peer));
		giant_unlock();
	}
	return (gfj_server_put_reply(peer, "unregister",
	    error, ""));
}
Exemplo n.º 10
0
Arquivo: job.c Projeto: ddk50/gfarm_v2
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);
}
Exemplo n.º 11
0
Arquivo: job.c Projeto: ddk50/gfarm_v2
gfarm_error_t
gfj_server_list(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;
	int i;
	gfarm_int32_t n;
	static const char diag[] = "GFJ_PROTO_LIST";

	e = gfj_server_get_request(peer, sizep, diag, "s", &user);
	if (e != GFARM_ERR_NO_ERROR) {
		gflog_debug(GFARM_MSG_1001694,
			"list request failure");
		return (e);
	}
	if (skip) {
		free(user);
		return (GFARM_ERR_NO_ERROR);
	}

	if (!from_client) {
		e = gfj_server_put_reply(peer, xid, sizep, diag,
		    GFARM_ERR_OPERATION_NOT_PERMITTED, "");
		if (e != GFARM_ERR_NO_ERROR) {
			gflog_debug(GFARM_MSG_1001695,
				"gfj_server_put_reply(list) failed");
			return (e);
		}
	} else {
		/* XXX FIXME too long giant lock */
		giant_lock();

		n = 0;
		for (i = 0; i < job_table_size; i++) {
			if (job_table[i] != NULL &&
			    (*user == '\0' ||
			     strcmp(user, job_table[i]->info->user) == 0))
				n++;
		}

		/* XXXRELAY FIXME, reply size is not correct */
		e = gfj_server_put_reply(peer, xid, sizep, diag,
		    GFARM_ERR_NO_ERROR, "i", n);
		if (e != GFARM_ERR_NO_ERROR) {
			gflog_debug(GFARM_MSG_1001696,
				"gfj_server_put_reply(register) failed");
			giant_unlock();
			return (e);
		}

		for (i = 0; i < job_table_size; i++) {
			if (job_table[i] != NULL &&
			    (*user == '\0' ||
			     strcmp(user, job_table[i]->info->user) == 0)) {
				/* XXXRELAY FIXME */
				e = gfp_xdr_send(client, "i",
				    (gfarm_int32_t)i);
				if (e != GFARM_ERR_NO_ERROR) {
					gflog_debug(GFARM_MSG_1001697,
						"gfp_xdr_send() failed");
					giant_unlock();
					return (e);
				}
			}
		}
		giant_unlock();
	}
	free(user);
	return (GFARM_ERR_NO_ERROR);
}
Exemplo n.º 12
0
Arquivo: job.c Projeto: ddk50/gfarm_v2
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));
}
Exemplo n.º 13
0
static gfarm_error_t
gfm_server_switch_back_channel_common(
	struct peer *peer, gfp_xdr_xid_t xid, size_t *sizep,
	int from_client,
	int version, const char *diag, struct relayed_request *relay)
{
	gfarm_error_t e = GFARM_ERR_NO_ERROR, e2;
	struct host *host;
	gfp_xdr_async_peer_t async = NULL;
	struct local_peer *local_peer = NULL;
	int is_direct_connection;
	int i = 0;

#ifdef __GNUC__ /* workaround gcc warning: might be used uninitialized */
	host = NULL;
#endif
	is_direct_connection = (peer_get_parent(peer) == NULL);

	giant_lock();

	if (from_client) {
		gflog_debug(GFARM_MSG_1001995,
		    "Operation not permitted: from_client");
		e = GFARM_ERR_OPERATION_NOT_PERMITTED;
	} else if ((host = peer_get_host(peer)) == NULL) {
		gflog_debug(GFARM_MSG_1001996,
		    "Operation not permitted: peer_get_host() failed");
		e = GFARM_ERR_OPERATION_NOT_PERMITTED;
	} else if (is_direct_connection &&
	    (e = gfp_xdr_async_peer_new(&async)) != GFARM_ERR_NO_ERROR) {
		gflog_error(GFARM_MSG_1002288,
		    "%s: gfp_xdr_async_peer_new(): %s",
		    diag, gfarm_error_string(e));
	}
	giant_unlock();

	e2 = gfm_server_relay_put_reply(peer, xid, sizep, relay,
	    diag, &e,  "i", &i/*XXX FIXME*/);
	if (e2 != GFARM_ERR_NO_ERROR)
		return (e2);
	if (debug_mode)
		gflog_debug(GFARM_MSG_1000404, "gfp_xdr_flush");
	e2 = gfp_xdr_flush(peer_get_conn(peer));
	if (e2 != GFARM_ERR_NO_ERROR) {
		gflog_warning(GFARM_MSG_1000405,
		    "%s: protocol flush: %s",
		    diag, gfarm_error_string(e2));
		return (e2);
	} else if (e != GFARM_ERR_NO_ERROR)
		return (e2);

	if (is_direct_connection) {
		local_peer = peer_to_local_peer(peer);
		local_peer_set_async(local_peer, async); /* XXXRELAY */
		local_peer_set_readable_watcher(local_peer,
		    back_channel_recv_watcher);
	}

	if (host_is_up(host)) /* throw away old connetion */ {
		gflog_warning(GFARM_MSG_1002440,
		    "back_channel(%s): switching to new connection",
		    host_name(host));
		host_disconnect_request(host, NULL);
	}

	giant_lock();
	peer_set_peer_type(peer, peer_type_back_channel);
	abstract_host_set_peer(host_to_abstract_host(host), peer, version);
	giant_unlock();

	if (is_direct_connection) {
		local_peer_watch_readable(local_peer);
		gfarm_thr_statewait_signal(
		    local_peer_get_statewait(local_peer), e2, diag);
	}

	callout_setfunc(host_status_callout(host),
	    NULL /* or, use back_channel_send_manager thread pool? */,
	    gfs_client_status_callout, host);
	gfs_client_status_schedule(host, 1);
	gflog_info(GFARM_MSG_1004035,
	    "back_channel(%s): started", host_name(host));

	return (e2);
}
Exemplo n.º 14
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);
}
Exemplo n.º 15
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));
}