/* * '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); }
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); }
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)); }
/* * 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); }
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); }
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)); }