mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Cleanup: manually port the polishing parts from Alik's changeset for
BUG#22306: STOP INSTANCE can not be applied for instances in Crashed, Failed and Abandoned mysql-test/t/im_options.imtest: Update test for new framework. server-tools/instance-manager/IMService.cpp: Use Manager class instead of manager(). Reformat comments. server-tools/instance-manager/Makefile.am: Treat warnings as errors. server-tools/instance-manager/command.cc: Store references to Guardian_thread and Instance_map in Command attributes. server-tools/instance-manager/command.h: Store references to Guardian_thread and Instance_map in Command attributes. server-tools/instance-manager/commands.cc: Remove Instance_map argument from command constructors. server-tools/instance-manager/commands.h: Remove Instance_map argument from command constructors. server-tools/instance-manager/guardian.cc: Rename: Guardian_thread -> Guardian server-tools/instance-manager/guardian.h: Rename: Guardian_thread -> Guardian server-tools/instance-manager/instance_map.cc: Rename: Guardian_thread -> Guardian. server-tools/instance-manager/instance_map.h: Rename: Guardian_thread -> Guardian. server-tools/instance-manager/manager.cc: Use Manager class instead of manager() function. server-tools/instance-manager/manager.h: Transfer manager() function into Manager class (singleton). server-tools/instance-manager/mysql_connection.cc: Polishing. server-tools/instance-manager/mysqlmanager.cc: Use Manager class instead of manager() function. server-tools/instance-manager/parse.cc: Rename: Guardian_thread -> Guardian server-tools/instance-manager/parse.h: Rename: Guardian_thread -> Guardian server-tools/instance-manager/priv.cc: Move create_pid_file() out of manager.cc. server-tools/instance-manager/priv.h: Move create_pid_file() out of manager.cc. server-tools/instance-manager/thread_registry.h: Prevent copying. server-tools/instance-manager/user_map.cc: Fix alignment.
This commit is contained in:
@ -32,33 +32,7 @@
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
--source include/im_check_os.inc
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Check starting conditions.
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# - check the configuration file;
|
||||
|
||||
--echo --------------------------------------------------------------------
|
||||
--exec grep '^server_id[^a-zA-Z0-9_-]' $MYSQLTEST_VARDIR/im.cnf ;
|
||||
--echo --------------------------------------------------------------------
|
||||
|
||||
# - check the running instances.
|
||||
|
||||
--connect (mysql1_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK)
|
||||
|
||||
--connection mysql1_con
|
||||
|
||||
SHOW VARIABLES LIKE 'server_id';
|
||||
|
||||
--connection default
|
||||
|
||||
# - check the internal cache.
|
||||
|
||||
SHOW INSTANCES;
|
||||
--source include/im_check_env.inc
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
|
@ -21,22 +21,22 @@ void IMService::Stop()
|
||||
{
|
||||
ReportStatus(SERVICE_STOP_PENDING);
|
||||
|
||||
// stop the IM work
|
||||
/* stop the IM work */
|
||||
raise(SIGTERM);
|
||||
}
|
||||
|
||||
void IMService::Run(DWORD argc, LPTSTR *argv)
|
||||
{
|
||||
// report to the SCM that we're about to start
|
||||
/* report to the SCM that we're about to start */
|
||||
ReportStatus((DWORD)SERVICE_START_PENDING);
|
||||
|
||||
Options::load(argc, argv);
|
||||
|
||||
// init goes here
|
||||
/* init goes here */
|
||||
ReportStatus((DWORD)SERVICE_RUNNING);
|
||||
|
||||
// wait for main loop to terminate
|
||||
manager();
|
||||
/* wait for main loop to terminate */
|
||||
(void) Manager::main();
|
||||
Options::cleanup();
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,8 @@ client_settings.h:
|
||||
|
||||
libexec_PROGRAMS= mysqlmanager
|
||||
|
||||
mysqlmanager_CXXFLAGS= -Werror
|
||||
|
||||
mysqlmanager_SOURCES= command.cc command.h mysqlmanager.cc \
|
||||
manager.h manager.cc log.h log.cc \
|
||||
thread_registry.h thread_registry.cc \
|
||||
|
@ -19,10 +19,12 @@
|
||||
#endif
|
||||
|
||||
#include "command.h"
|
||||
#include "manager.h"
|
||||
|
||||
|
||||
Command::Command(Instance_map *instance_map_arg)
|
||||
:instance_map(instance_map_arg)
|
||||
Command::Command()
|
||||
:guardian(Manager::get_guardian()),
|
||||
instance_map(Manager::get_instance_map())
|
||||
{}
|
||||
|
||||
Command::~Command()
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
/* Class responsible for allocation of IM commands. */
|
||||
|
||||
class Guardian;
|
||||
class Instance_map;
|
||||
|
||||
struct st_net;
|
||||
@ -36,7 +37,7 @@ struct st_net;
|
||||
class Command
|
||||
{
|
||||
public:
|
||||
Command(Instance_map *instance_map_arg= 0);
|
||||
Command();
|
||||
virtual ~Command();
|
||||
|
||||
/*
|
||||
@ -53,6 +54,7 @@ public:
|
||||
virtual int execute(st_net *net, ulong connection_id) = 0;
|
||||
|
||||
protected:
|
||||
Guardian *guardian;
|
||||
Instance_map *instance_map;
|
||||
};
|
||||
|
||||
|
@ -242,10 +242,8 @@ int Flush_instances::execute(st_net *net, ulong connection_id)
|
||||
Implementation of Abstract_instance_cmd.
|
||||
**************************************************************************/
|
||||
|
||||
Abstract_instance_cmd::Abstract_instance_cmd(
|
||||
Instance_map *instance_map_arg, const LEX_STRING *instance_name_arg)
|
||||
:Command(instance_map_arg),
|
||||
instance_name(instance_name_arg)
|
||||
Abstract_instance_cmd::Abstract_instance_cmd(const LEX_STRING *instance_name_arg)
|
||||
:instance_name(instance_name_arg)
|
||||
{
|
||||
/*
|
||||
MT-NOTE: we can not make a search for Instance object here,
|
||||
@ -285,9 +283,8 @@ int Abstract_instance_cmd::execute(st_net *net, ulong connection_id)
|
||||
Implementation of Show_instance_status.
|
||||
**************************************************************************/
|
||||
|
||||
Show_instance_status::Show_instance_status(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg)
|
||||
:Abstract_instance_cmd(instance_map_arg, instance_name_arg)
|
||||
Show_instance_status::Show_instance_status(const LEX_STRING *instance_name_arg)
|
||||
:Abstract_instance_cmd(instance_name_arg)
|
||||
{
|
||||
}
|
||||
|
||||
@ -406,8 +403,8 @@ int Show_instance_status::write_data(st_net *net, Instance *instance)
|
||||
**************************************************************************/
|
||||
|
||||
Show_instance_options::Show_instance_options(
|
||||
Instance_map *instance_map_arg, const LEX_STRING *instance_name_arg)
|
||||
:Abstract_instance_cmd(instance_map_arg, instance_name_arg)
|
||||
const LEX_STRING *instance_name_arg)
|
||||
:Abstract_instance_cmd(instance_name_arg)
|
||||
{
|
||||
}
|
||||
|
||||
@ -501,9 +498,8 @@ int Show_instance_options::write_data(st_net *net, Instance *instance)
|
||||
Implementation of Start_instance.
|
||||
**************************************************************************/
|
||||
|
||||
Start_instance::Start_instance(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg)
|
||||
:Abstract_instance_cmd(instance_map_arg, instance_name_arg)
|
||||
Start_instance::Start_instance(const LEX_STRING *instance_name_arg)
|
||||
:Abstract_instance_cmd(instance_name_arg)
|
||||
{
|
||||
}
|
||||
|
||||
@ -543,9 +539,8 @@ int Start_instance::send_ok_response(st_net *net, ulong connection_id)
|
||||
Implementation of Stop_instance.
|
||||
**************************************************************************/
|
||||
|
||||
Stop_instance::Stop_instance(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg)
|
||||
:Abstract_instance_cmd(instance_map_arg, instance_name_arg)
|
||||
Stop_instance::Stop_instance(const LEX_STRING *instance_name_arg)
|
||||
:Abstract_instance_cmd(instance_name_arg)
|
||||
{
|
||||
}
|
||||
|
||||
@ -585,10 +580,8 @@ int Stop_instance::send_ok_response(st_net *net, ulong connection_id)
|
||||
Implementation for Create_instance.
|
||||
**************************************************************************/
|
||||
|
||||
Create_instance::Create_instance(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg)
|
||||
:Command(instance_map_arg),
|
||||
instance_name(instance_name_arg)
|
||||
Create_instance::Create_instance(const LEX_STRING *instance_name_arg)
|
||||
:instance_name(instance_name_arg)
|
||||
{
|
||||
}
|
||||
|
||||
@ -795,9 +788,8 @@ int Create_instance::execute(st_net *net, ulong connection_id)
|
||||
Implementation for Drop_instance.
|
||||
**************************************************************************/
|
||||
|
||||
Drop_instance::Drop_instance(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg)
|
||||
:Abstract_instance_cmd(instance_map_arg, instance_name_arg)
|
||||
Drop_instance::Drop_instance(const LEX_STRING *instance_name_arg)
|
||||
:Abstract_instance_cmd(instance_name_arg)
|
||||
{
|
||||
}
|
||||
|
||||
@ -863,11 +855,10 @@ int Drop_instance::send_ok_response(st_net *net, ulong connection_id)
|
||||
Implementation for Show_instance_log.
|
||||
**************************************************************************/
|
||||
|
||||
Show_instance_log::Show_instance_log(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg,
|
||||
Show_instance_log::Show_instance_log(const LEX_STRING *instance_name_arg,
|
||||
Log_type log_type_arg,
|
||||
uint size_arg, uint offset_arg)
|
||||
:Abstract_instance_cmd(instance_map_arg, instance_name_arg),
|
||||
:Abstract_instance_cmd(instance_name_arg),
|
||||
log_type(log_type_arg),
|
||||
size(size_arg),
|
||||
offset(offset_arg)
|
||||
@ -1013,9 +1004,8 @@ int Show_instance_log::write_data(st_net *net, Instance *instance)
|
||||
**************************************************************************/
|
||||
|
||||
Show_instance_log_files::Show_instance_log_files
|
||||
(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg)
|
||||
:Abstract_instance_cmd(instance_map_arg, instance_name_arg)
|
||||
(const LEX_STRING *instance_name_arg)
|
||||
:Abstract_instance_cmd(instance_name_arg)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1214,9 +1204,8 @@ C_MODE_END
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
Abstract_option_cmd::Abstract_option_cmd(Instance_map *instance_map_arg)
|
||||
:Command(instance_map_arg),
|
||||
initialized(FALSE)
|
||||
Abstract_option_cmd::Abstract_option_cmd()
|
||||
:initialized(FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1400,12 +1389,6 @@ int Abstract_option_cmd::execute_impl(st_net *net, ulong connection_id)
|
||||
Implementation of Set_option.
|
||||
**************************************************************************/
|
||||
|
||||
Set_option::Set_option(Instance_map *instance_map_arg)
|
||||
:Abstract_option_cmd(instance_map_arg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This operation parses SET options.
|
||||
|
||||
@ -1580,12 +1563,6 @@ int Set_option::process_option(Instance *instance, Named_value *option)
|
||||
Implementation of Unset_option.
|
||||
**************************************************************************/
|
||||
|
||||
Unset_option::Unset_option(Instance_map *instance_map_arg)
|
||||
:Abstract_option_cmd(instance_map_arg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This operation parses UNSET options.
|
||||
|
||||
|
@ -38,9 +38,6 @@
|
||||
class Show_instances : public Command
|
||||
{
|
||||
public:
|
||||
Show_instances(Instance_map *instance_map_arg): Command(instance_map_arg)
|
||||
{}
|
||||
|
||||
int execute(st_net *net, ulong connection_id);
|
||||
|
||||
private:
|
||||
@ -57,9 +54,6 @@ private:
|
||||
class Flush_instances : public Command
|
||||
{
|
||||
public:
|
||||
Flush_instances(Instance_map *instance_map_arg): Command(instance_map_arg)
|
||||
{}
|
||||
|
||||
int execute(st_net *net, ulong connection_id);
|
||||
};
|
||||
|
||||
@ -71,8 +65,7 @@ public:
|
||||
class Abstract_instance_cmd : public Command
|
||||
{
|
||||
public:
|
||||
Abstract_instance_cmd(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg);
|
||||
Abstract_instance_cmd(const LEX_STRING *instance_name_arg);
|
||||
|
||||
public:
|
||||
virtual int execute(st_net *net, ulong connection_id);
|
||||
@ -108,8 +101,7 @@ private:
|
||||
class Show_instance_status : public Abstract_instance_cmd
|
||||
{
|
||||
public:
|
||||
Show_instance_status(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg);
|
||||
Show_instance_status(const LEX_STRING *instance_name_arg);
|
||||
|
||||
protected:
|
||||
virtual int execute_impl(st_net *net, Instance *instance);
|
||||
@ -129,8 +121,7 @@ private:
|
||||
class Show_instance_options : public Abstract_instance_cmd
|
||||
{
|
||||
public:
|
||||
Show_instance_options(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg);
|
||||
Show_instance_options(const LEX_STRING *instance_name_arg);
|
||||
|
||||
protected:
|
||||
virtual int execute_impl(st_net *net, Instance *instance);
|
||||
@ -150,8 +141,7 @@ private:
|
||||
class Start_instance : public Abstract_instance_cmd
|
||||
{
|
||||
public:
|
||||
Start_instance(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg);
|
||||
Start_instance(const LEX_STRING *instance_name_arg);
|
||||
|
||||
protected:
|
||||
virtual int execute_impl(st_net *net, Instance *instance);
|
||||
@ -167,8 +157,7 @@ protected:
|
||||
class Stop_instance : public Abstract_instance_cmd
|
||||
{
|
||||
public:
|
||||
Stop_instance(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg);
|
||||
Stop_instance(const LEX_STRING *instance_name_arg);
|
||||
|
||||
protected:
|
||||
virtual int execute_impl(st_net *net, Instance *instance);
|
||||
@ -184,8 +173,7 @@ protected:
|
||||
class Create_instance : public Command
|
||||
{
|
||||
public:
|
||||
Create_instance(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg);
|
||||
Create_instance(const LEX_STRING *instance_name_arg);
|
||||
|
||||
public:
|
||||
bool init(const char **text);
|
||||
@ -220,8 +208,7 @@ private:
|
||||
class Drop_instance : public Abstract_instance_cmd
|
||||
{
|
||||
public:
|
||||
Drop_instance(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg);
|
||||
Drop_instance(const LEX_STRING *instance_name_arg);
|
||||
|
||||
protected:
|
||||
virtual int execute_impl(st_net *net, Instance *instance);
|
||||
@ -238,8 +225,7 @@ protected:
|
||||
class Show_instance_log : public Abstract_instance_cmd
|
||||
{
|
||||
public:
|
||||
Show_instance_log(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg,
|
||||
Show_instance_log(const LEX_STRING *instance_name_arg,
|
||||
Log_type log_type_arg, uint size_arg, uint offset_arg);
|
||||
|
||||
protected:
|
||||
@ -266,8 +252,7 @@ private:
|
||||
class Show_instance_log_files : public Abstract_instance_cmd
|
||||
{
|
||||
public:
|
||||
Show_instance_log_files(Instance_map *instance_map_arg,
|
||||
const LEX_STRING *instance_name_arg);
|
||||
Show_instance_log_files(const LEX_STRING *instance_name_arg);
|
||||
|
||||
protected:
|
||||
virtual int execute_impl(st_net *net, Instance *instance);
|
||||
@ -299,7 +284,7 @@ public:
|
||||
virtual int execute(st_net *net, ulong connection_id);
|
||||
|
||||
protected:
|
||||
Abstract_option_cmd(Instance_map *instance_map_arg);
|
||||
Abstract_option_cmd();
|
||||
|
||||
int correct_file(Instance *instance, Named_value *option, bool skip);
|
||||
|
||||
@ -326,9 +311,6 @@ private:
|
||||
|
||||
class Set_option : public Abstract_option_cmd
|
||||
{
|
||||
public:
|
||||
Set_option(Instance_map *instance_map_arg);
|
||||
|
||||
protected:
|
||||
virtual bool parse_args(const char **text);
|
||||
virtual int process_option(Instance *instance, Named_value *option);
|
||||
@ -342,9 +324,6 @@ protected:
|
||||
|
||||
class Unset_option: public Abstract_option_cmd
|
||||
{
|
||||
public:
|
||||
Unset_option(Instance_map *instance_map_arg);
|
||||
|
||||
protected:
|
||||
virtual bool parse_args(const char **text);
|
||||
virtual int process_option(Instance *instance, Named_value *option);
|
||||
@ -362,11 +341,6 @@ protected:
|
||||
|
||||
class Syntax_error : public Command
|
||||
{
|
||||
public:
|
||||
/* This is just to avoid compiler warning. */
|
||||
Syntax_error() :Command(NULL)
|
||||
{}
|
||||
|
||||
public:
|
||||
int execute(st_net *net, ulong connection_id);
|
||||
};
|
||||
|
@ -31,16 +31,16 @@
|
||||
#include "mysql_manager_error.h"
|
||||
|
||||
|
||||
pthread_handler_t guardian(void *arg)
|
||||
pthread_handler_t guardian_thread_func(void *arg)
|
||||
{
|
||||
Guardian_thread *guardian_thread= (Guardian_thread *) arg;
|
||||
guardian_thread->run();
|
||||
Guardian *guardian= (Guardian *) arg;
|
||||
guardian->run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
Guardian_thread::get_instance_state_name(enum_instance_state state)
|
||||
Guardian::get_instance_state_name(enum_instance_state state)
|
||||
{
|
||||
switch (state) {
|
||||
case NOT_STARTED:
|
||||
@ -69,10 +69,10 @@ Guardian_thread::get_instance_state_name(enum_instance_state state)
|
||||
}
|
||||
|
||||
|
||||
Guardian_thread::Guardian_thread(Thread_registry &thread_registry_arg,
|
||||
Guardian::Guardian(Thread_registry &thread_registry_arg,
|
||||
Instance_map *instance_map_arg,
|
||||
uint monitoring_interval_arg) :
|
||||
Guardian_thread_args(thread_registry_arg, instance_map_arg,
|
||||
Guardian_args(thread_registry_arg, instance_map_arg,
|
||||
monitoring_interval_arg),
|
||||
thread_info(pthread_self(), TRUE), guarded_instances(0)
|
||||
{
|
||||
@ -84,7 +84,7 @@ Guardian_thread::Guardian_thread(Thread_registry &thread_registry_arg,
|
||||
}
|
||||
|
||||
|
||||
Guardian_thread::~Guardian_thread()
|
||||
Guardian::~Guardian()
|
||||
{
|
||||
/* delay guardian destruction to the moment when no one needs it */
|
||||
pthread_mutex_lock(&LOCK_guardian);
|
||||
@ -95,7 +95,7 @@ Guardian_thread::~Guardian_thread()
|
||||
}
|
||||
|
||||
|
||||
void Guardian_thread::request_shutdown()
|
||||
void Guardian::request_shutdown()
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_guardian);
|
||||
/* stop instances or just clean up Guardian repository */
|
||||
@ -105,7 +105,7 @@ void Guardian_thread::request_shutdown()
|
||||
}
|
||||
|
||||
|
||||
void Guardian_thread::process_instance(Instance *instance,
|
||||
void Guardian::process_instance(Instance *instance,
|
||||
GUARD_NODE *current_node,
|
||||
LIST **guarded_instances,
|
||||
LIST *node)
|
||||
@ -244,7 +244,7 @@ void Guardian_thread::process_instance(Instance *instance,
|
||||
is fine go and sleep for some time.
|
||||
*/
|
||||
|
||||
void Guardian_thread::run()
|
||||
void Guardian::run()
|
||||
{
|
||||
Instance *instance;
|
||||
LIST *node;
|
||||
@ -292,7 +292,7 @@ void Guardian_thread::run()
|
||||
}
|
||||
|
||||
|
||||
int Guardian_thread::is_stopped()
|
||||
int Guardian::is_stopped()
|
||||
{
|
||||
int var;
|
||||
pthread_mutex_lock(&LOCK_guardian);
|
||||
@ -307,10 +307,10 @@ int Guardian_thread::is_stopped()
|
||||
add all of the instances, which don't have 'nonguarded' option specified.
|
||||
|
||||
SYNOPSYS
|
||||
Guardian_thread::init()
|
||||
Guardian::init()
|
||||
|
||||
NOTE: The operation should be invoked with the following locks acquired:
|
||||
- Guardian_thread;
|
||||
- Guardian;
|
||||
- Instance_map;
|
||||
|
||||
RETURN
|
||||
@ -318,7 +318,7 @@ int Guardian_thread::is_stopped()
|
||||
1 - error occured
|
||||
*/
|
||||
|
||||
int Guardian_thread::init()
|
||||
int Guardian::init()
|
||||
{
|
||||
Instance *instance;
|
||||
Instance_map::Iterator iterator(instance_map);
|
||||
@ -360,7 +360,7 @@ int Guardian_thread::init()
|
||||
1 - error occured
|
||||
*/
|
||||
|
||||
int Guardian_thread::guard(Instance *instance, bool nolock)
|
||||
int Guardian::guard(Instance *instance, bool nolock)
|
||||
{
|
||||
LIST *node;
|
||||
GUARD_NODE *content;
|
||||
@ -397,7 +397,7 @@ int Guardian_thread::guard(Instance *instance, bool nolock)
|
||||
a piece of the MEM_ROOT).
|
||||
*/
|
||||
|
||||
int Guardian_thread::stop_guard(Instance *instance)
|
||||
int Guardian::stop_guard(Instance *instance)
|
||||
{
|
||||
LIST *node;
|
||||
|
||||
@ -434,7 +434,7 @@ int Guardian_thread::stop_guard(Instance *instance)
|
||||
1 - error occured
|
||||
*/
|
||||
|
||||
int Guardian_thread::stop_instances()
|
||||
int Guardian::stop_instances()
|
||||
{
|
||||
LIST *node;
|
||||
node= guarded_instances;
|
||||
@ -462,19 +462,19 @@ int Guardian_thread::stop_instances()
|
||||
}
|
||||
|
||||
|
||||
void Guardian_thread::lock()
|
||||
void Guardian::lock()
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_guardian);
|
||||
}
|
||||
|
||||
|
||||
void Guardian_thread::unlock()
|
||||
void Guardian::unlock()
|
||||
{
|
||||
pthread_mutex_unlock(&LOCK_guardian);
|
||||
}
|
||||
|
||||
|
||||
LIST *Guardian_thread::find_instance_node(Instance *instance)
|
||||
LIST *Guardian::find_instance_node(Instance *instance)
|
||||
{
|
||||
LIST *node= guarded_instances;
|
||||
|
||||
@ -494,7 +494,7 @@ LIST *Guardian_thread::find_instance_node(Instance *instance)
|
||||
}
|
||||
|
||||
|
||||
bool Guardian_thread::is_active(Instance *instance)
|
||||
bool Guardian::is_active(Instance *instance)
|
||||
{
|
||||
bool guarded;
|
||||
|
||||
|
@ -31,15 +31,15 @@ class Instance_map;
|
||||
class Thread_registry;
|
||||
struct GUARD_NODE;
|
||||
|
||||
pthread_handler_t guardian(void *arg);
|
||||
pthread_handler_t guardian_thread_func(void *arg);
|
||||
|
||||
struct Guardian_thread_args
|
||||
struct Guardian_args
|
||||
{
|
||||
Thread_registry &thread_registry;
|
||||
Instance_map *instance_map;
|
||||
int monitoring_interval;
|
||||
|
||||
Guardian_thread_args(Thread_registry &thread_registry_arg,
|
||||
Guardian_args(Thread_registry &thread_registry_arg,
|
||||
Instance_map *instance_map_arg,
|
||||
uint monitoring_interval_arg) :
|
||||
thread_registry(thread_registry_arg),
|
||||
@ -54,7 +54,7 @@ struct Guardian_thread_args
|
||||
instances.
|
||||
*/
|
||||
|
||||
class Guardian_thread: public Guardian_thread_args
|
||||
class Guardian: public Guardian_args
|
||||
{
|
||||
public:
|
||||
/* states of an instance */
|
||||
@ -82,10 +82,10 @@ public:
|
||||
/* Return client state name. */
|
||||
static const char *get_instance_state_name(enum_instance_state state);
|
||||
|
||||
Guardian_thread(Thread_registry &thread_registry_arg,
|
||||
Guardian(Thread_registry &thread_registry_arg,
|
||||
Instance_map *instance_map_arg,
|
||||
uint monitoring_interval_arg);
|
||||
~Guardian_thread();
|
||||
~Guardian();
|
||||
/* Main funtion of the thread */
|
||||
void run();
|
||||
/* Initialize or refresh the list of guarded instances */
|
||||
@ -140,8 +140,8 @@ private:
|
||||
};
|
||||
|
||||
|
||||
inline Guardian_thread::enum_instance_state
|
||||
Guardian_thread::get_instance_state(LIST *instance_node)
|
||||
inline Guardian::enum_instance_state
|
||||
Guardian::get_instance_state(LIST *instance_node)
|
||||
{
|
||||
return ((GUARD_NODE *) instance_node->data)->state;
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ void Instance_map::unlock()
|
||||
FLUSH INSTANCES without prior stop of all running instances.
|
||||
|
||||
NOTE: The operation should be invoked with the following locks acquired:
|
||||
- Guardian_thread;
|
||||
- Guardian;
|
||||
- Instance_map;
|
||||
*/
|
||||
|
||||
@ -537,7 +537,7 @@ const char *Instance_map::get_instance_state_name(Instance *instance)
|
||||
{
|
||||
/* The instance is managed by Guardian: we can report precise state. */
|
||||
|
||||
return Guardian_thread::get_instance_state_name(
|
||||
return Guardian::get_instance_state_name(
|
||||
guardian->get_instance_state(instance_node));
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
class Guardian_thread;
|
||||
class Guardian;
|
||||
class Instance;
|
||||
class Named_value_arr;
|
||||
class Thread_registry;
|
||||
@ -115,13 +115,13 @@ public:
|
||||
MT-NOTE: the options must be called under acquired locks of the following
|
||||
objects:
|
||||
- Instance_map;
|
||||
- Guardian_thread;
|
||||
- Guardian;
|
||||
*/
|
||||
const char *get_instance_state_name(Instance *instance);
|
||||
|
||||
public:
|
||||
const char *mysqld_path;
|
||||
Guardian_thread *guardian;
|
||||
Guardian *guardian;
|
||||
|
||||
private:
|
||||
/* loads options from config files */
|
||||
|
@ -37,33 +37,6 @@
|
||||
#include "user_map.h"
|
||||
|
||||
|
||||
int create_pid_file(const char *pid_file_name, int pid)
|
||||
{
|
||||
FILE *pid_file;
|
||||
|
||||
if (!(pid_file= my_fopen(pid_file_name, O_WRONLY | O_CREAT | O_BINARY,
|
||||
MYF(0))))
|
||||
{
|
||||
log_error("Error: can not create pid file '%s': %s (errno: %d)",
|
||||
(const char *) pid_file_name,
|
||||
(const char *) strerror(errno),
|
||||
(int) errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fprintf(pid_file, "%d\n", (int) pid) <= 0)
|
||||
{
|
||||
log_error("Error: can not write to pid file '%s': %s (errno: %d)",
|
||||
(const char *) pid_file_name,
|
||||
(const char *) strerror(errno),
|
||||
(int) errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
my_fclose(pid_file, MYF(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef __WIN__
|
||||
void set_signals(sigset_t *mask)
|
||||
@ -120,7 +93,7 @@ int my_sigwait(const sigset_t *set, int *sig)
|
||||
#endif
|
||||
|
||||
|
||||
void stop_all(Guardian_thread *guardian, Thread_registry *registry)
|
||||
void stop_all(Guardian *guardian, Thread_registry *registry)
|
||||
{
|
||||
/*
|
||||
Let guardian thread know that it should break it's processing cycle,
|
||||
@ -133,6 +106,13 @@ void stop_all(Guardian_thread *guardian, Thread_registry *registry)
|
||||
registry->deliver_shutdown();
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Manager implementation
|
||||
***********************************************************************/
|
||||
|
||||
Guardian *Manager::p_guardian;
|
||||
Instance_map *Manager::p_instance_map;
|
||||
|
||||
/*
|
||||
manager - entry point to the main instance manager process: start
|
||||
listener thread, write pid file and enter into signal handling.
|
||||
@ -142,9 +122,10 @@ void stop_all(Guardian_thread *guardian, Thread_registry *registry)
|
||||
TODO: how about returning error status.
|
||||
*/
|
||||
|
||||
void manager()
|
||||
int Manager::main()
|
||||
{
|
||||
int err_code;
|
||||
int rc= 1;
|
||||
const char *err_msg;
|
||||
bool shutdown_complete= FALSE;
|
||||
|
||||
@ -158,21 +139,21 @@ void manager()
|
||||
User_map user_map;
|
||||
Instance_map instance_map(Options::Main::default_mysqld_path,
|
||||
thread_registry);
|
||||
Guardian_thread guardian_thread(thread_registry,
|
||||
&instance_map,
|
||||
Guardian guardian(thread_registry, &instance_map,
|
||||
Options::Main::monitoring_interval);
|
||||
|
||||
Listener_thread_args listener_args(thread_registry, user_map, instance_map);
|
||||
|
||||
manager_pid= getpid();
|
||||
instance_map.guardian= &guardian_thread;
|
||||
p_instance_map= &instance_map;
|
||||
p_guardian= instance_map.guardian= &guardian;
|
||||
|
||||
/* Initialize instance map. */
|
||||
|
||||
if (instance_map.init())
|
||||
{
|
||||
log_error("Error: can not initialize instance list: out of memory.");
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Initialize user map and load password file. */
|
||||
@ -180,7 +161,7 @@ void manager()
|
||||
if (user_map.init())
|
||||
{
|
||||
log_error("Error: can not initialize user list: out of memory.");
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((err_code= user_map.load(Options::Main::password_file_name, &err_msg)))
|
||||
@ -199,7 +180,7 @@ void manager()
|
||||
else
|
||||
{
|
||||
log_error("Error: %s.", (const char *) err_msg);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,7 +191,7 @@ void manager()
|
||||
(int) manager_pid);
|
||||
|
||||
if (create_pid_file(Options::Main::pid_file_name, manager_pid))
|
||||
return; /* necessary logging has been already done. */
|
||||
return 1; /* necessary logging has been already done. */
|
||||
|
||||
/*
|
||||
Initialize signals and alarm-infrastructure.
|
||||
@ -253,7 +234,7 @@ void manager()
|
||||
pthread_attr_init(&guardian_thd_attr);
|
||||
pthread_attr_setdetachstate(&guardian_thd_attr, PTHREAD_CREATE_DETACHED);
|
||||
rc= set_stacksize_n_create_thread(&guardian_thd_id, &guardian_thd_attr,
|
||||
guardian, &guardian_thread);
|
||||
guardian_thread_func, &guardian);
|
||||
pthread_attr_destroy(&guardian_thd_attr);
|
||||
if (rc)
|
||||
{
|
||||
@ -279,7 +260,7 @@ void manager()
|
||||
log_error("Cannot init instances repository. This might be caused by "
|
||||
"the wrong config file options. For instance, missing mysqld "
|
||||
"binary. Aborting.");
|
||||
stop_all(&guardian_thread, &thread_registry);
|
||||
stop_all(&guardian, &thread_registry);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
@ -298,7 +279,7 @@ void manager()
|
||||
if (rc)
|
||||
{
|
||||
log_error("manager(): set_stacksize_n_create_thread(listener) failed");
|
||||
stop_all(&guardian_thread, &thread_registry);
|
||||
stop_all(&guardian, &thread_registry);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
@ -307,7 +288,7 @@ void manager()
|
||||
After the list of guarded instances have been initialized,
|
||||
Guardian should start them.
|
||||
*/
|
||||
pthread_cond_signal(&guardian_thread.COND_guardian);
|
||||
pthread_cond_signal(&guardian.COND_guardian);
|
||||
|
||||
log_info("Main loop: started.");
|
||||
|
||||
@ -319,7 +300,7 @@ void manager()
|
||||
if ((status= my_sigwait(&mask, &signo)) != 0)
|
||||
{
|
||||
log_error("sigwait() failed");
|
||||
stop_all(&guardian_thread, &thread_registry);
|
||||
stop_all(&guardian, &thread_registry);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -328,8 +309,8 @@ void manager()
|
||||
- we are waiting for SIGINT, SIGTERM -- signals that mean we should
|
||||
shutdown;
|
||||
- as shutdown signal is caught, we stop Guardian thread (by calling
|
||||
Guardian_thread::request_shutdown());
|
||||
- as Guardian_thread is stopped, it sends SIGTERM to this thread
|
||||
Guardian::request_shutdown());
|
||||
- as Guardian is stopped, it sends SIGTERM to this thread
|
||||
(by calling Thread_registry::request_shutdown()), so that the
|
||||
my_sigwait() above returns;
|
||||
- as we catch the second SIGTERM, we send signals to all threads
|
||||
@ -355,10 +336,10 @@ void manager()
|
||||
{
|
||||
log_info("Main loop: got shutdown signal.");
|
||||
|
||||
if (!guardian_thread.is_stopped())
|
||||
if (!guardian.is_stopped())
|
||||
{
|
||||
guardian_thread.request_shutdown();
|
||||
pthread_cond_signal(&guardian_thread.COND_guardian);
|
||||
guardian.request_shutdown();
|
||||
pthread_cond_signal(&guardian.COND_guardian);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -370,6 +351,8 @@ void manager()
|
||||
|
||||
log_info("Main loop: finished.");
|
||||
|
||||
rc= 0;
|
||||
|
||||
err:
|
||||
/* delete the pid file */
|
||||
my_delete(Options::Main::pid_file_name, MYF(0));
|
||||
@ -379,4 +362,5 @@ err:
|
||||
end_thr_alarm(1);
|
||||
/* don't pthread_exit to kill all threads who did not shut down in time */
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
@ -16,8 +16,29 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
void manager();
|
||||
#if defined(__GNUC__) && defined(USE_PRAGMA_INTERFACE)
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
int create_pid_file(const char *pid_file_name, int pid);
|
||||
class Guardian;
|
||||
class Instance_map;
|
||||
|
||||
class Manager
|
||||
{
|
||||
public:
|
||||
static int main();
|
||||
/**
|
||||
These methods return a non-zero value only for the duration
|
||||
of main().
|
||||
*/
|
||||
static Instance_map *get_instance_map() { return p_instance_map; }
|
||||
static Guardian *get_guardian() { return p_guardian; }
|
||||
|
||||
private:
|
||||
static int manager_impl();
|
||||
private:
|
||||
static Guardian *p_guardian;
|
||||
static Instance_map *p_instance_map;
|
||||
};
|
||||
|
||||
#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_MANAGER_H
|
||||
|
@ -315,7 +315,7 @@ int Mysql_connection_thread::do_command()
|
||||
packet= (char*) net.read_pos;
|
||||
enum enum_server_command command= (enum enum_server_command)
|
||||
(uchar) *packet;
|
||||
log_info("connection %lu: packet_length=%lu, command=%d",
|
||||
log_info("connection %d: packet_length=%d, command=%d",
|
||||
(int) connection_id, (int) packet_length, (int) command);
|
||||
return dispatch_command(command, packet + 1, packet_length - 1);
|
||||
}
|
||||
@ -336,10 +336,10 @@ int Mysql_connection_thread::dispatch_command(enum enum_server_command command,
|
||||
break;
|
||||
case COM_QUERY:
|
||||
{
|
||||
log_info("query for connection %lu : ----\n%s\n-------------------------",
|
||||
log_info("query for connection %d : ----\n%s\n-------------------------",
|
||||
(int) connection_id,
|
||||
(const char *) packet);
|
||||
if (Command *command= parse_command(&instance_map, packet))
|
||||
if (Command *command= parse_command(packet))
|
||||
{
|
||||
int res= 0;
|
||||
log_info("query for connection %lu successfully parsed",
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "log.h"
|
||||
#include "manager.h"
|
||||
#include "options.h"
|
||||
#include "priv.h"
|
||||
#include "user_management_commands.h"
|
||||
|
||||
#ifdef __WIN__
|
||||
@ -117,7 +118,7 @@ int main(int argc, char *argv[])
|
||||
angel();
|
||||
}
|
||||
|
||||
manager();
|
||||
(void) Manager::main(); /* ignore the return value for now */
|
||||
|
||||
#else
|
||||
|
||||
@ -131,7 +132,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
else
|
||||
{
|
||||
manager();
|
||||
(void) Manager::main(); /* ignore the return value for now */
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -384,8 +385,8 @@ spawn:
|
||||
}
|
||||
/*
|
||||
mysqlmanager successfully exited, let's silently evaporate
|
||||
If we return to main we fall into the manager() function, so let's
|
||||
simply exit().
|
||||
If we return to main we will fall into the manager functionality,
|
||||
so let's simply exit().
|
||||
*/
|
||||
exit(0);
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ void skip_spaces(const char **text)
|
||||
}
|
||||
|
||||
|
||||
Command *parse_command(Instance_map *map, const char *text)
|
||||
Command *parse_command(const char *text)
|
||||
{
|
||||
uint word_len;
|
||||
LEX_STRING instance_name;
|
||||
@ -294,7 +294,7 @@ Command *parse_command(Instance_map *map, const char *text)
|
||||
|
||||
if (tok1 == TOK_CREATE)
|
||||
{
|
||||
Create_instance *cmd= new Create_instance(map, &instance_name);
|
||||
Create_instance *cmd= new Create_instance(&instance_name);
|
||||
|
||||
if (!cmd)
|
||||
return NULL; /* Report ER_OUT_OF_RESOURCES. */
|
||||
@ -317,16 +317,16 @@ Command *parse_command(Instance_map *map, const char *text)
|
||||
|
||||
switch (tok1) {
|
||||
case TOK_START:
|
||||
command= new Start_instance(map, &instance_name);
|
||||
command= new Start_instance(&instance_name);
|
||||
break;
|
||||
case TOK_STOP:
|
||||
command= new Stop_instance(map, &instance_name);
|
||||
command= new Stop_instance(&instance_name);
|
||||
break;
|
||||
case TOK_CREATE:
|
||||
; /* command already initialized. */
|
||||
break;
|
||||
case TOK_DROP:
|
||||
command= new Drop_instance(map, &instance_name);
|
||||
command= new Drop_instance(&instance_name);
|
||||
break;
|
||||
default: /* this is impossible, but nevertheless... */
|
||||
DBUG_ASSERT(0);
|
||||
@ -340,7 +340,7 @@ Command *parse_command(Instance_map *map, const char *text)
|
||||
if (word_len)
|
||||
goto syntax_error;
|
||||
|
||||
command= new Flush_instances(map);
|
||||
command= new Flush_instances();
|
||||
break;
|
||||
case TOK_UNSET:
|
||||
case TOK_SET:
|
||||
@ -348,9 +348,9 @@ Command *parse_command(Instance_map *map, const char *text)
|
||||
Abstract_option_cmd *cmd;
|
||||
|
||||
if (tok1 == TOK_SET)
|
||||
cmd= new Set_option(map);
|
||||
cmd= new Set_option();
|
||||
else
|
||||
cmd= new Unset_option(map);
|
||||
cmd= new Unset_option();
|
||||
|
||||
if (!cmd)
|
||||
return NULL; /* Report ER_OUT_OF_RESOURCES. */
|
||||
@ -371,7 +371,7 @@ Command *parse_command(Instance_map *map, const char *text)
|
||||
get_word(&text, &word_len, NONSPACE);
|
||||
if (word_len)
|
||||
goto syntax_error;
|
||||
command= new Show_instances(map);
|
||||
command= new Show_instances();
|
||||
break;
|
||||
case TOK_INSTANCE:
|
||||
switch (Token tok2= shift_token(&text, &word_len)) {
|
||||
@ -385,9 +385,9 @@ Command *parse_command(Instance_map *map, const char *text)
|
||||
if (word_len)
|
||||
goto syntax_error;
|
||||
if (tok2 == TOK_STATUS)
|
||||
command= new Show_instance_status(map, &instance_name);
|
||||
command= new Show_instance_status(&instance_name);
|
||||
else
|
||||
command= new Show_instance_options(map, &instance_name);
|
||||
command= new Show_instance_options(&instance_name);
|
||||
break;
|
||||
default:
|
||||
goto syntax_error;
|
||||
@ -414,7 +414,7 @@ Command *parse_command(Instance_map *map, const char *text)
|
||||
/* check that this is the end of the command */
|
||||
if (word_len)
|
||||
goto syntax_error;
|
||||
command= new Show_instance_log_files(map, &instance_name);
|
||||
command= new Show_instance_log_files(&instance_name);
|
||||
break;
|
||||
case TOK_ERROR:
|
||||
case TOK_GENERAL:
|
||||
@ -484,7 +484,7 @@ Command *parse_command(Instance_map *map, const char *text)
|
||||
goto syntax_error;
|
||||
}
|
||||
|
||||
command= new Show_instance_log(map, &instance_name,
|
||||
command= new Show_instance_log(&instance_name,
|
||||
log_type, log_size, log_offset);
|
||||
break;
|
||||
default:
|
||||
@ -504,5 +504,8 @@ Command *parse_command(Instance_map *map, const char *text)
|
||||
syntax_error:
|
||||
command= new Syntax_error();
|
||||
}
|
||||
|
||||
DBUG_ASSERT(command);
|
||||
|
||||
return command;
|
||||
}
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include <m_string.h>
|
||||
|
||||
class Command;
|
||||
class Instance_map;
|
||||
|
||||
enum Log_type
|
||||
{
|
||||
@ -30,7 +29,7 @@ enum Log_type
|
||||
IM_LOG_SLOW
|
||||
};
|
||||
|
||||
Command *parse_command(Instance_map *map, const char *text);
|
||||
Command *parse_command(const char *text);
|
||||
|
||||
bool parse_option_value(const char *text, uint *text_len, char **value);
|
||||
|
||||
|
@ -18,6 +18,9 @@
|
||||
|
||||
#include <my_global.h>
|
||||
#include <mysql_com.h>
|
||||
#include <my_sys.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#if defined(__ia64__) || defined(__ia64)
|
||||
/*
|
||||
@ -90,3 +93,32 @@ int set_stacksize_n_create_thread(pthread_t *thread, pthread_attr_t *attr,
|
||||
rc= pthread_create(thread, attr, start_routine, arg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int create_pid_file(const char *pid_file_name, int pid)
|
||||
{
|
||||
FILE *pid_file;
|
||||
|
||||
if (!(pid_file= my_fopen(pid_file_name, O_WRONLY | O_CREAT | O_BINARY,
|
||||
MYF(0))))
|
||||
{
|
||||
log_error("Error: can not create pid file '%s': %s (errno: %d)",
|
||||
(const char *) pid_file_name,
|
||||
(const char *) strerror(errno),
|
||||
(int) errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fprintf(pid_file, "%d\n", (int) pid) <= 0)
|
||||
{
|
||||
log_error("Error: can not write to pid file '%s': %s (errno: %d)",
|
||||
(const char *) pid_file_name,
|
||||
(const char *) strerror(errno),
|
||||
(int) errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
my_fclose(pid_file, MYF(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -109,4 +109,6 @@ extern unsigned long open_files_limit;
|
||||
int set_stacksize_n_create_thread(pthread_t *thread, pthread_attr_t *attr,
|
||||
void *(*start_routine)(void *), void *arg);
|
||||
|
||||
int create_pid_file(const char *pid_file_name, int pid);
|
||||
|
||||
#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_PRIV_H
|
||||
|
@ -101,6 +101,7 @@ public:
|
||||
pthread_mutex_t *mutex);
|
||||
int cond_timedwait(Thread_info *info, pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex, struct timespec *wait_time);
|
||||
|
||||
private:
|
||||
void interrupt_threads();
|
||||
void wait_for_threads_to_unregister();
|
||||
@ -111,6 +112,10 @@ private:
|
||||
pthread_mutex_t LOCK_thread_registry;
|
||||
pthread_cond_t COND_thread_registry_is_empty;
|
||||
pthread_t sigwait_thread_pid;
|
||||
|
||||
private:
|
||||
Thread_registry(const Thread_registry &);
|
||||
Thread_registry &operator =(const Thread_registry &);
|
||||
};
|
||||
|
||||
|
||||
|
@ -74,7 +74,8 @@ int User::init(const char *line)
|
||||
password_length= strlen(password);
|
||||
if (password_length > SCRAMBLED_PASSWORD_CHAR_LENGTH)
|
||||
{
|
||||
log_info("Error: password is too long (%d). Max length: %d. User line: '%s'.",
|
||||
log_info("Error: password is too long (%d). Max length: %d."
|
||||
"User line: '%s'.",
|
||||
(int) password_length,
|
||||
(int) SCRAMBLED_PASSWORD_CHAR_LENGTH,
|
||||
line);
|
||||
|
Reference in New Issue
Block a user