| #include <DrbdResource.h> |
| #include <comparators.h> |
| |
| const std::string DrbdResource::PROP_KEY_RES_NAME = "name"; |
| |
| // @throws std::bad_alloc |
| DrbdResource::DrbdResource(std::string& resource_name): |
| name(resource_name), |
| conn_list(new ConnectionsMap(&comparators::compare_string)) |
| { |
| } |
| |
| DrbdResource::~DrbdResource() noexcept |
| { |
| ConnectionsMap::NodesIterator dtor_iter(*conn_list); |
| while (dtor_iter.has_next()) |
| { |
| ConnectionsMap::Node* node = dtor_iter.next(); |
| delete node->get_key(); |
| delete node->get_value(); |
| } |
| conn_list->clear(); |
| } |
| |
| const std::string& DrbdResource::get_name() const |
| { |
| return name; |
| } |
| |
| // @throws EventMessageException |
| void DrbdResource::update(PropsMap& event_props) |
| { |
| std::string* prop_role = event_props.get(&PROP_KEY_ROLE); |
| if (prop_role != nullptr) |
| { |
| role = parse_role(*prop_role); |
| } |
| } |
| |
| // @throws std::bad_alloc, dsaext::DuplicateInsertException |
| void DrbdResource::add_connection(DrbdConnection* connection) |
| { |
| std::unique_ptr<std::string> conn_name(new std::string(connection->get_name())); |
| conn_list->insert(conn_name.get(), connection); |
| static_cast<void> (conn_name.release()); |
| } |
| |
| DrbdConnection* DrbdResource::get_connection(const std::string& connection_name) const |
| { |
| DrbdConnection* connection = conn_list->get(&connection_name); |
| return connection; |
| } |
| |
| void DrbdResource::remove_connection(const std::string& connection_name) |
| { |
| ConnectionsMap::Node* node = conn_list->get_node(&connection_name); |
| delete node->get_key(); |
| delete node->get_value(); |
| conn_list->remove_node(node); |
| } |
| |
| DrbdResource::ConnectionsIterator DrbdResource::connections_iterator() |
| { |
| return ConnectionsIterator(*this); |
| } |
| |
| bool DrbdResource::has_role_alert() |
| { |
| return role_alert; |
| } |
| |
| void DrbdResource::clear_state_flags() |
| { |
| role_alert = false; |
| StateFlags::clear_state_flags(); |
| } |
| |
| StateFlags::state DrbdResource::update_state_flags() |
| { |
| // Reset the state to normal |
| StateFlags::clear_state_flags(); |
| role_alert = false; |
| |
| // Alert for unknown resource role |
| switch (role) |
| { |
| case DrbdRole::resource_role::PRIMARY: |
| // fall-through |
| case DrbdRole::resource_role::SECONDARY: |
| // no warning, no alert |
| break; |
| case DrbdRole::resource_role::UNKNOWN: |
| // fall-through |
| default: |
| role_alert = true; |
| set_alert(); |
| break; |
| } |
| |
| // Check the resource's volumes |
| VolumesMap::ValuesIterator vol_iter = volumes_iterator(); |
| size_t vol_count = vol_iter.get_size(); |
| for (size_t vol_index = 0; vol_index < vol_count; ++vol_index) |
| { |
| DrbdVolume& vol = *(vol_iter.next()); |
| if (vol.update_state_flags() != StateFlags::state::NORM) |
| { |
| set_mark(); |
| } |
| } |
| |
| // Check the resource's connections |
| ConnectionsMap::ValuesIterator conn_iter = connections_iterator(); |
| size_t conn_count = conn_iter.get_size(); |
| for (size_t conn_index = 0; conn_index < conn_count; ++conn_index) |
| { |
| DrbdConnection& conn = *(conn_iter.next()); |
| if (conn.update_state_flags() != StateFlags::state::NORM) |
| { |
| // Connections are in an abnormal state, mark this resource |
| set_mark(); |
| } |
| } |
| |
| return obj_state; |
| } |
| |
| // Creates (allocates and initializes) a new DrbdResource object from a map of properties |
| // |
| // @param event_props Reference to the map of properties from a 'drbdsetup events2' line |
| // @return Pointer to a newly created DrbdResource object |
| // @throws std::bad_alloc, dsaext::DuplicateInsertException |
| DrbdResource* DrbdResource::new_from_props(PropsMap& event_props) |
| { |
| DrbdResource* new_res {nullptr}; |
| std::string* res_name = event_props.get(&PROP_KEY_RES_NAME); |
| if (res_name != nullptr) |
| { |
| new_res = new DrbdResource(*res_name); |
| } |
| if (new_res == nullptr) |
| { |
| throw EventMessageException(); |
| } |
| return new_res; |
| } |