Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
6b50b5b0
Commit
6b50b5b0
authored
Feb 11, 2005
by
petr@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Post-review fixes + some bugs fixed + several minor features
parent
0eddb07f
Changes
21
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
591 additions
and
374 deletions
+591
-374
server-tools/instance-manager/Makefile.am
server-tools/instance-manager/Makefile.am
+1
-1
server-tools/instance-manager/buffer.cc
server-tools/instance-manager/buffer.cc
+14
-2
server-tools/instance-manager/buffer.h
server-tools/instance-manager/buffer.h
+11
-3
server-tools/instance-manager/client_func.c
server-tools/instance-manager/client_func.c
+0
-32
server-tools/instance-manager/commands.cc
server-tools/instance-manager/commands.cc
+8
-4
server-tools/instance-manager/guardian.cc
server-tools/instance-manager/guardian.cc
+215
-102
server-tools/instance-manager/guardian.h
server-tools/instance-manager/guardian.h
+23
-26
server-tools/instance-manager/instance.cc
server-tools/instance-manager/instance.cc
+134
-56
server-tools/instance-manager/instance.h
server-tools/instance-manager/instance.h
+8
-1
server-tools/instance-manager/instance_map.cc
server-tools/instance-manager/instance_map.cc
+0
-20
server-tools/instance-manager/instance_map.h
server-tools/instance-manager/instance_map.h
+0
-8
server-tools/instance-manager/instance_options.cc
server-tools/instance-manager/instance_options.cc
+51
-40
server-tools/instance-manager/instance_options.h
server-tools/instance-manager/instance_options.h
+5
-3
server-tools/instance-manager/listener.cc
server-tools/instance-manager/listener.cc
+4
-0
server-tools/instance-manager/manager.cc
server-tools/instance-manager/manager.cc
+8
-18
server-tools/instance-manager/options.cc
server-tools/instance-manager/options.cc
+36
-1
server-tools/instance-manager/parse.cc
server-tools/instance-manager/parse.cc
+0
-23
server-tools/instance-manager/parse.h
server-tools/instance-manager/parse.h
+30
-0
server-tools/instance-manager/parse_output.cc
server-tools/instance-manager/parse_output.cc
+40
-32
server-tools/instance-manager/protocol.cc
server-tools/instance-manager/protocol.cc
+2
-1
server-tools/instance-manager/user_map.cc
server-tools/instance-manager/user_map.cc
+1
-1
No files found.
server-tools/instance-manager/Makefile.am
View file @
6b50b5b0
...
@@ -74,7 +74,7 @@ mysqlmanager_SOURCES= command.cc command.h mysqlmanager.cc \
...
@@ -74,7 +74,7 @@ mysqlmanager_SOURCES= command.cc command.h mysqlmanager.cc \
buffer.h buffer.cc parse.cc parse.h
\
buffer.h buffer.cc parse.cc parse.h
\
guardian.cc guardian.h
\
guardian.cc guardian.h
\
parse_output.cc parse_output.h
\
parse_output.cc parse_output.h
\
mysql_manager_error.h
client_func.c
mysql_manager_error.h
mysqlmanager_LDADD
=
liboptions.a
\
mysqlmanager_LDADD
=
liboptions.a
\
libnet.a
\
libnet.a
\
...
...
server-tools/instance-manager/buffer.cc
View file @
6b50b5b0
...
@@ -40,7 +40,7 @@
...
@@ -40,7 +40,7 @@
RETURN
RETURN
0 - ok
0 - ok
1 -
The buffer came to 16Mb barrier
1 -
got an error in reserve()
*/
*/
int
Buffer
::
append
(
uint
position
,
const
char
*
string
,
uint
len_arg
)
int
Buffer
::
append
(
uint
position
,
const
char
*
string
,
uint
len_arg
)
...
@@ -71,7 +71,7 @@ int Buffer::append(uint position, const char *string, uint len_arg)
...
@@ -71,7 +71,7 @@ int Buffer::append(uint position, const char *string, uint len_arg)
RETURN
RETURN
0 - ok
0 - ok
1 -
The buffer came to
16Mb barrier
1 -
realloc error or we have come to the
16Mb barrier
*/
*/
int
Buffer
::
reserve
(
uint
position
,
uint
len_arg
)
int
Buffer
::
reserve
(
uint
position
,
uint
len_arg
)
...
@@ -92,6 +92,18 @@ int Buffer::reserve(uint position, uint len_arg)
...
@@ -92,6 +92,18 @@ int Buffer::reserve(uint position, uint len_arg)
return
0
;
return
0
;
err:
err:
error
=
1
;
return
1
;
return
1
;
}
}
int
Buffer
::
get_size
()
{
return
buffer_size
;
}
int
Buffer
::
is_error
()
{
return
error
;
}
server-tools/instance-manager/buffer.h
View file @
6b50b5b0
...
@@ -36,11 +36,17 @@ class Buffer
...
@@ -36,11 +36,17 @@ class Buffer
/* maximum buffer size is 16Mb */
/* maximum buffer size is 16Mb */
enum
{
MAX_BUFFER_SIZE
=
16777216
};
enum
{
MAX_BUFFER_SIZE
=
16777216
};
size_t
buffer_size
;
size_t
buffer_size
;
/* Error flag. Triggered if we get an error of some kind */
int
error
;
public:
public:
Buffer
()
Buffer
(
size_t
buffer_size_arg
=
BUFFER_INITIAL_SIZE
)
:
buffer_size
(
BUFFER_INITIAL_SIZE
),
error
(
0
)
{
{
buffer
=
(
char
*
)
malloc
(
BUFFER_INITIAL_SIZE
);
/*
buffer_size
=
BUFFER_INITIAL_SIZE
;
As append() will invokes realloc() anyway, it's ok if malloc returns 0
*/
if
(
!
(
buffer
=
(
char
*
)
malloc
(
buffer_size
)))
buffer_size
=
0
;
}
}
~
Buffer
()
~
Buffer
()
...
@@ -50,6 +56,8 @@ class Buffer
...
@@ -50,6 +56,8 @@ class Buffer
public:
public:
char
*
buffer
;
char
*
buffer
;
int
get_size
();
int
is_error
();
int
append
(
uint
position
,
const
char
*
string
,
uint
len_arg
);
int
append
(
uint
position
,
const
char
*
string
,
uint
len_arg
);
int
reserve
(
uint
position
,
uint
len_arg
);
int
reserve
(
uint
position
,
uint
len_arg
);
};
};
...
...
server-tools/instance-manager/client_func.c
deleted
100644 → 0
View file @
0eddb07f
#include <my_global.h>
#include <my_sys.h>
#include <mysql.h>
/*
Currently we cannot use libmysqlclient directly because of the linking
issues. Here we provide needed libmysqlclient functions.
TODO: to think how to use libmysqlclient code instead of copy&paste.
The other possible solution is to use simple_command directly.
*/
const
char
*
STDCALL
mysql_get_server_info
(
MYSQL
*
mysql
)
{
return
((
char
*
)
mysql
->
server_version
);
}
int
STDCALL
mysql_ping
(
MYSQL
*
mysql
)
{
DBUG_ENTER
(
"mysql_ping"
);
DBUG_RETURN
(
simple_command
(
mysql
,
COM_PING
,
0
,
0
,
0
));
}
int
STDCALL
mysql_shutdown
(
MYSQL
*
mysql
,
enum
mysql_enum_shutdown_level
shutdown_level
)
{
uchar
level
[
1
];
DBUG_ENTER
(
"mysql_shutdown"
);
level
[
0
]
=
(
uchar
)
shutdown_level
;
DBUG_RETURN
(
simple_command
(
mysql
,
COM_SHUTDOWN
,
(
char
*
)
level
,
1
,
0
));
}
server-tools/instance-manager/commands.cc
View file @
6b50b5b0
...
@@ -184,7 +184,8 @@ int Show_instance_status::do_command(struct st_net *net,
...
@@ -184,7 +184,8 @@ int Show_instance_status::do_command(struct st_net *net,
}
}
if
(
my_net_write
(
net
,
send_buff
.
buffer
,
(
uint
)
position
))
if
(
my_net_write
(
net
,
send_buff
.
buffer
,
(
uint
)
position
)
||
send_buff
.
is_error
())
goto
err
;
goto
err
;
}
}
...
@@ -270,7 +271,8 @@ int Show_instance_options::do_command(struct st_net *net,
...
@@ -270,7 +271,8 @@ int Show_instance_options::do_command(struct st_net *net,
store_to_string
(
&
send_buff
,
store_to_string
(
&
send_buff
,
(
char
*
)
instance
->
options
.
mysqld_path
,
(
char
*
)
instance
->
options
.
mysqld_path
,
&
position
);
&
position
);
if
(
my_net_write
(
net
,
send_buff
.
buffer
,
(
uint
)
position
))
if
(
my_net_write
(
net
,
send_buff
.
buffer
,
(
uint
)
position
)
||
send_buff
.
is_error
())
goto
err
;
goto
err
;
}
}
...
@@ -279,7 +281,8 @@ int Show_instance_options::do_command(struct st_net *net,
...
@@ -279,7 +281,8 @@ int Show_instance_options::do_command(struct st_net *net,
position
=
0
;
position
=
0
;
store_to_string
(
&
send_buff
,
(
char
*
)
"nonguarded"
,
&
position
);
store_to_string
(
&
send_buff
,
(
char
*
)
"nonguarded"
,
&
position
);
store_to_string
(
&
send_buff
,
""
,
&
position
);
store_to_string
(
&
send_buff
,
""
,
&
position
);
if
(
my_net_write
(
net
,
send_buff
.
buffer
,
(
uint
)
position
))
if
(
my_net_write
(
net
,
send_buff
.
buffer
,
(
uint
)
position
)
||
send_buff
.
is_error
())
goto
err
;
goto
err
;
}
}
...
@@ -296,7 +299,8 @@ int Show_instance_options::do_command(struct st_net *net,
...
@@ -296,7 +299,8 @@ int Show_instance_options::do_command(struct st_net *net,
store_to_string
(
&
send_buff
,
option_value
+
1
,
&
position
);
store_to_string
(
&
send_buff
,
option_value
+
1
,
&
position
);
/* join name and the value into the same option again */
/* join name and the value into the same option again */
*
option_value
=
'='
;
*
option_value
=
'='
;
if
(
my_net_write
(
net
,
send_buff
.
buffer
,
(
uint
)
position
))
if
(
my_net_write
(
net
,
send_buff
.
buffer
,
(
uint
)
position
)
||
send_buff
.
is_error
())
goto
err
;
goto
err
;
}
}
}
}
...
...
server-tools/instance-manager/guardian.cc
View file @
6b50b5b0
This diff is collapsed.
Click to expand it.
server-tools/instance-manager/guardian.h
View file @
6b50b5b0
...
@@ -19,6 +19,7 @@
...
@@ -19,6 +19,7 @@
#include <my_global.h>
#include <my_global.h>
#include <my_sys.h>
#include <my_sys.h>
#include <my_list.h>
#include <my_list.h>
#include "thread_registry.h"
#ifdef __GNUC__
#ifdef __GNUC__
#pragma interface
#pragma interface
...
@@ -26,9 +27,8 @@
...
@@ -26,9 +27,8 @@
class
Instance
;
class
Instance
;
class
Instance_map
;
class
Instance_map
;
class
Thread_registry
;
#include "thread_registry.h"
struct
GUARD_NODE
;
#include "instance.h"
C_MODE_START
C_MODE_START
...
@@ -36,19 +36,11 @@ pthread_handler_decl(guardian, arg);
...
@@ -36,19 +36,11 @@ pthread_handler_decl(guardian, arg);
C_MODE_END
C_MODE_END
typedef
struct
st_guard_node
{
Instance
*
instance
;
uint
restart_counter
;
time_t
crash_moment
;
}
GUARD_NODE
;
struct
Guardian_thread_args
struct
Guardian_thread_args
{
{
Thread_registry
&
thread_registry
;
Thread_registry
&
thread_registry
;
Instance_map
*
instance_map
;
Instance_map
*
instance_map
;
u
int
monitoring_interval
;
int
monitoring_interval
;
Guardian_thread_args
(
Thread_registry
&
thread_registry_arg
,
Guardian_thread_args
(
Thread_registry
&
thread_registry_arg
,
Instance_map
*
instance_map_arg
,
Instance_map
*
instance_map_arg
,
...
@@ -72,36 +64,41 @@ class Guardian_thread: public Guardian_thread_args
...
@@ -72,36 +64,41 @@ class Guardian_thread: public Guardian_thread_args
Instance_map
*
instance_map_arg
,
Instance_map
*
instance_map_arg
,
uint
monitoring_interval_arg
);
uint
monitoring_interval_arg
);
~
Guardian_thread
();
~
Guardian_thread
();
/* Main funtion of the thread */
void
run
();
void
run
();
int
start
();
/* Initialize list of guarded instances */
void
shutdown
();
int
init
();
void
request_stop_instances
();
/* Request guardian shutdown. Stop instances if needed */
void
request_shutdown
(
bool
stop_instances
);
/* Start instance protection */
int
guard
(
Instance
*
instance
);
int
guard
(
Instance
*
instance
);
/* Stop instance protection */
int
stop_guard
(
Instance
*
instance
);
int
stop_guard
(
Instance
*
instance
);
bool
is_stopped
;
/* Returns true if guardian thread is stopped */
int
is_stopped
();
public:
public:
pthread_cond_t
COND_guardian
;
pthread_cond_t
COND_guardian
;
private:
private:
int
stop_instances
();
/* Prepares Guardian shutdown. Stops instances is needed */
int
add_instance_to_list
(
Instance
*
instance
,
LIST
**
list
);
int
stop_instances
(
bool
stop_instances_arg
);
void
move_to_list
(
LIST
**
from
,
LIST
**
to
);
/* check instance state and act accordingly */
void
process_instance
(
Instance
*
instance
,
GUARD_NODE
*
current_node
,
LIST
**
guarded_instances
,
LIST
*
elem
);
int
stopped
;
private:
private:
/* states of an instance */
enum
{
NOT_STARTED
=
1
,
STARTING
,
STARTED
,
JUST_CRASHED
,
CRASHED
,
CRASHED_AND_ABANDONED
,
STOPPING
};
pthread_mutex_t
LOCK_guardian
;
pthread_mutex_t
LOCK_guardian
;
Thread_info
thread_info
;
Thread_info
thread_info
;
LIST
*
guarded_instances
;
LIST
*
guarded_instances
;
LIST
*
starting_instances
;
MEM_ROOT
alloc
;
MEM_ROOT
alloc
;
enum
{
MEM_ROOT_BLOCK_SIZE
=
512
};
enum
{
MEM_ROOT_BLOCK_SIZE
=
512
};
/* this variable is set to TRUE when we want to stop Guardian thread */
/* this variable is set to TRUE when we want to stop Guardian thread */
bool
shutdown_guardian
;
bool
shutdown_requested
;
/*
This var is usually set together with shutdown_guardian. this way we
request guardian to shut down all instances before termination
*/
bool
request_stop
;
};
};
#endif
/* INCLUDES_MYSQL_INSTANCE_MANAGER_GUARDIAN_H */
#endif
/* INCLUDES_MYSQL_INSTANCE_MANAGER_GUARDIAN_H */
server-tools/instance-manager/instance.cc
View file @
6b50b5b0
...
@@ -27,6 +27,19 @@
...
@@ -27,6 +27,19 @@
#include <m_string.h>
#include <m_string.h>
#include <sys/wait.h>
#include <sys/wait.h>
C_MODE_START
pthread_handler_decl
(
proxy
,
arg
)
{
Instance
*
instance
=
(
Instance
*
)
arg
;
instance
->
fork_and_monitor
();
return
0
;
}
C_MODE_END
/*
/*
The method starts an instance.
The method starts an instance.
...
@@ -44,6 +57,12 @@ int Instance::start()
...
@@ -44,6 +57,12 @@ int Instance::start()
{
{
pid_t
pid
;
pid_t
pid
;
/* clear crash flag */
pthread_mutex_lock
(
&
LOCK_instance
);
crashed
=
0
;
pthread_mutex_unlock
(
&
LOCK_instance
);
if
(
!
is_running
())
if
(
!
is_running
())
{
{
if
((
pid
=
options
.
get_pid
())
!=
0
)
/* check the pidfile */
if
((
pid
=
options
.
get_pid
())
!=
0
)
/* check the pidfile */
...
@@ -52,6 +71,36 @@ int Instance::start()
...
@@ -52,6 +71,36 @@ int Instance::start()
since IM lacks permmissions or hasn't found the pidifle"
,
since IM lacks permmissions or hasn't found the pidifle"
,
options
.
instance_name
);
options
.
instance_name
);
/*
No need to monitor this thread in the Thread_registry, as all
instances are to be stopped during shutdown.
*/
pthread_t
proxy_thd_id
;
pthread_attr_t
proxy_thd_attr
;
int
rc
;
pthread_attr_init
(
&
proxy_thd_attr
);
pthread_attr_setdetachstate
(
&
proxy_thd_attr
,
PTHREAD_CREATE_DETACHED
);
rc
=
pthread_create
(
&
proxy_thd_id
,
&
proxy_thd_attr
,
proxy
,
this
);
pthread_attr_destroy
(
&
proxy_thd_attr
);
if
(
rc
)
{
log_error
(
"Instance::start(): pthread_create(proxy) failed"
);
return
ER_CANNOT_START_INSTANCE
;
}
return
0
;
}
/* the instance is started already */
return
ER_INSTANCE_ALREADY_STARTED
;
}
void
Instance
::
fork_and_monitor
()
{
pid_t
pid
;
log_info
(
"starting instance %s"
,
options
.
instance_name
);
log_info
(
"starting instance %s"
,
options
.
instance_name
);
switch
(
pid
=
fork
())
{
switch
(
pid
=
fork
())
{
case
0
:
case
0
:
...
@@ -59,20 +108,52 @@ int Instance::start()
...
@@ -59,20 +108,52 @@ int Instance::start()
/* exec never returns */
/* exec never returns */
exit
(
1
);
exit
(
1
);
case
-
1
:
case
-
1
:
return
ER_CANNOT_START_INSTANCE
;
log_info
(
"cannot fork() to start instance %s"
,
options
.
instance_name
);
return
;
default:
default:
return
0
;
wait
(
NULL
);
}
/* set instance state to crashed */
pthread_mutex_lock
(
&
LOCK_instance
);
crashed
=
1
;
pthread_mutex_unlock
(
&
LOCK_instance
);
/*
Wake connection threads waiting for an instance to stop. This
is needed if a user issued command to stop an instance via
mysql connection. This is not the case if Guardian stop the thread.
*/
pthread_cond_signal
(
&
COND_instance_restarted
);
/* wake guardian */
pthread_cond_signal
(
&
instance_map
->
guardian
->
COND_guardian
);
/* thread exits */
return
;
}
}
/* we should never end up here */
DBUG_ASSERT
(
0
);
}
/* the instance is started already */
return
ER_INSTANCE_ALREADY_STARTED
;
Instance
::
Instance
()
:
crashed
(
0
)
{
pthread_mutex_init
(
&
LOCK_instance
,
0
);
pthread_cond_init
(
&
COND_instance_restarted
,
0
);
}
}
Instance
::~
Instance
()
Instance
::~
Instance
()
{
{
pthread_mutex_destroy
(
&
LOCK_instance
);
pthread_mutex_destroy
(
&
LOCK_instance
);
pthread_cond_destroy
(
&
COND_instance_restarted
);
}
int
Instance
::
is_crashed
()
{
int
val
;
pthread_mutex_lock
(
&
LOCK_instance
);
val
=
crashed
;
pthread_mutex_unlock
(
&
LOCK_instance
);
return
val
;
}
}
...
@@ -95,20 +176,19 @@ bool Instance::is_running()
...
@@ -95,20 +176,19 @@ bool Instance::is_running()
pthread_mutex_lock
(
&
LOCK_instance
);
pthread_mutex_lock
(
&
LOCK_instance
);
mysql_init
(
&
mysql
);
mysql_init
(
&
mysql
);
/* try to connect to a server with
the
fake username/password pair */
/* try to connect to a server with
a
fake username/password pair */
if
(
mysql_real_connect
(
&
mysql
,
LOCAL_HOST
,
username
,
if
(
mysql_real_connect
(
&
mysql
,
LOCAL_HOST
,
username
,
password
,
password
,
NullS
,
port
,
NullS
,
port
,
socket
,
0
))
socket
,
0
))
{
{
/*
/*
Very strange. We have successfully connected to the server using
We have successfully connected to the server using fake
bullshit as
username/password. Write a warning to the logfile.
username/password. Write a warning to the logfile.
*/
*/
log_info
(
"The Instance Manager was able to log into you server \
log_info
(
"The Instance Manager was able to log into you server \
with faked compiled-in password while checking server status. \
with faked compiled-in password while checking server status. \
Looks like something is wrong."
);
Looks like something is wrong."
);
mysql_close
(
&
mysql
);
pthread_mutex_unlock
(
&
LOCK_instance
);
pthread_mutex_unlock
(
&
LOCK_instance
);
return_val
=
TRUE
;
/* server is alive */
return_val
=
TRUE
;
/* server is alive */
}
}
...
@@ -151,53 +231,30 @@ int Instance::stop()
...
@@ -151,53 +231,30 @@ int Instance::stop()
if
(
options
.
shutdown_delay
!=
NULL
)
if
(
options
.
shutdown_delay
!=
NULL
)
waitchild
=
atoi
(
options
.
shutdown_delay
);
waitchild
=
atoi
(
options
.
shutdown_delay
);
if
((
pid
=
options
.
get_pid
())
!=
0
)
/* get pid from pidfile */
kill_instance
(
SIGTERM
);
{
/*
If we cannot kill mysqld, then it has propably crashed.
Let us try to remove staled pidfile and return succes as mysqld
is probably stopped
*/
if
(
kill
(
pid
,
SIGTERM
))
{
if
(
options
.
unlink_pidfile
())
log_error
(
"cannot remove pidfile for instance %i, this might be \
since IM lacks permmissions or hasn't found the pidifle"
,
options
.
instance_name
);
return
0
;
}
/* sleep on condition to wait for SIGCHLD */
/* sleep on condition to wait for SIGCHLD */
timeout
.
tv_sec
=
time
(
NULL
)
+
waitchild
;
timeout
.
tv_sec
=
time
(
NULL
)
+
waitchild
;
timeout
.
tv_nsec
=
0
;
timeout
.
tv_nsec
=
0
;
if
(
pthread_mutex_lock
(
&
instance_map
->
pid_cond
.
LOCK_pid
))
if
(
pthread_mutex_lock
(
&
LOCK_instance
))
goto
err
;
/* perhaps this should be procecced differently */
goto
err
;
while
(
options
.
get_pid
()
!=
0
)
/* while server isn't stopped */
while
(
options
.
get_pid
()
!=
0
)
/* while server isn't stopped */
{
{
int
status
;
int
status
;
status
=
pthread_cond_timedwait
(
&
instance_map
->
pid_cond
.
COND_pi
d
,
status
=
pthread_cond_timedwait
(
&
COND_instance_restarte
d
,
&
instance_map
->
pid_cond
.
LOCK_pid
,
&
LOCK_instance
,
&
timeout
);
&
timeout
);
if
(
status
==
ETIMEDOUT
)
if
(
status
==
ETIMEDOUT
)
break
;
break
;
}
}
pthread_mutex_unlock
(
&
instance_map
->
pid_cond
.
LOCK_pid
);
pthread_mutex_unlock
(
&
LOCK_instance
);
if
(
!
kill
(
pid
,
SIGKILL
))
kill_instance
(
SIGKILL
);
{
log_error
(
"The instance %s has been stopped forsibly. Normally \
it should not happed. Probably the instance has been \
hanging. You should also check your IM setup"
,
options
.
instance_name
);
}
return
0
;
return
0
;
}
return
ER_INSTANCE_IS_NOT_STARTED
;
return
ER_INSTANCE_IS_NOT_STARTED
;
err:
err:
...
@@ -205,6 +262,29 @@ int Instance::stop()
...
@@ -205,6 +262,29 @@ int Instance::stop()
}
}
void
Instance
::
kill_instance
(
int
signum
)
{
pid_t
pid
;
/* if there are no pid, everything seems to be fine */
if
((
pid
=
options
.
get_pid
())
!=
0
)
/* get pid from pidfile */
{
/*
If we cannot kill mysqld, then it has propably crashed.
Let us try to remove staled pidfile and return successfully
as mysqld is probably stopped.
*/
if
(
!
kill
(
pid
,
signum
))
options
.
unlink_pidfile
();
else
if
(
signum
==
SIGKILL
)
/* really killed instance with SIGKILL */
log_error
(
"The instance %s is being stopped forsibly. Normally \
it should not happed. Probably the instance has been \
hanging. You should also check your IM setup"
,
options
.
instance_name
);
}
return
;
}
/*
/*
We execute this function to initialize instance parameters.
We execute this function to initialize instance parameters.
Return value: 0 - ok. 1 - unable to init DYNAMIC_ARRAY.
Return value: 0 - ok. 1 - unable to init DYNAMIC_ARRAY.
...
@@ -212,8 +292,6 @@ int Instance::stop()
...
@@ -212,8 +292,6 @@ int Instance::stop()
int
Instance
::
init
(
const
char
*
name_arg
)
int
Instance
::
init
(
const
char
*
name_arg
)
{
{
pthread_mutex_init
(
&
LOCK_instance
,
0
);
return
options
.
init
(
name_arg
);
return
options
.
init
(
name_arg
);
}
}
...
...
server-tools/instance-manager/instance.h
View file @
6b50b5b0
...
@@ -30,14 +30,19 @@ class Instance_map;
...
@@ -30,14 +30,19 @@ class Instance_map;
class
Instance
class
Instance
{
{
public:
public:
Instance
();
~
Instance
();
~
Instance
();
int
init
(
const
char
*
name
);
int
init
(
const
char
*
name
);
int
complete_initialization
(
Instance_map
*
instance_map_arg
);
int
complete_initialization
(
Instance_map
*
instance_map_arg
);
/* check if the instance is running and set up mysql connection if yes */
bool
is_running
();
bool
is_running
();
int
start
();
int
start
();
int
stop
();
int
stop
();
/* send a signal to the instance */
void
kill_instance
(
int
signo
);
int
is_crashed
();
void
fork_and_monitor
();
public:
public:
enum
{
DEFAULT_SHUTDOWN_DELAY
=
35
};
enum
{
DEFAULT_SHUTDOWN_DELAY
=
35
};
...
@@ -49,7 +54,9 @@ class Instance
...
@@ -49,7 +54,9 @@ class Instance
double start of the instance. This happens when the instance is starting
double start of the instance. This happens when the instance is starting
and we issue the start command once more.
and we issue the start command once more.
*/
*/
int
crashed
;
pthread_mutex_t
LOCK_instance
;
pthread_mutex_t
LOCK_instance
;
pthread_cond_t
COND_instance_restarted
;
Instance_map
*
instance_map
;
Instance_map
*
instance_map
;
};
};
...
...
server-tools/instance-manager/instance_map.cc
View file @
6b50b5b0
...
@@ -120,9 +120,6 @@ Instance_map::Instance_map(const char *default_mysqld_path_arg)
...
@@ -120,9 +120,6 @@ Instance_map::Instance_map(const char *default_mysqld_path_arg)
int
Instance_map
::
init
()
int
Instance_map
::
init
()
{
{
pthread_mutex_init
(
&
pid_cond
.
LOCK_pid
,
0
);
pthread_cond_init
(
&
pid_cond
.
COND_pid
,
0
);
if
(
hash_init
(
&
hash
,
default_charset_info
,
START_HASH_SIZE
,
0
,
0
,
if
(
hash_init
(
&
hash
,
default_charset_info
,
START_HASH_SIZE
,
0
,
0
,
get_instance_key
,
delete_instance
,
0
))
get_instance_key
,
delete_instance
,
0
))
return
1
;
return
1
;
...
@@ -135,8 +132,6 @@ Instance_map::~Instance_map()
...
@@ -135,8 +132,6 @@ Instance_map::~Instance_map()
hash_free
(
&
hash
);
hash_free
(
&
hash
);
pthread_mutex_unlock
(
&
LOCK_instance_map
);
pthread_mutex_unlock
(
&
LOCK_instance_map
);
pthread_mutex_destroy
(
&
LOCK_instance_map
);
pthread_mutex_destroy
(
&
LOCK_instance_map
);
pthread_mutex_destroy
(
&
pid_cond
.
LOCK_pid
);
pthread_cond_destroy
(
&
pid_cond
.
COND_pid
);
}
}
...
@@ -198,21 +193,6 @@ void Instance_map::complete_initialization()
...
@@ -198,21 +193,6 @@ void Instance_map::complete_initialization()
}
}
Instance
*
Instance_map
::
find
(
uint
instance_number
)
{
Instance
*
instance
;
char
name
[
80
];
snprintf
(
name
,
sizeof
(
name
)
-
1
,
"mysqld%i"
,
instance_number
);
name
[
sizeof
(
name
)
-
1
]
=
0
;
/* safety */
pthread_mutex_lock
(
&
LOCK_instance_map
);
instance
=
(
Instance
*
)
hash_search
(
&
hash
,
(
byte
*
)
name
,
strlen
(
name
));
pthread_mutex_unlock
(
&
LOCK_instance_map
);
return
instance
;
}
/* load options from config files and create appropriate instance structures */
/* load options from config files and create appropriate instance structures */
int
Instance_map
::
load
()
int
Instance_map
::
load
()
...
...
server-tools/instance-manager/instance_map.h
View file @
6b50b5b0
...
@@ -27,12 +27,6 @@
...
@@ -27,12 +27,6 @@
#include "protocol.h"
#include "protocol.h"
#include "guardian.h"
#include "guardian.h"
typedef
struct
st_instance_cond
{
pthread_mutex_t
LOCK_pid
;
pthread_cond_t
COND_pid
;
}
CHILD_COND
;
class
Instance
;
class
Instance
;
extern
int
load_all_groups
(
char
***
groups
,
const
char
*
filename
);
extern
int
load_all_groups
(
char
***
groups
,
const
char
*
filename
);
extern
void
free_groups
(
char
**
groups
);
extern
void
free_groups
(
char
**
groups
);
...
@@ -83,8 +77,6 @@ class Instance_map
...
@@ -83,8 +77,6 @@ class Instance_map
public:
public:
const
char
*
mysqld_path
;
const
char
*
mysqld_path
;
Guardian_thread
*
guardian
;
Guardian_thread
*
guardian
;
/* structure used for syncronization reasons in the stop command */
CHILD_COND
pid_cond
;
private:
private:
enum
{
START_HASH_SIZE
=
16
};
enum
{
START_HASH_SIZE
=
16
};
...
...
server-tools/instance-manager/instance_options.cc
View file @
6b50b5b0
...
@@ -27,25 +27,50 @@
...
@@ -27,25 +27,50 @@
#include <m_string.h>
#include <m_string.h>
/* option_name should be prefixed with "--" */
/*
int
Instance_options
::
get_default_option
(
char
*
result
,
const
char
*
option_name
,
Get compiled-in value of default_option
size_t
result_len
)
SYNOPSYS
get_default_option()
result buffer to put found value
result_len buffer size
oprion_name the name of the option, prefixed with "--"
DESCRIPTION
Get compile-in value of requested option from server
RETURN
0 - ok
1 - error occured
*/
int
Instance_options
::
get_default_option
(
char
*
result
,
size_t
result_len
,
const
char
*
option_name
)
{
{
int
position
=
0
;
int
position
=
0
;
int
rc
=
1
;
char
verbose_option
[]
=
" --no-defaults --verbose --help"
;
char
verbose_option
[]
=
" --no-defaults --verbose --help"
;
Buffer
cmd
;
Buffer
cmd
(
strlen
(
mysqld_path
)
+
sizeof
(
verbose_option
)
+
1
);
if
(
cmd
.
get_size
())
/* malloc succeeded */
{
cmd
.
append
(
position
,
mysqld_path
,
strlen
(
mysqld_path
));
cmd
.
append
(
position
,
mysqld_path
,
strlen
(
mysqld_path
));
position
+=
strlen
(
mysqld_path
);
position
+=
strlen
(
mysqld_path
);
cmd
.
append
(
position
,
verbose_option
,
sizeof
(
verbose_option
)
-
1
);
cmd
.
append
(
position
,
verbose_option
,
sizeof
(
verbose_option
)
-
1
);
position
+=
sizeof
(
verbose_option
)
-
1
;
position
+=
sizeof
(
verbose_option
)
-
1
;
cmd
.
append
(
position
,
"
\0
"
,
1
);
cmd
.
append
(
position
,
"
\0
"
,
1
);
if
(
cmd
.
is_error
())
goto
err
;
/* get the value from "mysqld --help --verbose" */
/* get the value from "mysqld --help --verbose" */
if
(
parse_output_and_get_value
(
cmd
.
buffer
,
option_name
+
2
,
rc
=
parse_output_and_get_value
(
cmd
.
buffer
,
option_name
+
2
,
result
,
result_len
))
result
,
result_len
);
return
1
;
}
return
0
;
return
rc
;
err:
return
1
;
}
}
...
@@ -56,50 +81,32 @@ void Instance_options::get_pid_filename(char *result)
...
@@ -56,50 +81,32 @@ void Instance_options::get_pid_filename(char *result)
if
(
mysqld_datadir
==
NULL
)
if
(
mysqld_datadir
==
NULL
)
{
{
get_default_option
(
datadir
,
"--datadir"
,
MAX_PATH_LEN
);
get_default_option
(
datadir
,
sizeof
(
datadir
),
"--datadir"
);
}
}
else
else
strxnmov
(
datadir
,
MAX_PATH_LEN
-
1
,
strchr
(
mysqld_datadir
,
'='
)
+
1
,
strxnmov
(
datadir
,
MAX_PATH_LEN
-
1
,
strchr
(
mysqld_datadir
,
'='
)
+
1
,
"/"
,
NullS
);
"/"
,
NullS
);
/* well, we should never get it */
DBUG_ASSERT
(
mysqld_pid_file
);
if
(
mysqld_pid_file
!=
NULL
)
pid_file
=
strchr
(
pid_file
,
'='
)
+
1
;
pid_file
=
strchr
(
pid_file
,
'='
)
+
1
;
else
DBUG_ASSERT
(
0
);
/* get the full path to the pidfile */
/* get the full path to the pidfile */
my_load_path
(
result
,
pid_file
,
datadir
);
my_load_path
(
result
,
pid_file
,
datadir
);
}
}
int
Instance_options
::
unlink_pidfile
()
int
Instance_options
::
unlink_pidfile
()
{
{
char
pid_file_path
[
MAX_PATH_LEN
];
return
unlink
(
pid_file_with_path
);
/*
This works as we know that pid_file_path is of
MAX_PATH_LEN == FN_REFLEN length
*/
get_pid_filename
((
char
*
)
&
pid_file_path
);
return
unlink
(
pid_file_path
);
}
}
pid_t
Instance_options
::
get_pid
()
pid_t
Instance_options
::
get_pid
()
{
{
char
pid_file_path
[
MAX_PATH_LEN
];
FILE
*
pid_file_stream
;
/*
This works as we know that pid_file_path is of
MAX_PATH_LEN == FN_REFLEN length
*/
get_pid_filename
((
char
*
)
&
pid_file_path
);
/* get the pid */
/* get the pid */
if
(
FILE
*
pid_file_stream
=
my_fopen
(
pid_file
_path
,
if
(
pid_file_stream
=
my_fopen
(
pid_file_with
_path
,
O_RDONLY
|
O_BINARY
,
MYF
(
0
)))
O_RDONLY
|
O_BINARY
,
MYF
(
0
)))
{
{
pid_t
pid
;
pid_t
pid
;
...
@@ -140,6 +147,8 @@ int Instance_options::complete_initialization(const char *default_path)
...
@@ -140,6 +147,8 @@ int Instance_options::complete_initialization(const char *default_path)
add_option
(
pidfilename
);
add_option
(
pidfilename
);
}
}
get_pid_filename
(
pid_file_with_path
);
/* we need to reserve space for the final zero + possible default options */
/* we need to reserve space for the final zero + possible default options */
if
(
!
(
argv
=
(
char
**
)
alloc_root
(
&
alloc
,
(
options_array
.
elements
+
1
if
(
!
(
argv
=
(
char
**
)
alloc_root
(
&
alloc
,
(
options_array
.
elements
+
1
+
MAX_NUMBER_OF_DEFAULT_OPTIONS
)
*
sizeof
(
char
*
))))
+
MAX_NUMBER_OF_DEFAULT_OPTIONS
)
*
sizeof
(
char
*
))))
...
@@ -244,6 +253,8 @@ int Instance_options::add_to_argv(const char* option)
...
@@ -244,6 +253,8 @@ int Instance_options::add_to_argv(const char* option)
return
0
;
return
0
;
}
}
/* function for debug purposes */
void
Instance_options
::
print_argv
()
void
Instance_options
::
print_argv
()
{
{
int
i
;
int
i
;
...
...
server-tools/instance-manager/instance_options.h
View file @
6b50b5b0
...
@@ -39,7 +39,7 @@ class Instance_options
...
@@ -39,7 +39,7 @@ class Instance_options
Instance_options
()
:
Instance_options
()
:
mysqld_socket
(
0
),
mysqld_datadir
(
0
),
mysqld_bind_address
(
0
),
mysqld_socket
(
0
),
mysqld_datadir
(
0
),
mysqld_bind_address
(
0
),
mysqld_pid_file
(
0
),
mysqld_port
(
0
),
mysqld_path
(
0
),
nonguarded
(
0
),
mysqld_pid_file
(
0
),
mysqld_port
(
0
),
mysqld_path
(
0
),
nonguarded
(
0
),
filled_default_options
(
0
)
shutdown_delay
(
0
),
filled_default_options
(
0
)
{}
{}
~
Instance_options
();
~
Instance_options
();
/* fills in argv */
/* fills in argv */
...
@@ -60,6 +60,7 @@ class Instance_options
...
@@ -60,6 +60,7 @@ class Instance_options
enum
{
MAX_PATH_LEN
=
512
};
enum
{
MAX_PATH_LEN
=
512
};
enum
{
MAX_NUMBER_OF_DEFAULT_OPTIONS
=
2
};
enum
{
MAX_NUMBER_OF_DEFAULT_OPTIONS
=
2
};
enum
{
MEM_ROOT_BLOCK_SIZE
=
512
};
enum
{
MEM_ROOT_BLOCK_SIZE
=
512
};
char
pid_file_with_path
[
MAX_PATH_LEN
];
char
**
argv
;
char
**
argv
;
/* We need the some options, so we store them as a separate pointers */
/* We need the some options, so we store them as a separate pointers */
const
char
*
mysqld_socket
;
const
char
*
mysqld_socket
;
...
@@ -72,11 +73,12 @@ class Instance_options
...
@@ -72,11 +73,12 @@ class Instance_options
const
char
*
mysqld_path
;
const
char
*
mysqld_path
;
const
char
*
nonguarded
;
const
char
*
nonguarded
;
const
char
*
shutdown_delay
;
const
char
*
shutdown_delay
;
/* this value is computed and cashed here */
DYNAMIC_ARRAY
options_array
;
DYNAMIC_ARRAY
options_array
;
private:
private:
int
add_to_argv
(
const
char
*
option
);
int
add_to_argv
(
const
char
*
option
);
int
get_default_option
(
char
*
result
,
const
char
*
option_name
,
int
get_default_option
(
char
*
result
,
size_t
result_len
,
size_t
result_len
);
const
char
*
option_name
);
private:
private:
uint
filled_default_options
;
uint
filled_default_options
;
MEM_ROOT
alloc
;
MEM_ROOT
alloc
;
...
...
server-tools/instance-manager/listener.cc
View file @
6b50b5b0
...
@@ -85,6 +85,8 @@ void Listener_thread::run()
...
@@ -85,6 +85,8 @@ void Listener_thread::run()
thread_registry
.
register_thread
(
&
thread_info
);
thread_registry
.
register_thread
(
&
thread_info
);
my_thread_init
();
/* I. prepare 'listen' sockets */
/* I. prepare 'listen' sockets */
int
ip_socket
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
int
ip_socket
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
...
@@ -263,11 +265,13 @@ void Listener_thread::run()
...
@@ -263,11 +265,13 @@ void Listener_thread::run()
unlink
(
unix_socket_address
.
sun_path
);
unlink
(
unix_socket_address
.
sun_path
);
thread_registry
.
unregister_thread
(
&
thread_info
);
thread_registry
.
unregister_thread
(
&
thread_info
);
my_thread_end
();
return
;
return
;
err:
err:
thread_registry
.
unregister_thread
(
&
thread_info
);
thread_registry
.
unregister_thread
(
&
thread_info
);
thread_registry
.
request_shutdown
();
thread_registry
.
request_shutdown
();
my_thread_end
();
return
;
return
;
}
}
...
...
server-tools/instance-manager/manager.cc
View file @
6b50b5b0
...
@@ -90,7 +90,6 @@ void manager(const Options &options)
...
@@ -90,7 +90,6 @@ void manager(const Options &options)
sigemptyset
(
&
mask
);
sigemptyset
(
&
mask
);
sigaddset
(
&
mask
,
SIGINT
);
sigaddset
(
&
mask
,
SIGINT
);
sigaddset
(
&
mask
,
SIGTERM
);
sigaddset
(
&
mask
,
SIGTERM
);
sigaddset
(
&
mask
,
SIGCHLD
);
sigaddset
(
&
mask
,
SIGPIPE
);
sigaddset
(
&
mask
,
SIGPIPE
);
sigaddset
(
&
mask
,
SIGHUP
);
sigaddset
(
&
mask
,
SIGHUP
);
/*
/*
...
@@ -128,7 +127,7 @@ void manager(const Options &options)
...
@@ -128,7 +127,7 @@ void manager(const Options &options)
int
rc
;
int
rc
;
/*
/*
NOTE: Guardian should be shutdown
ed
first. Only then all other threads
NOTE: Guardian should be shutdown first. Only then all other threads
need to be stopped. This should be done, as guardian is responsible for
need to be stopped. This should be done, as guardian is responsible for
shutting down the instances, and this is a long operation.
shutting down the instances, and this is a long operation.
*/
*/
...
@@ -160,12 +159,8 @@ void manager(const Options &options)
...
@@ -160,12 +159,8 @@ void manager(const Options &options)
more then 10 alarms at the same time.
more then 10 alarms at the same time.
*/
*/
init_thr_alarm
(
10
);
init_thr_alarm
(
10
);
/*
/* init list of guarded instances */
Now we can init the list of guarded instances. We have to do it after
guardian_thread
.
init
();
alarm structures initialization as we have to use net_* functions while
making the list. And they in their turn need alarms for timeout suppport.
*/
guardian_thread
.
start
();
/*
/*
After the list of guarded instances have been initialized,
After the list of guarded instances have been initialized,
Guardian should start them.
Guardian should start them.
...
@@ -182,18 +177,12 @@ void manager(const Options &options)
...
@@ -182,18 +177,12 @@ void manager(const Options &options)
case
THR_SERVER_ALARM
:
case
THR_SERVER_ALARM
:
process_alarm
(
signo
);
process_alarm
(
signo
);
break
;
break
;
case
SIGCHLD
:
wait
(
NULL
);
/* wake threads waiting for an instance to shutdown */
pthread_cond_broadcast
(
&
instance_map
.
pid_cond
.
COND_pid
);
/* wake guardian */
pthread_cond_signal
(
&
guardian_thread
.
COND_guardian
);
break
;
default:
default:
if
(
!
guardian_thread
.
is_stopped
)
{
{
guardian_thread
.
request_stop_instances
();
if
(
!
guardian_thread
.
is_stopped
())
guardian_thread
.
shutdown
();
{
bool
stop_instances
=
true
;
guardian_thread
.
request_shutdown
(
stop_instances
);
pthread_cond_signal
(
&
guardian_thread
.
COND_guardian
);
pthread_cond_signal
(
&
guardian_thread
.
COND_guardian
);
}
}
else
else
...
@@ -201,6 +190,7 @@ void manager(const Options &options)
...
@@ -201,6 +190,7 @@ void manager(const Options &options)
thread_registry
.
deliver_shutdown
();
thread_registry
.
deliver_shutdown
();
shutdown_complete
=
TRUE
;
shutdown_complete
=
TRUE
;
}
}
}
break
;
break
;
}
}
}
}
...
...
server-tools/instance-manager/options.cc
View file @
6b50b5b0
...
@@ -23,6 +23,8 @@
...
@@ -23,6 +23,8 @@
#include <my_global.h>
#include <my_global.h>
#include <my_sys.h>
#include <my_sys.h>
#include <my_getopt.h>
#include <my_getopt.h>
#include <m_string.h>
#include <mysql_com.h>
#include "priv.h"
#include "priv.h"
...
@@ -77,6 +79,9 @@ static struct my_option my_long_options[] =
...
@@ -77,6 +79,9 @@ static struct my_option my_long_options[] =
(
gptr
*
)
&
Options
::
socket_file_name
,
(
gptr
*
)
&
Options
::
socket_file_name
,
(
gptr
*
)
&
Options
::
socket_file_name
,
(
gptr
*
)
&
Options
::
socket_file_name
,
0
,
GET_STR
,
REQUIRED_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
0
,
GET_STR
,
REQUIRED_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
{
"passwd"
,
'P'
,
"Prepare entry for passwd file and exit."
,
0
,
0
,
0
,
GET_NO_ARG
,
NO_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
{
"bind-address"
,
OPT_BIND_ADDRESS
,
"Bind address to use for connection."
,
{
"bind-address"
,
OPT_BIND_ADDRESS
,
"Bind address to use for connection."
,
(
gptr
*
)
&
Options
::
bind_address
,
(
gptr
*
)
&
Options
::
bind_address
,
(
gptr
*
)
&
Options
::
bind_address
,
(
gptr
*
)
&
Options
::
bind_address
,
0
,
GET_STR
,
REQUIRED_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
0
,
GET_STR
,
REQUIRED_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
...
@@ -142,6 +147,34 @@ static void usage()
...
@@ -142,6 +147,34 @@ static void usage()
my_print_variables
(
my_long_options
);
my_print_variables
(
my_long_options
);
}
}
static
void
passwd
()
{
char
user
[
1024
],
pw
[
1024
],
*
p
;
char
crypted_pw
[
SCRAMBLED_PASSWORD_CHAR_LENGTH
+
1
];
fprintf
(
stderr
,
"Creating record for new user.
\n
"
);
fprintf
(
stderr
,
"Enter user name: "
);
if
(
!
fgets
(
user
,
sizeof
(
user
),
stdin
))
{
fprintf
(
stderr
,
"Unable to read user.
\n
"
);
return
;
}
if
((
p
=
strchr
(
user
,
'\n'
)))
*
p
=
0
;
fprintf
(
stderr
,
"Enter password: "
);
if
(
!
fgets
(
pw
,
sizeof
(
pw
),
stdin
))
{
fprintf
(
stderr
,
"Unable to read password.
\n
"
);
return
;
}
if
((
p
=
strchr
(
pw
,
'\n'
)))
*
p
=
0
;
make_scrambled_password
(
crypted_pw
,
pw
);
printf
(
"%s:%s
\n
"
,
user
,
crypted_pw
);
}
C_MODE_START
C_MODE_START
static
my_bool
static
my_bool
...
@@ -153,7 +186,9 @@ get_one_option(int optid,
...
@@ -153,7 +186,9 @@ get_one_option(int optid,
case
'V'
:
case
'V'
:
version
();
version
();
exit
(
0
);
exit
(
0
);
case
'I'
:
case
'P'
:
passwd
();
exit
(
0
);
case
'?'
:
case
'?'
:
usage
();
usage
();
exit
(
0
);
exit
(
0
);
...
...
server-tools/instance-manager/parse.cc
View file @
6b50b5b0
...
@@ -49,29 +49,6 @@ static struct tokens_st tokens[]= {
...
@@ -49,29 +49,6 @@ static struct tokens_st tokens[]= {
};
};
/*
tries to find next word in the text
if found, returns the beginning and puts word length to word_len argument.
if not found returns pointer to first non-space or to '\0', word_len == 0
*/
inline
void
get_word
(
const
char
**
text
,
uint
*
word_len
)
{
const
char
*
word_end
;
/* skip space */
while
(
my_isspace
(
default_charset_info
,
**
text
))
++
(
*
text
);
word_end
=
*
text
;
while
(
my_isalnum
(
default_charset_info
,
*
word_end
))
++
word_end
;
*
word_len
=
word_end
-
*
text
;
}
/*
/*
Returns token no if word corresponds to some token, otherwise returns
Returns token no if word corresponds to some token, otherwise returns
TOK_NOT_FOUND
TOK_NOT_FOUND
...
...
server-tools/instance-manager/parse.h
View file @
6b50b5b0
...
@@ -20,4 +20,34 @@
...
@@ -20,4 +20,34 @@
Command
*
parse_command
(
Command_factory
*
factory
,
const
char
*
text
);
Command
*
parse_command
(
Command_factory
*
factory
,
const
char
*
text
);
/* define kinds of the word seek method */
enum
{
ALPHANUM
=
1
,
NONSPACE
};
/*
tries to find next word in the text
if found, returns the beginning and puts word length to word_len argument.
if not found returns pointer to first non-space or to '\0', word_len == 0
*/
inline
void
get_word
(
const
char
**
text
,
uint
*
word_len
,
int
seek_method
=
ALPHANUM
)
{
const
char
*
word_end
;
/* skip space */
while
(
my_isspace
(
default_charset_info
,
**
text
))
++
(
*
text
);
word_end
=
*
text
;
if
(
seek_method
==
ALPHANUM
)
while
(
my_isalnum
(
default_charset_info
,
*
word_end
))
++
word_end
;
else
while
(
!
my_isspace
(
default_charset_info
,
*
word_end
))
++
word_end
;
*
word_len
=
word_end
-
*
text
;
}
#endif
/* INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_H */
#endif
/* INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_H */
server-tools/instance-manager/parse_output.cc
View file @
6b50b5b0
...
@@ -14,43 +14,38 @@
...
@@ -14,43 +14,38 @@
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "parse.h"
#include <stdio.h>
#include <stdio.h>
#include <my_global.h>
#include <my_global.h>
#include <my_sys.h>
#include <my_sys.h>
#include <string.h>
#include <string.h>
/* buf should be of appropriate size. Otherwise the word will be truncated */
static
int
get_word
(
FILE
*
file
,
char
*
buf
,
size_t
size
)
{
int
currchar
;
currchar
=
getc
(
file
);
/*
Parse output of the given command
/* skip space */
SYNOPSYS
while
(
my_isspace
(
default_charset_info
,
(
char
)
currchar
)
&&
parse_output_and_get_value()
currchar
!=
EOF
&&
size
>
1
)
{
currchar
=
getc
(
file
);
}
while
(
!
my_isspace
(
default_charset_info
,
(
char
)
currchar
)
&&
command the command to execue with popen.
currchar
!=
EOF
&&
size
>
1
)
word the word to look for (usually an option name)
{
result the buffer to store the next word (option value)
*
buf
++=
(
char
)
currchar
;
result_len self-explanatory
currchar
=
getc
(
file
);
size
--
;
}
*
buf
=
'\0'
;
DESCRIPTION
return
0
;
}
Parse output of the "command". Find the "word" and return the next one
*/
int
parse_output_and_get_value
(
const
char
*
command
,
const
char
*
word
,
int
parse_output_and_get_value
(
const
char
*
command
,
const
char
*
word
,
char
*
result
,
size_t
result_len
)
char
*
result
,
size_t
result_len
)
{
{
FILE
*
output
;
FILE
*
output
;
int
wordlen
;
uint
wordlen
;
/* should be enought to store the string from the output */
enum
{
MAX_LINE_LEN
=
512
};
char
linebuf
[
MAX_LINE_LEN
];
wordlen
=
strlen
(
word
);
wordlen
=
strlen
(
word
);
...
@@ -62,19 +57,32 @@ int parse_output_and_get_value(const char *command, const char *word,
...
@@ -62,19 +57,32 @@ int parse_output_and_get_value(const char *command, const char *word,
*/
*/
setvbuf
(
output
,
NULL
,
_IOFBF
,
0
);
setvbuf
(
output
,
NULL
,
_IOFBF
,
0
);
get_word
(
output
,
result
,
result_len
);
while
(
fgets
(
linebuf
,
sizeof
(
linebuf
)
-
1
,
output
))
while
(
strncmp
(
word
,
result
,
wordlen
)
&&
*
result
!=
'\0'
)
{
{
get_word
(
output
,
result
,
result_len
);
uint
lineword_len
=
0
;
}
char
*
linep
=
linebuf
;
linebuf
[
sizeof
(
linebuf
)
-
1
]
=
'\0'
;
/* safety */
/*
Get the word, which might contain non-alphanumeric characters. (Usually
these are '/', '-' and '.' in the path expressions and filenames)
*/
get_word
((
const
char
**
)
&
linep
,
&
lineword_len
,
NONSPACE
);
if
(
!
strncmp
(
word
,
linep
,
wordlen
)
&&
*
result
!=
'\0'
)
{
/*
/*
If we have found the word, return the next one. This is usually
If we have found the word, return the next one. This is usually
an option value.
an option value.
*/
*/
if
(
*
result
!=
'\0'
)
get_word
((
const
char
**
)
&
linep
,
&
lineword_len
,
NONSPACE
);
get_word
(
output
,
result
,
result_len
);
DBUG_ASSERT
(
result_len
>
lineword_len
);
strncpy
(
result
,
linep
,
lineword_len
);
goto
pclose
;
}
}
pclose:
if
(
pclose
(
output
))
if
(
pclose
(
output
))
return
1
;
return
1
;
...
...
server-tools/instance-manager/protocol.cc
View file @
6b50b5b0
...
@@ -154,7 +154,8 @@ int send_fields(struct st_net *net, LIST *fields)
...
@@ -154,7 +154,8 @@ int send_fields(struct st_net *net, LIST *fields)
store_to_string
(
&
send_buff
,
(
char
*
)
""
,
&
position
);
/* table name alias */
store_to_string
(
&
send_buff
,
(
char
*
)
""
,
&
position
);
/* table name alias */
store_to_string
(
&
send_buff
,
field
->
name
,
&
position
);
/* column name */
store_to_string
(
&
send_buff
,
field
->
name
,
&
position
);
/* column name */
store_to_string
(
&
send_buff
,
field
->
name
,
&
position
);
/* column name alias */
store_to_string
(
&
send_buff
,
field
->
name
,
&
position
);
/* column name alias */
if
(
send_buff
.
reserve
(
position
,
12
))
send_buff
.
reserve
(
position
,
12
);
if
(
send_buff
.
is_error
())
goto
err
;
goto
err
;
send_buff
.
buffer
[
position
++
]
=
12
;
send_buff
.
buffer
[
position
++
]
=
12
;
int2store
(
send_buff
.
buffer
+
position
,
1
);
/* charsetnr */
int2store
(
send_buff
.
buffer
+
position
,
1
);
/* charsetnr */
...
...
server-tools/instance-manager/user_map.cc
View file @
6b50b5b0
...
@@ -69,7 +69,7 @@ int User::init(const char *line)
...
@@ -69,7 +69,7 @@ int User::init(const char *line)
return
0
;
return
0
;
err:
err:
log_error
(
"error parsing user and password at line %
d
"
,
line
);
log_error
(
"error parsing user and password at line %
s
"
,
line
);
return
1
;
return
1
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment