Exemple #1
0
void
ClusterMgr::execAPI_REGCONF(const Uint32 * theData){
  const ApiRegConf * const apiRegConf = (ApiRegConf *)&theData[0];
  const NodeId nodeId = refToNode(apiRegConf->qmgrRef);
  
#ifdef DEBUG_REG
  ndbout_c("ClusterMgr: Recd API_REGCONF from node %d", nodeId);
#endif

  assert(nodeId > 0 && nodeId < MAX_NODES);
  
  Node & node = theNodes[nodeId];
  assert(node.defined == true);
  assert(node.connected == true);

  if(node.m_info.m_version != apiRegConf->version){
    node.m_info.m_version = apiRegConf->version;
    if(theNodes[theFacade.ownId()].m_info.m_type == NodeInfo::MGM)
      node.compatible = ndbCompatible_mgmt_ndb(NDB_VERSION,
					       node.m_info.m_version);
    else
      node.compatible = ndbCompatible_api_ndb(NDB_VERSION,
					      node.m_info.m_version);
  }

  node.m_api_reg_conf = true;

  node.m_state = apiRegConf->nodeState;
  if (node.compatible && (node.m_state.startLevel == NodeState::SL_STARTED  ||
			  node.m_state.getSingleUserMode())){
    set_node_alive(node, true);
  } else {
    set_node_alive(node, false);
  }//if
  node.m_info.m_heartbeat_cnt = 0;
  node.hbCounter = 0;

  if(waitingForHB)
  {
    waitForHBFromNodes.clear(nodeId);

    if(waitForHBFromNodes.isclear())
    {
      waitingForHB= false;
      NdbCondition_Broadcast(waitForHBCond);
    }
  }
  node.hbFrequency = (apiRegConf->apiHeartbeatFrequency * 10) - 50;
}
void
MgmApiSession::getConfig(Parser_t::Context &,
                         const class Properties &args)
{
  Uint32 version, node = 0;

  args.get("version", &version);
  args.get("node", &node);

  const Config *conf = m_mgmsrv.getConfig();
  if(conf == NULL) {
    m_output->println("get config reply");
    m_output->println("result: Could not fetch configuration");
    m_output->println("");
    return;
  }

  if(node != 0){
    bool compatible;
    switch (m_mgmsrv.getNodeType(node)) {
    case NDB_MGM_NODE_TYPE_NDB:
      compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, version);
      break;
    case NDB_MGM_NODE_TYPE_API:
    case NDB_MGM_NODE_TYPE_MGM:
      compatible = ndbCompatible_mgmt_api(NDB_VERSION, version);
      break;
    default:
      m_output->println("get config");
      m_output->println("result: unrecognignized node type");
      m_output->println("");
      return;
    }
    
    if (!compatible){
      m_output->println("get config");
      m_output->println("result: incompatible version mgmt 0x%x and node 0x%x",
			NDB_VERSION, version);
      m_output->println("");
      return;
    }
  }  
  
  NdbMutex_Lock(m_mgmsrv.m_configMutex);
  const ConfigValues * cfg = &conf->m_configValues->m_config;
  
  UtilBuffer src;
  cfg->pack(src);
  NdbMutex_Unlock(m_mgmsrv.m_configMutex);
  
  char *tmp_str = (char *) malloc(base64_needed_encoded_length(src.length()));
  (void) base64_encode(src.get_data(), src.length(), tmp_str);

  SLEEP_ERROR_INSERTED(1);

  m_output->println("get config reply");
  m_output->println("result: Ok");
  m_output->println("Content-Length: %d", strlen(tmp_str));
  m_output->println("Content-Type: ndbconfig/octet-stream");
  SLEEP_ERROR_INSERTED(2);
  m_output->println("Content-Transfer-Encoding: base64");
  m_output->println("");
  if(ERROR_INSERTED(3))
  {
    int l= strlen(tmp_str);
    tmp_str[l/2]='\0';
    m_output->println(tmp_str);
    NdbSleep_SecSleep(10);
  }
  m_output->println(tmp_str);

  free(tmp_str);
  return;
}
void
MgmApiSession::get_nodeid(Parser_t::Context &,
			  const class Properties &args)
{
  const char *cmd= "get nodeid reply";
  Uint32 version, nodeid= 0, nodetype= 0xff;
  Uint32 timeout= 20;  // default seconds timeout
  const char * transporter;
  const char * user;
  const char * password;
  const char * public_key;
  const char * endian= NULL;
  const char * name= NULL;
  Uint32 log_event= 1;
  bool log_event_version;
  union { long l; char c[sizeof(long)]; } endian_check;

  args.get("version", &version);
  args.get("nodetype", &nodetype);
  args.get("transporter", &transporter);
  args.get("nodeid", &nodeid);
  args.get("user", &user);
  args.get("password", &password);
  args.get("public key", &public_key);
  args.get("endian", &endian);
  args.get("name", &name);
  args.get("timeout", &timeout);
  /* for backwards compatability keep track if client uses new protocol */
  log_event_version= args.get("log_event", &log_event);

  endian_check.l = 1;
  if(endian 
     && strcmp(endian,(endian_check.c[sizeof(long)-1])?"big":"little")!=0) {
    m_output->println(cmd);
    m_output->println("result: Node does not have the same endianness as the management server.");
    m_output->println("");
    return;
  }

  bool compatible;
  switch (nodetype) {
  case NODE_TYPE_MGM:
  case NODE_TYPE_API:
    compatible = ndbCompatible_mgmt_api(NDB_VERSION, version);
    break;
  case NODE_TYPE_DB:
    compatible = ndbCompatible_mgmt_ndb(NDB_VERSION, version);
    break;
  default:
    m_output->println(cmd);
    m_output->println("result: unknown nodetype %d", nodetype);
    m_output->println("");
    return;
  }

  struct sockaddr_in addr;
  SOCKET_SIZE_TYPE addrlen= sizeof(addr);
  int r = getpeername(m_socket, (struct sockaddr*)&addr, &addrlen);
  if (r != 0 ) {
    m_output->println(cmd);
    m_output->println("result: getpeername(%d) failed, err= %d", m_socket, r);
    m_output->println("");
    return;
  }

  NodeId tmp= nodeid;
  if(tmp == 0 || !m_allocated_resources->is_reserved(tmp)){
    BaseString error_string;
    int error_code;
    NDB_TICKS tick= 0;
    /* only report error on second attempt as not to clog the cluster log */
    while (!m_mgmsrv.alloc_node_id(&tmp, (enum ndb_mgm_node_type)nodetype, 
                                   (struct sockaddr*)&addr, &addrlen,
                                   error_code, error_string,
                                   tick == 0 ? 0 : log_event))
    {
      /* NDB_MGM_ALLOCID_CONFIG_MISMATCH is a non retriable error */
      if (tick == 0 && error_code != NDB_MGM_ALLOCID_CONFIG_MISMATCH)
      {
        // attempt to free any timed out reservations
        tick= NdbTick_CurrentMillisecond();
        struct PurgeStruct ps;
        m_mgmsrv.get_connected_nodes(ps.free_nodes);
        // invert connected_nodes to get free nodes
        ps.free_nodes.bitXORC(NodeBitmask());
        ps.str= 0;
        ps.tick= tick;
        m_mgmsrv.get_socket_server()->
          foreachSession(stop_session_if_timed_out,&ps);
	m_mgmsrv.get_socket_server()->checkSessions();
        error_string = "";
        continue;
      }
      const char *alias;
      const char *str;
      alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)
						nodetype, &str);
      m_output->println(cmd);
      m_output->println("result: %s", error_string.c_str());
      /* only use error_code protocol if client knows about it */
      if (log_event_version)
        m_output->println("error_code: %d", error_code);
      m_output->println("");
      return;
    }
  }    
  
