struct pbsnode *AVL_find( u_long key, uint16_t port, AvlTree tree) { if (tree == NULL) { return( NULL ); } if (key < tree->key) return( AVL_find( key, port, tree->left )); else if ( key > tree->key ) return( AVL_find( key, port, tree->right )); else { if (port < tree->port) return( AVL_find( key, port, tree->left ) ); else if ( port > tree->port ) return( AVL_find( key, port, tree->right )); } return( tree->pbsnode ); } /* end AVL_find */
/* * Returns true if the signature is found. * */ bool dd_has_sig(const sig_t sig) { int i; //dd_printf("FND_SIG: "); //for (i = 0; i < SHA_DIGEST_LENGTH; ++i) dd_printf("%02x", sig[i]); //dd_printf("\n"); return (AVL_find( (const Element*) sig, sigtree ) != NULL); }
struct pbsnode *get_numa_from_str( const char *str, /* I */ struct pbsnode *np) /* I */ { const char *numa_id; struct pbsnode *numa; unsigned long numa_index; char log_buf[LOCAL_LOG_BUF_SIZE]; if (np->node_boards == NULL) { /* ERROR */ snprintf(log_buf,sizeof(log_buf), "Node %s isn't declared to be NUMA, but mom is reporting\n", np->nd_name); log_err(-1, __func__, log_buf); unlock_node(np, __func__, "np numa update", LOGLEVEL); return(NULL); } numa_id = str + strlen(NUMA_KEYWORD); numa_index = atoi(numa_id); numa = AVL_find(numa_index, np->nd_mom_port, np->node_boards); if (numa == NULL) { /* ERROR */ snprintf(log_buf,sizeof(log_buf), "Could not find NUMA index %lu for node %s\n", numa_index, np->nd_name); log_err(-1, __func__, log_buf); unlock_node(np, __func__, "np numa update", LOGLEVEL); return(NULL); } /* SUCCESS */ unlock_node(np, __func__, "np numa update", LOGLEVEL); lock_node(numa, __func__, "numa numa update", LOGLEVEL); numa->nd_lastupdate = time(NULL); return(numa); } /* END get_numa_from_str() */
/* instead of getting the status on a node with numa nodes, report * the status of all the numa nodes * * @param pnode - the node to report on * @param preq - the batch request * @param pstathd - the list to add this response to * * @return - 0 on SUCCESS, error code otherwise */ int get_numa_statuses( struct pbsnode *pnode, /* ptr to node receiving status query */ struct batch_request *preq, int *bad, /* O */ tlist_head *pstathd) /* head of list to append status to */ { int i; int rc = 0; struct pbsnode *pn; if (pnode->num_node_boards == 0) { /* no numa nodes, just return the status for this node */ rc = status_node(pnode, preq, bad, pstathd); return(rc); } for (i = 0; i < pnode->num_node_boards; i++) { pn = AVL_find(i,pnode->nd_mom_port,pnode->node_boards); if (pn == NULL) continue; lock_node(pn, __func__, NULL, LOGLEVEL); rc = status_node(pn, preq, bad, pstathd); unlock_node(pn, __func__, NULL, LOGLEVEL); if (rc != PBSE_NONE) { return(rc); } } return(rc); } /* END get_numa_statuses() */
/************************************************* * 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 {
/** * Steps the world. * * This function is not complete, may need some rework. */ void DYN_stepWorld(DYN_Context *context) { int i, j; double remainingTime = 1; double nearestPoints[6]; int stuckCtr = 0; if (simStopped) return; while (remainingTime > 0) { char wasCollision = 0; // STEP 1: Moving bodies for (i = 0; i < context->bodyCount; i++) { moveBody(&context->bodies[i], remainingTime); } // STEP 2: Collision detection for (i = 0; i < context->bodyCount; i++) { context->bodies[i].colliding = 0; context->bodies[i].inContact = 0; } for (i = 0; i < context->bodyCount; i++) { for (j = i + 1; j < context->bodyCount; j++) { double nearestPoints[6]; int tmp[2]; tmp[0] = i; tmp[1] = j; if (AVL_find(&context->ncPairIndex, tmp)) { continue; } if (COL_collide(&context->bodies[i], &context->bodies[j], nearestPoints, 0)) { addCollidingPair(context, i, j); wasCollision = 1; } } } if (wasCollision) { double currentImpulseVector[3]; double currentCollisionPoint[3]; double minTime = 1; int earlyAIndex = -1, earlyBIndex = -1; // There was collision // STEP 3: Find earliest collision int i; int cpCount = DYNA_getLength(&context->collidingPairs); int (*collidingPairs)[2] = DYNA_getStorage(&context->collidingPairs); // Find the earliest collision. assert(cpCount); for (i = 0; i < cpCount; i++) { DYN_Body *a = &context->bodies[collidingPairs[i][0]]; DYN_Body *b = &context->bodies[collidingPairs[i][1]]; double lower = 0; double upper = remainingTime; int stuckCtr2 = 0; char nearestSet = 0; for(;;stuckCtr2++) { double middle = (lower + upper) * 0.5; revertMovement(a); revertMovement(b); moveBody(a, middle); moveBody(b, middle); if (COL_collide(a, b, nearestPoints, 0)) { upper = middle; } else { nearestSet = 1; lower = middle; } assert(lower != upper); if (nearestSet) { double tmp[3]; ALG_getPointToPointVector(tmp, nearestPoints, &nearestPoints[3]); if ((ALG_dotProduct(tmp, tmp) < 1e-6) || (fabs(upper-lower) < 1e-6)) { // The two bodies are near each other. if (middle <= minTime) { minTime = middle; earlyAIndex = collidingPairs[i][0]; earlyBIndex = collidingPairs[i][1]; memcpy(currentImpulseVector, tmp, sizeof(currentImpulseVector)); memcpy(currentCollisionPoint, nearestPoints, sizeof(currentCollisionPoint)); } break; } } } } { DYN_Body *a = &context->bodies[earlyAIndex]; DYN_Body *b = &context->bodies[earlyBIndex]; fprintf(DYN_log, "Collision!\n"); fprintf(DYN_log, "Body index A: %d\n", earlyAIndex); fprintf(DYN_log, "Body index B: %d\n", earlyBIndex); fprintf(DYN_log, "Velocity A [%g, %g, %g] %g\n", a->velocity[0], a->velocity[1], a->velocity[2], ALG_getVectorLength(a->velocity)); fprintf(DYN_log, "Velocity B [%g, %g, %g] %g\n", b->velocity[0], b->velocity[1], b->velocity[2], ALG_getVectorLength(b->velocity)); fprintf(DYN_log, "Collision point [%g, %g, %g]\n", currentCollisionPoint[0], currentCollisionPoint[1], currentCollisionPoint[2]); fprintf( DYN_log, "Impulse vector [%g, %g, %g] %g\n", currentImpulseVector[0], currentImpulseVector[1], currentImpulseVector[2], ALG_getVectorLength(currentImpulseVector) ); fprintf(DYN_log, "Elapsed time: %g\n", context->elapsedTime + context->timeStep * (1 - remainingTime)); } // Revert and move all bodies to the collision moment. for (i = 0; i < context->bodyCount; i++) { DYN_Body *current = &context->bodies[i]; revertMovement(current); moveBody(current, minTime); } assert(earlyAIndex >= 0); assert(earlyBIndex >= 0); // Resolve the collision { CollisionResult result = resolveCollision( context, &context->bodies[earlyAIndex], &context->bodies[earlyBIndex], currentCollisionPoint, currentImpulseVector ); if (result == DYN_STICKEDTOGETHER) { addNonCollidingPair(context, earlyAIndex, earlyBIndex); context->bodies[earlyAIndex].inContact = 1; context->bodies[earlyBIndex].inContact = 1; } } memcpy(DYN_lastCollisionPoint, currentCollisionPoint, sizeof(DYN_lastCollisionPoint)); memcpy(DYN_lastImpulse, currentImpulseVector, sizeof(DYN_lastImpulse)); fprintf(DYN_log, "==============================\n"); // clearCollidingPairs(context); // Continue the simulation remainingTime -= minTime; } else { // No collision, step finished break; } stuckCtr++; if (stuckCtr >= 100) { simStopped = 1; return; } } // STEP 4: repelling non-colliding pairs { int i; int n = DYNA_getLength(&context->nonCollidingPairs); int (*ncPairs)[2] = (int (*)[2])DYNA_getStorage(&context->nonCollidingPairs); double lastSimplex[12]; for (i = 0; i < n; i++) { DYN_Body *a = &context->bodies[ncPairs[i][0]]; DYN_Body *b = &context->bodies[ncPairs[i][1]]; if (COL_collide(a, b, 0, lastSimplex)) { double penetrationVector[3]; fprintf(DYN_log, "Sticked and colliding after timestep!\n"); COL_getPenetrationVector(a, b, lastSimplex, penetrationVector); fprintf( DYN_log, "Penetration vector was: [%g, %g, %g]\n", penetrationVector[0], penetrationVector[1], penetrationVector[2] ); { // push it out from the body and a little. double penetrationVectorLength = ALG_getVectorLength(penetrationVector); double scaleFactor = (penetrationVectorLength + 0.01) / penetrationVectorLength; ALG_scale(penetrationVector, scaleFactor); } ALG_translate(b->position, penetrationVector); fprintf(DYN_log, "==============================\n"); a->colliding = a->inContact = 0; b->colliding = a->inContact = 0; { // Body b may collide with other bodies. Translate those bodies as well. DYNA_Array tmp; int j; DYNA_initialize(&tmp, sizeof(DYN_Body*)); DYNA_add(&tmp, b); for (j = 0; j < DYNA_getLength(&tmp); j++) { DYN_Body **storage = DYNA_getStorage(&tmp); DYN_Body *current = storage[j]; int k = 0; for (k = 0; k < context->bodyCount; k++) { DYN_Body *other = &context->bodies[k]; if (other == current) continue; if (COL_collide(current, other, 0, 0)) { ALG_translate(other->position, penetrationVector); current->colliding = 0; other->colliding = 0; DYNA_add(&tmp, other); } } } DYNA_deinitialize(&tmp); } } } } clearNonCollidingPairs(context); context->elapsedTime += context->timeStep; }
/************************************************* * 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 {