MXS-2273 Move code for setting maintenance bit to monitor.cc

Applies to being-drained as well.

Better that this special handling is handled by Monitor that needs it.
This commit is contained in:
Johan Wikman
2019-01-28 14:00:32 +02:00
parent 05b650ed91
commit 727d3feb3b
3 changed files with 143 additions and 61 deletions

View File

@ -2336,6 +2336,121 @@ bool Monitor::set_disk_space_threshold(const string& dst_setting)
return rv;
}
namespace
{
bool is_monitored_server(MXS_MONITORED_SERVER* pMs, SERVER* pServer)
{
while (pMs && (pMs->server != pServer))
{
pMs = pMs->next;
}
return pMs != nullptr;
}
const char ERR_CANNOT_MODIFY[] =
"The server is monitored, so only the maintenance status can be "
"set/cleared manually. Status was not modified.";
const char WRN_REQUEST_OVERWRITTEN[] =
"Previous maintenance request was not yet read by the monitor and was overwritten.";
}
bool Monitor::set_server_status(SERVER* srv, int bit, string* errmsg_out)
{
mxb_assert(is_monitored_server(this->monitored_servers, srv));
bool written = false;
if (this->state == MONITOR_STATE_RUNNING)
{
/* This server is monitored, in which case modifying any other status bit than Maintenance is
* disallowed. */
if (bit & ~(SERVER_MAINT | SERVER_BEING_DRAINED))
{
MXS_ERROR(ERR_CANNOT_MODIFY);
if (errmsg_out)
{
*errmsg_out = ERR_CANNOT_MODIFY;
}
}
else if (bit & SERVER_MAINT)
{
/* Maintenance is set/cleared using a special variable which the monitor reads when
* starting the next update cycle. */
int previous_request = atomic_exchange_int(&srv->maint_request, SERVER::MAINTENANCE_ON);
written = true;
// Warn if the previous request hasn't been read.
if (previous_request != SERVER::MAINTENANCE_NO_CHANGE)
{
MXS_WARNING(WRN_REQUEST_OVERWRITTEN);
}
// Also set a flag so the next loop happens sooner.
atomic_store_int(&this->check_maintenance_flag, SERVER::MAINTENANCE_FLAG_CHECK);
}
else
{
// TODO: This should be set the same way the maintenance bit is set.
srv->set_status(bit);
written = true;
}
}
else
{
/* The monitor is not running, the bit can be set directly */
srv->set_status(bit);
written = true;
}
return written;
}
bool Monitor::clear_server_status(SERVER* srv, int bit, string* errmsg_out)
{
mxb_assert(is_monitored_server(this->monitored_servers, srv));
bool written = false;
if (this->state == MONITOR_STATE_RUNNING)
{
if (bit & ~(SERVER_MAINT | SERVER_BEING_DRAINED))
{
MXS_ERROR(ERR_CANNOT_MODIFY);
if (errmsg_out)
{
*errmsg_out = ERR_CANNOT_MODIFY;
}
}
else if (bit & SERVER_MAINT)
{
// Warn if the previous request hasn't been read.
int previous_request = atomic_exchange_int(&srv->maint_request, SERVER::MAINTENANCE_OFF);
written = true;
if (previous_request != SERVER::MAINTENANCE_NO_CHANGE)
{
MXS_WARNING(WRN_REQUEST_OVERWRITTEN);
}
atomic_store_int(&this->check_maintenance_flag, SERVER::MAINTENANCE_FLAG_CHECK);
}
else
{
// TODO: This should be set the same way the maintenance bit is set.
srv->clear_status(bit);
written = true;
}
}
else
{
/* The monitor is not running, the bit can be cleared directly */
srv->clear_status(bit);
written = true;
}
return written;
}
void monitor_debug_wait()
{
using namespace std::chrono;