1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
#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;
}
bool DrbdResource::has_quorum_alert()
{
return quorum_alert;
}
void DrbdResource::clear_state_flags()
{
role_alert = false;
quorum_alert = false;
StateFlags::clear_state_flags();
}
StateFlags::state DrbdResource::update_state_flags()
{
StateFlags::state last_state = obj_state;
role_alert = false;
quorum_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;
}
// If the state may have improved, adjust to child objects status
if (last_state != StateFlags::state::NORM)
{
static_cast<void> (child_state_flags_changed());
}
return obj_state;
}
StateFlags::state DrbdResource::child_state_flags_changed()
{
StateFlags::clear_state_flags();
// quorum_alert depends on the state of the resource's volumes
quorum_alert = false;
// If any of the resource's volumes has marks/warnings/alerts, mark the resource
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();
}
if (vol.has_quorum_alert())
{
quorum_alert = true;
set_alert();
}
}
if (obj_state == StateFlags::state::NORM)
{
// If any of the resource's connections has marks/warnings/alerts, mark the resource
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();
break;
}
}
}
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;
}
|