#if 0
  if (!compatible){
    m_output->println(cmd);
    m_output->println("result: incompatible version mgmt 0x%x and node 0x%x",
		      NDB_VERSION, version);
    m_output->println("");
    return;
  }
#endif
  
  m_output->println(cmd);
  m_output->println("nodeid: %u", tmp);
  m_output->println("result: Ok");
  m_output->println("");
  m_allocated_resources->reserve_node(tmp, timeout*1000);
  
  if (name)
    g_eventLogger.info("Node %d: %s", tmp, name);

  return;
}
Exemple #4
0
void
ClusterMgr::execAPI_REGCONF(const NdbApiSignal * signal,
                            const LinearSectionPtr ptr[])
{
    const ApiRegConf * apiRegConf = CAST_CONSTPTR(ApiRegConf,
                                    signal->getDataPtr());
    const NodeId nodeId = refToNode(apiRegConf->qmgrRef);

#ifdef DEBUG_REG
    ndbout_c("ClusterMgr: Recd API_REGCONF from node %d", nodeId);
#endif

    assert(nodeId > 0 && nodeId < MAX_NODES);

    Node & cm_node = theNodes[nodeId];
    trp_node & node = cm_node;
    assert(node.defined == true);
    assert(node.is_connected() == true);

    if(node.m_info.m_version != apiRegConf->version) {
        node.m_info.m_version = apiRegConf->version;
        node.m_info.m_mysql_version = apiRegConf->mysql_version;
        if (node.m_info.m_version < NDBD_SPLIT_VERSION)
            node.m_info.m_mysql_version = 0;

        if(theNodes[theFacade.ownId()].m_info.m_type == NodeInfo::MGM)
            node.compatible = ndbCompatible_mgmt_ndb(NDB_VERSION,
                              node.m_info.m_version);
        else
            node.compatible = ndbCompatible_api_ndb(NDB_VERSION,
                                                    node.m_info.m_version);
    }

    node.set_confirmed(true);

    if (node.minDbVersion != apiRegConf->minDbVersion)
    {
        node.minDbVersion = apiRegConf->minDbVersion;
        recalcMinDbVersion();
    }

    if (node.m_info.m_version >= NDBD_255_NODES_VERSION)
    {
        node.m_state = apiRegConf->nodeState;
    }
    else
    {
        /**
         * from 2 to 8 words = 6 words diff, 6*4 = 24
         */
        memcpy(&node.m_state, &apiRegConf->nodeState, sizeof(node.m_state) - 24);
    }

    if (node.m_info.m_type == NodeInfo::DB)
    {
        /**
         * Only set DB nodes to "alive"
         */
        if (node.compatible && (node.m_state.startLevel == NodeState::SL_STARTED ||
                                node.m_state.getSingleUserMode()))
        {
            set_node_alive(node, true);
        }
        else
        {
            set_node_alive(node, false);
        }
    }

    cm_node.hbMissed = 0;
    cm_node.hbCounter = 0;
    /*
      By convention, conf->apiHeartbeatFrequency is in centiseconds rather than
      milliseconds. See also Qmgr::sendApiRegConf().
     */
    const Int64 freq =
        (static_cast<Int64>(apiRegConf->apiHeartbeatFrequency) * 10) - 50;

    if (freq > UINT_MAX32)
    {
        // In case of overflow.
        assert(false);  /* Note this assert fails on some upgrades... */
        cm_node.hbFrequency = UINT_MAX32;
    }
    else if (freq < minHeartBeatInterval)
    {
        /**
         * We use minHeartBeatInterval as a lower limit. This also prevents
         * against underflow.
         */
        cm_node.hbFrequency = minHeartBeatInterval;
    }
    else
    {
        cm_node.hbFrequency = static_cast<Uint32>(freq);
    }

    // If responding nodes indicates that it is connected to other
    // nodes, that makes it probable that those nodes are alive and
    // available also for this node.
    for (int db_node_id = 1; db_node_id <= MAX_DATA_NODE_ID; db_node_id ++)
    {
        if (node.m_state.m_connected_nodes.get(db_node_id))
        {
            // Tell this nodes start clients thread that db_node_id
            // is up and probable connectable.
            theFacade.theTransporterRegistry->indicate_node_up(db_node_id);
        }
    }

    // Distribute signal to all threads/blocks
    // TODO only if state changed...
    theFacade.for_each(this, signal, ptr);
}
Exemple #5
0
void
ClusterMgr::execAPI_REGCONF(const NdbApiSignal * signal,
                            const LinearSectionPtr ptr[])
{
  const ApiRegConf * apiRegConf = CAST_CONSTPTR(ApiRegConf,
                                                signal->getDataPtr());
  const NodeId nodeId = refToNode(apiRegConf->qmgrRef);
  
#ifdef DEBUG_REG
  ndbout_c("ClusterMgr: Recd API_REGCONF from node %d", nodeId);
#endif

  assert(nodeId > 0 && nodeId < MAX_NODES);
  
  Node & cm_node = theNodes[nodeId];
  trp_node & node = cm_node;
  assert(node.defined == true);
  assert(node.is_connected() == true);

  if(node.m_info.m_version != apiRegConf->version){
    node.m_info.m_version = apiRegConf->version;
    node.m_info.m_mysql_version = apiRegConf->mysql_version;
    if (node.m_info.m_version < NDBD_SPLIT_VERSION)
      node.m_info.m_mysql_version = 0;
        
    if(theNodes[theFacade.ownId()].m_info.m_type == NodeInfo::MGM)
      node.compatible = ndbCompatible_mgmt_ndb(NDB_VERSION,
					       node.m_info.m_version);
    else
      node.compatible = ndbCompatible_api_ndb(NDB_VERSION,
					      node.m_info.m_version);
  }

  node.set_confirmed(true);

  if (node.minDbVersion != apiRegConf->minDbVersion)
  {
    node.minDbVersion = apiRegConf->minDbVersion;
    recalcMinDbVersion();
  }

  if (node.m_info.m_version >= NDBD_255_NODES_VERSION)
  {
    node.m_state = apiRegConf->nodeState;
  }
  else
  {
    /**
     * from 2 to 8 words = 6 words diff, 6*4 = 24
     */
    memcpy(&node.m_state, &apiRegConf->nodeState, sizeof(node.m_state) - 24);
  }
  
  if (node.m_info.m_type == NodeInfo::DB)
  {
    /**
     * Only set DB nodes to "alive"
     */
    if (node.compatible && (node.m_state.startLevel == NodeState::SL_STARTED ||
                            node.m_state.getSingleUserMode()))
    {
      set_node_alive(node, true);
    }
    else
    {
      set_node_alive(node, false);
    }
  }

  cm_node.hbMissed = 0;
  cm_node.hbCounter = 0;
  cm_node.hbFrequency = (apiRegConf->apiHeartbeatFrequency * 10) - 50;

  // Distribute signal to all threads/blocks
  // TODO only if state changed...
  theFacade.for_each(this, signal, ptr);

  check_wait_for_hb(nodeId);
}