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, "")); }
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, "")); }
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); }