int decode_DIS_ReqHdr( struct tcp_chan *chan, struct batch_request *preq, int *proto_type, int *proto_ver) { int rc; /* We got the protocol type in process_pbs_server_port We are just hard coding it here */ *proto_type = PBS_BATCH_PROT_TYPE; *proto_ver = disrui(chan, &rc); if (rc == 0) { preq->rq_type = disrui(chan, &rc); } if (rc != 0) { return(rc); } return(disrfst(chan, PBS_MAXUSER, preq->rq_user)); } /* END decode_DIS_ReqHdr() */
int decode_DIS_JobFile( int sock, struct batch_request *preq) { int rc; size_t amt; preq->rq_ind.rq_jobfile.rq_data = 0; preq->rq_ind.rq_jobfile.rq_sequence = disrui(sock, &rc); if (rc) { return(rc); } preq->rq_ind.rq_jobfile.rq_type = disrui(sock, &rc); if (rc) { return(rc); } preq->rq_ind.rq_jobfile.rq_size = disrui(sock, &rc); if (rc) { return(rc); } if ((rc = disrfst(sock, PBS_MAXSVRJOBID + 1, preq->rq_ind.rq_jobfile.rq_jobid)) != 0) { return(rc); } preq->rq_ind.rq_jobfile.rq_data = disrcs(sock, &amt, &rc); if (((long)amt != preq->rq_ind.rq_jobfile.rq_size) && (rc == 0)) rc = DIS_EOD; if (rc) { if (preq->rq_ind.rq_jobfile.rq_data) free(preq->rq_ind.rq_jobfile.rq_data); preq->rq_ind.rq_jobfile.rq_data = 0; } return(rc); }
int decode_DIS_SchedLock(int sock, struct batch_request *preq) { int rc; preq->rq_ind.rq_lock = disrui(sock, &rc); return rc; }
/** * @brief * Decode PBS batch request to authenticate user * @param [in] sock socket connection * @param [in] preq PBS bath request * @return in * @retval 0 on success * @retval > 0 on failure */ int decode_DIS_AuthenResvPort(int sock, struct batch_request *preq) { int rc; preq->rq_ind.rq_authen_resvport.rq_port = disrui(sock, &rc); return rc; }
int decode_DIS_ShutDown(int sock, struct batch_request *preq) { int rc; preq->rq_ind.rq_shutdown = disrui(sock, &rc); return rc; }
int decode_DIS_PowerState( struct tcp_chan *chan, struct batch_request *preq) { int rc; preq->rq_ind.rq_powerstate = disrui(chan,&rc); return rc; }
int decode_DIS_ShutDown( struct tcp_chan *chan, struct batch_request *preq) { int rc; preq->rq_ind.rq_shutdown = disrui(chan, &rc); return rc; }
int decode_DIS_Authen( struct tcp_chan *chan, struct batch_request *preq) { int rc; preq->rq_ind.rq_authen.rq_port = disrui(chan, &rc); return(rc); } /* END decode_DIS_Authen() */
int decode_DIS_ReqHdr( int sock, struct batch_request *preq, int *proto_type, int *proto_ver) { int rc; *proto_type = disrui(sock, &rc); if (rc != 0) { return(rc); } if (*proto_type != PBS_BATCH_PROT_TYPE) { return(DIS_PROTO); } *proto_ver = disrui(sock, &rc); if (rc) { return(rc); } preq->rq_type = disrui(sock, &rc); if (rc != 0) { return(rc); } return(disrfst(sock, PBS_MAXUSER + 1, preq->rq_user)); } /* END decode_DIS_ReqHdr() */
int decode_DIS_JobCred(int sock, struct batch_request *preq) { int rc; preq->rq_ind.rq_jobcred.rq_data = 0; preq->rq_ind.rq_jobcred.rq_type = disrui(sock, &rc); if (rc) return rc; preq->rq_ind.rq_jobcred.rq_data = disrcs(sock, (size_t *)&preq->rq_ind.rq_jobcred.rq_size, &rc); return rc; }
int decode_DIS_ReqExtend(int sock, struct batch_request *preq) { int i; int rc; i = disrui(sock, &rc); /* indicates if an extension exists */ if (rc == 0) { if (i != 0) { preq->rq_extend = disrst(sock, &rc); } } return (rc); }
int decode_DIS_AltAuthen(int sock, struct batch_request *preq) { int rc; preq->rq_ind.rq_authen.rq_port = disrui(sock, &rc); if(rc != 0) { return(rc); } rc = disrfst(sock, PBS_MAXCREDENTIAL_LEN + 1, preq->rq_ind.rq_authen.rq_cred); return rc; }
int decode_DIS_MessageJob(int sock, struct batch_request *preq) { int rc; preq->rq_ind.rq_message.rq_text = 0; rc = disrfst(sock, PBS_MAXSVRJOBID+1, preq->rq_ind.rq_message.rq_jid); if (rc) return rc; preq->rq_ind.rq_message.rq_file = disrui(sock, &rc); if (rc) return rc; preq->rq_ind.rq_message.rq_text = disrst(sock, &rc); return rc; }
int decode_DIS_TrackJob(int sock, struct batch_request *preq) { int rc; rc = disrfst(sock, PBS_MAXSVRJOBID+1, preq->rq_ind.rq_track.rq_jid); if (rc) return rc; preq->rq_ind.rq_track.rq_hopcount = disrui(sock, &rc); if (rc) return rc; rc = disrfst(sock, PBS_MAXDEST+1, preq->rq_ind.rq_track.rq_location); if (rc) return rc; preq->rq_ind.rq_track.rq_state[0] = disruc(sock, &rc); return rc; }
int decode_DIS_UserCred(int sock, struct batch_request *preq) { int rc; rc = disrfst(sock, PBS_MAXUSER+1, preq->rq_ind.rq_usercred.rq_user); if (rc) return rc; preq->rq_ind.rq_usercred.rq_type = disrui(sock, &rc); if (rc) return rc; preq->rq_ind.rq_usercred.rq_data = 0; preq->rq_ind.rq_usercred.rq_data = disrcs(sock, (size_t *)&preq->rq_ind.rq_usercred.rq_size, &rc); return rc; }
int decode_DIS_AltAuthen( struct tcp_chan *chan, struct batch_request *preq) { int rc; preq->rq_ind.rq_authen.rq_port = disrui(chan, &rc); if (rc != 0) { return(rc); } rc = disrfst(chan, PBS_MAXCREDENTIAL_LEN, preq->rq_ind.rq_authen.rq_cred); return rc; } /* END decode_DIS_AltAuthen() */
/** * @brief * vn_decode_DIS - read verison 3 or 4 vnode definition information from * Mom. * @par Functionality: * The V4 over-the-wire representation of a placement set list (vnl_t) is * a superset of V3. V4 adds the ability to specify the type of an * attribute/resource (and reserves a place in the protocol for flags). * The V3 over-the-wire representation of a placement set list (vnl_t) is * * version unsigned integer the version of the following * information * * Version PS_DIS_V3 consists of * * vnl_modtime signed long this OTW format could be * problematic: the Open Group * Base Specifications Issue 6 * says that time_t ``shall be * integer or real-floating'' * * vnl_used unsigned integer number of entries in the vnal_t * array to follow * * * There follows, for each element of the vnal_t array, * * vnal_id string * * vnal_used unsigned integer number of entries in the vna_t * array to follow * * vna_name string name of resource * vna_val string value of resource * Following added in V4 * vna_type int type of attribute/resource * vna_flag int flag of attribute/resource (-h) * * * @param[in] fd - file (socket) descriptor from which to read * @param[out] rcp - pointer to int into which to return the error value, * either DIS_SUCCESS or some DIS_* error. * * @return vnl_t * * @retval pointer to decoded vnode information which has been malloc-ed. * @retval NULL on error, see rcp value * * @par Side Effects: None * * @par MT-safe: yes * */ vnl_t * vn_decode_DIS(int fd, int *rcp) { unsigned int vers; vers = disrui(fd, rcp); if (*rcp != DIS_SUCCESS) return ((vnl_t *) NULL); switch (vers) { case PS_DIS_V3: return (vn_decode_DIS_V3(fd, rcp)); case PS_DIS_V4: return (vn_decode_DIS_V4(fd, rcp)); default: *rcp = DIS_PROTO; return ((vnl_t *) NULL); } }
int dis_request_read( struct tcp_chan *chan, struct batch_request *request) /* server internal structure */ { int proto_type; int proto_ver; int rc; /* return code */ char log_buf[LOCAL_LOG_BUF_SIZE]; #ifdef PBS_MOM /* NYI: talk to Ken about this. This is necessary due to the changes to * decode_DIS_ReqHdr */ proto_type = disrui(chan, &rc); #endif /* Decode the Request Header, that will tell the request type */ if ((rc = decode_DIS_ReqHdr(chan, request, &proto_type, &proto_ver))) { if (rc == DIS_EOF) { return(EOF); } sprintf(log_buf, "req header bad, dis error %d (%s), type=%s", rc, dis_emsg[rc], reqtype_to_txt(request->rq_type)); log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_REQUEST, __func__, log_buf); return(PBSE_DISPROTO); } if (proto_ver != PBS_BATCH_PROT_VER) { sprintf(log_buf, "conflicting version numbers, %d detected, %d expected", proto_ver, PBS_BATCH_PROT_VER); log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_REQUEST, __func__, log_buf); return(PBSE_DISPROTO); } if ((request->rq_type < 0) || (request->rq_type >= PBS_BATCH_CEILING)) { sprintf(log_buf, "invalid request type: %d", request->rq_type); log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_REQUEST, __func__, log_buf); return(PBSE_DISPROTO); } /* Decode the Request Body based on the type */ if (LOGLEVEL >= 5) { sprintf(log_buf, "decoding command %s from %s", reqtype_to_txt(request->rq_type), request->rq_user); log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_REQUEST, __func__, log_buf); } switch (request->rq_type) { case PBS_BATCH_Disconnect: return(PBSE_SOCKET_CLOSE); /* set EOF return */ /*NOTREACHED*/ break; case PBS_BATCH_QueueJob: CLEAR_HEAD(request->rq_ind.rq_queuejob.rq_attr); rc = decode_DIS_QueueJob(chan, request); break; case PBS_BATCH_JobCred: rc = decode_DIS_JobCred(chan, request); break; case PBS_BATCH_jobscript: case PBS_BATCH_MvJobFile: rc = decode_DIS_JobFile(chan, request); break; case PBS_BATCH_RdytoCommit: case PBS_BATCH_Commit: case PBS_BATCH_Rerun: rc = decode_DIS_JobId(chan, request->rq_ind.rq_commit); break; case PBS_BATCH_DeleteJob: case PBS_BATCH_HoldJob: case PBS_BATCH_CheckpointJob: case PBS_BATCH_ModifyJob: case PBS_BATCH_AsyModifyJob: rc = decode_DIS_Manage(chan, request); break; case PBS_BATCH_MessJob: rc = decode_DIS_MessageJob(chan, request); break; case PBS_BATCH_Shutdown: rc = decode_DIS_ShutDown(chan, request); break; case PBS_BATCH_SignalJob: rc = decode_DIS_SignalJob(chan, request); break; case PBS_BATCH_StatusJob: rc = decode_DIS_Status(chan, request); break; case PBS_BATCH_GpuCtrl: rc = decode_DIS_GpuCtrl(chan, request); break; #ifndef PBS_MOM case PBS_BATCH_LocateJob: rc = decode_DIS_JobId(chan, request->rq_ind.rq_locate); break; case PBS_BATCH_Manager: case PBS_BATCH_ReleaseJob: rc = decode_DIS_Manage(chan, request); break; case PBS_BATCH_MoveJob: case PBS_BATCH_OrderJob: rc = decode_DIS_MoveJob(chan, request); break; case PBS_BATCH_RunJob: case PBS_BATCH_AsyrunJob: case PBS_BATCH_StageIn: rc = decode_DIS_RunJob(chan, request); break; case PBS_BATCH_SelectJobs: case PBS_BATCH_SelStat: CLEAR_HEAD(request->rq_ind.rq_select); rc = decode_DIS_svrattrl(chan, &request->rq_ind.rq_select); break; case PBS_BATCH_StatusNode: case PBS_BATCH_StatusQue: case PBS_BATCH_StatusSvr: /* DIAGTODO: add PBS_BATCH_StatusDiag */ rc = decode_DIS_Status(chan, request); break; case PBS_BATCH_TrackJob: rc = decode_DIS_TrackJob(chan, request); break; case PBS_BATCH_Rescq: case PBS_BATCH_ReserveResc: case PBS_BATCH_ReleaseResc: rc = decode_DIS_Rescl(chan, request); break; case PBS_BATCH_RegistDep: rc = decode_DIS_Register(chan, request); break; case PBS_BATCH_AuthenUser: rc = decode_DIS_Authen(chan, request); break; case PBS_BATCH_AltAuthenUser: rc = decode_DIS_AltAuthen(chan, request); break; case PBS_BATCH_JobObit: rc = decode_DIS_JobObit(chan, request); break; #else /* PBS_MOM */ /* pbs_mom services */ case PBS_BATCH_DeleteReservation: /* NO-OP: this one is just a header and an extension string */ break; case PBS_BATCH_ReturnFiles: rc = decode_DIS_ReturnFiles(chan, request); break; case PBS_BATCH_CopyFiles: case PBS_BATCH_DelFiles: rc = decode_DIS_CopyFiles(chan, request); break; #endif /* PBS_MOM */ default: sprintf(log_buf, "%s: %d from %s", pbse_to_txt(PBSE_NOSUP), request->rq_type, request->rq_user); log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_REQUEST, __func__, log_buf); rc = PBSE_UNKREQ; break; } /* END switch (request->rq_type) */ if (rc == DIS_SUCCESS) { /* Decode the Request Extension, if present */ rc = decode_DIS_ReqExtend(chan, request); if (rc != 0) { sprintf(log_buf, "req extension bad, dis error %d (%s), type=%s", rc, dis_emsg[rc], reqtype_to_txt(request->rq_type)); log_event(PBSEVENT_DEBUG,PBS_EVENTCLASS_REQUEST,"?",log_buf); rc = PBSE_DISPROTO; } } else if (rc != PBSE_UNKREQ) { sprintf(log_buf, "req body bad, dis error %d (%s), type=%s", rc, dis_emsg[rc], reqtype_to_txt(request->rq_type)); log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_REQUEST, "?", log_buf); rc = PBSE_DISPROTO; } return(rc); } /* END dis_request_read() */
/************************************************* * svr_is_request * * Return: svr_is_request always returns a non-zero value * and it must call close_conn to close the connection * before returning. PBSE_SOCKET_CLOSE is the code * for a successful return. But which ever retun * code is iused it must terminate the while loop * in start_process_pbs_server_port. *************************************************/ int svr_is_request( struct tcp_chan *chan, int version) { int command = 0; int ret = DIS_SUCCESS; int i; int err; char nodename[PBS_MAXHOSTNAME]; int perm = ATR_DFLAG_MGRD | ATR_DFLAG_MGWR; unsigned long ipaddr; unsigned short mom_port; unsigned short rm_port; unsigned long tmpaddr; struct sockaddr_in *addr = NULL; struct sockaddr s_addr; unsigned int len = sizeof(s_addr); struct pbsnode *node = NULL; char *node_name = NULL; char log_buf[LOCAL_LOG_BUF_SIZE+1]; command = disrsi(chan, &ret); if (ret != DIS_SUCCESS) goto err; if (LOGLEVEL >= 4) { snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "message received from sock %d (version %d)", chan->sock, version); log_event(PBSEVENT_ADMIN,PBS_EVENTCLASS_SERVER,__func__,log_buf); } if (getpeername(chan->sock, &s_addr, &len) != 0) { close_conn(chan->sock, FALSE); log_err(errno,__func__, (char *)"Cannot get socket name using getpeername\n"); return(PBSE_SOCKET_CLOSE); } addr = (struct sockaddr_in *)&s_addr; if (version != IS_PROTOCOL_VER) { snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "protocol version %d unknown from %s", version, netaddr(addr)); log_err(-1, __func__, log_buf); close_conn(chan->sock, FALSE); return PBSE_SOCKET_DATA; } /* check that machine is known */ mom_port = disrsi(chan, &ret); rm_port = disrsi(chan, &ret); if (LOGLEVEL >= 3) { snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "message received from addr %s: mom_port %d - rm_port %d", netaddr(addr), mom_port, rm_port); log_event(PBSEVENT_ADMIN,PBS_EVENTCLASS_SERVER,__func__,log_buf); } ipaddr = ntohl(addr->sin_addr.s_addr); if ((node = AVL_find(ipaddr, mom_port, ipaddrs)) != NULL) { lock_node(node, __func__, "AVL_find", LOGLEVEL); } /* END if AVL_find != NULL) */ else if (allow_any_mom) { char *name = get_cached_nameinfo(addr); if (name != NULL) snprintf(nodename, sizeof(nodename), "%s", name); else if (getnameinfo(&s_addr, len, nodename, sizeof(nodename)-1, NULL, 0, 0) != 0) { tmpaddr = ntohl(addr->sin_addr.s_addr); sprintf(nodename, "0x%lX", tmpaddr); } else insert_addr_name_info(nodename, NULL, addr); err = create_partial_pbs_node(nodename, ipaddr, perm); if (err == PBSE_NONE) { node = AVL_find(ipaddr, 0, ipaddrs); lock_node(node, __func__, "no error", LOGLEVEL); } } if (node == NULL) { /* node not listed in trusted ipaddrs list */ snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "bad attempt to connect from %s (address not trusted - check entry in server_priv/nodes)", netaddr(addr)); if (LOGLEVEL >= 2) { log_record(PBSEVENT_SCHED, PBS_EVENTCLASS_REQUEST, __func__, log_buf); } else { log_err(-1, __func__, log_buf); } close_conn(chan->sock, FALSE); return PBSE_SOCKET_CLOSE; } if (LOGLEVEL >= 3) { snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "message %s (%d) received from mom on host %s (%s) (sock %d)", PBSServerCmds2[command], command, node->nd_name, netaddr(addr), chan->sock); log_event(PBSEVENT_ADMIN,PBS_EVENTCLASS_SERVER,__func__,log_buf); } switch (command) { case IS_NULL: /* a ping from server */ DBPRT(("%s: IS_NULL\n", __func__)) break; case IS_UPDATE: DBPRT(("%s: IS_UPDATE\n", __func__)) i = disrui(chan, &ret); if (ret != DIS_SUCCESS) { if (LOGLEVEL >= 1) { snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "IS_UPDATE error %d on node %s\n", ret, node->nd_name); log_err(ret, __func__, log_buf); } goto err; } DBPRT(("%s: IS_UPDATE %s 0x%x\n", __func__, node->nd_name, i)) update_node_state(node, i); if ((node->nd_state & INUSE_DOWN) != 0) { node->nd_mom_reported_down = TRUE; } break; case IS_STATUS: if (LOGLEVEL >= 2) { snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "IS_STATUS received from %s", node->nd_name); log_event(PBSEVENT_ADMIN, PBS_EVENTCLASS_SERVER, __func__, log_buf); } if ((node_name = strdup(node->nd_name)) == NULL) goto err; unlock_node(node, __func__, "before is_stat_get", LOGLEVEL); ret = is_stat_get(node_name, chan); node = find_nodebyname(node_name); if (ret == SEND_HELLO) { struct hello_info *hi = (struct hello_info *)calloc(1, sizeof(struct hello_info)); write_tcp_reply(chan, IS_PROTOCOL, IS_PROTOCOL_VER, IS_STATUS, DIS_SUCCESS); hi->name = strdup(node_name); enqueue_threadpool_request(send_hierarchy_threadtask, hi); ret = DIS_SUCCESS; } else write_tcp_reply(chan,IS_PROTOCOL,IS_PROTOCOL_VER,IS_STATUS,ret); if(node != NULL) node->nd_stream = -1; if (ret != DIS_SUCCESS) { if (LOGLEVEL >= 1) { snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "IS_STATUS error %d on node %s", ret, node_name); log_err(ret, __func__, log_buf); } free(node_name); goto err; } free(node_name); break; default: snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "unknown command %d sent from %s", command, node->nd_name); log_err(-1, __func__, log_buf); goto err; break; } /* END switch (command) */ /* must be closed because mom opens and closes this connection each time */ close_conn(chan->sock, FALSE); if(node != NULL) unlock_node(node, __func__, "close", LOGLEVEL); return PBSE_SOCKET_CLOSE; err: /* a DIS write error has occurred */ if (node != NULL) { if (LOGLEVEL >= 1) { DBPRT(("%s: error processing node %s\n", __func__, node->nd_name)) } sprintf(log_buf, "%s from %s(%s)", dis_emsg[ret], node->nd_name, netaddr(addr)); unlock_node(node, __func__, "err", LOGLEVEL); } else {
int decode_DIS_svrattrl(int sock, pbs_list_head *phead) { int i; unsigned int hasresc; size_t ls; unsigned int data_len; unsigned int numattr; svrattrl *psvrat; int rc; size_t tsize; numattr = disrui(sock, &rc); /* number of attributes in set */ if (rc) return rc; for (i=0; i<numattr; ++i) { data_len = disrui(sock, &rc); /* here it is used */ if (rc) return rc; tsize = sizeof(svrattrl) + data_len; if ((psvrat = (svrattrl *)malloc(tsize)) == 0) return DIS_NOMALLOC; CLEAR_LINK(psvrat->al_link); psvrat->al_sister = (svrattrl *)0; psvrat->al_atopl.next = 0; psvrat->al_tsize = tsize; psvrat->al_name = (char *)psvrat + sizeof(svrattrl); psvrat->al_resc = 0; psvrat->al_value = 0; psvrat->al_nameln = 0; psvrat->al_rescln = 0; psvrat->al_valln = 0; psvrat->al_flags = 0; psvrat->al_refct = 1; if ((rc = disrfcs(sock, &ls, data_len, psvrat->al_name)) != 0) break; *(psvrat->al_name + ls++) = '\0'; psvrat->al_nameln = (int)ls; data_len -= ls; hasresc = disrui(sock, &rc); if (rc) break; if (hasresc) { psvrat->al_resc = psvrat->al_name + ls; rc = disrfcs(sock, &ls, data_len, psvrat->al_resc); if (rc) break; *(psvrat->al_resc + ls++) = '\0'; psvrat->al_rescln = (int)ls; data_len -= ls; } psvrat->al_value = psvrat->al_name + psvrat->al_nameln + psvrat->al_rescln; if ((rc = disrfcs(sock, &ls, data_len, psvrat->al_value)) != 0) break; *(psvrat->al_value + ls++) = '\0'; psvrat->al_valln = (int)ls; psvrat->al_op = (enum batch_op)disrui(sock, &rc); if (rc) break; append_link(phead, &psvrat->al_link, psvrat); } if (rc) { (void)free(psvrat); } return (rc); }
/** * @brief * vn_decode_DIS_V3 - decode version 3 vnode information from Mom * * @par Functionality: * See vn_decode_DIS() above, This is called from there to decode * V3 information. * * @param[in] fd - socket descriptor from which to read * @param[out] rcp - pointer to place to return error code if error. * * @return vnl_t * * @retval pointer to decoded vnode information which has been malloc-ed. * @retval NULL on error, see rcp value * * @par Side Effects: None * * @par MT-safe: yes * */ static vnl_t * vn_decode_DIS_V3(int fd, int *rcp) { unsigned int i, j; unsigned int size; time_t t; vnl_t *vnlp; if ((vnlp = malloc(sizeof(vnl_t))) == NULL) { *rcp = DIS_NOMALLOC; return ((vnl_t *) NULL); } t = (time_t) disrsl(fd, rcp); if (*rcp != DIS_SUCCESS) return ((vnl_t *) NULL); else vnlp->vnl_modtime = t; size = disrui(fd, rcp); if (*rcp != DIS_SUCCESS) return ((vnl_t *) NULL); else vnlp->vnl_nelem = vnlp->vnl_used = size; if ((vnlp->vnl_list = calloc(vnlp->vnl_nelem, sizeof(vnal_t))) == NULL) { free(vnlp); *rcp = DIS_NOMALLOC; return ((vnl_t *) NULL); } for (i = 0; i < vnlp->vnl_used; i++) { vnal_t *curreslist = VNL_NODENUM(vnlp, i); /* * In case an error occurs and we need to free * whatever's been allocated so far, we use the * vnal_cur entry to record the number of vnal_t * entries to free. */ vnlp->vnl_cur = i; curreslist->vnal_id = disrst(fd, rcp); if (*rcp != DIS_SUCCESS) return (free_and_return(vnlp)); size = disrui(fd, rcp); if (*rcp != DIS_SUCCESS) return (free_and_return(vnlp)); else curreslist->vnal_nelem = curreslist->vnal_used = size; if ((curreslist->vnal_list = calloc(curreslist->vnal_nelem, sizeof(vna_t))) == NULL) return (free_and_return(vnlp)); for (j = 0; j < size; j++) { vna_t *curres = VNAL_NODENUM(curreslist, j); /* * In case an error occurs and we need to free * whatever's been allocated so far, we use the * vnal_cur entry to record the number of vna_t * entries to free. */ curreslist->vnal_cur = j; curres->vna_name = disrst(fd, rcp); if (*rcp != DIS_SUCCESS) return (free_and_return(vnlp)); curres->vna_val = disrst(fd, rcp); if (*rcp != DIS_SUCCESS) return (free_and_return(vnlp)); } } *rcp = DIS_SUCCESS; return (vnlp); }
int decode_DIS_attropl(int sock, struct attropl **ppatt) { int hasresc; unsigned int i; unsigned int name_len; unsigned int numpat; struct attropl *pat = NULL; struct attropl *patprior = NULL; int rc; numpat = disrui(sock, &rc); if (rc) return rc; for (i = 0; i < numpat; ++i) { name_len = disrui(sock, &rc); /* name_len is unused here */ if (rc) break; pat = malloc(sizeof(struct attropl)); if (pat == 0) return DIS_NOMALLOC; pat->next = (struct attropl *)0; pat->name = (char *)0; pat->resource = (char *)0; pat->value = (char *)0; pat->name = disrst(sock, &rc); if (rc) break; hasresc = disrui(sock, &rc); if (rc) break; if (hasresc) { pat->resource = disrst(sock, &rc); if (rc) break; } pat->value = disrst(sock, &rc); if (rc) break; pat->op = (enum batch_op)disrui(sock, &rc); if (rc) break; if (i == 0) { /* first one, link to passing in pointer */ *ppatt = pat; } else { patprior->next = pat; } patprior = pat; } if (rc) PBS_free_aopl(pat); return rc; }
int decode_DIS_svrattrl( struct tcp_chan *chan, tlist_head *phead) { unsigned int i; unsigned int hasresc; size_t ls; unsigned int data_len; unsigned int numattr; svrattrl *psvrat = NULL; int rc; size_t tsize; numattr = disrui(chan, &rc); /* number of attributes in set */ if (rc) return rc; for (i = 0; i < numattr; ++i) { data_len = disrui(chan, &rc); /* here it is used */ if (data_len == 0) data_len = sizeof(char); if (rc) return(rc); tsize = sizeof(svrattrl) + data_len + 2; /* 2 more for nulls in name & resc*/ if ((psvrat = (svrattrl *)calloc(1, tsize)) == 0) return DIS_NOMALLOC; CLEAR_LINK(psvrat->al_link); psvrat->al_atopl.next = 0; psvrat->al_tsize = tsize; psvrat->al_name = (char *)psvrat + sizeof(svrattrl); psvrat->al_resc = 0; psvrat->al_value = 0; psvrat->al_nameln = 0; psvrat->al_rescln = 0; psvrat->al_valln = 0; psvrat->al_flags = 0; if ((rc = disrfcs(chan, &ls, data_len, psvrat->al_name))) break; *(psvrat->al_name + ls++) = '\0'; psvrat->al_nameln = (int)ls; data_len -= ls; hasresc = disrui(chan, &rc); if (rc) break; if (hasresc) { psvrat->al_resc = psvrat->al_name + ls; if ((rc = disrfcs(chan, &ls, data_len, psvrat->al_resc))) break; *(psvrat->al_resc + ls++) = '\0'; psvrat->al_rescln = (int)ls; data_len -= ls; } psvrat->al_value = psvrat->al_name + psvrat->al_nameln + psvrat->al_rescln; if ((rc = disrfcs(chan, &ls, data_len, psvrat->al_value))) break; *(psvrat->al_value + ls++) = '\0'; psvrat->al_valln = (int)ls; psvrat->al_op = (enum batch_op)disrui(chan, &rc); if (rc) break; append_link(phead, &psvrat->al_link, psvrat); } if (rc) { (void)free(psvrat); } return (rc); }
/************************************************* * svr_is_request * * Return: svr_is_request always returns a non-zero value * and it must call close_conn to close the connection * before returning. PBSE_SOCKET_CLOSE is the code * for a successful return. But which ever retun * code is iused it must terminate the while loop * in start_process_pbs_server_port. *************************************************/ void *svr_is_request( void *v) { int command = 0; int ret = DIS_SUCCESS; int i; int err; char nodename[PBS_MAXHOSTNAME]; int perm = ATR_DFLAG_MGRD | ATR_DFLAG_MGWR; unsigned long ipaddr; unsigned short mom_port; unsigned short rm_port; unsigned long tmpaddr; struct sockaddr_in addr; struct pbsnode *node = NULL; char log_buf[LOCAL_LOG_BUF_SIZE+1]; char msg_buf[80]; char tmp[80]; int version; struct tcp_chan *chan; long *args; is_request_info *isr = (is_request_info *)v; if (isr == NULL) return(NULL); chan = isr->chan; args = isr->args; version = disrsi(chan, &ret); if (ret != DIS_SUCCESS) { log_err(-1, __func__, "Cannot read version - skipping this request.\n"); close_conn(chan->sock, FALSE); DIS_tcp_cleanup(chan); return(NULL); } command = disrsi(chan, &ret); if (ret != DIS_SUCCESS) { snprintf(log_buf, sizeof(log_buf), "could not read command: %d", ret); log_err(-1, __func__, log_buf); close_conn(chan->sock, FALSE); DIS_tcp_cleanup(chan); return(NULL); } if (LOGLEVEL >= 4) { snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "message received from sock %d (version %d)", chan->sock, version); log_event(PBSEVENT_ADMIN, PBS_EVENTCLASS_SERVER, __func__, log_buf); } /* Just a note to let us know we only do IPv4 for now */ addr.sin_family = AF_INET; memcpy(&addr.sin_addr, (void *)&args[1], sizeof(struct in_addr)); addr.sin_port = args[2]; if (version != IS_PROTOCOL_VER) { netaddr_long(args[1], tmp); sprintf(msg_buf, "%s:%ld", tmp, args[2]); snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "protocol version %d unknown from %s", version, msg_buf); log_err(-1, __func__, log_buf); close_conn(chan->sock, FALSE); DIS_tcp_cleanup(chan); return(NULL); } /* check that machine is known */ mom_port = disrsi(chan, &ret); rm_port = disrsi(chan, &ret); if (LOGLEVEL >= 3) { netaddr_long(args[1], tmp); sprintf(msg_buf, "%s:%ld", tmp, args[2]); snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "message received from addr %s: mom_port %d - rm_port %d", msg_buf, mom_port, rm_port); log_event(PBSEVENT_ADMIN,PBS_EVENTCLASS_SERVER,__func__,log_buf); } ipaddr = args[1]; if ((node = AVL_find(ipaddr, mom_port, ipaddrs)) != NULL) { node->lock_node(__func__, "AVL_find", LOGLEVEL); } /* END if AVL_find != NULL) */ else if (allow_any_mom) { const char *name = get_cached_nameinfo(&addr); if (name != NULL) snprintf(nodename, sizeof(nodename), "%s", name); else if (getnameinfo((struct sockaddr *)&addr, sizeof(addr), nodename, sizeof(nodename)-1, NULL, 0, 0) != 0) { tmpaddr = ntohl(addr.sin_addr.s_addr); sprintf(nodename, "0x%lX", tmpaddr); } else insert_addr_name_info(NULL, nodename); err = create_partial_pbs_node(nodename, ipaddr, perm); if (err == PBSE_NONE) { node = AVL_find(ipaddr, 0, ipaddrs); node->lock_node(__func__, "no error", LOGLEVEL); } } if (node == NULL) { /* node not listed in trusted ipaddrs list */ netaddr_long(args[1], tmp); sprintf(msg_buf, "%s:%ld", tmp, args[2]); snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "bad attempt to connect from %s (address not trusted - check entry in server_priv/nodes)", msg_buf); if (LOGLEVEL >= 2) { log_record(PBSEVENT_SCHED, PBS_EVENTCLASS_REQUEST, __func__, log_buf); } else { log_err(-1, __func__, log_buf); } close_conn(chan->sock, FALSE); DIS_tcp_cleanup(chan); return(NULL); } if (LOGLEVEL >= 3) { netaddr_long(args[1], tmp); sprintf(msg_buf, "%s:%ld", tmp, args[2]); snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "message %s (%d) received from mom on host %s (%s) (sock %d)", PBSServerCmds2[command], command, node->get_name(), msg_buf, chan->sock); log_event(PBSEVENT_ADMIN,PBS_EVENTCLASS_SERVER,__func__,log_buf); } mutex_mgr node_mutex(&node->nd_mutex, true); switch (command) { case IS_NULL: /* a ping from server */ DBPRT(("%s: IS_NULL\n", __func__)) break; case IS_UPDATE: DBPRT(("%s: IS_UPDATE\n", __func__)) i = disrui(chan, &ret); if (ret != DIS_SUCCESS) { if (LOGLEVEL >= 1) { snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "IS_UPDATE error %d on node %s\n", ret, node->get_name()); log_err(ret, __func__, log_buf); } goto err; } DBPRT(("%s: IS_UPDATE %s 0x%x\n", __func__, node->get_name(), i)) update_node_state(node, i); if ((node->nd_state & INUSE_DOWN) != 0) { node->nd_mom_reported_down = TRUE; } break; case IS_STATUS: { std::string node_name = node->get_name(); if (LOGLEVEL >= 2) { snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "IS_STATUS received from %s", node->get_name()); log_event(PBSEVENT_ADMIN, PBS_EVENTCLASS_SERVER, __func__, log_buf); } node_mutex.unlock(); ret = is_stat_get(node_name.c_str(), chan); node = find_nodebyname(node_name.c_str()); if (node != NULL) { node->nd_stream = -1; node_mutex.mark_as_locked(); if (ret == SEND_HELLO) { //struct hello_info *hi = new hello_info(node->nd_id); write_tcp_reply(chan, IS_PROTOCOL, IS_PROTOCOL_VER, IS_STATUS, DIS_SUCCESS); hierarchy_handler.sendHierarchyToANode(node); ret = DIS_SUCCESS; } else write_tcp_reply(chan,IS_PROTOCOL,IS_PROTOCOL_VER,IS_STATUS,ret); } if (ret != DIS_SUCCESS) { if (LOGLEVEL >= 1) { snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "IS_STATUS error %d on node %s", ret, node_name.c_str()); log_err(ret, __func__, log_buf); } goto err; } break; } default: snprintf(log_buf, LOCAL_LOG_BUF_SIZE, "unknown command %d sent from %s", command, node->get_name()); log_err(-1, __func__, log_buf); goto err; break; } /* END switch (command) */ /* must be closed because mom opens and closes this connection each time */ close_conn(chan->sock, FALSE); DIS_tcp_cleanup(chan); return(NULL); err: /* a DIS write error has occurred */ if (node != NULL) { if (LOGLEVEL >= 1) { DBPRT(("%s: error processing node %s\n", __func__, node->get_name())) } netaddr_long(args[1], tmp); sprintf(msg_buf, "%s:%ld", tmp, args[2]); sprintf(log_buf, "%s from %s(%s)", dis_emsg[ret], node->get_name(), msg_buf); } else {
int decode_DIS_attrl(int sock, struct attrl **ppatt) { int hasresc; int i; unsigned int numpat; struct attrl *pat = 0; struct attrl *patprior = 0; int rc; numpat = disrui(sock, &rc); if (rc) return rc; for (i=0; i < numpat; ++i) { (void) disrui(sock, &rc); if (rc) break; pat = malloc(sizeof(struct attrl)); if (pat == 0) return DIS_NOMALLOC; pat->next = (struct attrl *)0; pat->name = (char *)0; pat->resource = (char *)0; pat->value = (char *)0; pat->name = disrst(sock, &rc); if (rc) break; hasresc = disrui(sock, &rc); if (rc) break; if (hasresc) { pat->resource = disrst(sock, &rc); if (rc) break; } pat->value = disrst(sock, &rc); if (rc) break; #ifdef NAS /* localmod 005 */ pat->op = (enum batch_op) disrui(sock, &rc); #else pat->op = disrui(sock, &rc); #endif /* localmod 005 */ if (rc) break; if (i == 0) { /* first one, link to passing in pointer */ *ppatt = pat; } else { patprior->next = pat; } patprior = pat; } if (rc) PBS_free_aopl((struct attropl *)pat); return rc; }