From a175314c3e5827eb193872241446f2f8f5c9d33c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 20:07:14 +0200 Subject: Adding upstream version 1:10.5.12. Signed-off-by: Daniel Baumann --- storage/perfschema/pfs_setup_actor.cc | 342 ++++++++++++++++++++++++++++++++++ 1 file changed, 342 insertions(+) create mode 100644 storage/perfschema/pfs_setup_actor.cc (limited to 'storage/perfschema/pfs_setup_actor.cc') diff --git a/storage/perfschema/pfs_setup_actor.cc b/storage/perfschema/pfs_setup_actor.cc new file mode 100644 index 00000000..96b367b6 --- /dev/null +++ b/storage/perfschema/pfs_setup_actor.cc @@ -0,0 +1,342 @@ +/* Copyright (c) 2010, 2015, 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, version 2.0, + as published by the Free Software Foundation. + + This program is also distributed with certain software (including + but not limited to OpenSSL) that is licensed under separate terms, + as designated in a particular file or component or in included license + documentation. The authors of MySQL hereby grant you an additional + permission to link the program and your derivative works with the + separately licensed software that they have included with MySQL. + + 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, version 2.0, 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, + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ + +/** + @file storage/perfschema/pfs_setup_actor.cc + Performance schema setup actor (implementation). +*/ + +#include "my_global.h" +#include "my_sys.h" +#include "my_base.h" +#include "pfs.h" +#include "pfs_stat.h" +#include "pfs_instr.h" +#include "pfs_setup_actor.h" +#include "pfs_account.h" +#include "pfs_global.h" +#include "pfs_buffer_container.h" + +/** + @addtogroup Performance_schema_buffers + @{ +*/ + +/** Hash table for setup_actor records. */ +LF_HASH setup_actor_hash; +/** True if @c setup_actor_hash is initialized. */ +static bool setup_actor_hash_inited= false; + +/** + Initialize the setup actor buffers. + @param param sizing parameters + @return 0 on success +*/ +int init_setup_actor(const PFS_global_param *param) +{ + return global_setup_actor_container.init(param->m_setup_actor_sizing); +} + +/** Cleanup all the setup actor buffers. */ +void cleanup_setup_actor(void) +{ + global_setup_actor_container.cleanup(); +} + +C_MODE_START +static uchar *setup_actor_hash_get_key(const uchar *entry, size_t *length, + my_bool) +{ + const PFS_setup_actor * const *typed_entry; + const PFS_setup_actor *setup_actor; + const void *result; + typed_entry= reinterpret_cast (entry); + DBUG_ASSERT(typed_entry != NULL); + setup_actor= *typed_entry; + DBUG_ASSERT(setup_actor != NULL); + *length= setup_actor->m_key.m_key_length; + result= setup_actor->m_key.m_hash_key; + return const_cast (reinterpret_cast (result)); +} +C_MODE_END + +/** + Initialize the setup actor hash. + @return 0 on success +*/ +int init_setup_actor_hash(const PFS_global_param *param) +{ + if ((! setup_actor_hash_inited) && (param->m_setup_actor_sizing != 0)) + { + lf_hash_init(&setup_actor_hash, sizeof(PFS_setup_actor*), LF_HASH_UNIQUE, + 0, 0, setup_actor_hash_get_key, &my_charset_bin); + /* setup_actor_hash.size= param->m_setup_actor_sizing; */ + setup_actor_hash_inited= true; + } + return 0; +} + +/** Cleanup the setup actor hash. */ +void cleanup_setup_actor_hash(void) +{ + if (setup_actor_hash_inited) + { + lf_hash_destroy(&setup_actor_hash); + setup_actor_hash_inited= false; + } +} + +static LF_PINS* get_setup_actor_hash_pins(PFS_thread *thread) +{ + if (unlikely(thread->m_setup_actor_hash_pins == NULL)) + { + if (! setup_actor_hash_inited) + return NULL; + thread->m_setup_actor_hash_pins= lf_hash_get_pins(&setup_actor_hash); + } + return thread->m_setup_actor_hash_pins; +} + +static void set_setup_actor_key(PFS_setup_actor_key *key, + const char *user, uint user_length, + const char *host, uint host_length, + const char *role, uint role_length) +{ + DBUG_ASSERT(user_length <= USERNAME_LENGTH); + DBUG_ASSERT(host_length <= HOSTNAME_LENGTH); + + char *ptr= &key->m_hash_key[0]; + memcpy(ptr, user, user_length); + ptr+= user_length; + ptr[0]= 0; + ptr++; + memcpy(ptr, host, host_length); + ptr+= host_length; + ptr[0]= 0; + ptr++; + memcpy(ptr, role, role_length); + ptr+= role_length; + ptr[0]= 0; + ptr++; + key->m_key_length= (uint)(ptr - &key->m_hash_key[0]); +} + +int insert_setup_actor(const String *user, const String *host, const String *role, + bool enabled, bool history) +{ + PFS_thread *thread= PFS_thread::get_current_thread(); + if (unlikely(thread == NULL)) + return HA_ERR_OUT_OF_MEM; + + LF_PINS *pins= get_setup_actor_hash_pins(thread); + if (unlikely(pins == NULL)) + return HA_ERR_OUT_OF_MEM; + + PFS_setup_actor *pfs; + pfs_dirty_state dirty_state; + + pfs= global_setup_actor_container.allocate(& dirty_state); + if (pfs != NULL) + { + set_setup_actor_key(&pfs->m_key, + user->ptr(), user->length(), + host->ptr(), host->length(), + role->ptr(), role->length()); + pfs->m_username= &pfs->m_key.m_hash_key[0]; + pfs->m_username_length= user->length(); + pfs->m_hostname= pfs->m_username + pfs->m_username_length + 1; + pfs->m_hostname_length= host->length(); + pfs->m_rolename= pfs->m_hostname + pfs->m_hostname_length + 1; + pfs->m_rolename_length= role->length(); + pfs->m_enabled= enabled; + pfs->m_history= history; + + int res; + pfs->m_lock.dirty_to_allocated(& dirty_state); + res= lf_hash_insert(&setup_actor_hash, pins, &pfs); + if (likely(res == 0)) + { + update_setup_actors_derived_flags(); + return 0; + } + + global_setup_actor_container.deallocate(pfs); + + if (res > 0) + return HA_ERR_FOUND_DUPP_KEY; + return HA_ERR_OUT_OF_MEM; + } + + return HA_ERR_RECORD_FILE_FULL; +} + +int delete_setup_actor(const String *user, const String *host, const String *role) +{ + PFS_thread *thread= PFS_thread::get_current_thread(); + if (unlikely(thread == NULL)) + return HA_ERR_OUT_OF_MEM; + + LF_PINS* pins= get_setup_actor_hash_pins(thread); + if (unlikely(pins == NULL)) + return HA_ERR_OUT_OF_MEM; + + PFS_setup_actor_key key; + set_setup_actor_key(&key, + user->ptr(), user->length(), + host->ptr(), host->length(), + role->ptr(), role->length()); + + PFS_setup_actor **entry; + entry= reinterpret_cast + (lf_hash_search(&setup_actor_hash, pins, key.m_hash_key, key.m_key_length)); + + if (entry && (entry != MY_ERRPTR)) + { + PFS_setup_actor *pfs= *entry; + lf_hash_delete(&setup_actor_hash, pins, key.m_hash_key, key.m_key_length); + global_setup_actor_container.deallocate(pfs); + } + + lf_hash_search_unpin(pins); + + update_setup_actors_derived_flags(); + + return 0; +} + +class Proc_reset_setup_actor + : public PFS_buffer_processor +{ +public: + Proc_reset_setup_actor(LF_PINS* pins) + : m_pins(pins) + {} + + virtual void operator()(PFS_setup_actor *pfs) + { + lf_hash_delete(&setup_actor_hash, m_pins, + pfs->m_key.m_hash_key, pfs->m_key.m_key_length); + + global_setup_actor_container.deallocate(pfs); + } + +private: + LF_PINS* m_pins; +}; + +int reset_setup_actor() +{ + PFS_thread *thread= PFS_thread::get_current_thread(); + if (unlikely(thread == NULL)) + return HA_ERR_OUT_OF_MEM; + + LF_PINS* pins= get_setup_actor_hash_pins(thread); + if (unlikely(pins == NULL)) + return HA_ERR_OUT_OF_MEM; + + Proc_reset_setup_actor proc(pins); + // FIXME: delete helper instead + global_setup_actor_container.apply(proc); + + update_setup_actors_derived_flags(); + + return 0; +} + +long setup_actor_count() +{ + return setup_actor_hash.count; +} + +/* + - '%' should be replaced by NULL in table SETUP_ACTOR + - add an ENABLED column to include/exclude patterns, more flexible + - the principle is similar to SETUP_OBJECTS +*/ +void lookup_setup_actor(PFS_thread *thread, + const char *user, uint user_length, + const char *host, uint host_length, + bool *enabled, bool *history) +{ + PFS_setup_actor_key key; + PFS_setup_actor **entry; + int i; + + LF_PINS* pins= get_setup_actor_hash_pins(thread); + if (unlikely(pins == NULL)) + { + *enabled= false; + *history= false; + return; + } + + for (i= 1; i<=4; i++) + { + /* + WL#988 Roles is not implemented, so we do not have a role name. + Looking up "%" in SETUP_ACTORS.ROLE. + */ + switch(i) + { + case 1: + set_setup_actor_key(&key, user, user_length, host, host_length, "%", 1); + break; + case 2: + set_setup_actor_key(&key, user, user_length, "%", 1, "%", 1); + break; + case 3: + set_setup_actor_key(&key, "%", 1, host, host_length, "%", 1); + break; + case 4: + set_setup_actor_key(&key, "%", 1, "%", 1, "%", 1); + break; + } + entry= reinterpret_cast + (lf_hash_search(&setup_actor_hash, pins, key.m_hash_key, key.m_key_length)); + + if (entry && (entry != MY_ERRPTR)) + { + PFS_setup_actor *pfs= *entry; + lf_hash_search_unpin(pins); + *enabled= pfs->m_enabled; + *history= pfs->m_history; + return; + } + + lf_hash_search_unpin(pins); + } + *enabled= false; + *history= false; + return; +} + +int update_setup_actors_derived_flags() +{ + PFS_thread *thread= PFS_thread::get_current_thread(); + if (unlikely(thread == NULL)) + return HA_ERR_OUT_OF_MEM; + + update_accounts_derived_flags(thread); + return 0; +} + +/** @} */ -- cgit v1.2.3