components/mysql_server/server_component.cc (337 lines of code) (raw):

/* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <my_sys.h> // my_error #include <mysql/components/component_implementation.h> #include <mysql/components/my_service.h> #include <stddef.h> #include <new> #include <stdexcept> // std::exception subclasses #include "dynamic_loader.h" #include "dynamic_loader_path_filter.h" #include "dynamic_loader_scheme_file.h" #include "log.h" #include "log_builtins_imp.h" #include "log_builtins_filter_imp.h" #include "my_inttypes.h" #include "mysqld_error.h" #include "persistent_dynamic_loader.h" #include "mysql_string_service.h" #include "registry.h" #include "server_component.h" #include "auth/dynamic_privileges_impl.h" #include "udf_registration_imp.h" BEGIN_SERVICE_IMPLEMENTATION(mysql_server, registry) mysql_registry_imp::acquire, mysql_registry_imp::acquire_related, mysql_registry_imp::release END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, registry_registration) mysql_registry_imp::register_service, mysql_registry_imp::unregister, mysql_registry_imp::set_default END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, registry_query) mysql_registry_imp::iterator_create, mysql_registry_imp::iterator_get, mysql_registry_imp::iterator_next, mysql_registry_imp::iterator_is_valid, mysql_registry_imp::iterator_release, END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, registry_metadata_enumerate) mysql_registry_imp::metadata_iterator_create, mysql_registry_imp::metadata_iterator_get, mysql_registry_imp::metadata_iterator_next, mysql_registry_imp::metadata_iterator_is_valid, mysql_registry_imp::metadata_iterator_release, END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, registry_metadata_query) mysql_registry_imp::metadata_get_value, END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, dynamic_loader) mysql_dynamic_loader_imp::load, mysql_dynamic_loader_imp::unload END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, dynamic_loader_query) mysql_dynamic_loader_imp::iterator_create, mysql_dynamic_loader_imp::iterator_get, mysql_dynamic_loader_imp::iterator_next, mysql_dynamic_loader_imp::iterator_is_valid, mysql_dynamic_loader_imp::iterator_release END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, dynamic_loader_metadata_enumerate) mysql_dynamic_loader_imp::metadata_iterator_create, mysql_dynamic_loader_imp::metadata_iterator_get, mysql_dynamic_loader_imp::metadata_iterator_next, mysql_dynamic_loader_imp::metadata_iterator_is_valid, mysql_dynamic_loader_imp::metadata_iterator_release END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, dynamic_loader_metadata_query) mysql_dynamic_loader_imp::metadata_get_value, END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION( mysql_server_path_filter, dynamic_loader_scheme_file) mysql_dynamic_loader_scheme_file_path_filter_imp::load, mysql_dynamic_loader_scheme_file_path_filter_imp::unload END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, dynamic_loader_scheme_file) mysql_dynamic_loader_scheme_file_imp::load, mysql_dynamic_loader_scheme_file_imp::unload END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, persistent_dynamic_loader) mysql_persistent_dynamic_loader_imp::load, mysql_persistent_dynamic_loader_imp::unload END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, dynamic_privilege_register) dynamic_privilege_services_impl::register_privilege, dynamic_privilege_services_impl::unregister_privilege END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, global_grants_check) dynamic_privilege_services_impl::has_global_grant END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, mysql_string_factory) mysql_string_imp::create, mysql_string_imp::destroy END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, mysql_string_case) mysql_string_imp::tolower, mysql_string_imp::toupper END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, mysql_string_converter) mysql_string_imp::convert_from_buffer, mysql_string_imp::convert_to_buffer END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, mysql_string_character_access) mysql_string_imp::get_char, mysql_string_imp::get_char_length END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, mysql_string_byte_access) mysql_string_imp::get_byte, mysql_string_imp::get_byte_length END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, mysql_string_iterator) mysql_string_imp::iterator_create, mysql_string_imp::iterator_get_next, mysql_string_imp::iterator_destroy END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, mysql_string_ctype) mysql_string_imp::is_upper, mysql_string_imp::is_lower, mysql_string_imp::is_digit END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, log_builtins) log_builtins_imp::wellknown_by_type, log_builtins_imp::wellknown_by_name, log_builtins_imp::wellknown_get_type, log_builtins_imp::wellknown_get_name, log_builtins_imp::item_inconsistent, log_builtins_imp::item_generic_type, log_builtins_imp::item_string_class, log_builtins_imp::item_numeric_class, log_builtins_imp::item_set_int, log_builtins_imp::item_set_float, log_builtins_imp::item_set_lexstring, log_builtins_imp::item_set_cstring, log_builtins_imp::item_set_with_key, log_builtins_imp::item_set, log_builtins_imp::line_item_set_with_key, log_builtins_imp::line_item_set, log_builtins_imp::line_init, log_builtins_imp::line_exit, log_builtins_imp::line_item_count, log_builtins_imp::line_item_types_seen, log_builtins_imp::line_item_iter_acquire, log_builtins_imp::line_item_iter_release, log_builtins_imp::line_item_iter_first, log_builtins_imp::line_item_iter_next, log_builtins_imp::line_item_iter_current, log_builtins_imp::line_submit, log_builtins_imp::message, log_builtins_imp::sanitize, log_builtins_imp::errmsg_by_errcode, log_builtins_imp::errcode_by_errsymbol, log_builtins_imp::label_from_prio, log_builtins_imp::open_errstream, log_builtins_imp::write_errstream, log_builtins_imp::dedicated_errstream, log_builtins_imp::close_errstream END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, log_builtins_filter) log_builtins_filter_imp::filter_run, log_builtins_filter_imp::filter_ruleset_get, log_builtins_filter_imp::filter_ruleset_drop, log_builtins_filter_imp::filter_ruleset_release, log_builtins_filter_imp::filter_rule_init END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, log_builtins_string) log_builtins_string_imp::malloc, log_builtins_string_imp::strndup, log_builtins_string_imp::free, log_builtins_string_imp::length, log_builtins_string_imp::find_first, log_builtins_string_imp::find_last, log_builtins_string_imp::compare, log_builtins_string_imp::substitutev, log_builtins_string_imp::substitute END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, log_builtins_tmp) log_builtins_tmp_imp::connection_loop_aborted END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, log_builtins_syseventlog) log_builtins_syseventlog_imp::open, log_builtins_syseventlog_imp::write, log_builtins_syseventlog_imp::close END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, udf_registration) mysql_udf_registration_imp::udf_register, mysql_udf_registration_imp::udf_unregister END_SERVICE_IMPLEMENTATION() BEGIN_SERVICE_IMPLEMENTATION(mysql_server, udf_registration_aggregate) mysql_udf_registration_imp::udf_register_aggregate, mysql_udf_registration_imp::udf_unregister END_SERVICE_IMPLEMENTATION() BEGIN_COMPONENT_PROVIDES(mysql_server) PROVIDES_SERVICE(mysql_server, registry) PROVIDES_SERVICE(mysql_server, registry_registration) PROVIDES_SERVICE(mysql_server, registry_query) PROVIDES_SERVICE(mysql_server, registry_metadata_enumerate) PROVIDES_SERVICE(mysql_server, registry_metadata_query) PROVIDES_SERVICE(mysql_server, dynamic_loader) PROVIDES_SERVICE(mysql_server_path_filter, dynamic_loader_scheme_file) PROVIDES_SERVICE(mysql_server, persistent_dynamic_loader) PROVIDES_SERVICE(mysql_server, dynamic_loader_query) PROVIDES_SERVICE(mysql_server, dynamic_loader_metadata_enumerate) PROVIDES_SERVICE(mysql_server, dynamic_loader_metadata_query) PROVIDES_SERVICE(mysql_server, dynamic_loader_scheme_file) PROVIDES_SERVICE(mysql_server, dynamic_privilege_register) PROVIDES_SERVICE(mysql_server, global_grants_check) PROVIDES_SERVICE(mysql_server, mysql_string_factory) PROVIDES_SERVICE(mysql_server, mysql_string_case) PROVIDES_SERVICE(mysql_server, mysql_string_converter) PROVIDES_SERVICE(mysql_server, mysql_string_character_access) PROVIDES_SERVICE(mysql_server, mysql_string_byte_access) PROVIDES_SERVICE(mysql_server, mysql_string_iterator) PROVIDES_SERVICE(mysql_server, mysql_string_ctype) PROVIDES_SERVICE(mysql_server, log_builtins) PROVIDES_SERVICE(mysql_server, log_builtins_filter) PROVIDES_SERVICE(mysql_server, log_builtins_string) PROVIDES_SERVICE(mysql_server, log_builtins_tmp) PROVIDES_SERVICE(mysql_server, log_builtins_syseventlog) PROVIDES_SERVICE(mysql_server, udf_registration) PROVIDES_SERVICE(mysql_server, udf_registration_aggregate) END_COMPONENT_PROVIDES() static BEGIN_COMPONENT_REQUIRES(mysql_server) END_COMPONENT_REQUIRES() BEGIN_COMPONENT_METADATA(mysql_server) METADATA("mysql.author", "Oracle Corporation") METADATA("mysql.license", "GPL") END_COMPONENT_METADATA() DECLARE_COMPONENT(mysql_server, "mysql:core") /* There are no initialization/deinitialization functions, they will not be called as this component is not a regular one. */ NULL, NULL END_DECLARE_COMPONENT() /** Bootstraps service registry and dynamic loader and make ready all basic server services. @param [out] registry A service handle to registry service. May be NULL. @return Status of performed operation @retval false success @retval true failure */ bool mysql_services_bootstrap(SERVICE_TYPE(registry)** registry) { /* Create the registry service suite internal structure mysql_registry. */ registry_init(); /* Seed the registry through registering the registry implementation into it, as well as other main bootstrap dynamic loader service implementations. */ for (int inx= 0; mysql_component_mysql_server.provides[inx].implementation != NULL; ++inx) { if (imp_mysql_server_registry_registration.register_service( mysql_component_mysql_server.provides[inx].name, reinterpret_cast<my_h_service>( mysql_component_mysql_server.provides[inx].implementation))) { return true; } } if (registry != NULL) { my_h_service registry_handle; if (imp_mysql_server_registry.acquire( "registry.mysql_server", &registry_handle)) { return true; } *registry= reinterpret_cast<SERVICE_TYPE(registry)*>(registry_handle); } dynamic_loader_init(); dynamic_loader_scheme_file_init(); my_service<SERVICE_TYPE(registry_registration)> registrator( "registry_registration", &imp_mysql_server_registry); // Sets default file scheme loader for MySQL server. registrator->set_default( "dynamic_loader_scheme_file.mysql_server_path_filter"); return false; } /** Shutdowns dynamic loader. */ void shutdown_dynamic_loader() { /* Dynamic loader deinitialization still needs all scheme service implementations to be functional. */ dynamic_loader_deinit(); dynamic_loader_scheme_file_deinit(); } /** Shutdowns service registry making sure all basic services are unregistered. Will fail if any service implementation is in use. @return Status of performed operation @retval false success @retval true failure */ bool mysql_services_shutdown() { for (int inx= 0; mysql_component_mysql_server.provides[inx].implementation != NULL; ++inx) { if (imp_mysql_server_registry_registration.unregister( mysql_component_mysql_server.provides[inx].name)) { return true; } } registry_deinit(); return false; } /** Checks if last thrown exception is any kind of standard exceptions, i.e. the exceptions inheriting from std::exception. If so, reports an error message that states exception type and message. On any other thrown value it just reports general error. */ void mysql_components_handle_std_exception(const char *funcname) { try { throw; } catch (const std::bad_alloc &e) { my_error(ER_STD_BAD_ALLOC_ERROR, MYF(0), e.what(), funcname); } catch (const std::domain_error &e) { my_error(ER_STD_DOMAIN_ERROR, MYF(0), e.what(), funcname); } catch (const std::length_error &e) { my_error(ER_STD_LENGTH_ERROR, MYF(0), e.what(), funcname); } catch (const std::invalid_argument &e) { my_error(ER_STD_INVALID_ARGUMENT, MYF(0), e.what(), funcname); } catch (const std::out_of_range &e) { my_error(ER_STD_OUT_OF_RANGE_ERROR, MYF(0), e.what(), funcname); } catch (const std::overflow_error &e) { my_error(ER_STD_OVERFLOW_ERROR, MYF(0), e.what(), funcname); } catch (const std::range_error &e) { my_error(ER_STD_RANGE_ERROR, MYF(0), e.what(), funcname); } catch (const std::underflow_error &e) { my_error(ER_STD_UNDERFLOW_ERROR, MYF(0), e.what(), funcname); } catch (const std::logic_error &e) { my_error(ER_STD_LOGIC_ERROR, MYF(0), e.what(), funcname); } catch (const std::runtime_error &e) { my_error(ER_STD_RUNTIME_ERROR, MYF(0), e.what(), funcname); } catch (const std::exception &e) { my_error(ER_STD_UNKNOWN_EXCEPTION, MYF(0), e.what(), funcname); } catch (...) { my_error(ER_UNKNOWN_ERROR, MYF(0)); } }