Exemple #1
0
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() */
Exemple #2
0
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);
  }
Exemple #3
0
int decode_DIS_SchedLock(int sock, struct batch_request *preq)
  {
  int rc;

  preq->rq_ind.rq_lock = disrui(sock, &rc);

  return rc;
  }
Exemple #4
0
/**
 * @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;
}
Exemple #5
0
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;
  }
Exemple #7
0
int decode_DIS_ShutDown(
    
  struct tcp_chan *chan,
  struct batch_request *preq)

  {
  int rc;

  preq->rq_ind.rq_shutdown = disrui(chan, &rc);

  return rc;
  }
Exemple #8
0
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() */
Exemple #9
0
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() */
Exemple #10
0
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;
}
Exemple #11
0
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);
}
Exemple #12
0
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;
  }
Exemple #13
0
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;
}
Exemple #14
0
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;
}
Exemple #15
0
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;
}
Exemple #16
0
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() */
Exemple #17
0
/**
 * @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
    {
Exemple #20
0
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);
}
Exemple #21
0
/**
 * @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);
}
Exemple #22
0
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;
  }
Exemple #23
0
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
    {
Exemple #25
0
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;
}