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
1c530b36
Commit
1c530b36
authored
Mar 05, 2012
by
Sergei Golubchik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mdev-20: INSTALL PLUGIN SONAME
parent
98141ea4
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
330 additions
and
159 deletions
+330
-159
include/my_global.h
include/my_global.h
+0
-2
mysql-test/r/plugin.result
mysql-test/r/plugin.result
+50
-7
mysql-test/r/plugin_maturity.result
mysql-test/r/plugin_maturity.result
+7
-1
mysql-test/t/plugin.test
mysql-test/t/plugin.test
+14
-10
mysql-test/t/plugin_maturity.test
mysql-test/t/plugin_maturity.test
+6
-0
mysql-test/t/ps.test
mysql-test/t/ps.test
+0
-3
sql/sql_parse.cc
sql/sql_parse.cc
+2
-1
sql/sql_plugin.cc
sql/sql_plugin.cc
+204
-127
sql/sql_plugin.h
sql/sql_plugin.h
+2
-1
sql/sql_yacc.yy
sql/sql_yacc.yy
+14
-0
storage/example/ha_example.cc
storage/example/ha_example.cc
+31
-7
No files found.
include/my_global.h
View file @
1c530b36
...
...
@@ -462,8 +462,6 @@ extern "C" int madvise(void *addr, size_t len, int behav);
#ifndef SO_EXT
#ifdef _WIN32
#define SO_EXT ".dll"
#elif defined(__APPLE__)
#define SO_EXT ".dylib"
#else
#define SO_EXT ".so"
#endif
...
...
mysql-test/r/plugin.result
View file @
1c530b36
...
...
@@ -3,15 +3,41 @@ Warnings:
Warning 1286 Unknown storage engine 'EXAMPLE'
Warning 1266 Using storage engine MyISAM for table 't1'
DROP TABLE t1;
INSTALL PLUGIN example SONAME 'ha_example
.so
';
INSTALL PLUGIN EXAMPLE SONAME 'ha_example
.so
';
INSTALL PLUGIN example SONAME 'ha_example';
INSTALL PLUGIN EXAMPLE SONAME 'ha_example';
ERROR HY000: Function 'EXAMPLE' already exists
UNINSTALL PLUGIN example;
INSTALL PLUGIN example SONAME 'ha_example.so';
INSTALL SONAME 'ha_example';
select * from information_schema.plugins where plugin_library like 'ha_example%';
PLUGIN_NAME EXAMPLE
PLUGIN_VERSION 0.1
PLUGIN_STATUS ACTIVE
PLUGIN_TYPE STORAGE ENGINE
PLUGIN_TYPE_VERSION #
PLUGIN_LIBRARY ha_example.so
PLUGIN_LIBRARY_VERSION 1.1
PLUGIN_AUTHOR Brian Aker, MySQL AB
PLUGIN_DESCRIPTION Example storage engine
PLUGIN_LICENSE GPL
LOAD_OPTION ON
PLUGIN_MATURITY Experimental
PLUGIN_AUTH_VERSION 0.1
PLUGIN_NAME UNUSABLE
PLUGIN_VERSION 3.14
PLUGIN_STATUS ACTIVE
PLUGIN_TYPE DAEMON
PLUGIN_TYPE_VERSION #
PLUGIN_LIBRARY ha_example.so
PLUGIN_LIBRARY_VERSION 1.1
PLUGIN_AUTHOR Sergei Golubchik
PLUGIN_DESCRIPTION Unusable Daemon
PLUGIN_LICENSE GPL
LOAD_OPTION ON
PLUGIN_MATURITY Experimental
PLUGIN_AUTH_VERSION 3.14.15.926
CREATE TABLE t1(a int) ENGINE=EXAMPLE;
SELECT * FROM t1;
a
DROP TABLE t1;
set global example_ulong_var=500;
set global example_enum_var= e1;
show status like 'example%';
...
...
@@ -21,7 +47,24 @@ show variables like 'example%';
Variable_name Value
example_enum_var e1
example_ulong_var 500
UNINSTALL PLUGIN example;
UNINSTALL SONAME 'ha_example';
Warnings:
Warning 1620 Plugin is busy and will be uninstalled on shutdown
select * from information_schema.plugins where plugin_library like 'ha_example%';
PLUGIN_NAME EXAMPLE
PLUGIN_VERSION 0.1
PLUGIN_STATUS DELETED
PLUGIN_TYPE STORAGE ENGINE
PLUGIN_TYPE_VERSION #
PLUGIN_LIBRARY ha_example.so
PLUGIN_LIBRARY_VERSION 1.1
PLUGIN_AUTHOR Brian Aker, MySQL AB
PLUGIN_DESCRIPTION Example storage engine
PLUGIN_LICENSE GPL
LOAD_OPTION ON
PLUGIN_MATURITY Experimental
PLUGIN_AUTH_VERSION 0.1
DROP TABLE t1;
UNINSTALL PLUGIN EXAMPLE;
ERROR 42000: PLUGIN EXAMPLE does not exist
UNINSTALL PLUGIN non_exist;
...
...
@@ -30,13 +73,13 @@ ERROR 42000: PLUGIN non_exist does not exist
# Bug#32034: check_func_enum() does not check correct values but set it
# to impossible int val
#
INSTALL PLUGIN example SONAME 'ha_example
.so
';
INSTALL PLUGIN example SONAME 'ha_example';
SET GLOBAL example_enum_var= e1;
SET GLOBAL example_enum_var= e2;
SET GLOBAL example_enum_var= impossible;
ERROR 42000: Variable 'example_enum_var' can't be set to the value of 'impossible'
UNINSTALL PLUGIN example;
INSTALL PLUGIN example SONAME 'ha_example
.so
';
INSTALL PLUGIN example SONAME 'ha_example';
select @@session.sql_mode into @old_sql_mode;
set session sql_mode='';
set global example_ulong_var=500;
...
...
mysql-test/r/plugin_maturity.result
View file @
1c530b36
INSTALL PLUGIN example SONAME 'ha_example.so';
ERROR HY000: Can't open shared library 'ha_example.so' (errno: 0 Loading of experimental plugins is prohibited by --plugin-maturity=stable)
ERROR HY000: Can't open shared library 'ha_example.so' (errno: 0 Loading of experimental plugin EXAMPLE is prohibited by --plugin-maturity=stable)
INSTALL SONAME 'ha_example.so';
ERROR HY000: Can't open shared library 'ha_example.so' (errno: 0 Loading of experimental plugin EXAMPLE is prohibited by --plugin-maturity=stable)
show warnings;
Level Code Message
Error 1126 Can't open shared library 'ha_example.so' (errno: 0 Loading of experimental plugin EXAMPLE is prohibited by --plugin-maturity=stable)
Error 1126 Can't open shared library 'ha_example.so' (errno: 0 Loading of experimental plugin UNUSABLE is prohibited by --plugin-maturity=stable)
mysql-test/t/plugin.test
View file @
1c530b36
...
...
@@ -4,23 +4,23 @@
CREATE
TABLE
t1
(
a
int
)
ENGINE
=
EXAMPLE
;
DROP
TABLE
t1
;
--
replace_regex
/
\
.
dll
/.
so
/
eval
INSTALL
PLUGIN
example
SONAME
'$HA_EXAMPLE_SO'
;
eval
INSTALL
PLUGIN
example
SONAME
'ha_example'
;
--
replace_regex
/
\
.
dll
/.
so
/
--
error
1125
eval
INSTALL
PLUGIN
EXAMPLE
SONAME
'
$HA_EXAMPLE_SO
'
;
eval
INSTALL
PLUGIN
EXAMPLE
SONAME
'
ha_example
'
;
UNINSTALL
PLUGIN
example
;
eval
INSTALL
SONAME
'ha_example'
;
--
replace_column
5
#
--
replace_regex
/
\
.
dll
/.
so
/
eval
INSTALL
PLUGIN
example
SONAME
'$HA_EXAMPLE_SO'
;
--
query_vertical
select
*
from
information_schema
.
plugins
where
plugin_library
like
'ha_example%'
CREATE
TABLE
t1
(
a
int
)
ENGINE
=
EXAMPLE
;
# Let's do some advanced ops with the example engine :)
SELECT
*
FROM
t1
;
DROP
TABLE
t1
;
# a couple of tests for variables
set
global
example_ulong_var
=
500
;
...
...
@@ -28,7 +28,13 @@ set global example_enum_var= e1;
show
status
like
'example%'
;
show
variables
like
'example%'
;
UNINSTALL
PLUGIN
example
;
eval
UNINSTALL
SONAME
'ha_example'
;
--
replace_column
5
#
--
replace_regex
/
\
.
dll
/.
so
/
--
query_vertical
select
*
from
information_schema
.
plugins
where
plugin_library
like
'ha_example%'
DROP
TABLE
t1
;
--
error
1305
UNINSTALL
PLUGIN
EXAMPLE
;
...
...
@@ -40,8 +46,7 @@ UNINSTALL PLUGIN non_exist;
--
echo
# Bug#32034: check_func_enum() does not check correct values but set it
--
echo
# to impossible int val
--
echo
#
--
replace_regex
/
\
.
dll
/.
so
/
eval
INSTALL
PLUGIN
example
SONAME
'$HA_EXAMPLE_SO'
;
eval
INSTALL
PLUGIN
example
SONAME
'ha_example'
;
SET
GLOBAL
example_enum_var
=
e1
;
SET
GLOBAL
example_enum_var
=
e2
;
...
...
@@ -55,8 +60,7 @@ UNINSTALL PLUGIN example;
#
# Bug #32757 hang with sql_mode set when setting some global variables
#
--
replace_regex
/
\
.
dll
/.
so
/
eval
INSTALL
PLUGIN
example
SONAME
'$HA_EXAMPLE_SO'
;
eval
INSTALL
PLUGIN
example
SONAME
'ha_example'
;
select
@@
session
.
sql_mode
into
@
old_sql_mode
;
...
...
mysql-test/t/plugin_maturity.test
View file @
1c530b36
...
...
@@ -4,3 +4,9 @@
--
replace_regex
/
\
.
dll
/.
so
/
--
error
1126
eval
INSTALL
PLUGIN
example
SONAME
'$HA_EXAMPLE_SO'
;
--
replace_regex
/
\
.
dll
/.
so
/
--
error
1126
eval
INSTALL
SONAME
'$HA_EXAMPLE_SO'
;
--
replace_regex
/
\
.
dll
/.
so
/
show
warnings
;
mysql-test/t/ps.test
View file @
1c530b36
...
...
@@ -2594,13 +2594,10 @@ drop table t1;
create
procedure
proc_1
()
install
plugin
my_plug
soname
'some_plugin.so'
;
--
replace_regex
/
(
Can
\
't open shared library).*$/\1/
--
error
ER_CANT_OPEN_LIBRARY
,
ER_FEATURE_DISABLED
call
proc_1
();
--replace_regex /(Can\'t open shared library).*$/\1/
--
error
ER_CANT_OPEN_LIBRARY
,
ER_FEATURE_DISABLED
call
proc_1
();
--replace_regex /(Can\'t open shared library).*$/\1/
--
error
ER_CANT_OPEN_LIBRARY
,
ER_FEATURE_DISABLED
call
proc_1
();
drop
procedure
proc_1
;
...
...
sql/sql_parse.cc
View file @
1c530b36
...
...
@@ -4363,7 +4363,8 @@ case SQLCOM_PREPARE:
my_ok
(
thd
);
break
;
case
SQLCOM_UNINSTALL_PLUGIN
:
if
(
!
(
res
=
mysql_uninstall_plugin
(
thd
,
&
thd
->
lex
->
comment
)))
if
(
!
(
res
=
mysql_uninstall_plugin
(
thd
,
&
thd
->
lex
->
comment
,
&
thd
->
lex
->
ident
)))
my_ok
(
thd
);
break
;
case
SQLCOM_BINLOG_BASE64_EVENT
:
...
...
sql/sql_plugin.cc
View file @
1c530b36
...
...
@@ -297,8 +297,7 @@ class sys_var_pluginvar: public sys_var
/* prototypes */
static
void
plugin_load
(
MEM_ROOT
*
tmp_root
,
int
*
argc
,
char
**
argv
);
static
bool
plugin_load_list
(
MEM_ROOT
*
tmp_root
,
int
*
argc
,
char
**
argv
,
const
char
*
list
);
static
bool
plugin_load_list
(
MEM_ROOT
*
,
int
*
,
char
**
,
const
char
*
);
static
int
test_plugin_options
(
MEM_ROOT
*
,
struct
st_plugin_int
*
,
int
*
,
char
**
);
static
bool
register_builtin
(
struct
st_maria_plugin
*
,
struct
st_plugin_int
*
,
...
...
@@ -318,6 +317,7 @@ static void reap_plugins(void);
static
void
report_error
(
int
where_to
,
uint
error
,
...)
{
va_list
args
;
DBUG_ASSERT
(
where_to
&
(
REPORT_TO_USER
|
REPORT_TO_LOG
));
if
(
where_to
&
REPORT_TO_USER
)
{
va_start
(
args
,
error
);
...
...
@@ -351,6 +351,20 @@ bool check_valid_path(const char *path, size_t len)
return
prefix
<
len
;
}
static
void
fix_dl_name
(
MEM_ROOT
*
root
,
LEX_STRING
*
dl
)
{
const
size_t
so_ext_len
=
sizeof
(
SO_EXT
)
-
1
;
if
(
my_strcasecmp
(
&
my_charset_latin1
,
dl
->
str
+
dl
->
length
-
so_ext_len
,
SO_EXT
))
{
char
*
s
=
(
char
*
)
alloc_root
(
root
,
dl
->
length
+
so_ext_len
+
1
);
memcpy
(
s
,
dl
->
str
,
dl
->
length
);
strcpy
(
s
+
dl
->
length
,
SO_EXT
);
dl
->
str
=
s
;
dl
->
length
+=
so_ext_len
;
}
}
/****************************************************************************
Value type thunks, allows the C world to play in the C++ world
...
...
@@ -1017,31 +1031,40 @@ static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin)
Requires that a write-lock is held on LOCK_system_variables_hash
*/
static
bool
plugin_add
(
MEM_ROOT
*
tmp_root
,
const
LEX_STRING
*
name
,
const
LEX_STRING
*
dl
,
const
LEX_STRING
*
name
,
LEX_STRING
*
dl
,
int
*
argc
,
char
**
argv
,
int
report
)
{
struct
st_plugin_int
tmp
;
struct
st_maria_plugin
*
plugin
;
uint
oks
=
0
,
errs
=
0
;
DBUG_ENTER
(
"plugin_add"
);
if
(
plugin_find_internal
(
name
,
MYSQL_ANY_PLUGIN
))
if
(
name
->
str
&&
plugin_find_internal
(
name
,
MYSQL_ANY_PLUGIN
))
{
report_error
(
report
,
ER_UDF_EXISTS
,
name
->
str
);
DBUG_RETURN
(
TRUE
);
}
/* Clear the whole struct to catch future extensions. */
bzero
((
char
*
)
&
tmp
,
sizeof
(
tmp
));
fix_dl_name
(
tmp_root
,
dl
);
if
(
!
(
tmp
.
plugin_dl
=
plugin_dl_add
(
dl
,
report
)))
DBUG_RETURN
(
TRUE
);
/* Find plugin by name */
for
(
plugin
=
tmp
.
plugin_dl
->
plugins
;
plugin
->
info
;
plugin
++
)
{
uint
name_len
=
strlen
(
plugin
->
name
);
if
(
plugin
->
type
>=
0
&&
plugin
->
type
<
MYSQL_MAX_PLUGIN_TYPE_NUM
&&
!
my_strnncoll
(
system_charset_info
,
(
const
uchar
*
)
name
->
str
,
name
->
length
,
(
const
uchar
*
)
plugin
->
name
,
name_len
))
{
tmp
.
name
.
str
=
(
char
*
)
plugin
->
name
;
tmp
.
name
.
length
=
strlen
(
plugin
->
name
);
if
(
plugin
->
type
<
0
||
plugin
->
type
>=
MYSQL_MAX_PLUGIN_TYPE_NUM
)
continue
;
// invalid plugin
if
(
name
->
str
&&
my_strnncoll
(
system_charset_info
,
(
const
uchar
*
)
name
->
str
,
name
->
length
,
(
const
uchar
*
)
tmp
.
name
.
str
,
tmp
.
name
.
length
))
continue
;
// plugin name doesn't match
if
(
!
name
->
str
&&
plugin_find_internal
(
&
tmp
.
name
,
MYSQL_ANY_PLUGIN
))
continue
;
// already installed
struct
st_plugin_int
*
tmp_plugin_ptr
;
if
(
*
(
int
*
)
plugin
->
info
<
min_plugin_info_interface_version
[
plugin
->
type
]
||
...
...
@@ -1051,7 +1074,8 @@ static bool plugin_add(MEM_ROOT *tmp_root,
char
buf
[
256
];
strxnmov
(
buf
,
sizeof
(
buf
)
-
1
,
"API version for "
,
plugin_type_names
[
plugin
->
type
].
str
,
" plugin is too different"
,
NullS
);
" plugin "
,
tmp
.
name
.
str
,
" not supported by this version of the server"
,
NullS
);
report_error
(
report
,
ER_CANT_OPEN_LIBRARY
,
dl
->
str
,
0
,
buf
);
goto
err
;
}
...
...
@@ -1060,40 +1084,49 @@ static bool plugin_add(MEM_ROOT *tmp_root,
char
buf
[
256
];
strxnmov
(
buf
,
sizeof
(
buf
)
-
1
,
"Loading of "
,
plugin_maturity_names
[
plugin
->
maturity
],
" plugins is prohibited by --plugin-maturity="
,
" plugin "
,
tmp
.
name
.
str
,
" is prohibited by --plugin-maturity="
,
plugin_maturity_names
[
plugin_maturity
],
NullS
);
report_error
(
report
,
ER_CANT_OPEN_LIBRARY
,
dl
->
str
,
0
,
buf
);
goto
err
;
}
tmp
.
plugin
=
plugin
;
tmp
.
name
.
str
=
(
char
*
)
plugin
->
name
;
tmp
.
name
.
length
=
name_len
;
tmp
.
ref_count
=
0
;
tmp
.
state
=
PLUGIN_IS_UNINITIALIZED
;
tmp
.
load_option
=
PLUGIN_ON
;
if
(
test_plugin_options
(
tmp_root
,
&
tmp
,
argc
,
argv
))
tmp
.
state
=
PLUGIN_IS_DISABLED
;
if
((
tmp_plugin_ptr
=
plugin_insert_or_reuse
(
&
tmp
)))
if
(
!
(
tmp_plugin_ptr
=
plugin_insert_or_reuse
(
&
tmp
)))
{
plugin_array_version
++
;
if
(
!
my_hash_insert
(
&
plugin_hash
[
plugin
->
type
],
(
uchar
*
)
tmp_plugin_ptr
))
{
init_alloc_root
(
&
tmp_plugin_ptr
->
mem_root
,
4096
,
4096
);
DBUG_RETURN
(
FALSE
);
}
tmp_plugin_ptr
->
state
=
PLUGIN_IS_FREED
;
mysql_del_sys_var_chain
(
tmp
.
system_vars
);
restore_pluginvar_names
(
tmp
.
system_vars
);
goto
err
;
}
mysql_del_sys_var_chain
(
tmp
.
system_vars
);
restore_pluginvar_names
(
tmp
.
system_vars
);
goto
err
;
}
}
report_error
(
report
,
ER_CANT_FIND_DL_ENTRY
,
name
->
str
);
plugin_array_version
++
;
if
(
my_hash_insert
(
&
plugin_hash
[
plugin
->
type
],
(
uchar
*
)
tmp_plugin_ptr
))
tmp_plugin_ptr
->
state
=
PLUGIN_IS_FREED
;
init_alloc_root
(
&
tmp_plugin_ptr
->
mem_root
,
4096
,
4096
);
if
(
name
->
str
)
DBUG_RETURN
(
FALSE
);
// all done
oks
++
;
tmp
.
plugin_dl
->
ref_count
++
;
continue
;
// otherwise - go on
err:
errs
++
;
if
(
name
->
str
)
break
;
}
if
(
errs
==
0
&&
oks
==
0
)
// no plugin was found
report_error
(
report
,
ER_CANT_FIND_DL_ENTRY
,
name
->
str
);
plugin_dl_del
(
dl
);
DBUG_RETURN
(
TRUE
);
DBUG_RETURN
(
errs
>
0
||
oks
==
0
);
}
...
...
@@ -1760,8 +1793,6 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
{
char
buffer
[
FN_REFLEN
];
LEX_STRING
name
=
{
buffer
,
0
},
dl
=
{
NULL
,
0
},
*
str
=
&
name
;
struct
st_plugin_dl
*
plugin_dl
;
struct
st_maria_plugin
*
plugin
;
char
*
p
=
buffer
;
DBUG_ENTER
(
"plugin_load_list"
);
while
(
list
)
...
...
@@ -1791,19 +1822,10 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
dl
=
name
;
mysql_mutex_lock
(
&
LOCK_plugin
);
if
((
plugin_dl
=
plugin_dl_add
(
&
dl
,
REPORT_TO_LOG
)))
{
for
(
plugin
=
plugin_dl
->
plugins
;
plugin
->
info
;
plugin
++
)
{
name
.
str
=
(
char
*
)
plugin
->
name
;
name
.
length
=
strlen
(
name
.
str
);
free_root
(
tmp_root
,
MYF
(
MY_MARK_BLOCKS_FREE
));
if
(
plugin_add
(
tmp_root
,
&
name
,
&
dl
,
argc
,
argv
,
REPORT_TO_LOG
))
goto
error
;
}
plugin_dl_del
(
&
dl
);
// reduce ref count
}
free_root
(
tmp_root
,
MYF
(
MY_MARK_BLOCKS_FREE
));
name
.
str
=
0
;
// load everything
if
(
plugin_add
(
tmp_root
,
&
name
,
&
dl
,
argc
,
argv
,
REPORT_TO_LOG
))
goto
error
;
}
else
{
...
...
@@ -1970,14 +1992,68 @@ void plugin_shutdown(void)
DBUG_VOID_RETURN
;
}
/**
complete plugin installation (after plugin_add).
That is, initialize it, and update mysql.plugin table
*/
static
bool
finalize_install
(
THD
*
thd
,
TABLE
*
table
,
const
LEX_STRING
*
name
)
{
struct
st_plugin_int
*
tmp
=
plugin_find_internal
(
name
,
MYSQL_ANY_PLUGIN
);
int
error
;
DBUG_ASSERT
(
tmp
);
mysql_mutex_assert_owner
(
&
LOCK_plugin
);
if
(
tmp
->
state
==
PLUGIN_IS_DISABLED
)
{
if
(
global_system_variables
.
log_warnings
)
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_CANT_INITIALIZE_UDF
,
ER
(
ER_CANT_INITIALIZE_UDF
),
name
->
str
,
"Plugin is disabled"
);
}
else
{
DBUG_ASSERT
(
tmp
->
state
==
PLUGIN_IS_UNINITIALIZED
);
if
(
plugin_initialize
(
tmp
))
{
report_error
(
REPORT_TO_USER
,
ER_CANT_INITIALIZE_UDF
,
name
->
str
,
"Plugin initialization function failed."
);
tmp
->
state
=
PLUGIN_IS_DELETED
;
return
1
;
}
}
/*
We do not replicate the INSTALL PLUGIN statement. Disable binlogging
of the insert into the plugin table, so that it is not replicated in
row based mode.
*/
tmp_disable_binlog
(
thd
);
table
->
use_all_columns
();
restore_record
(
table
,
s
->
default_values
);
table
->
field
[
0
]
->
store
(
name
->
str
,
name
->
length
,
system_charset_info
);
table
->
field
[
1
]
->
store
(
tmp
->
plugin_dl
->
dl
.
str
,
tmp
->
plugin_dl
->
dl
.
length
,
files_charset_info
);
error
=
table
->
file
->
ha_write_row
(
table
->
record
[
0
]);
reenable_binlog
(
thd
);
if
(
error
)
{
table
->
file
->
print_error
(
error
,
MYF
(
0
));
tmp
->
state
=
PLUGIN_IS_DELETED
;
return
1
;
}
return
0
;
}
bool
mysql_install_plugin
(
THD
*
thd
,
const
LEX_STRING
*
name
,
const
LEX_STRING
*
dl
)
bool
mysql_install_plugin
(
THD
*
thd
,
const
LEX_STRING
*
name
,
const
LEX_STRING
*
dl_arg
)
{
TABLE_LIST
tables
;
TABLE
*
table
;
int
error
,
argc
=
orig_argc
;
LEX_STRING
dl
=
*
dl_arg
;
bool
error
;
int
argc
=
orig_argc
;
char
**
argv
=
orig_argv
;
struct
st_plugin_int
*
tmp
;
DBUG_ENTER
(
"mysql_install_plugin"
);
if
(
opt_noacl
)
...
...
@@ -2024,53 +2100,34 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
report_error
(
REPORT_TO_USER
,
ER_PLUGIN_IS_NOT_LOADED
,
name
->
str
);
goto
err
;
}
error
=
plugin_add
(
thd
->
mem_root
,
name
,
dl
,
&
argc
,
argv
,
REPORT_TO_USER
);
error
=
plugin_add
(
thd
->
mem_root
,
name
,
&
dl
,
&
argc
,
argv
,
REPORT_TO_USER
);
if
(
argv
)
free_defaults
(
argv
);
mysql_rwlock_unlock
(
&
LOCK_system_variables_hash
);
if
(
error
||
!
(
tmp
=
plugin_find_internal
(
name
,
MYSQL_ANY_PLUGIN
))
)
if
(
error
)
goto
err
;
if
(
tmp
->
state
==
PLUGIN_IS_DISABLED
)
{
if
(
global_system_variables
.
log_warnings
)
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_CANT_INITIALIZE_UDF
,
ER
(
ER_CANT_INITIALIZE_UDF
),
name
->
str
,
"Plugin is disabled"
);
}
if
(
name
->
str
)
error
=
finalize_install
(
thd
,
table
,
name
);
else
{
if
(
plugin_initialize
(
tmp
))
st_plugin_dl
*
plugin_dl
=
plugin_dl_find
(
&
dl
);
struct
st_maria_plugin
*
plugin
;
for
(
plugin
=
plugin_dl
->
plugins
;
plugin
->
info
;
plugin
++
)
{
my_error
(
ER_CANT_INITIALIZE_UDF
,
MYF
(
0
),
name
->
str
,
"Plugin initialization function failed."
);
goto
deinit
;
LEX_STRING
str
=
{
const_cast
<
char
*>
(
plugin
->
name
),
strlen
(
plugin
->
name
)
};
error
|=
finalize_install
(
thd
,
table
,
&
str
);
}
}
/*
We do not replicate the INSTALL PLUGIN statement. Disable binlogging
of the insert into the plugin table, so that it is not replicated in
row based mode.
*/
tmp_disable_binlog
(
thd
);
table
->
use_all_columns
();
restore_record
(
table
,
s
->
default_values
);
table
->
field
[
0
]
->
store
(
name
->
str
,
name
->
length
,
system_charset_info
);
table
->
field
[
1
]
->
store
(
dl
->
str
,
dl
->
length
,
files_charset_info
);
error
=
table
->
file
->
ha_write_row
(
table
->
record
[
0
]);
reenable_binlog
(
thd
);
if
(
error
)
{
table
->
file
->
print_error
(
error
,
MYF
(
0
));
goto
deinit
;
}
mysql_mutex_unlock
(
&
LOCK_plugin
);
DBUG_RETURN
(
FALSE
);
deinit:
tmp
->
state
=
PLUGIN_IS_DELETED
;
reap_needed
=
true
;
reap_plugins
();
err:
...
...
@@ -2079,66 +2136,27 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
}
bool
mysql_uninstall_plugin
(
THD
*
thd
,
const
LEX_STRING
*
name
)
static
bool
do_uninstall
(
THD
*
thd
,
TABLE
*
table
,
const
LEX_STRING
*
name
)
{
TABLE
*
table
;
TABLE_LIST
tables
;
struct
st_plugin_int
*
plugin
;
DBUG_ENTER
(
"mysql_uninstall_plugin"
);
if
(
opt_noacl
)
{
my_error
(
ER_OPTION_PREVENTS_STATEMENT
,
MYF
(
0
),
"--skip-grant-tables"
);
DBUG_RETURN
(
TRUE
);
}
tables
.
init_one_table
(
"mysql"
,
5
,
"plugin"
,
6
,
"plugin"
,
TL_WRITE
);
if
(
check_table_access
(
thd
,
DELETE_ACL
,
&
tables
,
FALSE
,
1
,
FALSE
))
DBUG_RETURN
(
TRUE
);
/* need to open before acquiring LOCK_plugin or it will deadlock */
if
(
!
(
table
=
open_ltable
(
thd
,
&
tables
,
TL_WRITE
,
MYSQL_LOCK_IGNORE_TIMEOUT
)))
DBUG_RETURN
(
TRUE
);
/*
Pre-acquire audit plugins for events that may potentially occur
during [UN]INSTALL PLUGIN.
When audit event is triggered, audit subsystem acquires interested
plugins by walking through plugin list. Evidently plugin list
iterator protects plugin list by acquiring LOCK_plugin, see
plugin_foreach_with_mask().
On the other hand [UN]INSTALL PLUGIN is acquiring LOCK_plugin
rather for a long time.
When audit event is triggered during [UN]INSTALL PLUGIN, plugin
list iterator acquires the same lock (within the same thread)
second time.
This hack should be removed when LOCK_plugin is fixed so it
protects only what it supposed to protect.
*/
mysql_audit_acquire_plugins
(
thd
,
MYSQL_AUDIT_GENERAL_CLASS
);
mysql_mutex_assert_owner
(
&
LOCK_plugin
);
mysql_mutex_lock
(
&
LOCK_plugin
);
if
(
!
(
plugin
=
plugin_find_internal
(
name
,
MYSQL_ANY_PLUGIN
)))
{
my_error
(
ER_SP_DOES_NOT_EXIST
,
MYF
(
0
),
"PLUGIN"
,
name
->
str
);
goto
err
;
return
1
;
}
if
(
!
plugin
->
plugin_dl
)
{
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
WARN_PLUGIN_DELETE_BUILTIN
,
ER
(
WARN_PLUGIN_DELETE_BUILTIN
));
my_error
(
ER_SP_DOES_NOT_EXIST
,
MYF
(
0
),
"PLUGIN"
,
name
->
str
);
goto
err
;
return
1
;
}
if
(
plugin
->
load_option
==
PLUGIN_FORCE_PLUS_PERMANENT
)
{
my_error
(
ER_PLUGIN_IS_PERMANENT
,
MYF
(
0
),
name
->
str
);
goto
err
;
return
1
;
}
plugin
->
state
=
PLUGIN_IS_DELETED
;
...
...
@@ -2147,8 +2165,6 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
WARN_PLUGIN_BUSY
,
ER
(
WARN_PLUGIN_BUSY
));
else
reap_needed
=
true
;
reap_plugins
();
mysql_mutex_unlock
(
&
LOCK_plugin
);
uchar
user_key
[
MAX_KEY_LENGTH
];
table
->
use_all_columns
();
...
...
@@ -2170,13 +2186,74 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
if
(
error
)
{
table
->
file
->
print_error
(
error
,
MYF
(
0
));
DBUG_RETURN
(
TRUE
)
;
return
1
;
}
}
DBUG_RETURN
(
FALSE
);
err:
return
0
;
}
bool
mysql_uninstall_plugin
(
THD
*
thd
,
const
LEX_STRING
*
name
,
const
LEX_STRING
*
dl_arg
)
{
TABLE
*
table
;
TABLE_LIST
tables
;
LEX_STRING
dl
=
*
dl_arg
;
bool
error
=
false
;
DBUG_ENTER
(
"mysql_uninstall_plugin"
);
if
(
opt_noacl
)
{
my_error
(
ER_OPTION_PREVENTS_STATEMENT
,
MYF
(
0
),
"--skip-grant-tables"
);
DBUG_RETURN
(
TRUE
);
}
tables
.
init_one_table
(
"mysql"
,
5
,
"plugin"
,
6
,
"plugin"
,
TL_WRITE
);
if
(
check_table_access
(
thd
,
DELETE_ACL
,
&
tables
,
FALSE
,
1
,
FALSE
))
DBUG_RETURN
(
TRUE
);
/* need to open before acquiring LOCK_plugin or it will deadlock */
if
(
!
(
table
=
open_ltable
(
thd
,
&
tables
,
TL_WRITE
,
MYSQL_LOCK_IGNORE_TIMEOUT
)))
DBUG_RETURN
(
TRUE
);
/*
Pre-acquire audit plugins for events that may potentially occur
during [UN]INSTALL PLUGIN.
When audit event is triggered, audit subsystem acquires interested
plugins by walking through plugin list. Evidently plugin list
iterator protects plugin list by acquiring LOCK_plugin, see
plugin_foreach_with_mask().
On the other hand [UN]INSTALL PLUGIN is acquiring LOCK_plugin
rather for a long time.
When audit event is triggered during [UN]INSTALL PLUGIN, plugin
list iterator acquires the same lock (within the same thread)
second time.
*/
mysql_audit_acquire_plugins
(
thd
,
MYSQL_AUDIT_GENERAL_CLASS
);
mysql_mutex_lock
(
&
LOCK_plugin
);
if
(
name
->
str
)
error
=
do_uninstall
(
thd
,
table
,
name
);
else
{
fix_dl_name
(
thd
->
mem_root
,
&
dl
);
st_plugin_dl
*
plugin_dl
=
plugin_dl_find
(
&
dl
);
struct
st_maria_plugin
*
plugin
;
for
(
plugin
=
plugin_dl
->
plugins
;
plugin
->
info
;
plugin
++
)
{
LEX_STRING
str
=
{
const_cast
<
char
*>
(
plugin
->
name
),
strlen
(
plugin
->
name
)
};
error
|=
do_uninstall
(
thd
,
table
,
&
str
);
}
}
reap_plugins
();
mysql_mutex_unlock
(
&
LOCK_plugin
);
DBUG_RETURN
(
TRUE
);
DBUG_RETURN
(
error
);
}
...
...
sql/sql_plugin.h
View file @
1c530b36
...
...
@@ -159,7 +159,8 @@ extern void plugin_unlock(THD *thd, plugin_ref plugin);
extern
void
plugin_unlock_list
(
THD
*
thd
,
plugin_ref
*
list
,
uint
count
);
extern
bool
mysql_install_plugin
(
THD
*
thd
,
const
LEX_STRING
*
name
,
const
LEX_STRING
*
dl
);
extern
bool
mysql_uninstall_plugin
(
THD
*
thd
,
const
LEX_STRING
*
name
);
extern
bool
mysql_uninstall_plugin
(
THD
*
thd
,
const
LEX_STRING
*
name
,
const
LEX_STRING
*
dl
);
extern
bool
plugin_register_builtin
(
struct
st_mysql_plugin
*
plugin
);
extern
void
plugin_thdvar_init
(
THD
*
thd
);
extern
void
plugin_thdvar_cleanup
(
THD
*
thd
);
...
...
sql/sql_yacc.yy
View file @
1c530b36
...
...
@@ -15141,6 +15141,13 @@ install:
lex->comment= $3;
lex->ident= $5;
}
| INSTALL_SYM SONAME_SYM TEXT_STRING_sys
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_INSTALL_PLUGIN;
lex->comment= null_lex_str;
lex->ident= $3;
}
;
uninstall:
...
...
@@ -15150,6 +15157,13 @@ uninstall:
lex->sql_command= SQLCOM_UNINSTALL_PLUGIN;
lex->comment= $3;
}
| UNINSTALL_SYM SONAME_SYM TEXT_STRING_sys
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_UNINSTALL_PLUGIN;
lex->comment= null_lex_str;
lex->ident= $3;
}
;
/* Avoid compiler warning from sql_yacc.cc where yyerrlab1 is not used */
...
...
storage/example/ha_example.cc
View file @
1c530b36
...
...
@@ -19,17 +19,23 @@
@brief
The ha_example engine is a stubbed storage engine for example purposes only;
it does nothing at this point. Its purpose is to provide a source
it does
almost
nothing at this point. Its purpose is to provide a source
code illustration of how to begin writing new storage engines; see also
/storage/example/ha_example.h.
storage/example/ha_example.h.
Additionally, this file includes an example of a daemon plugin which does
nothing at all - absolutely nothing, even less than example storage engine.
But it shows that one dll/so can contain more than one plugin.
@details
ha_example will let you create/open/delete tables, but
nothing further (for example, indexes are not supported nor can data
be stored in the table). Use this example as a template for
implementing the same functionality in your own storage engine. You
can enable the example storage engine in your build by doing the
following during your build process:<br> ./configure
be stored in the table). It also provides new status (example_func_example)
and system (example_ulong_var and example_enum_var) variables.
Use this example as a template for implementing the same functionality in
your own storage engine. You can enable the example storage engine in your
build by doing the following during your build process:<br> ./configure
--with-example-storage-engine
Once this is done, MySQL will let you create tables with:<br>
...
...
@@ -1111,6 +1117,9 @@ static struct st_mysql_show_var func_status[]=
{
0
,
0
,
SHOW_UNDEF
}
};
struct
st_mysql_daemon
unusable_example
=
{
MYSQL_DAEMON_INTERFACE_VERSION
};
mysql_declare_plugin
(
example
)
{
MYSQL_STORAGE_ENGINE_PLUGIN
,
...
...
@@ -1138,10 +1147,25 @@ maria_declare_plugin(example)
PLUGIN_LICENSE_GPL
,
example_init_func
,
/* Plugin Init */
example_done_func
,
/* Plugin Deinit */
0x0001
/* 0.1 */
,
0x0001
,
/* version number (0.1) */
func_status
,
/* status variables */
example_system_variables
,
/* system variables */
"0.1"
,
/* string version */
MariaDB_PLUGIN_MATURITY_EXPERIMENTAL
/* maturity */
},
{
MYSQL_DAEMON_PLUGIN
,
&
unusable_example
,
"UNUSABLE"
,
"Sergei Golubchik"
,
"Unusable Daemon"
,
PLUGIN_LICENSE_GPL
,
NULL
,
/* Plugin Init */
NULL
,
/* Plugin Deinit */
0x030E
,
/* version number (3.14) */
NULL
,
/* status variables */
NULL
,
/* system variables */
"3.14.15.926"
,
/* version, as a string */
MariaDB_PLUGIN_MATURITY_EXPERIMENTAL
/* maturity */
}
maria_declare_plugin_end
;
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