/** * @brief * issue a batch request to another server or to a MOM * or even to ourself! * * If the request is meant for this every server, then * Set up work-task of type WORK_Deferred_Local with a dummy * connection handle (PBS_LOCAL_CONNECTION). * * Dispatch the request to be processed. [reply_send() will * dispatch the reply via the work task entry.] * * If the request is to another server/MOM, then * Set up work-task of type WORK_Deferred_Reply with the * connection handle as the event. * * Encode and send the request. * * When the reply is ready, process_reply() will decode it and * dispatch the work task. * * @note * IT IS UP TO THE FUNCTION DISPATCHED BY THE WORK TASK TO CLOSE THE * CONNECTION (connection handle not socket) and FREE THE REQUEST * STRUCTURE. The connection (non-negative if open) is in wt_event * and the pointer to the request structure is in wt_parm1. * * @param[in] conn - connection index * @param[in] request - batch request to send * @param[in] func - The callback function to invoke to handle the batch reply * @param[out] ppwt - Return work task to be maintained by server to handle * deferred replies * @param[in] rpp - conn is over tcp or rpp? * * @return Error code * @retval 0 - Success * @retval -1 - Failure * */ int issue_Drequest(int conn, struct batch_request *request, void (*func)(), struct work_task **ppwt, int rpp) { struct attropl *patrl; struct work_task *ptask; struct svrattrl *psvratl; int rc; int sock = -1; enum work_type wt; char *msgid = NULL; request->rppcmd_msgid = NULL; if (conn == PBS_LOCAL_CONNECTION) { wt = WORK_Deferred_Local; request->rq_conn = PBS_LOCAL_CONNECTION; } else if (rpp) { sock = conn; request->rq_conn = conn; wt = WORK_Deferred_Reply; } else { sock = connection[conn].ch_socket; request->rq_conn = sock; wt = WORK_Deferred_Reply; DIS_tcp_setup(sock); } ptask = set_task(wt, (long) conn, func, (void *) request); if (ptask == NULL) { log_err(errno, __func__, "could not set_task"); if (ppwt != 0) *ppwt = 0; return (-1); } if (conn == PBS_LOCAL_CONNECTION) { /* the request should be issued to ourself */ dispatch_request(PBS_LOCAL_CONNECTION, request); if (ppwt != 0) *ppwt = ptask; return (0); } /* the request is bound to another server, encode/send the request */ switch (request->rq_type) { #ifndef PBS_MOM case PBS_BATCH_DeleteJob: rc = PBSD_mgr_put(conn, PBS_BATCH_DeleteJob, MGR_CMD_DELETE, MGR_OBJ_JOB, request->rq_ind.rq_delete.rq_objname, NULL, request->rq_extend, rpp, &msgid); break; case PBS_BATCH_HoldJob: attrl_fixlink(&request->rq_ind.rq_hold.rq_orig.rq_attr); psvratl = (struct svrattrl *)GET_NEXT( request->rq_ind.rq_hold.rq_orig.rq_attr); patrl = &psvratl->al_atopl; rc = PBSD_mgr_put(conn, PBS_BATCH_HoldJob, MGR_CMD_SET, MGR_OBJ_JOB, request->rq_ind.rq_hold.rq_orig.rq_objname, patrl, NULL, rpp, &msgid); break; case PBS_BATCH_MessJob: rc = PBSD_msg_put(conn, request->rq_ind.rq_message.rq_jid, request->rq_ind.rq_message.rq_file, request->rq_ind.rq_message.rq_text, NULL, rpp, &msgid); break; case PBS_BATCH_RelnodesJob: rc = PBSD_relnodes_put(conn, request->rq_ind.rq_relnodes.rq_jid, request->rq_ind.rq_relnodes.rq_node_list, NULL, rpp, &msgid); break; case PBS_BATCH_PySpawn: rc = PBSD_py_spawn_put(conn, request->rq_ind.rq_py_spawn.rq_jid, request->rq_ind.rq_py_spawn.rq_argv, request->rq_ind.rq_py_spawn.rq_envp, rpp, &msgid); break; case PBS_BATCH_ModifyJob: attrl_fixlink(&request->rq_ind.rq_modify.rq_attr); patrl = (struct attropl *)&((struct svrattrl *)GET_NEXT( request->rq_ind.rq_modify.rq_attr))->al_atopl; rc = PBSD_mgr_put(conn, PBS_BATCH_ModifyJob, MGR_CMD_SET, MGR_OBJ_JOB, request->rq_ind.rq_modify.rq_objname, patrl, NULL, rpp, &msgid); break; case PBS_BATCH_Rerun: if (rpp) { rc = is_compose_cmd(sock, IS_CMD, &msgid); if (rc != 0) break; } rc=encode_DIS_ReqHdr(sock, PBS_BATCH_Rerun, pbs_current_user); if (rc != 0) break; rc=encode_DIS_JobId(sock, request->rq_ind.rq_rerun); if (rc != 0) break; rc=encode_DIS_ReqExtend(sock, 0); if (rc != 0) break; rc = DIS_wflush(sock, rpp); break; case PBS_BATCH_RegistDep: if (rpp) { rc = is_compose_cmd(sock, IS_CMD, &msgid); if (rc != 0) break; } rc=encode_DIS_ReqHdr(sock, PBS_BATCH_RegistDep, pbs_current_user); if (rc != 0) break; rc=encode_DIS_Register(sock, request); if (rc != 0) break; rc=encode_DIS_ReqExtend(sock, 0); if (rc != 0) break; rc = DIS_wflush(sock, rpp); break; case PBS_BATCH_SignalJob: rc = PBSD_sig_put(conn, request->rq_ind.rq_signal.rq_jid, request->rq_ind.rq_signal.rq_signame, NULL, rpp, &msgid); break; case PBS_BATCH_StatusJob: rc = PBSD_status_put(conn, PBS_BATCH_StatusJob, request->rq_ind.rq_status.rq_id, NULL, NULL, rpp, &msgid); break; case PBS_BATCH_TrackJob: if (rpp) { rc = is_compose_cmd(sock, IS_CMD, &msgid); if (rc != 0) break; } rc=encode_DIS_ReqHdr(sock, PBS_BATCH_TrackJob, pbs_current_user); if (rc != 0) break; rc=encode_DIS_TrackJob(sock, request); if (rc != 0) break; rc=encode_DIS_ReqExtend(sock, request->rq_extend); if (rc != 0) break; rc = DIS_wflush(sock, rpp); break; case PBS_BATCH_CopyFiles: if (rpp) { rc = is_compose_cmd(sock, IS_CMD, &msgid); if (rc != 0) break; } rc=encode_DIS_ReqHdr(sock, PBS_BATCH_CopyFiles, pbs_current_user); if (rc != 0) break; rc=encode_DIS_CopyFiles(sock, request); if (rc != 0) break; rc=encode_DIS_ReqExtend(sock, 0); if (rc != 0) break; rc = DIS_wflush(sock, rpp); break; case PBS_BATCH_CopyFiles_Cred: if (rpp) { rc = is_compose_cmd(sock, IS_CMD, &msgid); if (rc != 0) break; } rc=encode_DIS_ReqHdr(sock, PBS_BATCH_CopyFiles_Cred, pbs_current_user); if (rc != 0) break; rc=encode_DIS_CopyFiles_Cred(sock, request); if (rc != 0) break; rc=encode_DIS_ReqExtend(sock, 0); if (rc != 0) break; rc = DIS_wflush(sock, rpp); break; case PBS_BATCH_DelFiles: if (rpp) { rc = is_compose_cmd(sock, IS_CMD, &msgid); if (rc != 0) break; } rc=encode_DIS_ReqHdr(sock, PBS_BATCH_DelFiles, pbs_current_user); if (rc != 0) break; rc=encode_DIS_CopyFiles(sock, request); if (rc != 0) break; rc=encode_DIS_ReqExtend(sock, 0); if (rc != 0) break; rc = DIS_wflush(sock, rpp); break; case PBS_BATCH_DelFiles_Cred: if (rpp) { rc = is_compose_cmd(sock, IS_CMD, &msgid); if (rc != 0) break; } rc=encode_DIS_ReqHdr(sock, PBS_BATCH_DelFiles_Cred, pbs_current_user); if (rc != 0) break; rc=encode_DIS_CopyFiles_Cred(sock, request); if (rc != 0) break; rc=encode_DIS_ReqExtend(sock, 0); if (rc != 0) break; rc = DIS_wflush(sock, rpp); break; case PBS_BATCH_FailOver: rc = put_failover(sock, request); /* we should never do rpp for this one */ break; #else /* PBS_MOM */ case PBS_BATCH_JobObit: rc=encode_DIS_ReqHdr(sock, PBS_BATCH_JobObit, pbs_current_user); if (rc != 0) break; rc=encode_DIS_JobObit(sock, request); if (rc != 0) break; rc=encode_DIS_ReqExtend(sock, 0); if (rc != 0) break; rc = DIS_wflush(sock, rpp); break; #endif /* PBS_MOM */ default: (void)sprintf(log_buffer, msg_issuebad, request->rq_type); log_err(-1, __func__, log_buffer); delete_task(ptask); rc = -1; break; } if (rc) { sprintf(log_buffer, "issue_Drequest failed, error=%d on request %d", rc, request->rq_type); log_err(-1, __func__, log_buffer); if (msgid) free(msgid); delete_task(ptask); } else if (ppwt != 0) { if (rpp) { rpp_add_close_func(sock, process_DreplyRPP); /* register a close handler */ ptask->wt_event2 = msgid; /* * since its an rpp delayed task, remove it from the task_event list * caller will add to moms deferred cmd list */ delete_link(&ptask->wt_linkall); } ptask->wt_aux2 = rpp; /* 0 in case of non-TPP */ *ppwt = ptask; } return (rc); }
int send_request_to_remote_server( int conn, batch_request *request) { struct attropl *patrl; struct svrattrl *psvratl; int rc = PBSE_NONE; int tmp_rc = PBSE_NONE; int sock = 0; char log_buf[LOCAL_LOG_BUF_SIZE]; struct tcp_chan *chan = NULL; pthread_mutex_lock(connection[conn].ch_mutex); sock = connection[conn].ch_socket; pthread_mutex_unlock(connection[conn].ch_mutex); request->rq_conn = sock; if ((chan = DIS_tcp_setup(sock)) == NULL) { log_err(PBSE_MEM_MALLOC, __func__, "Could not allocate memory for socket buffer"); close_conn(sock, FALSE); return(PBSE_MEM_MALLOC); } /* the request is bound to another server, encode/send the request */ switch (request->rq_type) { case PBS_BATCH_DeleteJob: rc = PBSD_mgr_put( conn, PBS_BATCH_DeleteJob, MGR_CMD_DELETE, MGR_OBJ_JOB, request->rq_ind.rq_delete.rq_objname, NULL, NULL); break; case PBS_BATCH_HoldJob: attrl_fixlink(&request->rq_ind.rq_hold.rq_orig.rq_attr); psvratl = (struct svrattrl *)GET_NEXT(request->rq_ind.rq_hold.rq_orig.rq_attr); patrl = &psvratl->al_atopl; rc = PBSD_mgr_put( conn, PBS_BATCH_HoldJob, MGR_CMD_SET, MGR_OBJ_JOB, request->rq_ind.rq_hold.rq_orig.rq_objname, patrl, NULL); break; case PBS_BATCH_CheckpointJob: rc = PBSD_mgr_put( conn, PBS_BATCH_CheckpointJob, MGR_CMD_SET, MGR_OBJ_JOB, request->rq_ind.rq_hold.rq_orig.rq_objname, NULL, NULL); break; case PBS_BATCH_GpuCtrl: rc = PBSD_gpu_put( conn, request->rq_ind.rq_gpuctrl.rq_momnode, request->rq_ind.rq_gpuctrl.rq_gpuid, request->rq_ind.rq_gpuctrl.rq_gpumode, request->rq_ind.rq_gpuctrl.rq_reset_perm, request->rq_ind.rq_gpuctrl.rq_reset_vol, NULL); break; case PBS_BATCH_MessJob: rc = PBSD_msg_put( conn, request->rq_ind.rq_message.rq_jid, request->rq_ind.rq_message.rq_file, request->rq_ind.rq_message.rq_text, NULL); break; case PBS_BATCH_ModifyJob: case PBS_BATCH_AsyModifyJob: attrl_fixlink(&request->rq_ind.rq_modify.rq_attr); patrl = (struct attropl *) & ((struct svrattrl *)GET_NEXT( request->rq_ind.rq_modify.rq_attr))->al_atopl; rc = PBSD_mgr_put( conn, request->rq_type, MGR_CMD_SET, MGR_OBJ_JOB, request->rq_ind.rq_modify.rq_objname, patrl, NULL); break; case PBS_BATCH_Rerun: if ((rc = encode_DIS_ReqHdr(chan, PBS_BATCH_Rerun, msg_daemonname))) break; if ((rc = encode_DIS_JobId(chan, request->rq_ind.rq_rerun))) break; if ((rc = encode_DIS_ReqExtend(chan, 0))) break; rc = DIS_tcp_wflush(chan); break; case PBS_BATCH_RegistDep: if ((rc = encode_DIS_ReqHdr(chan, PBS_BATCH_RegistDep, msg_daemonname))) break; if ((rc = encode_DIS_Register(chan, request))) break; if ((rc = encode_DIS_ReqExtend(chan, 0))) break; rc = DIS_tcp_wflush(chan); break; case PBS_BATCH_AsySignalJob: case PBS_BATCH_SignalJob: rc = PBSD_sig_put( conn, request->rq_ind.rq_signal.rq_jid, request->rq_ind.rq_signal.rq_signame, request->rq_extra); break; case PBS_BATCH_StatusJob: rc = PBSD_status_put( conn, PBS_BATCH_StatusJob, request->rq_ind.rq_status.rq_id, NULL, NULL); break; case PBS_BATCH_TrackJob: if ((rc = encode_DIS_ReqHdr(chan, PBS_BATCH_TrackJob, msg_daemonname))) break; if ((rc = encode_DIS_TrackJob(chan, request))) break; if ((rc = encode_DIS_ReqExtend(chan, 0))) break; rc = DIS_tcp_wflush(chan); break; case PBS_BATCH_ReturnFiles: if ((rc = encode_DIS_ReqHdr(chan, PBS_BATCH_ReturnFiles, msg_daemonname))) break; if ((rc = encode_DIS_ReturnFiles(chan, request))) break; if ((rc = encode_DIS_ReqExtend(chan, 0))) break; rc = DIS_tcp_wflush(chan); break; case PBS_BATCH_CopyFiles: if ((rc = encode_DIS_ReqHdr(chan, PBS_BATCH_CopyFiles, msg_daemonname))) break; if ((rc = encode_DIS_CopyFiles(chan, request))) break; if ((rc = encode_DIS_ReqExtend(chan, 0))) break; rc = DIS_tcp_wflush(chan); break; case PBS_BATCH_DelFiles: if ((rc = encode_DIS_ReqHdr(chan, PBS_BATCH_DelFiles, msg_daemonname))) break; if ((rc = encode_DIS_CopyFiles(chan, request))) break; if ((rc = encode_DIS_ReqExtend(chan, 0))) break; rc = DIS_tcp_wflush(chan); break; case PBS_BATCH_DeleteReservation: if ((rc = encode_DIS_ReqHdr(chan, PBS_BATCH_DeleteReservation, msg_daemonname))) break; if ((rc = encode_DIS_ReqExtend(chan, request->rq_extend))) break; rc = DIS_tcp_wflush(chan); break; default: sprintf(log_buf, msg_issuebad, request->rq_type); log_err(-1, __func__, log_buf); rc = -1; break; } /* END switch (request->rq_type) */ if ((tmp_rc = DIS_reply_read(chan, &request->rq_reply)) != 0) { sprintf(log_buf, "DIS_reply_read failed: %d", tmp_rc); log_record(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, __func__, log_buf); request->rq_reply.brp_code = tmp_rc; request->rq_reply.brp_choice = BATCH_REPLY_CHOICE_NULL; } DIS_tcp_cleanup(chan); svr_disconnect(conn); return(rc); } /* END send_request_to_remote_server() */
int issue_Drequest( int conn, struct batch_request *request, void (*func) (struct work_task *), struct work_task **ppwt) { struct attropl *patrl; struct work_task *ptask; struct svrattrl *psvratl; int rc; int sock = 0; enum work_type wt; char *id = "issue_Drequest"; if (conn == PBS_LOCAL_CONNECTION) { wt = WORK_Deferred_Local; request->rq_conn = PBS_LOCAL_CONNECTION; } else { sock = connection[conn].ch_socket; request->rq_conn = sock; wt = WORK_Deferred_Reply; DIS_tcp_setup(sock); } ptask = set_task(wt, (long)conn, func, (void *)request); if (ptask == NULL) { log_err(errno, id, "could not set_task"); if (ppwt != NULL) *ppwt = 0; return(-1); } if (conn == PBS_LOCAL_CONNECTION) { /* the request should be issued to ourself */ dispatch_request(PBS_LOCAL_CONNECTION, request); if (ppwt != NULL) *ppwt = ptask; return(0); } /* the request is bound to another server, encode/send the request */ switch (request->rq_type) { #ifndef PBS_MOM case PBS_BATCH_DeleteJob: rc = PBSD_mgr_put( conn, PBS_BATCH_DeleteJob, MGR_CMD_DELETE, MGR_OBJ_JOB, request->rq_ind.rq_delete.rq_objname, NULL, NULL); break; case PBS_BATCH_HoldJob: attrl_fixlink(&request->rq_ind.rq_hold.rq_orig.rq_attr); psvratl = (struct svrattrl *)GET_NEXT(request->rq_ind.rq_hold.rq_orig.rq_attr); patrl = &psvratl->al_atopl; rc = PBSD_mgr_put( conn, PBS_BATCH_HoldJob, MGR_CMD_SET, MGR_OBJ_JOB, request->rq_ind.rq_hold.rq_orig.rq_objname, patrl, NULL); break; case PBS_BATCH_CheckpointJob: rc = PBSD_mgr_put( conn, PBS_BATCH_CheckpointJob, MGR_CMD_SET, MGR_OBJ_JOB, request->rq_ind.rq_hold.rq_orig.rq_objname, NULL, NULL); break; case PBS_BATCH_GpuCtrl: rc = PBSD_gpu_put( conn, request->rq_ind.rq_gpuctrl.rq_momnode, request->rq_ind.rq_gpuctrl.rq_gpuid, request->rq_ind.rq_gpuctrl.rq_gpumode, request->rq_ind.rq_gpuctrl.rq_reset_perm, request->rq_ind.rq_gpuctrl.rq_reset_vol, NULL); break; case PBS_BATCH_MessJob: rc = PBSD_msg_put( conn, request->rq_ind.rq_message.rq_jid, request->rq_ind.rq_message.rq_file, request->rq_ind.rq_message.rq_text, NULL); break; case PBS_BATCH_ModifyJob: case PBS_BATCH_AsyModifyJob: attrl_fixlink(&request->rq_ind.rq_modify.rq_attr); patrl = (struct attropl *) & ((struct svrattrl *)GET_NEXT( request->rq_ind.rq_modify.rq_attr))->al_atopl; rc = PBSD_mgr_put( conn, request->rq_type, MGR_CMD_SET, MGR_OBJ_JOB, request->rq_ind.rq_modify.rq_objname, patrl, NULL); break; case PBS_BATCH_Rerun: if ((rc = encode_DIS_ReqHdr(sock, PBS_BATCH_Rerun, msg_daemonname))) break; if ((rc = encode_DIS_JobId(sock, request->rq_ind.rq_rerun))) break; if ((rc = encode_DIS_ReqExtend(sock, 0))) break; rc = DIS_tcp_wflush(sock); break; case PBS_BATCH_RegistDep: if ((rc = encode_DIS_ReqHdr(sock, PBS_BATCH_RegistDep, msg_daemonname))) break; if ((rc = encode_DIS_Register(sock, request))) break; if ((rc = encode_DIS_ReqExtend(sock, 0))) break; rc = DIS_tcp_wflush(sock); break; case PBS_BATCH_AsySignalJob: case PBS_BATCH_SignalJob: rc = PBSD_sig_put( conn, request->rq_ind.rq_signal.rq_jid, request->rq_ind.rq_signal.rq_signame, request->rq_extra); break; case PBS_BATCH_StatusJob: rc = PBSD_status_put( conn, PBS_BATCH_StatusJob, request->rq_ind.rq_status.rq_id, NULL, NULL); break; case PBS_BATCH_TrackJob: if ((rc = encode_DIS_ReqHdr(sock, PBS_BATCH_TrackJob, msg_daemonname))) break; if ((rc = encode_DIS_TrackJob(sock, request))) break; if ((rc = encode_DIS_ReqExtend(sock, 0))) break; rc = DIS_tcp_wflush(sock); break; case PBS_BATCH_ReturnFiles: if ((rc = encode_DIS_ReqHdr(sock, PBS_BATCH_ReturnFiles, msg_daemonname))) break; if ((rc = encode_DIS_ReturnFiles(sock, request))) break; if ((rc = encode_DIS_ReqExtend(sock, 0))) break; rc = DIS_tcp_wflush(sock); break; case PBS_BATCH_CopyFiles: if ((rc = encode_DIS_ReqHdr(sock, PBS_BATCH_CopyFiles, msg_daemonname))) break; if ((rc = encode_DIS_CopyFiles(sock, request))) break; if ((rc = encode_DIS_ReqExtend(sock, 0))) break; rc = DIS_tcp_wflush(sock); break; case PBS_BATCH_DelFiles: if ((rc = encode_DIS_ReqHdr(sock, PBS_BATCH_DelFiles, msg_daemonname))) break; if ((rc = encode_DIS_CopyFiles(sock, request))) break; if ((rc = encode_DIS_ReqExtend(sock, 0))) break; rc = DIS_tcp_wflush(sock); break; #else /* PBS_MOM */ case PBS_BATCH_JobObit: /* who is sending obit request? */ if ((rc = encode_DIS_ReqHdr(sock, PBS_BATCH_JobObit, msg_daemonname))) break; if ((rc = encode_DIS_JobObit(sock, request))) break; if ((rc = encode_DIS_ReqExtend(sock, 0))) break; rc = DIS_tcp_wflush(sock); break; #endif /* PBS_MOM */ default: sprintf(log_buffer, msg_issuebad, request->rq_type); log_err(-1, id, log_buffer); delete_task(ptask); rc = -1; break; } /* END switch (request->rq_type) */ if (ppwt != NULL) *ppwt = ptask; return(rc); } /* END issue_Drequest() */