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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
83f9ee07
Commit
83f9ee07
authored
Apr 09, 2005
by
petr@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WL#2246 "IM: Add ability to change instance options, add server logs handling" ported to the
current version of the IM
parent
eeeedd31
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
1052 additions
and
47 deletions
+1052
-47
server-tools/instance-manager/commands.cc
server-tools/instance-manager/commands.cc
+481
-13
server-tools/instance-manager/commands.h
server-tools/instance-manager/commands.h
+86
-0
server-tools/instance-manager/factory.cc
server-tools/instance-manager/factory.cc
+45
-0
server-tools/instance-manager/factory.h
server-tools/instance-manager/factory.h
+18
-2
server-tools/instance-manager/instance_options.cc
server-tools/instance-manager/instance_options.cc
+133
-2
server-tools/instance-manager/instance_options.h
server-tools/instance-manager/instance_options.h
+7
-1
server-tools/instance-manager/messages.cc
server-tools/instance-manager/messages.cc
+9
-0
server-tools/instance-manager/mysql_connection.cc
server-tools/instance-manager/mysql_connection.cc
+2
-2
server-tools/instance-manager/mysql_manager_error.h
server-tools/instance-manager/mysql_manager_error.h
+4
-0
server-tools/instance-manager/parse.cc
server-tools/instance-manager/parse.cc
+199
-10
server-tools/instance-manager/parse.h
server-tools/instance-manager/parse.h
+18
-2
server-tools/instance-manager/parse_output.cc
server-tools/instance-manager/parse_output.cc
+2
-1
server-tools/instance-manager/parse_output.h
server-tools/instance-manager/parse_output.h
+3
-0
server-tools/instance-manager/protocol.cc
server-tools/instance-manager/protocol.cc
+40
-13
server-tools/instance-manager/protocol.h
server-tools/instance-manager/protocol.h
+5
-1
No files found.
server-tools/instance-manager/commands.cc
View file @
83f9ee07
...
@@ -27,6 +27,19 @@
...
@@ -27,6 +27,19 @@
#include <mysql.h>
#include <mysql.h>
/* some useful functions */
static
int
put_to_buff
(
Buffer
*
buff
,
const
char
*
str
,
uint
*
position
)
{
uint
len
=
strlen
(
str
);
if
(
buff
->
append
(
*
position
,
str
,
len
))
return
1
;
*
position
+=
len
;
return
0
;
}
/* implementation for Show_instances: */
/* implementation for Show_instances: */
...
@@ -106,7 +119,7 @@ int Flush_instances::execute(struct st_net *net, ulong connection_id)
...
@@ -106,7 +119,7 @@ int Flush_instances::execute(struct st_net *net, ulong connection_id)
if
(
instance_map
->
flush_instances
())
if
(
instance_map
->
flush_instances
())
return
ER_OUT_OF_RESOURCES
;
return
ER_OUT_OF_RESOURCES
;
net_send_ok
(
net
,
connection_id
);
net_send_ok
(
net
,
connection_id
,
NULL
);
return
0
;
return
0
;
}
}
...
@@ -119,7 +132,7 @@ Show_instance_status::Show_instance_status(Instance_map *instance_map_arg,
...
@@ -119,7 +132,7 @@ Show_instance_status::Show_instance_status(Instance_map *instance_map_arg,
{
{
Instance
*
instance
;
Instance
*
instance
;
/* we make a search here, since we don't want t store the name */
/* we make a search here, since we don't want t
o
store the name */
if
((
instance
=
instance_map
->
find
(
name
,
len
)))
if
((
instance
=
instance_map
->
find
(
name
,
len
)))
{
{
instance_name
=
instance
->
options
.
instance_name
;
instance_name
=
instance
->
options
.
instance_name
;
...
@@ -225,7 +238,7 @@ Show_instance_options::Show_instance_options(Instance_map *instance_map_arg,
...
@@ -225,7 +238,7 @@ Show_instance_options::Show_instance_options(Instance_map *instance_map_arg,
{
{
Instance
*
instance
;
Instance
*
instance
;
/* we make a search here, since we don't want t store the name */
/* we make a search here, since we don't want t
o
store the name */
if
((
instance
=
instance_map
->
find
(
name
,
len
)))
if
((
instance
=
instance_map
->
find
(
name
,
len
)))
{
{
instance_name
=
instance
->
options
.
instance_name
;
instance_name
=
instance
->
options
.
instance_name
;
...
@@ -294,13 +307,17 @@ int Show_instance_options::do_command(struct st_net *net,
...
@@ -294,13 +307,17 @@ int Show_instance_options::do_command(struct st_net *net,
char
*
tmp_option
,
*
option_value
;
char
*
tmp_option
,
*
option_value
;
get_dynamic
(
&
(
instance
->
options
.
options_array
),
(
gptr
)
&
tmp_option
,
i
);
get_dynamic
(
&
(
instance
->
options
.
options_array
),
(
gptr
)
&
tmp_option
,
i
);
option_value
=
strchr
(
tmp_option
,
'='
);
option_value
=
strchr
(
tmp_option
,
'='
);
/* split the option string into two parts */
/* split the option string into two parts if it has a value */
*
option_value
=
0
;
position
=
0
;
position
=
0
;
store_to_string
(
&
send_buff
,
tmp_option
+
2
,
&
position
);
if
(
option_value
!=
NULL
)
store_to_string
(
&
send_buff
,
option_value
+
1
,
&
position
);
{
/* join name and the value into the same option again */
*
option_value
=
0
;
*
option_value
=
'='
;
store_to_string
(
&
send_buff
,
tmp_option
+
2
,
&
position
);
store_to_string
(
&
send_buff
,
option_value
+
1
,
&
position
);
/* join name and the value into the same option again */
*
option_value
=
'='
;
}
else
store_to_string
(
&
send_buff
,
tmp_option
+
2
,
&
position
);
if
(
send_buff
.
is_error
()
||
if
(
send_buff
.
is_error
()
||
my_net_write
(
net
,
send_buff
.
buffer
,
(
uint
)
position
))
my_net_write
(
net
,
send_buff
.
buffer
,
(
uint
)
position
))
goto
err
;
goto
err
;
...
@@ -338,7 +355,7 @@ Start_instance::Start_instance(Instance_map *instance_map_arg,
...
@@ -338,7 +355,7 @@ Start_instance::Start_instance(Instance_map *instance_map_arg,
const
char
*
name
,
uint
len
)
const
char
*
name
,
uint
len
)
:
Command
(
instance_map_arg
)
:
Command
(
instance_map_arg
)
{
{
/* we make a search here, since we don't want t store the name */
/* we make a search here, since we don't want t
o
store the name */
if
((
instance
=
instance_map
->
find
(
name
,
len
)))
if
((
instance
=
instance_map
->
find
(
name
,
len
)))
instance_name
=
instance
->
options
.
instance_name
;
instance_name
=
instance
->
options
.
instance_name
;
}
}
...
@@ -359,9 +376,460 @@ int Start_instance::execute(struct st_net *net, ulong connection_id)
...
@@ -359,9 +376,460 @@ int Start_instance::execute(struct st_net *net, ulong connection_id)
if
(
!
(
instance
->
options
.
nonguarded
))
if
(
!
(
instance
->
options
.
nonguarded
))
instance_map
->
guardian
->
guard
(
instance
);
instance_map
->
guardian
->
guard
(
instance
);
net_send_ok
(
net
,
connection_id
);
net_send_ok
(
net
,
connection_id
,
"Instance started"
);
return
0
;
}
}
/* implementation for Show_instance_log: */
Show_instance_log
::
Show_instance_log
(
Instance_map
*
instance_map_arg
,
const
char
*
name
,
uint
len
,
Log_type
log_type_arg
,
const
char
*
size_arg
,
const
char
*
offset_arg
)
:
Command
(
instance_map_arg
)
{
Instance
*
instance
;
if
(
offset_arg
!=
NULL
)
offset
=
atoi
(
offset_arg
);
else
offset
=
0
;
size
=
atoi
(
size_arg
);
log_type
=
log_type_arg
;
/* we make a search here, since we don't want to store the name */
if
((
instance
=
instance_map
->
find
(
name
,
len
)))
{
instance_name
=
instance
->
options
.
instance_name
;
}
else
instance_name
=
NULL
;
}
int
Show_instance_log
::
do_command
(
struct
st_net
*
net
,
const
char
*
instance_name
)
{
enum
{
MAX_VERSION_LENGTH
=
40
};
Buffer
send_buff
;
/* buffer for packets */
LIST
name
;
LIST
*
field_list
;
NAME_WITH_LENGTH
name_field
;
uint
position
=
0
;
/* create list of the fileds to be passed to send_fields */
name_field
.
name
=
(
char
*
)
"Log"
;
name_field
.
length
=
20
;
name
.
data
=
&
name_field
;
field_list
=
list_add
(
NULL
,
&
name
);
/* cannot read negative number of bytes */
if
(
offset
>
size
)
return
ER_SYNTAX_ERROR
;
send_fields
(
net
,
field_list
);
{
Instance
*
instance
;
const
char
*
logpath
;
File
fd
;
if
((
instance
=
instance_map
->
find
(
instance_name
,
strlen
(
instance_name
)))
==
NULL
)
goto
err
;
switch
(
log_type
)
{
case
LOG_ERROR
:
logpath
=
instance
->
options
.
error_log
;
break
;
case
LOG_GENERAL
:
logpath
=
instance
->
options
.
query_log
;
break
;
case
LOG_SLOW
:
logpath
=
instance
->
options
.
slow_log
;
break
;
default:
logpath
=
NULL
;
}
/* Instance has no such log */
if
(
logpath
==
NULL
)
{
return
ER_NO_SUCH_LOG
;
}
else
if
(
*
logpath
==
'\0'
)
{
return
ER_GUESS_LOGFILE
;
}
if
((
fd
=
open
(
logpath
,
O_RDONLY
)))
{
size_t
buff_size
;
int
read_len
;
/* calculate buffer size */
struct
stat
file_stat
;
if
(
fstat
(
fd
,
&
file_stat
))
goto
err
;
buff_size
=
(
size
-
offset
);
/* read in one chunk */
read_len
=
my_seek
(
fd
,
file_stat
.
st_size
-
size
,
MY_SEEK_SET
,
MYF
(
0
));
char
*
bf
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
buff_size
);
read_len
=
my_read
(
fd
,
bf
,
buff_size
,
MYF
(
0
));
store_to_string
(
&
send_buff
,
(
char
*
)
bf
,
&
position
,
read_len
);
close
(
fd
);
}
else
{
return
ER_OPEN_LOGFILE
;
}
if
(
my_net_write
(
net
,
send_buff
.
buffer
,
(
uint
)
position
))
goto
err
;
}
send_eof
(
net
);
net_flush
(
net
);
return
0
;
err:
return
ER_OUT_OF_RESOURCES
;
}
int
Show_instance_log
::
execute
(
struct
st_net
*
net
,
ulong
connection_id
)
{
if
(
instance_name
!=
NULL
)
{
return
do_command
(
net
,
instance_name
);
}
else
{
return
ER_BAD_INSTANCE_NAME
;
}
}
/* implementation for Show_instance_log_files: */
Show_instance_log_files
::
Show_instance_log_files
(
Instance_map
*
instance_map_arg
,
const
char
*
name
,
uint
len
)
:
Command
(
instance_map_arg
)
{
Instance
*
instance
;
/* we make a search here, since we don't want to store the name */
if
((
instance
=
instance_map
->
find
(
name
,
len
)))
{
instance_name
=
instance
->
options
.
instance_name
;
}
else
instance_name
=
NULL
;
}
/*
The method sends a table with a the list of the log files
used by the instance.
SYNOPSYS
Show_instance_log_files::do_command()
net The network connection to the client.
instance_name The name of the instance.
RETURN
0 - ok
1 - error occured
*/
int
Show_instance_log_files
::
do_command
(
struct
st_net
*
net
,
const
char
*
instance_name
)
{
enum
{
MAX_VERSION_LENGTH
=
40
};
Buffer
send_buff
;
/* buffer for packets */
LIST
name
,
path
,
size
;
LIST
*
field_list
;
NAME_WITH_LENGTH
name_field
,
path_field
,
size_field
;
uint
position
=
0
;
/* create list of the fileds to be passed to send_fields */
name_field
.
name
=
(
char
*
)
"Logfile"
;
name_field
.
length
=
20
;
name
.
data
=
&
name_field
;
path_field
.
name
=
(
char
*
)
"Path"
;
path_field
.
length
=
20
;
path
.
data
=
&
path_field
;
size_field
.
name
=
(
char
*
)
"Filesize"
;
size_field
.
length
=
20
;
size
.
data
=
&
size_field
;
field_list
=
list_add
(
NULL
,
&
size
);
field_list
=
list_add
(
field_list
,
&
path
);
field_list
=
list_add
(
field_list
,
&
name
);
send_fields
(
net
,
field_list
);
Instance
*
instance
;
if
((
instance
=
instance_map
->
find
(
instance_name
,
strlen
(
instance_name
)))
==
NULL
)
goto
err
;
{
/*
We have alike structure in instance_options.cc. We use such to be able
to loop througt the options, which we need to handle in some common way.
*/
struct
log_files_st
{
const
char
*
name
;
const
char
*
value
;
}
logs
[]
=
{
{
"ERROR LOG"
,
instance
->
options
.
error_log
},
{
"GENERAL LOG"
,
instance
->
options
.
query_log
},
{
"SLOW LOG"
,
instance
->
options
.
slow_log
},
{
NULL
,
NULL
}
};
struct
log_files_st
*
log_files
;
instance
->
options
.
print_argv
();
for
(
log_files
=
logs
;
log_files
->
name
;
log_files
++
)
{
if
(
log_files
->
value
!=
NULL
)
{
struct
stat
file_stat
;
char
buff
[
20
];
position
=
0
;
/* store the type of the log in the send buffer */
store_to_string
(
&
send_buff
,
log_files
->
name
,
&
position
);
switch
(
stat
(
log_files
->
value
,
&
file_stat
))
{
case
0
:
if
(
S_ISREG
(
file_stat
.
st_mode
))
{
store_to_string
(
&
send_buff
,
(
char
*
)
log_files
->
value
,
&
position
);
int10_to_str
(
file_stat
.
st_size
,
buff
,
10
);
store_to_string
(
&
send_buff
,
(
char
*
)
buff
,
&
position
);
break
;
}
default:
store_to_string
(
&
send_buff
,
""
,
&
position
);
store_to_string
(
&
send_buff
,
(
char
*
)
"0"
,
&
position
);
}
if
(
my_net_write
(
net
,
send_buff
.
buffer
,
(
uint
)
position
))
goto
err
;
}
}
}
send_eof
(
net
);
net_flush
(
net
);
return
0
;
err:
return
1
;
}
int
Show_instance_log_files
::
execute
(
struct
st_net
*
net
,
ulong
connection_id
)
{
if
(
instance_name
!=
NULL
)
{
if
(
do_command
(
net
,
instance_name
))
return
ER_OUT_OF_RESOURCES
;
return
0
;
return
0
;
}
}
else
{
return
ER_BAD_INSTANCE_NAME
;
}
}
/* implementation for SET nstance_name.option=option_value: */
Set_option
::
Set_option
(
Instance_map
*
instance_map_arg
,
const
char
*
name
,
uint
len
,
const
char
*
option_arg
,
uint
option_len_arg
,
const
char
*
option_value_arg
,
uint
option_value_len_arg
)
:
Command
(
instance_map_arg
)
{
Instance
*
instance
;
/* we make a search here, since we don't want to store the name */
if
((
instance
=
instance_map
->
find
(
name
,
len
)))
{
instance_name
=
instance
->
options
.
instance_name
;
/* add prefix for add_option */
if
((
option_len_arg
<
MAX_OPTION_LEN
-
1
)
||
(
option_value_len_arg
<
MAX_OPTION_LEN
-
1
))
{
strncpy
(
option
,
option_arg
,
option_len_arg
);
option
[
option_len_arg
]
=
0
;
strncpy
(
option_value
,
option_value_arg
,
option_value_len_arg
);
option_value
[
option_value_len_arg
]
=
0
;
}
else
{
option
[
0
]
=
0
;
option_value
[
0
]
=
0
;
}
instance_name_len
=
len
;
}
else
{
instance_name
=
NULL
;
instance_name_len
=
0
;
}
}
/*
Correct the file. skip option could be used in future if we don't want to
let user change the options file (E.g. he lacks permissions to do that)
*/
int
Set_option
::
correct_file
(
bool
skip
)
{
FILE
*
cnf_file
;
const
char
*
default_location
=
"/etc/my.cnf"
;
char
linebuff
[
4096
],
*
ptr
;
uint
optlen
;
Buffer
file_buffer
;
uint
position
=
0
;
bool
isfound
=
false
;
optlen
=
strlen
(
option
);
if
(
!
(
cnf_file
=
my_fopen
(
default_location
,
O_RDONLY
,
MYF
(
0
))))
goto
err_fopen
;
while
(
fgets
(
linebuff
,
sizeof
(
linebuff
),
cnf_file
))
{
/* if the section is found traverse it */
if
(
isfound
)
{
/* skip the old value of the option we are changing */
if
(
strncmp
(
linebuff
,
option
,
optlen
))
{
/* copy all other lines line */
put_to_buff
(
&
file_buffer
,
linebuff
,
&
position
);
}
}
else
put_to_buff
(
&
file_buffer
,
linebuff
,
&
position
);
/* looking for appropriate instance section */
for
(
ptr
=
linebuff
;
my_isspace
(
&
my_charset_latin1
,
*
ptr
)
;
ptr
++
);
if
(
*
ptr
==
'['
)
{
/* copy the line to the buffer */
if
(
!
strncmp
(
++
ptr
,
instance_name
,
instance_name_len
))
{
isfound
=
true
;
/* add option */
if
(
!
skip
)
{
put_to_buff
(
&
file_buffer
,
option
,
&
position
);
if
(
option_value
[
0
]
!=
0
)
{
put_to_buff
(
&
file_buffer
,
"="
,
&
position
);
put_to_buff
(
&
file_buffer
,
option_value
,
&
position
);
}
/* add a newline */
put_to_buff
(
&
file_buffer
,
"
\n
"
,
&
position
);
}
}
else
isfound
=
false
;
/* mark that this section is of no interest to us */
}
}
if
(
my_fclose
(
cnf_file
,
MYF
(
0
)))
goto
err
;
/* we must hold an instance_map mutex while changing config file */
instance_map
->
lock
();
if
(
!
(
cnf_file
=
my_fopen
(
default_location
,
O_WRONLY
|
O_TRUNC
,
MYF
(
0
))))
goto
err
;
if
(
my_fwrite
(
cnf_file
,
file_buffer
.
buffer
,
position
,
MYF
(
MY_NABP
)))
goto
err
;
if
(
my_fclose
(
cnf_file
,
MYF
(
0
)))
goto
err
;
instance_map
->
unlock
();
return
0
;
err:
my_fclose
(
cnf_file
,
MYF
(
0
));
return
ER_OUT_OF_RESOURCES
;
err_fopen:
return
ER_ACCESS_OPTION_FILE
;
}
/*
The method sets an option in the the default config file (/etc/my.cnf).
SYNOPSYS
Set_option::do_command()
net The network connection to the client.
RETURN
0 - ok
1 - error occured
*/
int
Set_option
::
do_command
(
struct
st_net
*
net
)
{
return
correct_file
(
false
);
}
int
Set_option
::
execute
(
struct
st_net
*
net
,
ulong
connection_id
)
{
if
(
instance_name
!=
NULL
)
{
int
val
;
val
=
do_command
(
net
);
if
(
val
==
0
)
{
net_send_ok
(
net
,
connection_id
,
NULL
);
return
0
;
}
return
val
;
}
else
{
return
ER_BAD_INSTANCE_NAME
;
}
}
/* the only function from Unset_option we need to Implement */
int
Unset_option
::
do_command
(
struct
st_net
*
net
)
{
return
correct_file
(
true
);
}
}
...
@@ -371,7 +839,7 @@ Stop_instance::Stop_instance(Instance_map *instance_map_arg,
...
@@ -371,7 +839,7 @@ Stop_instance::Stop_instance(Instance_map *instance_map_arg,
const
char
*
name
,
uint
len
)
const
char
*
name
,
uint
len
)
:
Command
(
instance_map_arg
)
:
Command
(
instance_map_arg
)
{
{
/* we make a search here, since we don't want t store the name */
/* we make a search here, since we don't want t
o
store the name */
if
((
instance
=
instance_map
->
find
(
name
,
len
)))
if
((
instance
=
instance_map
->
find
(
name
,
len
)))
instance_name
=
instance
->
options
.
instance_name
;
instance_name
=
instance
->
options
.
instance_name
;
}
}
...
@@ -392,7 +860,7 @@ int Stop_instance::execute(struct st_net *net, ulong connection_id)
...
@@ -392,7 +860,7 @@ int Stop_instance::execute(struct st_net *net, ulong connection_id)
stop_guard
(
instance
);
stop_guard
(
instance
);
if
((
err_code
=
instance
->
stop
()))
if
((
err_code
=
instance
->
stop
()))
return
err_code
;
return
err_code
;
net_send_ok
(
net
,
connection_id
);
net_send_ok
(
net
,
connection_id
,
NULL
);
return
0
;
return
0
;
}
}
}
}
...
...
server-tools/instance-manager/commands.h
View file @
83f9ee07
...
@@ -18,6 +18,7 @@
...
@@ -18,6 +18,7 @@
#include "command.h"
#include "command.h"
#include "instance.h"
#include "instance.h"
#include "parse.h"
/*
/*
Print all instances of this instance manager.
Print all instances of this instance manager.
...
@@ -115,6 +116,45 @@ public:
...
@@ -115,6 +116,45 @@ public:
};
};
/*
Print requested part of the log
Grammar:
SHOW <instance_name> log {ERROR | SLOW | GENERAL} size[, offset_from_end]
*/
class
Show_instance_log
:
public
Command
{
public:
Show_instance_log
(
Instance_map
*
instance_map_arg
,
const
char
*
name
,
uint
len
,
Log_type
log_type_arg
,
const
char
*
size_arg
,
const
char
*
offset_arg
);
int
do_command
(
struct
st_net
*
net
,
const
char
*
instance_name
);
int
execute
(
struct
st_net
*
net
,
ulong
connection_id
);
Log_type
log_type
;
const
char
*
instance_name
;
uint
size
;
uint
offset
;
};
/*
Shows the list of the log files, used by an instance.
Grammar: SHOW <instance_name> LOG FILES
*/
class
Show_instance_log_files
:
public
Command
{
public:
Show_instance_log_files
(
Instance_map
*
instance_map_arg
,
const
char
*
name
,
uint
len
);
int
do_command
(
struct
st_net
*
net
,
const
char
*
instance_name
);
int
execute
(
struct
st_net
*
net
,
ulong
connection_id
);
const
char
*
instance_name
;
const
char
*
option
;
};
/*
/*
Syntax error command. This command is issued if parser reported a syntax error.
Syntax error command. This command is issued if parser reported a syntax error.
We need it to distinguish the parse error and the situation when parser internal
We need it to distinguish the parse error and the situation when parser internal
...
@@ -128,4 +168,50 @@ public:
...
@@ -128,4 +168,50 @@ public:
int
execute
(
struct
st_net
*
net
,
ulong
connection_id
);
int
execute
(
struct
st_net
*
net
,
ulong
connection_id
);
};
};
/*
Set an option for the instance.
Grammar: SET instance_name.option=option_value
*/
class
Set_option
:
public
Command
{
public:
Set_option
(
Instance_map
*
instance_map_arg
,
const
char
*
name
,
uint
len
,
const
char
*
option_arg
,
uint
option_len
,
const
char
*
option_value_arg
,
uint
option_value_len
);
/*
the following function is virtual to let Unset_option to use
*/
virtual
int
do_command
(
struct
st_net
*
net
);
int
execute
(
struct
st_net
*
net
,
ulong
connection_id
);
protected:
int
correct_file
(
bool
skip
);
public:
const
char
*
instance_name
;
uint
instance_name_len
;
/* buffer for the option */
enum
{
MAX_OPTION_LEN
=
1024
};
char
option
[
MAX_OPTION_LEN
];
char
option_value
[
MAX_OPTION_LEN
];
};
/*
Remove option of the instance from config file
Grammar: UNSET instance_name.option
*/
class
Unset_option
:
public
Set_option
{
public:
Unset_option
(
Instance_map
*
instance_map_arg
,
const
char
*
name
,
uint
len
,
const
char
*
option_arg
,
uint
option_len
,
const
char
*
option_value_arg
,
uint
option_value_len
)
:
Set_option
(
instance_map_arg
,
name
,
len
,
option_arg
,
option_len
,
option_value_arg
,
option_value_len
)
{}
int
do_command
(
struct
st_net
*
net
);
};
#endif
/* INCLUDES_MYSQL_INSTANCE_MANAGER_COMMANDS_H */
#endif
/* INCLUDES_MYSQL_INSTANCE_MANAGER_COMMANDS_H */
server-tools/instance-manager/factory.cc
View file @
83f9ee07
...
@@ -16,40 +16,85 @@
...
@@ -16,40 +16,85 @@
#include "factory.h"
#include "factory.h"
Show_instances
*
Command_factory
::
new_Show_instances
()
Show_instances
*
Command_factory
::
new_Show_instances
()
{
{
return
new
Show_instances
(
&
instance_map
);
return
new
Show_instances
(
&
instance_map
);
}
}
Flush_instances
*
Command_factory
::
new_Flush_instances
()
Flush_instances
*
Command_factory
::
new_Flush_instances
()
{
{
return
new
Flush_instances
(
&
instance_map
);
return
new
Flush_instances
(
&
instance_map
);
}
}
Show_instance_status
*
Command_factory
::
Show_instance_status
*
Command_factory
::
new_Show_instance_status
(
const
char
*
name
,
uint
len
)
new_Show_instance_status
(
const
char
*
name
,
uint
len
)
{
{
return
new
Show_instance_status
(
&
instance_map
,
name
,
len
);
return
new
Show_instance_status
(
&
instance_map
,
name
,
len
);
}
}
Show_instance_options
*
Command_factory
::
Show_instance_options
*
Command_factory
::
new_Show_instance_options
(
const
char
*
name
,
uint
len
)
new_Show_instance_options
(
const
char
*
name
,
uint
len
)
{
{
return
new
Show_instance_options
(
&
instance_map
,
name
,
len
);
return
new
Show_instance_options
(
&
instance_map
,
name
,
len
);
}
}
Start_instance
*
Command_factory
::
Start_instance
*
Command_factory
::
new_Start_instance
(
const
char
*
name
,
uint
len
)
new_Start_instance
(
const
char
*
name
,
uint
len
)
{
{
return
new
Start_instance
(
&
instance_map
,
name
,
len
);
return
new
Start_instance
(
&
instance_map
,
name
,
len
);
}
}
Stop_instance
*
Command_factory
::
new_Stop_instance
(
const
char
*
name
,
uint
len
)
Stop_instance
*
Command_factory
::
new_Stop_instance
(
const
char
*
name
,
uint
len
)
{
{
return
new
Stop_instance
(
&
instance_map
,
name
,
len
);
return
new
Stop_instance
(
&
instance_map
,
name
,
len
);
}
}
Syntax_error
*
Command_factory
::
new_Syntax_error
()
Syntax_error
*
Command_factory
::
new_Syntax_error
()
{
{
return
new
Syntax_error
();
return
new
Syntax_error
();
}
}
Set_option
*
Command_factory
::
new_Set_option
(
const
char
*
name
,
uint
len
,
const
char
*
option_arg
,
uint
option_len
,
const
char
*
option_value_arg
,
uint
option_value_len
)
{
return
new
Set_option
(
&
instance_map
,
name
,
len
,
option_arg
,
option_len
,
option_value_arg
,
option_value_len
);
}
Unset_option
*
Command_factory
::
new_Unset_option
(
const
char
*
name
,
uint
len
,
const
char
*
option_arg
,
uint
option_len
,
const
char
*
option_value_arg
,
uint
option_value_len
)
{
return
new
Unset_option
(
&
instance_map
,
name
,
len
,
option_arg
,
option_len
,
option_value_arg
,
option_value_len
);
}
Show_instance_log
*
Command_factory
::
new_Show_instance_log
(
const
char
*
name
,
uint
len
,
Log_type
log_type_arg
,
const
char
*
size
,
const
char
*
offset
)
{
return
new
Show_instance_log
(
&
instance_map
,
name
,
len
,
log_type_arg
,
size
,
offset
);
}
Show_instance_log_files
*
Command_factory
::
new_Show_instance_log_files
(
const
char
*
name
,
uint
len
)
{
return
new
Show_instance_log_files
(
&
instance_map
,
name
,
len
);
}
server-tools/instance-manager/factory.h
View file @
83f9ee07
...
@@ -26,6 +26,8 @@
...
@@ -26,6 +26,8 @@
Http_command_factory e.t.c. Also see comment in the instance_map.cc
Http_command_factory e.t.c. Also see comment in the instance_map.cc
*/
*/
class
Show_instances
;
class
Command_factory
class
Command_factory
{
{
public:
public:
...
@@ -33,12 +35,26 @@ public:
...
@@ -33,12 +35,26 @@ public:
{}
{}
Show_instances
*
new_Show_instances
();
Show_instances
*
new_Show_instances
();
Flush_instances
*
new_Flush_instances
();
Syntax_error
*
new_Syntax_error
();
Show_instance_status
*
new_Show_instance_status
(
const
char
*
name
,
uint
len
);
Show_instance_status
*
new_Show_instance_status
(
const
char
*
name
,
uint
len
);
Show_instance_options
*
new_Show_instance_options
(
const
char
*
name
,
uint
len
);
Show_instance_options
*
new_Show_instance_options
(
const
char
*
name
,
uint
len
);
Start_instance
*
new_Start_instance
(
const
char
*
name
,
uint
len
);
Start_instance
*
new_Start_instance
(
const
char
*
name
,
uint
len
);
Stop_instance
*
new_Stop_instance
(
const
char
*
name
,
uint
len
);
Stop_instance
*
new_Stop_instance
(
const
char
*
name
,
uint
len
);
Flush_instances
*
new_Flush_instances
();
Show_instance_log
*
new_Show_instance_log
(
const
char
*
name
,
uint
len
,
Syntax_error
*
new_Syntax_error
();
Log_type
log_type_arg
,
const
char
*
size
,
const
char
*
offset
);
Set_option
*
new_Set_option
(
const
char
*
name
,
uint
len
,
const
char
*
option_arg
,
uint
option_len
,
const
char
*
option_value_arg
,
uint
option_value_len
);
Unset_option
*
new_Unset_option
(
const
char
*
name
,
uint
len
,
const
char
*
option_arg
,
uint
option_len
,
const
char
*
option_value_arg
,
uint
option_value_len
);
Show_instance_log_files
*
new_Show_instance_log_files
(
const
char
*
name
,
uint
len
);
Instance_map
&
instance_map
;
Instance_map
&
instance_map
;
};
};
...
...
server-tools/instance-manager/instance_options.cc
View file @
83f9ee07
...
@@ -21,10 +21,10 @@
...
@@ -21,10 +21,10 @@
#include "instance_options.h"
#include "instance_options.h"
#include "parse_output.h"
#include "parse_output.h"
#include "parse.h"
#include "buffer.h"
#include "buffer.h"
#include <my_sys.h>
#include <my_sys.h>
#include <mysql.h>
#include <signal.h>
#include <signal.h>
#include <m_string.h>
#include <m_string.h>
...
@@ -54,7 +54,7 @@ int Instance_options::get_default_option(char *result, size_t result_len,
...
@@ -54,7 +54,7 @@ int Instance_options::get_default_option(char *result, size_t result_len,
int
rc
=
1
;
int
rc
=
1
;
char
verbose_option
[]
=
" --no-defaults --verbose --help"
;
char
verbose_option
[]
=
" --no-defaults --verbose --help"
;
Buffer
cmd
(
strlen
(
mysqld_path
)
+
sizeof
(
verbose_option
)
+
1
);
Buffer
cmd
(
strlen
(
mysqld_path
)
+
sizeof
(
verbose_option
)
+
1
);
if
(
cmd
.
get_size
())
/* malloc succeeded */
if
(
cmd
.
get_size
())
/* malloc succeeded */
{
{
cmd
.
append
(
position
,
mysqld_path
,
strlen
(
mysqld_path
));
cmd
.
append
(
position
,
mysqld_path
,
strlen
(
mysqld_path
));
...
@@ -76,6 +76,135 @@ err:
...
@@ -76,6 +76,135 @@ err:
}
}
int
Instance_options
::
fill_log_options
()
{
/* array for the log option for mysqld */
enum
{
MAX_LOG_OPTIONS
=
8
};
enum
{
MAX_LOG_OPTION_LENGTH
=
256
};
/* the last option must be '\0', so we reserve space for it */
char
log_options
[
MAX_LOG_OPTIONS
+
1
][
MAX_LOG_OPTION_LENGTH
];
Buffer
buff
;
uint
position
=
0
;
char
**
tmp_argv
=
argv
;
char
datadir
[
MAX_LOG_OPTION_LENGTH
];
char
hostname
[
MAX_LOG_OPTION_LENGTH
];
uint
hostname_length
;
struct
log_files_st
{
const
char
*
name
;
uint
length
;
const
char
**
value
;
const
char
*
default_suffix
;
}
logs
[]
=
{
{
"--log-error"
,
11
,
&
error_log
,
".err"
},
{
"--log"
,
5
,
&
query_log
,
".log"
},
{
"--log-slow-queries"
,
18
,
&
slow_log
,
"-slow.log"
},
{
NULL
,
0
,
NULL
,
NULL
}
};
struct
log_files_st
*
log_files
;
/* clean the buffer before usage */
bzero
(
log_options
,
sizeof
(
log_options
));
/* create a "mysqld <argv_options>" command in the buffer */
buff
.
append
(
position
,
mysqld_path
,
strlen
(
mysqld_path
));
position
=
strlen
(
mysqld_path
);
/* skip the first option */
tmp_argv
++
;
while
(
*
tmp_argv
!=
0
)
{
buff
.
append
(
position
,
" "
,
1
);
position
++
;
buff
.
append
(
position
,
*
tmp_argv
,
strlen
(
*
tmp_argv
));
position
+=
strlen
(
*
tmp_argv
);
tmp_argv
++
;
}
buff
.
append
(
position
,
"
\0
"
,
1
);
position
++
;
/* get options and parse them */
if
(
parse_arguments
(
buff
.
buffer
,
"--log"
,
(
char
*
)
log_options
,
MAX_LOG_OPTIONS
+
1
,
MAX_LOG_OPTION_LENGTH
))
goto
err
;
/* compute hostname and datadir for the instance */
if
(
mysqld_datadir
==
NULL
)
{
if
(
get_default_option
(
datadir
,
MAX_LOG_OPTION_LENGTH
,
"--datadir"
))
goto
err
;
}
else
/* below is safe, as --datadir always has a value */
strncpy
(
datadir
,
strchr
(
mysqld_datadir
,
'='
)
+
1
,
MAX_LOG_OPTION_LENGTH
);
if
(
gethostname
(
hostname
,
sizeof
(
hostname
)
-
1
)
<
0
)
strmov
(
hostname
,
"mysql"
);
hostname
[
MAX_LOG_OPTION_LENGTH
-
1
]
=
0
;
/* Safety */
hostname_length
=
strlen
(
hostname
);
for
(
log_files
=
logs
;
log_files
->
name
;
log_files
++
)
{
for
(
int
i
=
0
;
(
i
<
MAX_LOG_OPTIONS
)
&&
(
log_options
[
i
][
0
]
!=
'\0'
);
i
++
)
{
if
(
!
strncmp
(
log_options
[
i
],
log_files
->
name
,
log_files
->
length
))
{
/*
This is really log_files->name option if and only if it is followed
by '=', '\0' or space character. This way we can distinguish such
options as '--log' and '--log-bin'. This is checked in the following
two statements.
*/
if
(
log_options
[
i
][
log_files
->
length
]
==
'\0'
||
my_isspace
(
default_charset_info
,
log_options
[
i
][
log_files
->
length
]))
{
char
full_name
[
MAX_LOG_OPTION_LENGTH
];
fn_format
(
full_name
,
hostname
,
datadir
,
""
,
MY_UNPACK_FILENAME
|
MY_SAFE_PATH
);
if
((
MAX_LOG_OPTION_LENGTH
-
strlen
(
full_name
))
>
strlen
(
log_files
->
default_suffix
))
{
strcpy
(
full_name
+
strlen
(
full_name
),
log_files
->
default_suffix
);
}
else
goto
err
;
*
(
log_files
->
value
)
=
strdup_root
(
&
alloc
,
datadir
);
}
if
(
log_options
[
i
][
log_files
->
length
]
==
'='
)
{
char
full_name
[
MAX_LOG_OPTION_LENGTH
];
fn_format
(
full_name
,
log_options
[
i
]
+
log_files
->
length
+
1
,
datadir
,
""
,
MY_UNPACK_FILENAME
|
MY_SAFE_PATH
);
if
(
!
(
*
(
log_files
->
value
)
=
strdup_root
(
&
alloc
,
full_name
)))
goto
err
;
}
}
}
}
return
0
;
err:
return
1
;
}
int
Instance_options
::
get_pid_filename
(
char
*
result
)
int
Instance_options
::
get_pid_filename
(
char
*
result
)
{
{
const
char
*
pid_file
=
mysqld_pid_file
;
const
char
*
pid_file
=
mysqld_pid_file
;
...
@@ -190,6 +319,8 @@ int Instance_options::complete_initialization(const char *default_path,
...
@@ -190,6 +319,8 @@ int Instance_options::complete_initialization(const char *default_path,
options_array
.
elements
*
sizeof
(
char
*
));
options_array
.
elements
*
sizeof
(
char
*
));
argv
[
filled_default_options
+
options_array
.
elements
]
=
0
;
argv
[
filled_default_options
+
options_array
.
elements
]
=
0
;
fill_log_options
();
return
0
;
return
0
;
err:
err:
...
...
server-tools/instance-manager/instance_options.h
View file @
83f9ee07
...
@@ -40,7 +40,8 @@ public:
...
@@ -40,7 +40,8 @@ public:
mysqld_socket
(
0
),
mysqld_datadir
(
0
),
mysqld_socket
(
0
),
mysqld_datadir
(
0
),
mysqld_bind_address
(
0
),
mysqld_pid_file
(
0
),
mysqld_port
(
0
),
mysqld_bind_address
(
0
),
mysqld_pid_file
(
0
),
mysqld_port
(
0
),
mysqld_port_val
(
0
),
mysqld_path
(
0
),
nonguarded
(
0
),
shutdown_delay
(
0
),
mysqld_port_val
(
0
),
mysqld_path
(
0
),
nonguarded
(
0
),
shutdown_delay
(
0
),
shutdown_delay_val
(
0
),
filled_default_options
(
0
)
shutdown_delay_val
(
0
),
error_log
(
0
),
query_log
(
0
),
slow_log
(
0
),
filled_default_options
(
0
)
{}
{}
~
Instance_options
();
~
Instance_options
();
/* fills in argv */
/* fills in argv */
...
@@ -76,9 +77,14 @@ public:
...
@@ -76,9 +77,14 @@ public:
const
char
*
nonguarded
;
const
char
*
nonguarded
;
const
char
*
shutdown_delay
;
const
char
*
shutdown_delay
;
uint
shutdown_delay_val
;
uint
shutdown_delay_val
;
const
char
*
error_log
;
const
char
*
query_log
;
const
char
*
slow_log
;
/* this value is computed and cashed here */
/* this value is computed and cashed here */
DYNAMIC_ARRAY
options_array
;
DYNAMIC_ARRAY
options_array
;
private:
private:
int
fill_log_options
();
int
add_to_argv
(
const
char
*
option
);
int
add_to_argv
(
const
char
*
option
);
int
get_default_option
(
char
*
result
,
size_t
result_len
,
int
get_default_option
(
char
*
result
,
size_t
result_len
,
const
char
*
option_name
);
const
char
*
option_name
);
...
...
server-tools/instance-manager/messages.cc
View file @
83f9ee07
...
@@ -57,6 +57,15 @@ static const char *mysqld_error_message(unsigned sql_errno)
...
@@ -57,6 +57,15 @@ static const char *mysqld_error_message(unsigned sql_errno)
" or resources shortage"
;
" or resources shortage"
;
case
ER_STOP_INSTANCE
:
case
ER_STOP_INSTANCE
:
return
"Cannot stop instance"
;
return
"Cannot stop instance"
;
case
ER_NO_SUCH_LOG
:
return
"The instance has no such log enabled"
;
case
ER_OPEN_LOGFILE
:
return
"Cannot open log file"
;
case
ER_GUESS_LOGFILE
:
return
"Cannot guess the log filename. Try specifying full log name"
"in the instance options"
;
case
ER_ACCESS_OPTION_FILE
:
return
"Cannot open the option file to edit. Check permissions"
;
default:
default:
DBUG_ASSERT
(
0
);
DBUG_ASSERT
(
0
);
return
0
;
return
0
;
...
...
server-tools/instance-manager/mysql_connection.cc
View file @
83f9ee07
...
@@ -284,7 +284,7 @@ int Mysql_connection_thread::check_connection()
...
@@ -284,7 +284,7 @@ int Mysql_connection_thread::check_connection()
net_send_error
(
&
net
,
ER_ACCESS_DENIED_ERROR
);
net_send_error
(
&
net
,
ER_ACCESS_DENIED_ERROR
);
return
1
;
return
1
;
}
}
net_send_ok
(
&
net
,
connection_id
);
net_send_ok
(
&
net
,
connection_id
,
NULL
);
return
0
;
return
0
;
}
}
...
@@ -332,7 +332,7 @@ int Mysql_connection_thread::dispatch_command(enum enum_server_command command,
...
@@ -332,7 +332,7 @@ int Mysql_connection_thread::dispatch_command(enum enum_server_command command,
return
1
;
return
1
;
case
COM_PING
:
case
COM_PING
:
log_info
(
"query for connection %d received ping command"
,
connection_id
);
log_info
(
"query for connection %d received ping command"
,
connection_id
);
net_send_ok
(
&
net
,
connection_id
);
net_send_ok
(
&
net
,
connection_id
,
NULL
);
break
;
break
;
case
COM_QUERY
:
case
COM_QUERY
:
{
{
...
...
server-tools/instance-manager/mysql_manager_error.h
View file @
83f9ee07
...
@@ -23,5 +23,9 @@
...
@@ -23,5 +23,9 @@
#define ER_INSTANCE_ALREADY_STARTED 3002
#define ER_INSTANCE_ALREADY_STARTED 3002
#define ER_CANNOT_START_INSTANCE 3003
#define ER_CANNOT_START_INSTANCE 3003
#define ER_STOP_INSTANCE 3004
#define ER_STOP_INSTANCE 3004
#define ER_NO_SUCH_LOG 3005
#define ER_OPEN_LOGFILE 3006
#define ER_GUESS_LOGFILE 3007
#define ER_ACCESS_OPTION_FILE 3008
#endif
/* INCLUDES_MYSQL_INSTANCE_MANAGER_MYSQL_MANAGER_ERROR_H */
#endif
/* INCLUDES_MYSQL_INSTANCE_MANAGER_MYSQL_MANAGER_ERROR_H */
server-tools/instance-manager/parse.cc
View file @
83f9ee07
...
@@ -15,38 +15,56 @@
...
@@ -15,38 +15,56 @@
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 "parse.h"
#include "factory.h"
#include <string.h>
#include <string.h>
enum
Token
enum
Token
{
{
TOK_FLUSH
=
0
,
TOK_ERROR
=
0
,
/* Encodes the "ERROR" word, it doesn't indicate error. */
TOK_FILES
,
TOK_FLUSH
,
TOK_GENERAL
,
TOK_INSTANCE
,
TOK_INSTANCE
,
TOK_INSTANCES
,
TOK_INSTANCES
,
TOK_LOG
,
TOK_OPTIONS
,
TOK_OPTIONS
,
TOK_SET
,
TOK_SLOW
,
TOK_START
,
TOK_START
,
TOK_STATUS
,
TOK_STATUS
,
TOK_STOP
,
TOK_STOP
,
TOK_SHOW
,
TOK_SHOW
,
TOK_UNSET
,
TOK_NOT_FOUND
,
// must be after all tokens
TOK_NOT_FOUND
,
// must be after all tokens
TOK_END
TOK_END
};
};
struct
tokens_st
struct
tokens_st
{
{
uint
length
;
uint
length
;
const
char
*
tok_name
;
const
char
*
tok_name
;
};
};
static
struct
tokens_st
tokens
[]
=
{
static
struct
tokens_st
tokens
[]
=
{
{
5
,
"ERROR"
},
{
5
,
"FILES"
},
{
5
,
"FLUSH"
},
{
5
,
"FLUSH"
},
{
7
,
"GENERAL"
},
{
8
,
"INSTANCE"
},
{
8
,
"INSTANCE"
},
{
9
,
"INSTANCES"
},
{
9
,
"INSTANCES"
},
{
3
,
"LOG"
},
{
7
,
"OPTIONS"
},
{
7
,
"OPTIONS"
},
{
3
,
"SET"
},
{
4
,
"SLOW"
},
{
5
,
"START"
},
{
5
,
"START"
},
{
6
,
"STATUS"
},
{
6
,
"STATUS"
},
{
4
,
"STOP"
},
{
4
,
"STOP"
},
{
4
,
"SHOW"
}
{
4
,
"SHOW"
},
{
5
,
"UNSET"
}
};
};
...
@@ -86,13 +104,6 @@ Token shift_token(const char **text, uint *word_len)
...
@@ -86,13 +104,6 @@ Token shift_token(const char **text, uint *word_len)
}
}
void
print_token
(
const
char
*
token
,
uint
tok_len
)
{
for
(
uint
i
=
0
;
i
<
tok_len
;
++
i
)
printf
(
"%c"
,
token
[
i
]);
}
int
get_text_id
(
const
char
**
text
,
uint
*
word_len
,
const
char
**
id
)
int
get_text_id
(
const
char
**
text
,
uint
*
word_len
,
const
char
**
id
)
{
{
get_word
(
text
,
word_len
);
get_word
(
text
,
word_len
);
...
@@ -108,7 +119,15 @@ Command *parse_command(Command_factory *factory, const char *text)
...
@@ -108,7 +119,15 @@ Command *parse_command(Command_factory *factory, const char *text)
uint
word_len
;
uint
word_len
;
const
char
*
instance_name
;
const
char
*
instance_name
;
uint
instance_name_len
;
uint
instance_name_len
;
const
char
*
option
;
uint
option_len
;
const
char
*
option_value
;
uint
option_value_len
;
const
char
*
log_size
;
Command
*
command
;
Command
*
command
;
const
char
*
saved_text
=
text
;
bool
skip
=
false
;
const
char
*
tmp
;
Token
tok1
=
shift_token
(
&
text
,
&
word_len
);
Token
tok1
=
shift_token
(
&
text
,
&
word_len
);
...
@@ -143,6 +162,55 @@ Command *parse_command(Command_factory *factory, const char *text)
...
@@ -143,6 +162,55 @@ Command *parse_command(Command_factory *factory, const char *text)
command
=
factory
->
new_Flush_instances
();
command
=
factory
->
new_Flush_instances
();
break
;
break
;
case
TOK_UNSET
:
skip
=
true
;
case
TOK_SET
:
get_text_id
(
&
text
,
&
instance_name_len
,
&
instance_name
);
text
+=
instance_name_len
;
/* the next token should be a dot */
get_word
(
&
text
,
&
word_len
);
if
(
*
text
!=
'.'
)
goto
syntax_error
;
text
++
;
get_word
(
&
text
,
&
option_len
,
NONSPACE
);
option
=
text
;
if
((
tmp
=
strchr
(
text
,
'='
))
!=
NULL
)
option_len
=
tmp
-
text
;
text
+=
option_len
;
get_word
(
&
text
,
&
word_len
);
if
(
*
text
==
'='
)
{
text
++
;
/* skip '=' */
get_word
(
&
text
,
&
option_value_len
,
NONSPACE
);
option_value
=
text
;
text
+=
option_value_len
;
}
else
{
option_value
=
""
;
option_value_len
=
0
;
}
/* should be empty */
get_word
(
&
text
,
&
word_len
);
if
(
word_len
)
{
goto
syntax_error
;
}
if
(
skip
)
command
=
factory
->
new_Unset_option
(
instance_name
,
instance_name_len
,
option
,
option_len
,
option_value
,
option_value_len
);
else
command
=
factory
->
new_Set_option
(
instance_name
,
instance_name_len
,
option
,
option_len
,
option_value
,
option_value_len
);
break
;
case
TOK_SHOW
:
case
TOK_SHOW
:
switch
(
shift_token
(
&
text
,
&
word_len
))
{
switch
(
shift_token
(
&
text
,
&
word_len
))
{
case
TOK_INSTANCES
:
case
TOK_INSTANCES
:
...
@@ -157,6 +225,7 @@ Command *parse_command(Command_factory *factory, const char *text)
...
@@ -157,6 +225,7 @@ Command *parse_command(Command_factory *factory, const char *text)
case
TOK_STATUS
:
case
TOK_STATUS
:
get_text_id
(
&
text
,
&
instance_name_len
,
&
instance_name
);
get_text_id
(
&
text
,
&
instance_name_len
,
&
instance_name
);
text
+=
instance_name_len
;
text
+=
instance_name_len
;
/* check that this is the end of the command */
get_word
(
&
text
,
&
word_len
);
get_word
(
&
text
,
&
word_len
);
if
(
word_len
)
if
(
word_len
)
goto
syntax_error
;
goto
syntax_error
;
...
@@ -172,7 +241,87 @@ Command *parse_command(Command_factory *factory, const char *text)
...
@@ -172,7 +241,87 @@ Command *parse_command(Command_factory *factory, const char *text)
}
}
break
;
break
;
default:
default:
goto
syntax_error
;
instance_name
=
text
-
word_len
;
instance_name_len
=
word_len
;
if
(
instance_name_len
)
{
Log_type
log_type
;
switch
(
shift_token
(
&
text
,
&
word_len
))
{
case
TOK_LOG
:
switch
(
Token
tok3
=
shift_token
(
&
text
,
&
word_len
))
{
case
TOK_FILES
:
get_word
(
&
text
,
&
word_len
);
/* check that this is the end of the command */
if
(
word_len
)
goto
syntax_error
;
command
=
(
Command
*
)
factory
->
new_Show_instance_log_files
(
instance_name
,
instance_name_len
);
break
;
case
TOK_ERROR
:
case
TOK_GENERAL
:
case
TOK_SLOW
:
/* define a log type */
switch
(
tok3
)
{
case
TOK_ERROR
:
log_type
=
LOG_ERROR
;
break
;
case
TOK_GENERAL
:
log_type
=
LOG_GENERAL
;
break
;
case
TOK_SLOW
:
log_type
=
LOG_SLOW
;
break
;
default:
goto
syntax_error
;
}
/* get the size of the log we want to retrieve */
get_text_id
(
&
text
,
&
word_len
,
&
log_size
);
text
+=
word_len
;
/* this parameter is required */
if
(
!
word_len
)
goto
syntax_error
;
/* the next token should be comma, or nothing */
get_word
(
&
text
,
&
word_len
);
switch
(
*
text
)
{
case
','
:
text
++
;
/* swallow the comma */
/* read the next word */
get_word
(
&
text
,
&
word_len
);
if
(
!
word_len
)
goto
syntax_error
;
command
=
(
Command
*
)
factory
->
new_Show_instance_log
(
instance_name
,
instance_name_len
,
log_type
,
log_size
,
text
);
//get_text_id(&text, &log_size_len, &log_size);
break
;
case
'\0'
:
command
=
(
Command
*
)
factory
->
new_Show_instance_log
(
instance_name
,
instance_name_len
,
log_type
,
log_size
,
NULL
);
break
;
/* this is ok */
default:
goto
syntax_error
;
}
break
;
default:
goto
syntax_error
;
}
break
;
default:
goto
syntax_error
;
}
}
else
goto
syntax_error
;
break
;
}
}
break
;
break
;
default:
default:
...
@@ -182,3 +331,43 @@ syntax_error:
...
@@ -182,3 +331,43 @@ syntax_error:
return
command
;
return
command
;
}
}
/* additional parse function, needed to parse */
/* create an array of strings from the output, starting from "word" */
int
parse_arguments
(
const
char
*
command
,
const
char
*
word
,
char
*
result
,
int
max_result_cardinality
,
size_t
option_len
)
{
int
wordlen
;
int
i
=
0
;
/* result array index */
/* should be enough to store the string from the output */
enum
{
MAX_LINE_LEN
=
4096
};
char
linebuf
[
MAX_LINE_LEN
];
wordlen
=
strlen
(
word
);
uint
lineword_len
=
0
;
const
char
*
linep
=
command
;
get_word
((
const
char
**
)
&
linep
,
&
lineword_len
,
NONSPACE
);
while
((
*
linep
!=
'\0'
)
&&
(
i
<
max_result_cardinality
))
{
if
(
!
strncmp
(
word
,
linep
,
wordlen
))
{
strncpy
(
result
+
i
*
option_len
,
linep
,
lineword_len
);
*
(
result
+
i
*
option_len
+
lineword_len
)
=
'\0'
;
linep
+=
lineword_len
;
i
++
;
}
else
linep
+=
lineword_len
;
get_word
((
const
char
**
)
&
linep
,
&
lineword_len
,
NONSPACE
);
/* stop if we've filled the array */
if
(
i
>=
max_result_cardinality
)
break
;
}
return
0
;
}
server-tools/instance-manager/parse.h
View file @
83f9ee07
...
@@ -16,10 +16,24 @@
...
@@ -16,10 +16,24 @@
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 "factory.h"
#include <my_global.h>
#include <my_sys.h>
class
Command
;
class
Command_factory
;
enum
Log_type
{
LOG_ERROR
=
0
,
LOG_GENERAL
,
LOG_SLOW
};
Command
*
parse_command
(
Command_factory
*
factory
,
const
char
*
text
);
Command
*
parse_command
(
Command_factory
*
factory
,
const
char
*
text
);
int
parse_arguments
(
const
char
*
command
,
const
char
*
word
,
char
*
result
,
int
max_result_cardinality
,
size_t
option_len
);
/* define kinds of the word seek method */
/* define kinds of the word seek method */
enum
{
ALPHANUM
=
1
,
NONSPACE
};
enum
{
ALPHANUM
=
1
,
NONSPACE
};
...
@@ -44,10 +58,12 @@ inline void get_word(const char **text, uint *word_len,
...
@@ -44,10 +58,12 @@ inline void get_word(const char **text, uint *word_len,
while
(
my_isalnum
(
default_charset_info
,
*
word_end
))
while
(
my_isalnum
(
default_charset_info
,
*
word_end
))
++
word_end
;
++
word_end
;
else
else
while
(
!
my_isspace
(
default_charset_info
,
*
word_end
))
while
(
!
my_isspace
(
default_charset_info
,
*
word_end
)
&&
(
*
word_end
!=
'\0'
))
++
word_end
;
++
word_end
;
*
word_len
=
word_end
-
*
text
;
*
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 @
83f9ee07
...
@@ -47,7 +47,7 @@ int parse_output_and_get_value(const char *command, const char *word,
...
@@ -47,7 +47,7 @@ int parse_output_and_get_value(const char *command, const char *word,
{
{
FILE
*
output
;
FILE
*
output
;
uint
wordlen
;
uint
wordlen
;
/* should be enough
t
to store the string from the output */
/* should be enough to store the string from the output */
enum
{
MAX_LINE_LEN
=
512
};
enum
{
MAX_LINE_LEN
=
512
};
char
linebuf
[
MAX_LINE_LEN
];
char
linebuf
[
MAX_LINE_LEN
];
...
@@ -99,3 +99,4 @@ pclose:
...
@@ -99,3 +99,4 @@ pclose:
err:
err:
return
1
;
return
1
;
}
}
server-tools/instance-manager/parse_output.h
View file @
83f9ee07
#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_OUTPUT_H
#define INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_OUTPUT_H
/* Copyright (C) 2004 MySQL AB
/* Copyright (C) 2004 MySQL AB
This program is free software; you can redistribute it and/or modify
This program is free software; you can redistribute it and/or modify
...
@@ -17,3 +19,4 @@
...
@@ -17,3 +19,4 @@
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
);
#endif
/* INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_OUTPUT_H */
server-tools/instance-manager/protocol.cc
View file @
83f9ee07
...
@@ -24,15 +24,25 @@
...
@@ -24,15 +24,25 @@
static
char
eof_buff
[
1
]
=
{
(
char
)
254
};
/* Marker for end of fields */
static
char
eof_buff
[
1
]
=
{
(
char
)
254
};
/* Marker for end of fields */
int
net_send_ok
(
struct
st_net
*
net
,
unsigned
long
connection_id
)
int
net_send_ok
(
struct
st_net
*
net
,
unsigned
long
connection_id
,
const
char
*
message
)
{
{
char
buff
[
1
+
// packet type code
/*
9
+
// affected rows count
The format of a packet
9
+
// connection id
1 packet type code
2
+
// thread return status
1-9 affected rows count
2
];
// warning count
1-9 connection id
2 thread return status
2 warning count
1-9 + message length message to send (isn't stored if no message)
*/
Buffer
buff
;
char
*
pos
=
buff
.
buffer
;
/* check that we have space to hold mandatory fields */
buff
.
reserve
(
0
,
23
);
char
*
pos
=
buff
;
enum
{
OK_PACKET_CODE
=
0
};
enum
{
OK_PACKET_CODE
=
0
};
*
pos
++=
OK_PACKET_CODE
;
*
pos
++=
OK_PACKET_CODE
;
pos
=
net_store_length
(
pos
,
(
ulonglong
)
0
);
pos
=
net_store_length
(
pos
,
(
ulonglong
)
0
);
...
@@ -43,7 +53,15 @@ int net_send_ok(struct st_net *net, unsigned long connection_id)
...
@@ -43,7 +53,15 @@ int net_send_ok(struct st_net *net, unsigned long connection_id)
int2store
(
pos
,
0
);
int2store
(
pos
,
0
);
pos
+=
2
;
pos
+=
2
;
return
my_net_write
(
net
,
buff
,
pos
-
buff
)
||
net_flush
(
net
);
uint
position
=
pos
-
buff
.
buffer
;
/* we might need it for message */
if
(
message
!=
NULL
)
{
buff
.
reserve
(
position
,
9
+
strlen
(
message
));
store_to_string
(
&
buff
,
message
,
&
position
);
}
return
my_net_write
(
net
,
buff
.
buffer
,
position
)
||
net_flush
(
net
);
}
}
...
@@ -99,15 +117,15 @@ char *net_store_length(char *pkg, uint length)
...
@@ -99,15 +117,15 @@ char *net_store_length(char *pkg, uint length)
}
}
int
store_to_string
(
Buffer
*
buf
,
const
char
*
string
,
uint
*
position
)
int
store_to_string
(
Buffer
*
buf
,
const
char
*
string
,
uint
*
position
,
uint
string_len
)
{
{
uint
currpos
;
uint
currpos
;
uint
string_len
;
string_len
=
strlen
(
string
);
if
(
buf
->
reserve
(
*
position
,
9
))
if
(
buf
->
reserve
(
*
position
,
2
))
goto
err
;
goto
err
;
currpos
=
(
net_store_length
(
buf
->
buffer
+
*
position
,
string_len
)
-
buf
->
buffer
);
currpos
=
(
net_store_length
(
buf
->
buffer
+
*
position
,
(
ulonglong
)
string_len
)
-
buf
->
buffer
);
if
(
buf
->
append
(
currpos
,
string
,
string_len
))
if
(
buf
->
append
(
currpos
,
string
,
string_len
))
goto
err
;
goto
err
;
*
position
=
*
position
+
string_len
+
(
currpos
-
*
position
);
*
position
=
*
position
+
string_len
+
(
currpos
-
*
position
);
...
@@ -118,6 +136,15 @@ err:
...
@@ -118,6 +136,15 @@ err:
}
}
int
store_to_string
(
Buffer
*
buf
,
const
char
*
string
,
uint
*
position
)
{
uint
string_len
;
string_len
=
strlen
(
string
);
return
store_to_string
(
buf
,
string
,
position
,
string_len
);
}
int
send_eof
(
struct
st_net
*
net
)
int
send_eof
(
struct
st_net
*
net
)
{
{
char
buff
[
1
+
/* eof packet code */
char
buff
[
1
+
/* eof packet code */
...
...
server-tools/instance-manager/protocol.h
View file @
83f9ee07
...
@@ -27,7 +27,8 @@ typedef struct field {
...
@@ -27,7 +27,8 @@ typedef struct field {
struct
st_net
;
struct
st_net
;
int
net_send_ok
(
struct
st_net
*
net
,
unsigned
long
connection_id
);
int
net_send_ok
(
struct
st_net
*
net
,
unsigned
long
connection_id
,
const
char
*
message
);
int
net_send_error
(
struct
st_net
*
net
,
unsigned
sql_errno
);
int
net_send_error
(
struct
st_net
*
net
,
unsigned
sql_errno
);
...
@@ -39,6 +40,9 @@ char *net_store_length(char *pkg, uint length);
...
@@ -39,6 +40,9 @@ char *net_store_length(char *pkg, uint length);
int
store_to_string
(
Buffer
*
buf
,
const
char
*
string
,
uint
*
position
);
int
store_to_string
(
Buffer
*
buf
,
const
char
*
string
,
uint
*
position
);
int
store_to_string
(
Buffer
*
buf
,
const
char
*
string
,
uint
*
position
,
uint
string_len
);
int
send_eof
(
struct
st_net
*
net
);
int
send_eof
(
struct
st_net
*
net
);
#endif
/* INCLUDES_MYSQL_INSTANCE_MANAGER_PROTOCOL_H */
#endif
/* INCLUDES_MYSQL_INSTANCE_MANAGER_PROTOCOL_H */
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