CNode* CNodeTable::do_add_node(uint32_t node_id, uint32_t node_ip, bool managed) { // 无效节点ID if (!is_valid_node_id(node_id)) return NULL; // 节点已经存在 if (_node_array[node_id] != NULL) return NULL; // IP对应的ID存储在set中 node_id_set_t* node_id_set; ip_table_t::iterator iter = _ip_table.find(node_ip); if (iter == _ip_table.end()) { node_id_set = new node_id_set_t; node_id_set->insert(node_id); _ip_table.insert(std::make_pair(node_ip, node_id_set)); } else { // 相同IP的已经存在 if (_ip_uniq) return NULL; node_id_set = iter->second; node_id_set->insert(node_id); } ++_node_number; _node_array[node_id] = new CNode(node_id, node_ip, managed); _node_array[node_id]->inc_refcount(); return _node_array[node_id]; }
void CNodeTable::do_del_node(CNode* node) { if (node != NULL) { uint32_t node_id = node->get_id(); uint32_t node_ip = node->get_ip(); // 有效节点ID if (is_valid_node_id(node_id)) { if (_node_array[node_id] != NULL) { //delete _node_array[node_id]; _node_array[node_id]->dec_refcount(); // 如果引用计数值为0,则相当于delete _node_array[node_id] = NULL; --_node_number; // 处理IP表 ip_table_t::iterator iter = _ip_table.find(node_ip); if (iter != _ip_table.end()) { node_id_set_t* node_id_set = iter->second; node_id_set->erase(node_id); if (node_id_set->empty()) { _ip_table.erase(iter); delete node_id_set; } } } } } }
CNode* CNodeTable::get_node(uint32_t node_id, bool inc_refcount) { CNode* node = NULL; sys::ReadLockHelper read_lock(_lock); if (is_valid_node_id(node_id)) { if (_node_array[node_id] != NULL) { node = _node_array[node_id]; if (inc_refcount) node->inc_refcount(); } } return node; }
void CNodeTable::load(const char* filename, bool ignore_duplicate) { FILE* fp = fopen(filename, "r"); if (NULL == fp) throw sys::CSyscallException(errno, __FILE__, __LINE__); sys::CloseHelper<FILE*> ch(fp); sys::WriteLockHelper write_lock(_lock); try { int idc_id = 0; int node_id = 0; int rack_id = 0; int node_type = 0; char node_ip_str[IP_ADDRESS_MAX]; char check_field[100]; /** 用来探测是否多了一些字段 */ char line[LINE_MAX]; int line_number = 0; while (fgets(line, sizeof(line)-1, fp)) { ++line_number; // 跳过注释 if ('#' == line[0]) continue; // 跳过空行 if ('\n' == line[0]) continue; // 共5个有效字段 int field_count = sscanf(line, "%d%s%d%d%d%s", &node_id, node_ip_str, &node_type, &rack_id, &idc_id, check_field); if (field_count != 5) // 字段个数不对 throw util::CFileFormatException(filename, line_number, field_count); // 节点ID过大 if (!is_valid_node_id(node_id)) throw util::CFileFormatException(filename, line_number, 1); // IP格式不对 if (!net::CUtil::valid_ipv4(node_ip_str)) throw util::CFileFormatException(filename, line_number, 2); int node_ip = net::CUtil::convert_ipv4(node_ip_str); if (0 == node_ip) throw util::CFileFormatException(filename, line_number, 2); // 节点类型不对 if ((node_type != 0) && (node_type != 1)) throw util::CFileFormatException(filename, line_number, 3); // rack error if ((rack_id != -1) && (!is_valid_rack_id(rack_id))) throw util::CFileFormatException(filename, line_number, 4); // idc error if ((idc_id != -1) && (!is_valid_idc_id(idc_id))) throw util::CFileFormatException(filename, line_number, 5); // node_type等于1表示为受控节点,如果等于0则表示为非控节点 CNode* node = do_add_node(node_id, node_ip, 1==node_type); if (NULL == node) // 除非节点已经存在,否则不会为NULL { if (!ignore_duplicate) throw util::CFileFormatException(filename, line_number, 0); } else { if (idc_id > -1) node->set_owner_idc_id(idc_id); if (rack_id > -1) node->set_owner_rack_id(rack_id); } } } catch (util::CFileFormatException& ex) { //fclose(fp); // 使用了CloseHelper,会自动关闭的 clear_nodes(); throw; } }
int read_config_node_local_config(config_t * config) { config_setting_t * config_node_setting = config_lookup(config, "config_node"); if (config_node_setting == NULL) { message(LOG_WARNING, FACILITY_CONFIG, "Config node section is missing, using and config node this node"); zfs_config.config_node.node_id = zfs_config.this_node.node_id; zfs_config.config_node.host_port = zfs_config.this_node.host_port; xstringdup(&zfs_config.config_node.node_name, &zfs_config.this_node.node_name); return CONFIG_TRUE; } config_setting_t * setting_node_id = config_setting_get_member(config_node_setting, "id"); config_setting_t * setting_node_name = config_setting_get_member(config_node_setting, "name"); config_setting_t * setting_node_host = config_setting_get_member(config_node_setting, "host"); if (setting_node_id == NULL || setting_node_name == NULL || setting_node_host == NULL) { message(LOG_ERROR, FACILITY_CONFIG, "In local config node section name, node id or host name is missing, please add them to local config.\n"); return CONFIG_FALSE; } if (config_setting_type(setting_node_id) != CONFIG_TYPE_INT) { message(LOG_ERROR, FACILITY_CONFIG, "In local node section key id has wrong type, it should be int.\n"); return CONFIG_FALSE; } if (config_setting_type(setting_node_name) != CONFIG_TYPE_STRING) { message(LOG_ERROR, FACILITY_CONFIG, "In local node section key name has wrong type, it should be string.\n"); return CONFIG_FALSE; } if (config_setting_type(setting_node_host) != CONFIG_TYPE_STRING) { message(LOG_ERROR, FACILITY_CONFIG, "In local node section key name has wrong type, it should be string.\n"); return CONFIG_FALSE; } zfs_config.config_node.node_id = config_setting_get_int(setting_node_id); if (!is_valid_node_id(zfs_config.config_node.node_id)) { message(LOG_ERROR, FACILITY_CONFIG, "Node in config node id is invalid, please fix is.\n"); return CONFIG_FALSE; } if (zfs_config.this_node.node_id == zfs_config.config_node.node_id) { message(LOG_ERROR, FACILITY_CONFIG, "Node in config node id is same as this node id.\n"); return CONFIG_FALSE; } const char * local_node_name = config_setting_get_string(setting_node_name); if (!is_valid_node_name(local_node_name)) { message(LOG_ERROR, FACILITY_CONFIG, "Node name in config node is invalid.\n"); return CONFIG_FALSE; } xmkstring(&zfs_config.config_node.node_name, local_node_name); if (stringeq(&zfs_config.config_node.node_name, &zfs_config.this_node.node_name)) { message(LOG_ERROR, FACILITY_CONFIG, "Node name in config node is same as this node name.\n"); return CONFIG_FALSE; } const char * local_node_host = config_setting_get_string(setting_node_host); if (!is_valid_host_name(local_node_host)) { message(LOG_ERROR, FACILITY_CONFIG, "Host name in config node is invalid.\n"); return CONFIG_FALSE; } xmkstring(&(zfs_config.config_node.host_name), local_node_host); /*read port configuration*/ zfs_config.config_node.host_port = read_tcp_port_setting(config_node_setting); return CONFIG_TRUE; }