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 @@
#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: */
...
...
@@ -106,7 +119,7 @@ int Flush_instances::execute(struct st_net *net, ulong connection_id)
if
(
instance_map
->
flush_instances
())
return
ER_OUT_OF_RESOURCES
;
net_send_ok
(
net
,
connection_id
);
net_send_ok
(
net
,
connection_id
,
NULL
);
return
0
;
}
...
...
@@ -119,7 +132,7 @@ Show_instance_status::Show_instance_status(Instance_map *instance_map_arg,
{
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
)))
{
instance_name
=
instance
->
options
.
instance_name
;
...
...
@@ -225,7 +238,7 @@ Show_instance_options::Show_instance_options(Instance_map *instance_map_arg,
{
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
)))
{
instance_name
=
instance
->
options
.
instance_name
;
...
...
@@ -294,13 +307,17 @@ int Show_instance_options::do_command(struct st_net *net,
char
*
tmp_option
,
*
option_value
;
get_dynamic
(
&
(
instance
->
options
.
options_array
),
(
gptr
)
&
tmp_option
,
i
);
option_value
=
strchr
(
tmp_option
,
'='
);
/* split the option string into two parts */
*
option_value
=
0
;
/* split the option string into two parts if it has a value */
position
=
0
;
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
=
'='
;
if
(
option_value
!=
NULL
)
{
*
option_value
=
0
;
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
()
||
my_net_write
(
net
,
send_buff
.
buffer
,
(
uint
)
position
))
goto
err
;
...
...
@@ -338,7 +355,7 @@ Start_instance::Start_instance(Instance_map *instance_map_arg,
const
char
*
name
,
uint
len
)
:
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
)))
instance_name
=
instance
->
options
.
instance_name
;
}
...
...
@@ -359,9 +376,460 @@ int Start_instance::execute(struct st_net *net, ulong connection_id)
if
(
!
(
instance
->
options
.
nonguarded
))
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
;
}
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,
const
char
*
name
,
uint
len
)
:
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
)))
instance_name
=
instance
->
options
.
instance_name
;
}
...
...
@@ -392,7 +860,7 @@ int Stop_instance::execute(struct st_net *net, ulong connection_id)
stop_guard
(
instance
);
if
((
err_code
=
instance
->
stop
()))
return
err_code
;
net_send_ok
(
net
,
connection_id
);
net_send_ok
(
net
,
connection_id
,
NULL
);
return
0
;
}
}
...
...
server-tools/instance-manager/commands.h
View file @
83f9ee07
...
...
@@ -18,6 +18,7 @@
#include "command.h"
#include "instance.h"
#include "parse.h"
/*
Print all instances of this instance manager.
...
...
@@ -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.
We need it to distinguish the parse error and the situation when parser internal
...
...
@@ -128,4 +168,50 @@ public:
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 */
server-tools/instance-manager/factory.cc
View file @
83f9ee07
...
...
@@ -16,40 +16,85 @@
#include "factory.h"
Show_instances
*
Command_factory
::
new_Show_instances
()
{
return
new
Show_instances
(
&
instance_map
);
}
Flush_instances
*
Command_factory
::
new_Flush_instances
()
{
return
new
Flush_instances
(
&
instance_map
);
}
Show_instance_status
*
Command_factory
::
new_Show_instance_status
(
const
char
*
name
,
uint
len
)
{
return
new
Show_instance_status
(
&
instance_map
,
name
,
len
);
}
Show_instance_options
*
Command_factory
::
new_Show_instance_options
(
const
char
*
name
,
uint
len
)
{
return
new
Show_instance_options
(
&
instance_map
,
name
,
len
);
}
Start_instance
*
Command_factory
::
new_Start_instance
(
const
char
*
name
,
uint
len
)
{
return
new
Start_instance
(
&
instance_map
,
name
,
len
);
}
Stop_instance
*
Command_factory
::
new_Stop_instance
(
const
char
*
name
,
uint
len
)
{
return
new
Stop_instance
(
&
instance_map
,
name
,
len
);
}
Syntax_error
*
Command_factory
::
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 @@
Http_command_factory e.t.c. Also see comment in the instance_map.cc
*/
class
Show_instances
;
class
Command_factory
{
public:
...
...
@@ -33,12 +35,26 @@ public:
{}
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_options
*
new_Show_instance_options
(
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
);
Flush_instances
*
new_Flush_instances
();
Syntax_error
*
new_Syntax_error
();
Show_instance_log
*
new_Show_instance_log
(
const
char
*
name
,
uint
len
,
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
;
};
...
...
server-tools/instance-manager/instance_options.cc
View file @
83f9ee07
...
...
@@ -21,10 +21,10 @@
#include "instance_options.h"
#include "parse_output.h"
#include "parse.h"
#include "buffer.h"
#include <my_sys.h>
#include <mysql.h>
#include <signal.h>
#include <m_string.h>
...
...
@@ -54,7 +54,7 @@ int Instance_options::get_default_option(char *result, size_t result_len,
int
rc
=
1
;
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 */
{
cmd
.
append
(
position
,
mysqld_path
,
strlen
(
mysqld_path
));
...
...
@@ -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
)
{
const
char
*
pid_file
=
mysqld_pid_file
;
...
...
@@ -190,6 +319,8 @@ int Instance_options::complete_initialization(const char *default_path,
options_array
.
elements
*
sizeof
(
char
*
));
argv
[
filled_default_options
+
options_array
.
elements
]
=
0
;
fill_log_options
();
return
0
;
err:
...
...
server-tools/instance-manager/instance_options.h
View file @
83f9ee07
...
...
@@ -40,7 +40,8 @@ public:
mysqld_socket
(
0
),
mysqld_datadir
(
0
),
mysqld_bind_address
(
0
),
mysqld_pid_file
(
0
),
mysqld_port
(
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
();
/* fills in argv */
...
...
@@ -76,9 +77,14 @@ public:
const
char
*
nonguarded
;
const
char
*
shutdown_delay
;
uint
shutdown_delay_val
;
const
char
*
error_log
;
const
char
*
query_log
;
const
char
*
slow_log
;
/* this value is computed and cashed here */
DYNAMIC_ARRAY
options_array
;
private:
int
fill_log_options
();
int
add_to_argv
(
const
char
*
option
);
int
get_default_option
(
char
*
result
,
size_t
result_len
,
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)
" or resources shortage"
;
case
ER_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:
DBUG_ASSERT
(
0
);
return
0
;
...
...
server-tools/instance-manager/mysql_connection.cc
View file @
83f9ee07
...
...
@@ -284,7 +284,7 @@ int Mysql_connection_thread::check_connection()
net_send_error
(
&
net
,
ER_ACCESS_DENIED_ERROR
);
return
1
;
}
net_send_ok
(
&
net
,
connection_id
);
net_send_ok
(
&
net
,
connection_id
,
NULL
);
return
0
;
}
...
...
@@ -332,7 +332,7 @@ int Mysql_connection_thread::dispatch_command(enum enum_server_command command,
return
1
;
case
COM_PING
:
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
;
case
COM_QUERY
:
{
...
...
server-tools/instance-manager/mysql_manager_error.h
View file @
83f9ee07
...
...
@@ -23,5 +23,9 @@
#define ER_INSTANCE_ALREADY_STARTED 3002
#define ER_CANNOT_START_INSTANCE 3003
#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 */
server-tools/instance-manager/parse.cc
View file @
83f9ee07
...
...
@@ -15,38 +15,56 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "parse.h"
#include "factory.h"
#include <string.h>
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_INSTANCES
,
TOK_LOG
,
TOK_OPTIONS
,
TOK_SET
,
TOK_SLOW
,
TOK_START
,
TOK_STATUS
,
TOK_STOP
,
TOK_SHOW
,
TOK_UNSET
,
TOK_NOT_FOUND
,
// must be after all tokens
TOK_END
};
struct
tokens_st
{
uint
length
;
const
char
*
tok_name
;
};
static
struct
tokens_st
tokens
[]
=
{
{
5
,
"ERROR"
},
{
5
,
"FILES"
},
{
5
,
"FLUSH"
},
{
7
,
"GENERAL"
},
{
8
,
"INSTANCE"
},
{
9
,
"INSTANCES"
},
{
3
,
"LOG"
},
{
7
,
"OPTIONS"
},
{
3
,
"SET"
},
{
4
,
"SLOW"
},
{
5
,
"START"
},
{
6
,
"STATUS"
},
{
4
,
"STOP"
},
{
4
,
"SHOW"
}
{
4
,
"SHOW"
},
{
5
,
"UNSET"
}
};
...
...
@@ -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
)
{
get_word
(
text
,
word_len
);
...
...
@@ -108,7 +119,15 @@ Command *parse_command(Command_factory *factory, const char *text)
uint
word_len
;
const
char
*
instance_name
;
uint
instance_name_len
;
const
char
*
option
;
uint
option_len
;
const
char
*
option_value
;
uint
option_value_len
;
const
char
*
log_size
;
Command
*
command
;
const
char
*
saved_text
=
text
;
bool
skip
=
false
;
const
char
*
tmp
;
Token
tok1
=
shift_token
(
&
text
,
&
word_len
);
...
...
@@ -143,6 +162,55 @@ Command *parse_command(Command_factory *factory, const char *text)
command
=
factory
->
new_Flush_instances
();
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
:
switch
(
shift_token
(
&
text
,
&
word_len
))
{
case
TOK_INSTANCES
:
...
...
@@ -157,6 +225,7 @@ Command *parse_command(Command_factory *factory, const char *text)
case
TOK_STATUS
:
get_text_id
(
&
text
,
&
instance_name_len
,
&
instance_name
);
text
+=
instance_name_len
;
/* check that this is the end of the command */
get_word
(
&
text
,
&
word_len
);
if
(
word_len
)
goto
syntax_error
;
...
...
@@ -172,7 +241,87 @@ Command *parse_command(Command_factory *factory, const char *text)
}
break
;
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
;
default:
...
...
@@ -182,3 +331,43 @@ syntax_error:
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 @@
along with this program; if not, write to the Free Software
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
);
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 */
enum
{
ALPHANUM
=
1
,
NONSPACE
};
...
...
@@ -44,10 +58,12 @@ inline void get_word(const char **text, uint *word_len,
while
(
my_isalnum
(
default_charset_info
,
*
word_end
))
++
word_end
;
else
while
(
!
my_isspace
(
default_charset_info
,
*
word_end
))
while
(
!
my_isspace
(
default_charset_info
,
*
word_end
)
&&
(
*
word_end
!=
'\0'
))
++
word_end
;
*
word_len
=
word_end
-
*
text
;
}
#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,
{
FILE
*
output
;
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
};
char
linebuf
[
MAX_LINE_LEN
];
...
...
@@ -99,3 +99,4 @@ pclose:
err:
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
This program is free software; you can redistribute it and/or modify
...
...
@@ -17,3 +19,4 @@
int
parse_output_and_get_value
(
const
char
*
command
,
const
char
*
word
,
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 @@
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
9
+
// connection id
2
+
// thread return status
2
];
// warning count
/*
The format of a packet
1 packet type code
1-9 affected rows 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
};
*
pos
++=
OK_PACKET_CODE
;
pos
=
net_store_length
(
pos
,
(
ulonglong
)
0
);
...
...
@@ -43,7 +53,15 @@ int net_send_ok(struct st_net *net, unsigned long connection_id)
int2store
(
pos
,
0
);
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)
}
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
string_len
;
string_len
=
strlen
(
string
);
if
(
buf
->
reserve
(
*
position
,
2
))
if
(
buf
->
reserve
(
*
position
,
9
))
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
))
goto
err
;
*
position
=
*
position
+
string_len
+
(
currpos
-
*
position
);
...
...
@@ -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
)
{
char
buff
[
1
+
/* eof packet code */
...
...
server-tools/instance-manager/protocol.h
View file @
83f9ee07
...
...
@@ -27,7 +27,8 @@ typedef struct field {
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
);
...
...
@@ -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
,
uint
string_len
);
int
send_eof
(
struct
st_net
*
net
);
#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