* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* ---------------------------------------------------------------------------------------
*
* ss_dms.cpp
* Dynamic loading of the DMS
*
* IDENTIFICATION
* src/gausskernel/ddes/adapter/ss_dms.cpp
*
* ---------------------------------------------------------------------------------------
*/
#ifndef WIN32
#include "dlfcn.h"
#endif
#include "c.h"
#include "pgstat.h"
#include "ddes/dms/ss_dms.h"
#include "utils/elog.h"
ss_dms_func_t g_ss_dms_func = { 0 };
#define SS_RETURN_IFERR(ret) \
do { \
int _status_ = (ret); \
if (SECUREC_UNLIKELY(_status_ != DMS_SUCCESS)) { \
return _status_; \
} \
} while (0)
int dms_load_symbol(char *symbol, void **sym_lib_handle)
{
#ifndef WIN32
const char *dlsym_err = NULL;
*sym_lib_handle = dlsym(g_ss_dms_func.handle, symbol);
dlsym_err = dlerror();
if (dlsym_err != NULL) {
ereport(FATAL, (errcode(ERRCODE_INVALID_OPERATION),
errmsg("incompatible library \"%s\", load %s failed, %s", SS_LIBDMS_NAME, symbol, dlsym_err)));
return DMS_ERROR;
}
#endif
return DMS_SUCCESS;
}
int dms_open_dl(void **lib_handle, char *symbol)
{
#ifdef WIN32
return DMS_ERROR;
#else
*lib_handle = dlopen(symbol, RTLD_LAZY);
if (*lib_handle == NULL) {
ereport(ERROR, (errcode_for_file_access(), errmsg("could not load library %s, %s", SS_LIBDMS_NAME, dlerror())));
return DMS_ERROR;
}
return DMS_SUCCESS;
#endif
}
void dms_close_dl(void *lib_handle)
{
#ifndef WIN32
(void)dlclose(lib_handle);
#endif
}
#define DMS_LOAD_SYMBOL_FUNC(func) dms_load_symbol(#func, (void **)&g_ss_dms_func.func)
int ss_dms_func_init()
{
if (g_ss_dms_func.inited) {
return DMS_SUCCESS;
}
SS_RETURN_IFERR(dms_open_dl(&g_ss_dms_func.handle, (char *)SS_LIBDMS_NAME));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_show_version));
char version[DMS_VERSION_MAX_LEN] = { 0 };
g_ss_dms_func.dms_show_version((char *)version);
ereport(LOG, (errmsg("Dynamically loading the DMS library, version: \n%s", version)));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_get_version));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_init));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_get_error));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_uninit));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_request_page));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_broadcast_msg));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_request_opengauss_update_xid));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_request_opengauss_xid_csn));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_request_opengauss_txn_status));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_request_opengauss_txn_snapshot));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_request_opengauss_txn_of_master));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_request_opengauss_page_status));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_register_thread_init));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_register_thread_deinit));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_release_owner));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_wait_reform));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_get_event));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_buf_res_rebuild_drc_parallel));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_is_recovery_session));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(drc_get_page_master_id));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_register_ssl_decrypt_pwd));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_set_ssl_param));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_get_ssl_param));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_recovery_page_need_skip));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_reform_failed));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_switchover));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_drc_accessible));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_broadcast_opengauss_ddllock));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_reform_last_failed));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_latch_timed_x));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_latch_timed_s));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_unlatch));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_pre_uninit));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_init_logger));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_refresh_logger));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_validate_drc));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_reform_req_opengauss_ondemand_redo_buffer));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_get_mes_max_watting_rooms));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_send_opengauss_oldest_xmin));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_get_drc_info));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_info));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_get_buf_res));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_get_cmd_stat));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_req_opengauss_immediate_ckpt));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(dms_fsync_logfile));
#ifdef USE_ASSERT_CHECKING
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(ddes_fi_get_context_size));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(ddes_fi_set_and_init_context));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(ddes_fi_set_entries));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(ddes_fi_get_entry_value));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(ddes_fi_set_entry_value));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(ddes_fi_get_tls_trigger_custom));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(ddes_fi_set_tls_trigger_custom));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(ddes_fi_entry_custom_valid));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(ddes_fi_call));
SS_RETURN_IFERR(DMS_LOAD_SYMBOL_FUNC(ddes_fi_call_ex));
#endif
g_ss_dms_func.inited = true;
return DMS_SUCCESS;
}
void ss_dms_func_uninit()
{
if (g_ss_dms_func.handle != NULL) {
dms_close_dl(g_ss_dms_func.handle);
g_ss_dms_func.handle = NULL;
g_ss_dms_func.inited = false;
}
}
static int dms_get_lib_version()
{
return g_ss_dms_func.dms_get_version();
}
static int dms_get_my_version()
{
return DMS_LOCAL_MAJOR_VERSION * DMS_LOCAL_MAJOR_VER_WEIGHT + DMS_LOCAL_MINOR_VERSION * DMS_LOCAL_MINOR_VER_WEIGHT +
DMS_LOCAL_VERSION;
}
int dms_init(dms_profile_t *dms_profile)
{
int my_version = dms_get_my_version();
int lib_version = dms_get_lib_version();
if (my_version != lib_version) {
ereport(FATAL, (errmsg("dms library version is not matched, expected = %d, actual = %d",
my_version, lib_version)));
}
int ret = g_ss_dms_func.dms_init(dms_profile);
if (ret != DMS_SUCCESS) {
return ret;
}
return DMS_SUCCESS;
}
int dms_init_logger(logger_param_t *log_param)
{
return g_ss_dms_func.dms_init_logger(log_param);
}
void dms_refresh_logger(char *log_field, unsigned long long *value)
{
if (g_ss_dms_func.inited) {
g_ss_dms_func.dms_refresh_logger(log_field, value);
}
}
void dms_fsync_logfile(void)
{
if (g_ss_dms_func.inited) {
g_ss_dms_func.dms_fsync_logfile();
}
}
void dms_uninit(void)
{
g_ss_dms_func.dms_uninit();
ss_dms_func_uninit();
}
void dms_get_error(int *errcode, const char **errmsg)
{
g_ss_dms_func.dms_get_error(errcode, errmsg);
}
int dms_request_page(dms_context_t *dms_ctx, dms_buf_ctrl_t *ctrl, dms_lock_mode_t mode)
{
DMSWaiteventTarget target;
target.page.buffer = ctrl->buf_id + 1;
target.page.mode = mode;
pgstat_report_dms_waitevent(WAIT_EVENT_PCR_REQ_HEAP_PAGE, &target);
int res = g_ss_dms_func.dms_request_page(dms_ctx, ctrl, mode);
pgstat_report_dms_waitevent(WAIT_EVENT_END);
return res;
}
int dms_broadcast_msg(dms_context_t *dms_ctx, dms_broadcast_info_t *dms_broad_info)
{
return g_ss_dms_func.dms_broadcast_msg(dms_ctx, dms_broad_info);
}
int dms_request_opengauss_update_xid(dms_context_t *dms_ctx, unsigned short t_infomask, unsigned short t_infomask2,
unsigned long long *uxid)
{
return g_ss_dms_func.dms_request_opengauss_update_xid(dms_ctx, t_infomask, t_infomask2, uxid);
}
int dms_request_opengauss_xid_csn(dms_context_t *dms_ctx, dms_opengauss_xid_csn_t *dms_txn_info,
dms_opengauss_csn_result_t *xid_csn_result)
{
return g_ss_dms_func.dms_request_opengauss_xid_csn(dms_ctx, dms_txn_info, xid_csn_result);
}
int dms_request_opengauss_txn_status(dms_context_t *dms_ctx, unsigned char request, unsigned char *result)
{
return g_ss_dms_func.dms_request_opengauss_txn_status(dms_ctx, request, result);
}
int dms_request_opengauss_txn_snapshot(dms_context_t *dms_ctx, dms_opengauss_txn_snapshot_t *dms_txn_snapshot)
{
pgstat_report_dms_waitevent(WAIT_EVENT_TXN_REQ_SNAPSHOT);
int res = g_ss_dms_func.dms_request_opengauss_txn_snapshot(dms_ctx, dms_txn_snapshot);
pgstat_report_dms_waitevent(WAIT_EVENT_END);
return res;
}
int dms_request_opengauss_txn_of_master(dms_context_t *dms_ctx, dms_opengauss_txn_sw_info_t *dms_txn_swinfo)
{
return g_ss_dms_func.dms_request_opengauss_txn_of_master(dms_ctx, dms_txn_swinfo);
}
int dms_request_opengauss_page_status(dms_context_t *dms_ctx, unsigned int page, int page_num,
unsigned long int *page_map, int *bit_count)
{
return g_ss_dms_func.dms_request_opengauss_page_status(dms_ctx, page, page_num, page_map, bit_count);
}
int dms_broadcast_opengauss_ddllock(dms_context_t *dms_ctx, char *data, unsigned int len, unsigned char handle_recv_msg,
unsigned int timeout, unsigned char resend_after_reform)
{
return g_ss_dms_func.dms_broadcast_opengauss_ddllock(dms_ctx, data, len, handle_recv_msg, timeout,
resend_after_reform);
}
bool dms_latch_timed_x(dms_drlatch_t *dlatch, unsigned int sid, unsigned int wait_ticks, void *dms_stat)
{
return (bool)g_ss_dms_func.dms_latch_timed_x(dlatch, sid, wait_ticks, dms_stat);
}
bool dms_latch_timed_s(dms_drlatch_t *dlatch, unsigned int sid, unsigned int wait_ticks, unsigned char is_force, void *dms_stat)
{
return (bool)g_ss_dms_func.dms_latch_timed_s(dlatch, sid, wait_ticks, is_force, dms_stat);
}
void dms_unlatch(dms_drlatch_t *dlatch, void *dms_stat)
{
g_ss_dms_func.dms_unlatch(dlatch, dms_stat);
}
int dms_register_thread_init(dms_thread_init_t thrd_init)
{
return g_ss_dms_func.dms_register_thread_init(thrd_init);
}
int dms_register_thread_deinit(dms_thread_deinit_t thrd_deinit)
{
return g_ss_dms_func.dms_register_thread_deinit(thrd_deinit);
}
int dms_release_owner(dms_context_t *dms_ctx, dms_buf_ctrl_t *ctrl, unsigned char *released)
{
return g_ss_dms_func.dms_release_owner(dms_ctx, ctrl, released);
}
int dms_wait_reform(unsigned int *has_offline)
{
return g_ss_dms_func.dms_wait_reform(has_offline);
}
void dms_get_event(dms_wait_event_t event_type, unsigned long long *event_cnt, unsigned long long *event_time)
{
return g_ss_dms_func.dms_get_event(event_type, event_cnt, event_time);
}
int dms_buf_res_rebuild_drc_parallel(dms_context_t *dms_ctx, dms_ctrl_info_t *ctrl_info, unsigned char thread_index)
{
return g_ss_dms_func.dms_buf_res_rebuild_drc_parallel(dms_ctx, ctrl_info, thread_index);
}
int dms_is_recovery_session(unsigned int sid)
{
return g_ss_dms_func.dms_is_recovery_session(sid);
}
int drc_get_page_master_id(char pageid[DMS_PAGEID_SIZE], unsigned char *master_id)
{
return g_ss_dms_func.drc_get_page_master_id(pageid, master_id);
}
int dms_register_ssl_decrypt_pwd(dms_decrypt_pwd_t cb_func)
{
return g_ss_dms_func.dms_register_ssl_decrypt_pwd(cb_func);
}
int dms_set_ssl_param(const char *param_name, const char *param_value)
{
return g_ss_dms_func.dms_set_ssl_param(param_name, param_value);
}
int dms_get_ssl_param(const char *param_name, char *param_value, unsigned int size)
{
return g_ss_dms_func.dms_get_ssl_param(param_name, param_value, size);
}
int dms_recovery_page_need_skip(char *pageid, unsigned long long redo_lsn, unsigned char *skip)
{
return g_ss_dms_func.dms_recovery_page_need_skip(pageid, redo_lsn, skip);
}
int dms_reform_failed(void)
{
return g_ss_dms_func.dms_reform_failed();
}
int dms_switchover(unsigned int sess_id)
{
return g_ss_dms_func.dms_switchover(sess_id);
}
int dms_drc_accessible(unsigned char res_type)
{
return g_ss_dms_func.dms_drc_accessible(res_type);
}
int dms_reform_last_failed(void)
{
return g_ss_dms_func.dms_reform_last_failed();
}
void dms_pre_uninit(void)
{
return g_ss_dms_func.dms_pre_uninit();
}
void dms_validate_drc(dms_context_t *dms_ctx, dms_buf_ctrl_t *ctrl, unsigned long long lsn,
unsigned char is_dirty)
{
return g_ss_dms_func.dms_validate_drc(dms_ctx, ctrl, lsn, is_dirty);
}
int dms_reform_req_opengauss_ondemand_redo_buffer(dms_context_t *dms_ctx, void *block_key, unsigned int key_len,
int *redo_status)
{
return g_ss_dms_func.dms_reform_req_opengauss_ondemand_redo_buffer(dms_ctx, block_key, key_len, redo_status);
}
unsigned int dms_get_mes_max_watting_rooms(void)
{
return g_ss_dms_func.dms_get_mes_max_watting_rooms();
}
int dms_send_opengauss_oldest_xmin(dms_context_t *dms_ctx, unsigned long long oldest_xmin, unsigned char dest_id)
{
return g_ss_dms_func.dms_send_opengauss_oldest_xmin(dms_ctx, oldest_xmin, dest_id);
}
int get_drc_info(int *is_found, dv_drc_buf_info *drc_info)
{
return g_ss_dms_func.dms_get_drc_info(is_found, drc_info);
}
int dms_info(char *buf, unsigned int len, dms_info_id_e id)
{
if (g_ss_dms_func.inited) {
return g_ss_dms_func.dms_info(buf, len, id);
} else {
return DMS_SUCCESS;
}
}
void dms_get_buf_res(unsigned long long *row_id, dv_drc_buf_info *drc_info, int type)
{
g_ss_dms_func.dms_get_buf_res(row_id, drc_info, type);
}
void dms_get_cmd_stat(int index, wait_cmd_stat_result_t *cmd_stat_result)
{
g_ss_dms_func.dms_get_cmd_stat(index, cmd_stat_result);
}
int dms_req_opengauss_immediate_checkpoint(dms_context_t *dms_ctx, unsigned long long *redo_lsn)
{
return g_ss_dms_func.dms_req_opengauss_immediate_ckpt(dms_ctx, redo_lsn);
}