Пример #1
0
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 */
Пример #2
0
/*
 * 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);
}
Пример #3
0
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() */
Пример #4
0
/* 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() */
Пример #5
0
/*************************************************
 * 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
    {
Пример #6
0
/**
 * 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;
}
Пример #7
0
/*************************************************
 * 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
    {