📄 clientlib.c
字号:
/* * Client Library for Local Resource Manager API. * * Author: Huang Zhen <zhenh@cn.ibm.com> * Copyright (c) 2004 International Business Machines * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */#include <portability.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <string.h>#include <glib.h>#include <heartbeat.h>#include <clplumbing/ipc.h>#include <ha_msg.h>#include <lrm/lrm_api.h>#include <lrm/lrm_msg.h>/* Notice: this define should be replaced when merge to the whole pkg*/#define LRM_MAXPIDLEN 256#define LRM_ID "lrm"/* declare the functions used by the lrm_ops structure*/static int lrm_signon (ll_lrm_t* lrm, const char * app_name);static int lrm_signoff (ll_lrm_t*);static int lrm_delete (ll_lrm_t*);static int lrm_set_lrm_callback (ll_lrm_t* lrm, lrm_op_done_callback_t op_done_callback_func);static GList* lrm_get_rsc_class_supported (ll_lrm_t* lrm);static GList* lrm_get_rsc_type_supported (ll_lrm_t* lrm, const char* class);static GList* lrm_get_rsc_provider_supported (ll_lrm_t* lrm ,const char* class, const char* type);static char* lrm_get_rsc_type_metadata(ll_lrm_t* lrm, const char* class ,const char* type, const char* provider);static GHashTable* lrm_get_all_type_metadata(ll_lrm_t*, const char* class);static GList* lrm_get_all_rscs (ll_lrm_t* lrm);static lrm_rsc_t* lrm_get_rsc (ll_lrm_t* lrm, const char* rsc_id);static int lrm_add_rsc (ll_lrm_t*, const char* id, const char* class ,const char* type, const char* provider ,GHashTable* parameter);static int lrm_delete_rsc (ll_lrm_t*, const char* id);static int lrm_inputfd (ll_lrm_t*);static int lrm_msgready (ll_lrm_t*);static int lrm_rcvmsg (ll_lrm_t*, int blocking);static struct lrm_ops lrm_ops_instance ={ lrm_signon, lrm_signoff, lrm_delete, lrm_set_lrm_callback, lrm_get_rsc_class_supported, lrm_get_rsc_type_supported, lrm_get_rsc_provider_supported, lrm_get_rsc_type_metadata, lrm_get_all_type_metadata, lrm_get_all_rscs, lrm_get_rsc, lrm_add_rsc, lrm_delete_rsc, lrm_inputfd, lrm_msgready, lrm_rcvmsg};/* declare the functions used by the lrm_rsc_ops structure*/static int rsc_perform_op (lrm_rsc_t*, lrm_op_t* op);static int rsc_cancel_op (lrm_rsc_t*, int call_id);static int rsc_flush_ops (lrm_rsc_t*);static GList* rsc_get_cur_state (lrm_rsc_t*, state_flag_t* cur_state);static struct rsc_ops rsc_ops_instance ={ rsc_perform_op, rsc_cancel_op, rsc_flush_ops, rsc_get_cur_state,};/* define the internal data used by the client library*/static int is_signed_on = FALSE;static IPC_Channel* ch_cmd = NULL;static IPC_Channel* ch_cbk = NULL;static lrm_op_done_callback_t op_done_callback = NULL;/* define some utility functions*/static int get_rc_from_ch(IPC_Channel* ch);static int get_rc_from_msg(struct ha_msg* msg);static void client_log (int priority, const char* fmt);static struct ha_msg* op_to_msg (lrm_op_t* op);static lrm_op_t* msg_to_op(struct ha_msg* msg);static void free_op (lrm_op_t* op);/* define of the api functions*/ll_lrm_t*ll_lrm_new (const char * llctype){ ll_lrm_t* lrm; client_log(LOG_INFO, "ll_lrm_new: start."); /* check the parameter*/ if (0 != strncmp(LRM_ID, llctype, strlen(LRM_ID))) { client_log(LOG_ERR, "ll_lrm_new: wrong parameter"); return NULL; } /* alloc memory for lrm*/ if (NULL == (lrm = (ll_lrm_t*) g_new(ll_lrm_t,1))) { client_log(LOG_ERR, "ll_lrm_new: can not alloc memory"); return NULL; } /* assign the ops*/ lrm->lrm_ops = &lrm_ops_instance; client_log(LOG_INFO, "ll_lrm_new: end."); return lrm;}static intlrm_signon (ll_lrm_t* lrm, const char * app_name){ GHashTable* ch_cmd_attrs; GHashTable* ch_cbk_attrs; struct ha_msg* msg; char path[] = IPC_PATH_ATTR; char cmd_path[] = LRM_CMDPATH; char callback_path[] = LRM_CALLBACKPATH; client_log(LOG_INFO, "lrm_signon: start."); /* check parameters*/ if (NULL == lrm || NULL == app_name) { client_log(LOG_ERR, "lrm_signon: wrong parameter"); return HA_FAIL; } /* if already signed on, sign off first*/ if (is_signed_on) { client_log(LOG_INFO, "lrm_signon: the client is alreay signed on,re-sign"); lrm_signoff(lrm); } /* create the command ipc channel to lrmd*/ ch_cmd_attrs = g_hash_table_new(g_str_hash, g_str_equal); g_hash_table_insert(ch_cmd_attrs, path, cmd_path); ch_cmd = ipc_channel_constructor(IPC_ANYTYPE, ch_cmd_attrs); g_hash_table_destroy(ch_cmd_attrs); if (NULL == ch_cmd){ lrm_signoff(lrm); client_log(LOG_ERR, "lrm_signon: can not connect to lrmd for cmd channel"); return HA_FAIL; } if (IPC_OK != ch_cmd->ops->initiate_connection(ch_cmd)) { lrm_signoff(lrm); client_log(LOG_ERR, "lrm_signon: can not initiate connection"); return HA_FAIL; } /* construct the reg msg*/ if (NULL == (msg = create_lrm_reg_msg(app_name))) { lrm_signoff(lrm); client_log(LOG_ERR,"lrm_signon: can not create reg msg"); return HA_FAIL; } /* send the msg*/ if (HA_OK != msg2ipcchan(msg,ch_cmd)) { lrm_signoff(lrm); ha_msg_del(msg); client_log(LOG_ERR,"lrm_signon: can not send msg to lrmd"); return HA_FAIL; } /* parse the return msg*/ if (HA_OK != get_rc_from_ch(ch_cmd)) { ha_msg_del(msg); lrm_signoff(lrm); client_log(LOG_ERR, "lrm_signon: can not recv result from lrmd"); return HA_FAIL; } /* create the callback ipc channel to lrmd*/ ch_cbk_attrs = g_hash_table_new(g_str_hash, g_str_equal); g_hash_table_insert(ch_cbk_attrs, path, callback_path); ch_cbk = ipc_channel_constructor(IPC_ANYTYPE,ch_cbk_attrs); g_hash_table_destroy(ch_cbk_attrs); if (NULL == ch_cbk) { ha_msg_del(msg); lrm_signoff(lrm); client_log(LOG_ERR, "lrm_signon: can not connect to lrmd for callback"); return HA_FAIL; } if (IPC_OK != ch_cbk->ops->initiate_connection(ch_cbk)) { ha_msg_del(msg); lrm_signoff(lrm); client_log(LOG_ERR, "lrm_signon: can not initiate connection"); return HA_FAIL; } /* send the msg*/ if (HA_OK != msg2ipcchan(msg,ch_cbk)) { lrm_signoff(lrm); ha_msg_del(msg); client_log(LOG_ERR,"lrm_signon: can not send msg to lrmd"); return HA_FAIL; } ha_msg_del(msg); /* parse the return msg*/ if (HA_OK != get_rc_from_ch(ch_cbk)) { lrm_signoff(lrm); client_log(LOG_ERR, "lrm_signon: can not recv result from lrmd"); return HA_FAIL; } /* ok, we sign on sucessfully now*/ is_signed_on = TRUE; client_log(LOG_INFO, "lrm_signon: end."); return HA_OK;}static intlrm_signoff (ll_lrm_t* lrm){ int ret = HA_OK; struct ha_msg* msg = NULL; client_log(LOG_INFO,"lrm_signoff: start."); /* construct the unreg msg*/ if ( NULL == ch_cmd ) { client_log(LOG_INFO,"lrm_signoff: ch_cmd is NULL"); ret = HA_FAIL; } else if ( NULL == (msg = create_lrm_msg(UNREGISTER))) { client_log(LOG_INFO,"lrm_signoff: can not create unreg msg"); ret = HA_FAIL; } else /* send the msg*/ if (HA_OK != msg2ipcchan(msg,ch_cmd)) { client_log(LOG_INFO,"lrm_signoff: can not send msg to lrmd"); ret = HA_FAIL; } else /* parse the return msg*/ if (HA_OK != get_rc_from_ch(ch_cmd)) { client_log(LOG_INFO, "lrm_signoff: can not return failed from lrmd"); ret = HA_FAIL; } if( NULL != msg ) { ha_msg_del(msg); } /* close channels */ if (NULL != ch_cmd) { ch_cmd->ops->destroy(ch_cmd); ch_cmd = NULL; } if (NULL != ch_cbk) { ch_cbk->ops->destroy(ch_cbk); ch_cbk = NULL; } is_signed_on = FALSE; client_log(LOG_INFO, "lrm_signoff: end."); return ret;}static intlrm_delete (ll_lrm_t* lrm){ client_log(LOG_INFO,"lrm_delete: start."); /* check the parameter */ if (NULL == lrm) { client_log(LOG_ERR,"lrm_delete: lrm is null."); return HA_FAIL; } g_free(lrm); client_log(LOG_INFO,"lrm_delete: end."); return HA_OK;}static intlrm_set_lrm_callback (ll_lrm_t* lrm, lrm_op_done_callback_t op_done_callback_func){ client_log(LOG_INFO, "lrm_set_lrm_callback: start."); op_done_callback = op_done_callback_func; client_log(LOG_INFO, "lrm_set_lrm_callback: end."); return HA_OK;}static GList*lrm_get_rsc_class_supported (ll_lrm_t* lrm){ struct ha_msg* msg; struct ha_msg* ret; GList* class_list = NULL; /* check whether the channel to lrmd is available */ client_log(LOG_INFO, "lrm_get_rsc_class_supported: start."); if (NULL == ch_cmd) { client_log(LOG_ERR, "lrm_get_rsc_class_supported: ch_mod is null."); return NULL; } /* create the get ra type message */ msg = create_lrm_msg(GETRSCCLASSES); if ( NULL == msg) { client_log(LOG_ERR, "lrm_get_rsc_class_supported: can not create types msg"); return NULL; } /* send the msg to lrmd */ if (HA_OK != msg2ipcchan(msg,ch_cmd)) { ha_msg_del(msg); client_log(LOG_ERR, "lrm_get_rsc_class_supported: can not send msg to lrmd"); return NULL; } ha_msg_del(msg); /* get the return message */ ret = msgfromIPC_noauth(ch_cmd); if (NULL == ret) { client_log(LOG_ERR, "lrm_get_rsc_class_supported: can not recieve ret msg"); return NULL; } /* get the rc of the message */ if (HA_OK != get_rc_from_msg(ret)) { ha_msg_del(ret); client_log(LOG_ERR, "lrm_get_rsc_class_supported: rc from msg is fail"); return NULL; } /* get the ra type list from message */ class_list = ha_msg_value_str_list(ret,F_LRM_RCLASS); ha_msg_del(ret); client_log(LOG_INFO, "lrm_get_rsc_class_supported: end."); return class_list;}static GList*lrm_get_rsc_type_supported (ll_lrm_t* lrm, const char* rclass){ struct ha_msg* msg; struct ha_msg* ret; GList* type_list = NULL; /* check whether the channel to lrmd is available */ client_log(LOG_INFO, "lrm_get_rsc_type_supported: start."); if (NULL == ch_cmd) { client_log(LOG_ERR, "lrm_get_rsc_type_supported: ch_mod is null."); return NULL; } /* create the get ra type message */ msg = create_lrm_msg(GETRSCTYPES); if ( NULL == msg) { client_log(LOG_ERR, "lrm_get_rsc_type_supported: can not create types msg"); return NULL; } if ( HA_OK != ha_msg_add(msg, F_LRM_RCLASS, rclass)) { ha_msg_del(msg); client_log(LOG_ERR, "lrm_get_rsc_type_supported: can not add field to msg"); return NULL; } /* send the msg to lrmd */ if (HA_OK != msg2ipcchan(msg,ch_cmd)) { ha_msg_del(msg); client_log(LOG_ERR, "lrm_get_rsc_type_supported: can not send msg to lrmd"); return NULL; } ha_msg_del(msg); /* get the return message */ ret = msgfromIPC_noauth(ch_cmd); if (NULL == ret) { client_log(LOG_ERR, "lrm_get_rsc_type_supported: can not recieve ret msg"); return NULL; } /* get the rc of the message */ if (HA_OK != get_rc_from_msg(ret)) { ha_msg_del(ret); client_log(LOG_ERR, "lrm_get_rsc_type_supported: rc from msg is fail"); return NULL; } /* get the ra type list from message */ type_list = ha_msg_value_str_list(ret,F_LRM_RTYPES); ha_msg_del(ret); client_log(LOG_INFO, "lrm_get_rsc_type_supported: end."); return type_list;}static GList*lrm_get_rsc_provider_supported (ll_lrm_t* lrm, const char* class, const char* type){ struct ha_msg* msg; struct ha_msg* ret; GList* provider_list = NULL; /* check whether the channel to lrmd is available */ client_log(LOG_INFO, "lrm_get_rsc_provider_supported: start."); if (NULL == ch_cmd) { client_log(LOG_ERR, "lrm_get_rsc_provider_supported: ch_mod is null."); return NULL; } /* create the get ra providers message */ msg = create_lrm_msg(GETPROVIDERS); if ( NULL == msg) { client_log(LOG_ERR, "lrm_get_rsc_provider_supported: can not create types msg"); return NULL; } if (HA_OK != ha_msg_add(msg, F_LRM_RCLASS, class) || HA_OK != ha_msg_add(msg, F_LRM_RTYPE, type)) { ha_msg_del(msg); client_log(LOG_ERR, "lrm_get_rsc_provider_supported: can not add field to msg"); return NULL; } /* send the msg to lrmd */ if (HA_OK != msg2ipcchan(msg,ch_cmd)) { ha_msg_del(msg); client_log(LOG_ERR,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -