void net_add_close_func(int sd, void (*func)(int)) { int conn_idx = connection_find_actual_index(sd); if (conn_idx == -1) return; if (svr_conn[conn_idx].cn_active == Idle) return; svr_conn[conn_idx].cn_oncl = func; }
/** * @brief * Function that causes a rerun request to return with a timeout message. * * @param[in,out] pwt - work task which contains the job structure which holds the rerun request */ static void timeout_rerun_request(struct work_task *pwt) { job *pjob = (job *)pwt->wt_parm1; int conn_idx = -1; if ((pjob == NULL) || (pjob->ji_rerun_preq == NULL)) { return; /* nothing to timeout */ } if (pjob->ji_rerun_preq->rq_conn != PBS_LOCAL_CONNECTION) { conn_idx = connection_find_actual_index(pjob->ji_rerun_preq->rq_conn); } reply_text(pjob->ji_rerun_preq, PBSE_INTERNAL, "Response timed out. Job rerun request still in progress for"); /* clear no-timeout flag on connection */ if (conn_idx != -1) svr_conn[conn_idx].cn_authen &= ~PBS_NET_CONN_NOTIMEOUT; pjob->ji_rerun_preq = NULL; }
static void post_hold(struct work_task *pwt) { int code; job *pjob; struct batch_request *preq; int conn_idx; if (pwt->wt_aux2 != 1) svr_disconnect(pwt->wt_event); /* close connection to MOM */ preq = pwt->wt_parm1; code = preq->rq_reply.brp_code; preq->rq_conn = preq->rq_orgconn; /* restore client socket */ if (pwt->wt_aux2 != 1) { /* not rpp */ conn_idx = connection_find_actual_index(preq->rq_conn); if (conn_idx == -1) { req_reject(PBSE_SYSTEM, 0, preq); return; } svr_conn[conn_idx].cn_authen &= ~PBS_NET_CONN_NOTIMEOUT; } pjob = find_job(preq->rq_ind.rq_hold.rq_orig.rq_objname); if (pjob == (job *)0) { log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, LOG_DEBUG, preq->rq_ind.rq_hold.rq_orig.rq_objname, msg_postmomnojob); req_reject(PBSE_UNKJOBID, 0, preq); return; } if (code != 0) { if (code != PBSE_CKPBSY) pjob->ji_qs.ji_substate = JOB_SUBSTATE_RUNNING; /* reset it */ if (code != PBSE_NOSUP) { /* a "real" error - log message with return error code */ (void)sprintf(log_buffer, msg_mombadhold, code); log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, LOG_DEBUG, pjob->ji_qs.ji_jobid, log_buffer); /* send message back to server for display to user */ reply_text(preq, code, log_buffer); return; } } else if (code == 0) { /* record that MOM has a checkpoint file */ if (preq->rq_reply.brp_auxcode) /* chkpt can be moved */ pjob->ji_qs.ji_svrflags = (pjob->ji_qs.ji_svrflags & ~JOB_SVFLG_CHKPT) | JOB_SVFLG_HASRUN | JOB_SVFLG_ChkptMig; pjob->ji_modified = 1; /* indicate attributes changed */ (void)job_save(pjob, SAVEJOB_QUICK); /* note in accounting file */ account_record(PBS_ACCT_CHKPNT, pjob, (char *)0); } reply_ack(preq); }
void dispatch_request(int sfds, struct batch_request *request) { int conn_idx = -1; int rpp = request->isrpp; if (!rpp) { if (sfds != PBS_LOCAL_CONNECTION) { conn_idx = connection_find_actual_index(sfds); if (conn_idx == -1) { log_event(PBSEVENT_SYSTEM, PBS_EVENTCLASS_REQUEST, LOG_ERR, "dispatch_request", "did not find socket in connection table"); req_reject(PBSE_SYSTEM, 0, request); close_client(sfds); return; } } } switch (request->rq_type) { case PBS_BATCH_QueueJob: if (rpp) { request->rpp_ack = 0; rpp_add_close_func(sfds, close_quejob); } else net_add_close_func(sfds, close_quejob); req_quejob(request); break; case PBS_BATCH_JobCred: #ifndef PBS_MOM /* Reject if a user client (qsub -Wpwd) and not a */ /* server (qmove) enqueued a job with JobCredential */ if ( !request->rq_fromsvr && \ (server.sv_attr[SRV_ATR_ssignon_enable].at_flags \ & ATR_VFLAG_SET) && \ (server.sv_attr[SRV_ATR_ssignon_enable].at_val.at_long == 1) ) { req_reject(PBSE_SSIGNON_SET_REJECT, 0, request); close_client(sfds); break; } #endif if (rpp) request->rpp_ack = 0; req_jobcredential(request); break; case PBS_BATCH_UserCred: #ifdef PBS_MOM #ifdef WIN32 req_reject(PBSE_NOSUP, 0, request); #else req_reject(PBSE_UNKREQ, 0, request); #endif close_client(sfds); #else req_usercredential(request); #endif break; case PBS_BATCH_UserMigrate: #ifdef PBS_MOM #ifdef WIN32 req_reject(PBSE_NOSUP, 0, request); #else req_reject(PBSE_UNKREQ, 0, request); #endif /* WIN32 */ close_client(sfds); #else req_user_migrate(request); #endif /* PBS_MOM */ break; case PBS_BATCH_GSS_Context: req_gsscontext(request); break; case PBS_BATCH_jobscript: if (rpp) request->rpp_ack = 0; req_jobscript(request); break; /* * The PBS_BATCH_Rdytocommit message is deprecated. * The server does not do anything with it anymore, but * simply acks the request (in case some client makes this call) */ case PBS_BATCH_RdytoCommit: if (request->isrpp) request->rpp_ack = 0; reply_ack(request); break; case PBS_BATCH_Commit: if (rpp) request->rpp_ack = 0; req_commit(request); if (rpp) rpp_add_close_func(sfds, (void (*)(int))0); else net_add_close_func(sfds, (void (*)(int))0); break; case PBS_BATCH_DeleteJob: log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, LOG_INFO, request->rq_ind.rq_delete.rq_objname, "delete job request received"); req_deletejob(request); break; #ifndef PBS_MOM case PBS_BATCH_SubmitResv: req_resvSub(request); break; case PBS_BATCH_DeleteResv: req_deleteReservation(request); break; #endif case PBS_BATCH_HoldJob: if (sfds != PBS_LOCAL_CONNECTION && !rpp) svr_conn[conn_idx].cn_authen |= PBS_NET_CONN_NOTIMEOUT; req_holdjob(request); break; #ifndef PBS_MOM case PBS_BATCH_LocateJob: req_locatejob(request); break; case PBS_BATCH_Manager: req_manager(request); break; #endif case PBS_BATCH_MessJob: req_messagejob(request); break; case PBS_BATCH_PySpawn: if (sfds != PBS_LOCAL_CONNECTION && !rpp) svr_conn[conn_idx].cn_authen |= PBS_NET_CONN_NOTIMEOUT; req_py_spawn(request); break; case PBS_BATCH_ModifyJob: req_modifyjob(request); break; case PBS_BATCH_Rerun: req_rerunjob(request); break; #ifndef PBS_MOM case PBS_BATCH_MoveJob: req_movejob(request); break; case PBS_BATCH_OrderJob: req_orderjob(request); break; case PBS_BATCH_Rescq: req_reject(PBSE_NOSUP, 0, request); break; case PBS_BATCH_ReserveResc: req_reject(PBSE_NOSUP, 0, request); break; case PBS_BATCH_ReleaseResc: req_reject(PBSE_NOSUP, 0, request); break; case PBS_BATCH_ReleaseJob: if (sfds != PBS_LOCAL_CONNECTION && !rpp) svr_conn[conn_idx].cn_authen |= PBS_NET_CONN_NOTIMEOUT; req_releasejob(request); break; case PBS_BATCH_RunJob: case PBS_BATCH_AsyrunJob: req_runjob(request); break; case PBS_BATCH_DefSchReply: req_defschedreply(request); break; case PBS_BATCH_ConfirmResv: req_confirmresv(request); break; case PBS_BATCH_SelectJobs: case PBS_BATCH_SelStat: req_selectjobs(request); break; #endif /* !PBS_MOM */ case PBS_BATCH_Shutdown: req_shutdown(request); break; case PBS_BATCH_SignalJob: log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, LOG_INFO, request->rq_ind.rq_signal.rq_jid, "signal job request received"); req_signaljob(request); break; case PBS_BATCH_MvJobFile: req_mvjobfile(request); break; #ifndef PBS_MOM /* Server Only Functions */ case PBS_BATCH_StatusJob: if (set_to_non_blocking(sfds, conn_idx) == -1) { req_reject(PBSE_SYSTEM, 0, request); close_client(sfds); return; } req_stat_job(request); clear_non_blocking(sfds, conn_idx); break; case PBS_BATCH_StatusQue: if (set_to_non_blocking(sfds, conn_idx) == -1) { req_reject(PBSE_SYSTEM, 0, request); close_client(sfds); return; } req_stat_que(request); clear_non_blocking(sfds, conn_idx); break; case PBS_BATCH_StatusNode: if (set_to_non_blocking(sfds, conn_idx) == -1) { req_reject(PBSE_SYSTEM, 0, request); close_client(sfds); return; } req_stat_node(request); clear_non_blocking(sfds, conn_idx); break; case PBS_BATCH_StatusResv: if (set_to_non_blocking(sfds, conn_idx) == -1) { req_reject(PBSE_SYSTEM, 0, request); close_client(sfds); return; } req_stat_resv(request); clear_non_blocking(sfds, conn_idx); break; case PBS_BATCH_StatusSvr: req_stat_svr(request); break; case PBS_BATCH_StatusSched: req_stat_sched(request); break; case PBS_BATCH_StatusHook: if (!is_local_root(request->rq_user, request->rq_host)) { sprintf(log_buffer, "%s@%s is unauthorized to " "access hooks data from server %s", request->rq_user, request->rq_host, server_host); reply_text(request, PBSE_HOOKERROR, log_buffer); log_event(PBSEVENT_ADMIN, PBS_EVENTCLASS_HOOK, LOG_INFO, "", log_buffer); /* don't call close_client() to allow other */ /* non-hook related requests to continue */ break; } if (set_to_non_blocking(sfds, conn_idx) == -1) { req_reject(PBSE_SYSTEM, 0, request); close_client(sfds); return; } req_stat_hook(request); clear_non_blocking(sfds, conn_idx); break; case PBS_BATCH_TrackJob: req_track(request); break; case PBS_BATCH_RegistDep: req_register(request); break; case PBS_BATCH_AuthenResvPort: if (pbs_conf.auth_method == AUTH_MUNGE) { req_reject(PBSE_BADCRED, 0, request); close_client(sfds); return; } req_authenResvPort(request); break; case PBS_BATCH_StageIn: req_stagein(request); break; case PBS_BATCH_FailOver: req_failover(request); break; case PBS_BATCH_StatusRsc: req_stat_resc(request); break; case PBS_BATCH_MomRestart: log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_NODE, LOG_INFO, request->rq_ind.rq_momrestart.rq_momhost, "Mom restarted on host"); req_momrestart(request); break; #else /* MOM only functions */ case PBS_BATCH_CopyFiles: log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, LOG_INFO, request->rq_ind.rq_cpyfile.rq_jobid, "copy file request received"); /* don't time-out as copy may take long time */ if (sfds != PBS_LOCAL_CONNECTION && !rpp) svr_conn[conn_idx].cn_authen |= PBS_NET_CONN_NOTIMEOUT; req_cpyfile(request); break; case PBS_BATCH_CopyFiles_Cred: log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, LOG_INFO, request->rq_ind.rq_cpyfile_cred.rq_copyfile.rq_jobid, "copy file cred request received"); /* don't time-out as copy may take long time */ if (sfds != PBS_LOCAL_CONNECTION && !rpp) svr_conn[conn_idx].cn_authen |= PBS_NET_CONN_NOTIMEOUT; req_cpyfile(request); break; case PBS_BATCH_DelFiles: log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, LOG_INFO, request->rq_ind.rq_cpyfile.rq_jobid, "delete file request received"); req_delfile(request); break; case PBS_BATCH_DelFiles_Cred: log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, LOG_INFO, request->rq_ind.rq_cpyfile_cred.rq_copyfile.rq_jobid, "delete file cred request received"); req_delfile(request); break; case PBS_BATCH_CopyHookFile: log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_HOOK, LOG_INFO, request->rq_ind.rq_hookfile.rq_filename, "copy hook-related file request received"); req_copy_hookfile(request); break; case PBS_BATCH_DelHookFile: log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_HOOK, LOG_INFO, request->rq_ind.rq_hookfile.rq_filename, "delete hook-related file request received"); req_del_hookfile(request); break; #endif default: req_reject(PBSE_UNKREQ, 0, request); close_client(sfds); break; } return; }
void process_request(int sfds) { int rc; struct batch_request *request; int conn_idx; time_now = time((time_t *)0); conn_idx = connection_find_actual_index(sfds); if (conn_idx == -1) { log_event(PBSEVENT_SYSTEM, PBS_EVENTCLASS_REQUEST, LOG_ERR, "process_request", "did not find socket in connection table"); #ifdef WIN32 (void)closesocket(sfds); #else (void)close(sfds); #endif return; } if ((request = alloc_br(0)) == NULL) { log_event(PBSEVENT_SYSTEM, PBS_EVENTCLASS_REQUEST, LOG_ERR, "process_request", "Unable to allocate request structure"); close_conn(sfds); return; } request->rq_conn = sfds; /* * Read in the request and decode it to the internal request structure. */ if (get_connecthost(sfds, request->rq_host, PBS_MAXHOSTNAME)) { (void)sprintf(log_buffer, "%s: %lu", msg_reqbadhost, get_connectaddr(sfds)); log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_REQUEST, LOG_DEBUG, "", log_buffer); req_reject(PBSE_BADHOST, 0, request); return; } #ifndef PBS_MOM if (svr_conn[conn_idx].cn_active == FromClientDIS) { rc = dis_request_read(sfds, request); } else { log_event(PBSEVENT_SYSTEM, PBS_EVENTCLASS_REQUEST, LOG_ERR, "process_req", "request on invalid type of connection"); close_conn(sfds); free_br(request); return; } #else /* PBS_MOM */ rc = dis_request_read(sfds, request); #endif /* PBS_MOM */ if (rc == -1) { /* End of file */ close_client(sfds); free_br(request); return; } else if ((rc == PBSE_SYSTEM) || (rc == PBSE_INTERNAL)) { /* read error, likely cannot send reply so just disconnect */ /* ??? not sure about this ??? */ close_client(sfds); free_br(request); return; } else if (rc > 0) { /* * request didn't decode, either garbage or unknown * request type, in ether case, return reject-reply */ req_reject(rc, 0, request); close_client(sfds); return; } #ifndef PBS_MOM #if defined(PBS_SECURITY) && (PBS_SECURITY == KRB5) strcpy(svr_conn[sfds].cn_physhost,request->rq_host); if (request->rq_type == PBS_BATCH_GSSAuthenUser) { log_event(PBSEVENT_DEBUG | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, LOG_ERR, __func__,"Received GSSAuthenUser."); if (req_gssauthenuser(request,sfds) < 0) { log_event(PBSEVENT_DEBUG | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, LOG_ERR, __func__,"Authentication failed."); req_reject(PBSE_BADCRED, 0, request); return; } log_event(PBSEVENT_DEBUG | PBSEVENT_FORCE, PBS_EVENTCLASS_SERVER, LOG_ERR, __func__,"Authentication succeeded."); } else if ((svr_conn[sfds].cn_authen & PBS_NET_CONN_GSSAPIAUTH) != 0) { strcpy(request->rq_user,svr_conn[sfds].cn_username); strcpy(request->rq_host,svr_conn[sfds].cn_hostname); } #endif #endif #ifndef PBS_MOM /* If the request is coming on the socket we opened to the */ /* scheduler, change the "user" from "root" to "Scheduler" */ if (request->rq_conn == scheduler_sock) { strncpy(request->rq_user, PBS_SCHED_DAEMON_NAME, PBS_MAXUSER); request->rq_user[PBS_MAXUSER] = '\0'; } #endif /* PBS_MOM */ (void)sprintf(log_buffer, msg_request, request->rq_type, request->rq_user, request->rq_host, sfds); log_event(PBSEVENT_DEBUG2, PBS_EVENTCLASS_REQUEST, LOG_DEBUG, "", log_buffer); /* is the request from a host acceptable to the server */ if (request->rq_type == PBS_BATCH_AuthExternal) { rc = authenticate_external(conn_idx, request); if (rc == 0) reply_ack(request); else if (rc == -2) req_reject(PBSE_NOSUP, 0, request); else req_reject(PBSE_BADCRED, 0, request); return; } #ifndef PBS_MOM int access_by_krb = 0; #if defined(PBS_SECURITY) && (PBS_SECURITY == KRB5) if ((svr_conn[sfds].cn_authen & PBS_NET_CONN_GSSAPIAUTH) != 0) { if (server.sv_attr[(int)SRV_ATR_acl_krb_realm_enable].at_val.at_long) { if (acl_check(&server.sv_attr[(int)SRV_ATR_acl_krb_realms], svr_conn[sfds].cn_principal,ACL_Host) == 0) { req_reject(PBSE_BADHOST, 0, request); close_client(sfds); return; } } // this principal is allowed to access the server access_by_krb = 1; } #endif if (access_by_krb == 0) if (server.sv_attr[(int)SRV_ATR_acl_host_enable].at_val.at_long) { /* acl enabled, check it; always allow myself */ if ((acl_check(&server.sv_attr[(int)SRV_ATR_acl_hosts], request->rq_host, ACL_Host) == 0) && (strcasecmp(server_host, request->rq_host) != 0)) { req_reject(PBSE_BADHOST, 0, request); close_client(sfds); return; } } /* * determine source (user client or another server) of request. * set the permissions granted to the client */ if (svr_conn[conn_idx].cn_authen & PBS_NET_CONN_FROM_PRIVIL) { /* request came from another server */ request->rq_fromsvr = 1; request->rq_perm = ATR_DFLAG_USRD | ATR_DFLAG_USWR | ATR_DFLAG_OPRD | ATR_DFLAG_OPWR | ATR_DFLAG_MGRD | ATR_DFLAG_MGWR | ATR_DFLAG_SvWR; } else { /* request not from another server */ request->rq_fromsvr = 0; /* * Client must be authenticated by a Authenticate User Request, * if not, reject request and close connection. * -- The following is retained for compat with old cmds -- * The exception to this is of course the Connect Request which * cannot have been authenticated, because it contains the * needed ticket; so trap it here. Of course, there is no * prior authentication on the Authenticate User request either, * but it comes over a reserved port and appears from another * server, hence is automatically granted authorization. */ if (request->rq_type == PBS_BATCH_Connect) { req_connect(request); return; } if ((svr_conn[conn_idx].cn_authen & PBS_NET_CONN_AUTHENTICATED) ==0) { rc = PBSE_BADCRED; } else { rc = authenticate_user(request, &svr_conn[conn_idx]); } if (rc != 0) { req_reject(rc, 0, request); if (rc == PBSE_BADCRED) close_client(sfds); return; } request->rq_perm = svr_get_privilege(request->rq_user, request->rq_host); } /* if server shutting down, disallow new jobs and new running */ if (server.sv_attr[(int)SRV_ATR_State].at_val.at_long > SV_STATE_RUN) { switch (request->rq_type) { case PBS_BATCH_AsyrunJob: case PBS_BATCH_JobCred: case PBS_BATCH_UserCred: case PBS_BATCH_UserMigrate: case PBS_BATCH_MoveJob: case PBS_BATCH_QueueJob: case PBS_BATCH_RunJob: case PBS_BATCH_StageIn: case PBS_BATCH_jobscript: req_reject(PBSE_SVRDOWN, 0, request); return; } } #else /* THIS CODE FOR MOM ONLY */ /* check connecting host against allowed list of ok clients */ if (!addrfind(svr_conn[conn_idx].cn_addr)) { req_reject(PBSE_BADHOST, 0, request); close_client(sfds); return; } request->rq_fromsvr = 1; request->rq_perm = ATR_DFLAG_USRD | ATR_DFLAG_USWR | ATR_DFLAG_OPRD | ATR_DFLAG_OPWR | ATR_DFLAG_MGRD | ATR_DFLAG_MGWR | ATR_DFLAG_SvWR | ATR_DFLAG_MOM; #endif /* * dispatch the request to the correct processing function. * The processing function must call reply_send() to free * the request struture. */ if (request->rq_type == PBS_BATCH_GSSAuthenUser) return; dispatch_request(sfds, request); return; }
/** * @brief * req_rerunjob - service the Rerun Job Request * * @param[in,out] preq - Job Request * @param[in,out] pjob - ptr to the subjob */ static void req_rerunjob2(struct batch_request *preq, job *pjob) { long force = 0; struct work_task *ptask; time_t rerun_to; int conn_idx; int rc; int is_mgr = 0; void *force_rerun = (void *)0; if (preq->rq_extend && (strcmp(preq->rq_extend, "force") == 0)) force = 1; /* See if the request is coming from a manager */ if (preq->rq_perm & (ATR_DFLAG_MGRD | ATR_DFLAG_MGWR)) is_mgr = 1; /* the job must be rerunnable or force must be on */ if ((pjob->ji_wattr[(int)JOB_ATR_rerunable].at_val.at_long == 0) && (force == 0)) { req_reject(PBSE_NORERUN, 0, preq); return; } /* the job must be running */ if (pjob->ji_qs.ji_state != JOB_STATE_RUNNING) { req_reject(PBSE_BADSTATE, 0, preq); return; } if ((pjob->ji_qs.ji_substate != JOB_SUBSTATE_RUNNING) && (force==0)) { req_reject(PBSE_BADSTATE, 0, preq); return; } /* Set the flag for post_rerun only when * force is set and request is from manager */ if (force == 1 && is_mgr == 1) force_rerun = (void *)1; /* ask MOM to kill off the job */ rc = issue_signal(pjob, SIG_RERUN, post_rerun, force_rerun); /* * If force is set and request is from a PBS manager, * job is re-queued regardless of issue_signal to MoM * was a success or failure. * Eventually, when the mom updates server about the job, * server sends a discard message to mom and job is * then deleted from mom as well. */ if ((rc || is_mgr) && force == 1) { /* Mom is down and issue signal failed or * request is from a manager and "force" is on, * force the requeue */ pjob->ji_qs.ji_substate = JOB_SUBSTATE_RERUN3; discard_job(pjob, "Force rerun", 1); force_reque(pjob); reply_ack(preq); return; } if (rc != 0) { req_reject(rc, 0, preq); return; } /* So job has run and is to be rerun (not restarted) */ pjob->ji_qs.ji_svrflags = (pjob->ji_qs.ji_svrflags & ~(JOB_SVFLG_CHKPT | JOB_SVFLG_ChkptMig)) | JOB_SVFLG_HASRUN; svr_setjobstate(pjob, JOB_STATE_RUNNING, JOB_SUBSTATE_RERUN); (void)sprintf(log_buffer, msg_manager, msg_jobrerun, preq->rq_user, preq->rq_host); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, LOG_INFO, pjob->ji_qs.ji_jobid, log_buffer); /* The following means we've detected an outstanding rerun request */ /* for the same job which should not happen. But if it does, let's */ /* ack that previous request to also free up its request structure. */ if (pjob->ji_rerun_preq != NULL) { reply_ack(pjob->ji_rerun_preq); } pjob->ji_rerun_preq = preq; /* put a timeout on the rerun request so that it doesn't hang */ /* indefinitely; if it does, the scheduler would also hang on a */ /* requeue request */ time_now = time((time_t *)0); if ((server.sv_attr[(int)SRV_ATR_JobRequeTimeout].at_flags & ATR_VFLAG_SET) == 0) { rerun_to = time_now + PBS_DIS_TCP_TIMEOUT_RERUN; } else { rerun_to = time_now + server.sv_attr[(int)SRV_ATR_JobRequeTimeout].at_val.at_long; } ptask = set_task(WORK_Timed, rerun_to, timeout_rerun_request, pjob); if (ptask) { /* this ensures that the ptask created gets cleared in case */ /* pjob gets deleted before the task is served */ append_link(&pjob->ji_svrtask, &ptask->wt_linkobj, ptask); } /* set no-timeout flag on connection to client */ if (preq->rq_conn != PBS_LOCAL_CONNECTION) { conn_idx = connection_find_actual_index(preq->rq_conn); if (conn_idx != -1) svr_conn[conn_idx].cn_authen |= PBS_NET_CONN_NOTIMEOUT; } }