📄 cib_client.c
字号:
/* * 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 <crm/crm.h>#include <crm/cib.h>#include <crm/msg_xml.h>#include <crm/common/xml.h>gboolean verify_cib_cmds(cib_t *cib);int cib_client_set_op_callback( cib_t *cib, void (*callback)(const struct ha_msg *msg, int call_id, int rc, crm_data_t *output));int cib_client_noop(cib_t *cib, int call_options);int cib_client_ping(cib_t *cib, crm_data_t **output_data, int call_options);int cib_client_query(cib_t *cib, const char *section, crm_data_t **output_data, int call_options);int cib_client_query_from(cib_t *cib, const char *host, const char *section, crm_data_t **output_data, int call_options);int cib_client_sync(cib_t *cib, const char *section, int call_options);int cib_client_sync_from( cib_t *cib, const char *host, const char *section, int call_options);int cib_client_is_master(cib_t *cib);int cib_client_set_slave(cib_t *cib, int call_options);int cib_client_set_slave_all(cib_t *cib, int call_options);int cib_client_set_master(cib_t *cib, int call_options);int cib_client_bump_epoch(cib_t *cib, int call_options);int cib_client_create(cib_t *cib, const char *section, crm_data_t *data, crm_data_t **output_data, int call_options) ;int cib_client_modify(cib_t *cib, const char *section, crm_data_t *data, crm_data_t **output_data, int call_options) ;int cib_client_replace(cib_t *cib, const char *section, crm_data_t *data, crm_data_t **output_data, int call_options) ;int cib_client_delete(cib_t *cib, const char *section, crm_data_t *data, crm_data_t **output_data, int call_options) ;int cib_client_erase( cib_t *cib, crm_data_t **output_data, int call_options);int cib_client_quit(cib_t *cib, int call_options);int cib_client_add_notify_callback( cib_t *cib, const char *event, void (*callback)( const char *event, struct ha_msg *msg));int cib_client_del_notify_callback( cib_t *cib, const char *event, void (*callback)( const char *event, struct ha_msg *msg));gint ciblib_GCompareFunc(gconstpointer a, gconstpointer b);extern cib_t *cib_native_new(cib_t *cib);static enum cib_variant configured_variant = cib_native;/* define of the api functions*/cib_t*cib_new(void){ cib_t* new_cib = NULL; if(configured_variant != cib_native) { crm_err("Only the native CIB type is currently implemented"); return NULL; } crm_malloc(new_cib, sizeof(cib_t)); new_cib->call_id = 1; new_cib->type = cib_none; new_cib->state = cib_disconnected; new_cib->op_callback = NULL; new_cib->variant_opaque = NULL; new_cib->notify_list = NULL; /* the rest will get filled in by the variant constructor */ crm_malloc(new_cib->cmds, sizeof(cib_api_operations_t)); memset(new_cib->cmds, 0, sizeof(cib_api_operations_t)); new_cib->cmds->set_op_callback = cib_client_set_op_callback; new_cib->cmds->add_notify_callback = cib_client_add_notify_callback; new_cib->cmds->del_notify_callback = cib_client_del_notify_callback; new_cib->cmds->noop = cib_client_noop; new_cib->cmds->ping = cib_client_ping; new_cib->cmds->query = cib_client_query; new_cib->cmds->sync = cib_client_sync; new_cib->cmds->query_from = cib_client_query_from; new_cib->cmds->sync_from = cib_client_sync_from; new_cib->cmds->is_master = cib_client_is_master; new_cib->cmds->set_master = cib_client_set_master; new_cib->cmds->set_slave = cib_client_set_slave; new_cib->cmds->set_slave_all = cib_client_set_slave_all; new_cib->cmds->bump_epoch = cib_client_bump_epoch; new_cib->cmds->create = cib_client_create; new_cib->cmds->modify = cib_client_modify; new_cib->cmds->replace = cib_client_replace; new_cib->cmds->delete = cib_client_delete; new_cib->cmds->erase = cib_client_erase; new_cib->cmds->quit = cib_client_quit; cib_native_new(new_cib); if(verify_cib_cmds(new_cib) == FALSE) { return NULL; } return new_cib;}intcib_client_set_op_callback( cib_t *cib, void (*callback)(const struct ha_msg *msg, int call_id, int rc, crm_data_t *output)) { if(callback == NULL) { crm_info("Un-Setting operation callback"); } else { crm_devel("Setting operation callback"); } cib->op_callback = callback; return cib_ok;} int cib_client_noop(cib_t *cib, int call_options){ if(cib == NULL) { return cib_missing; } else if(cib->state == cib_disconnected) { return cib_not_connected; } else if(cib->cmds->variant_op == NULL) { return cib_variant; } return cib->cmds->variant_op( cib, CRM_OP_NOOP, NULL, NULL, NULL, NULL, call_options);}int cib_client_ping(cib_t *cib, crm_data_t **output_data, int call_options){ if(cib == NULL) { return cib_missing; } else if(cib->state == cib_disconnected) { return cib_not_connected; } else if(cib->cmds->variant_op == NULL) { return cib_variant; } return cib->cmds->variant_op( cib, CRM_OP_PING, NULL,NULL,NULL, output_data, call_options);}int cib_client_query(cib_t *cib, const char *section, crm_data_t **output_data, int call_options){ return cib->cmds->query_from( cib, NULL, section, output_data, call_options);}int cib_client_query_from(cib_t *cib, const char *host, const char *section, crm_data_t **output_data, int call_options){ if(cib == NULL) { return cib_missing; } else if(cib->state == cib_disconnected) { return cib_not_connected; } else if(cib->cmds->variant_op == NULL) { return cib_variant; } return cib->cmds->variant_op(cib, CRM_OP_CIB_QUERY, host, section, NULL, output_data, call_options);}int cib_client_is_master(cib_t *cib){ if(cib == NULL) { return cib_missing; } else if(cib->state == cib_disconnected) { return cib_not_connected; } else if(cib->cmds->variant_op == NULL) { return cib_variant; } return cib->cmds->variant_op( cib, CRM_OP_CIB_ISMASTER, NULL, NULL,NULL,NULL, cib_scope_local|cib_sync_call);}int cib_client_set_slave(cib_t *cib, int call_options){ if(cib == NULL) { return cib_missing; } else if(cib->state == cib_disconnected) { return cib_not_connected; } else if(cib->cmds->variant_op == NULL) { return cib_variant; } return cib->cmds->variant_op( cib, CRM_OP_CIB_SLAVE, NULL,NULL,NULL,NULL, call_options);}int cib_client_set_slave_all(cib_t *cib, int call_options){ if(cib == NULL) { return cib_missing; } else if(cib->state == cib_disconnected) { return cib_not_connected; } else if(cib->cmds->variant_op == NULL) { return cib_variant; } return cib->cmds->variant_op( cib, CRM_OP_CIB_SLAVEALL, NULL,NULL,NULL,NULL, call_options);}int cib_client_set_master(cib_t *cib, int call_options){ if(cib == NULL) { return cib_missing; } else if(cib->state == cib_disconnected) { return cib_not_connected; } else if(cib->cmds->variant_op == NULL) { return cib_variant; } crm_devel("Adding cib_scope_local to options"); return cib->cmds->variant_op( cib, CRM_OP_CIB_MASTER, NULL,NULL,NULL,NULL, call_options|cib_scope_local);}int cib_client_bump_epoch(cib_t *cib, int call_options){ if(cib == NULL) { return cib_missing; } else if(cib->state == cib_disconnected) { return cib_not_connected; } else if(cib->cmds->variant_op == NULL) { return cib_variant; } return cib->cmds->variant_op( cib, CRM_OP_CIB_BUMP, NULL, NULL, NULL, NULL, call_options);}int cib_client_sync(cib_t *cib, const char *section, int call_options){ return cib->cmds->sync_from(cib, NULL, section, call_options);}int cib_client_sync_from( cib_t *cib, const char *host, const char *section, int call_options){ enum cib_errors rc = cib_ok; crm_data_t *stored_cib = NULL; crm_data_t *current_cib = NULL; if(cib == NULL) { return cib_missing; } else if(cib->state == cib_disconnected) { return cib_not_connected; } else if(cib->cmds->variant_op == NULL) { return cib_variant; } crm_devel("Retrieving current CIB from %s", host); rc = cib->cmds->query_from( cib, host, section, ¤t_cib, call_options|cib_sync_call); if(current_cib == NULL) { crm_err("Could not retrive current CIB."); } else if(rc == cib_ok) { if(call_options & cib_scope_local) { /* having scope == local makes no sense from here on */ call_options ^= cib_scope_local; } crm_devel("Storing current CIB (should trigger a store everywhere)");/* crm_xml_devel(current_cib, "XML to store"); */ rc = cib->cmds->replace( cib, section, current_cib, &stored_cib, call_options); } free_xml(current_cib); free_xml(stored_cib); return rc; }int cib_client_create(cib_t *cib, const char *section, crm_data_t *data, crm_data_t **output_data, int call_options) { if(cib == NULL) { return cib_missing; } else if(cib->state == cib_disconnected) { return cib_not_connected; } else if(cib->cmds->variant_op == NULL) { return cib_variant; } return cib->cmds->variant_op(cib, CRM_OP_CIB_CREATE, NULL, section, data, output_data, call_options);}int cib_client_modify(cib_t *cib, const char *section, crm_data_t *data, crm_data_t **output_data, int call_options) { if(cib == NULL) { return cib_missing; } else if(cib->state == cib_disconnected) { return cib_not_connected; } else if(cib->cmds->variant_op == NULL) { return cib_variant; } return cib->cmds->variant_op(cib, CRM_OP_CIB_UPDATE, NULL, section, data, output_data, call_options);}int cib_client_replace(cib_t *cib, const char *section, crm_data_t *data, crm_data_t **output_data, int call_options) { if(cib == NULL) { return cib_missing; } else if(cib->state == cib_disconnected) { return cib_not_connected; } else if(cib->cmds->variant_op == NULL) { return cib_variant; } else if(data == NULL) { return cib_missing_data; } return cib->cmds->variant_op(cib, CRM_OP_CIB_REPLACE, NULL, section, data, output_data, call_options);}int cib_client_delete(cib_t *cib, const char *section, crm_data_t *data, crm_data_t **output_data, int call_options) { if(cib == NULL) { return cib_missing; } else if(cib->state == cib_disconnected) { return cib_not_connected; } else if(cib->cmds->variant_op == NULL) { return cib_variant; } return cib->cmds->variant_op(cib, CRM_OP_CIB_DELETE, NULL, section, data, output_data, call_options);}int cib_client_erase( cib_t *cib, crm_data_t **output_data, int call_options){ if(cib == NULL) { return cib_missing; } else if(cib->state == cib_disconnected) { return cib_not_connected; } else if(cib->cmds->variant_op == NULL) { return cib_variant; } return cib->cmds->variant_op(cib, CRM_OP_CIB_ERASE, NULL, NULL, NULL, output_data, call_options);}int cib_client_quit(cib_t *cib, int call_options){ if(cib == NULL) { return cib_missing; } else if(cib->state == cib_disconnected) { return cib_not_connected; } else if(cib->cmds->variant_op == NULL) { return cib_variant; } return cib->cmds->variant_op( cib, CRM_OP_QUIT, NULL, NULL, NULL, NULL, call_options);}int cib_client_add_notify_callback( cib_t *cib, const char *event, void (*callback)( const char *event, struct ha_msg *msg)){ GList *list_item = NULL; cib_notify_client_t *new_client = NULL; crm_debug("Adding callback for %s events (%d)", event, g_list_length(cib->notify_list)); crm_malloc(new_client, sizeof(cib_notify_client_t)); new_client->event = event; new_client->callback = callback; list_item = g_list_find_custom( cib->notify_list, new_client, ciblib_GCompareFunc); if(list_item != NULL) { crm_warn("Callback already present"); } else { cib->notify_list = g_list_append( cib->notify_list, new_client); crm_devel("Callback added (%d)", g_list_length(cib->notify_list)); } return cib_ok;}int cib_client_del_notify_callback( cib_t *cib, const char *event, void (*callback)( const char *event, struct ha_msg *msg)){ GList *list_item = NULL; cib_notify_client_t *new_client = NULL; crm_debug("Removing callback for %s events", event); crm_malloc(new_client, sizeof(cib_notify_client_t)); new_client->event = event; new_client->callback = callback; list_item = g_list_find_custom( cib->notify_list, new_client, ciblib_GCompareFunc); if(list_item != NULL) { cib_notify_client_t *list_client = list_item->data; cib->notify_list = g_list_remove(cib->notify_list, list_client); crm_free(list_client); crm_devel("Removed callback"); } else { crm_devel("Callback not present"); } crm_free(new_client); return cib_ok;}gint ciblib_GCompareFunc(gconstpointer a, gconstpointer b){ const cib_notify_client_t *a_client = a; const cib_notify_client_t *b_client = b; if(a_client->callback == b_client->callback && safe_str_neq(a_client->event, b_client->event)) { return 0; } else if(((long)a_client->callback) < ((long)b_client->callback)) { return -1; } return 1;}char *cib_pluralSection(const char *a_section){ char *a_section_parent = NULL; if (a_section == NULL) { a_section_parent = crm_strdup("all"); } else if(strcmp(a_section, XML_TAG_CIB) == 0) { a_section_parent = crm_strdup("all"); } else if(strcmp(a_section, XML_CIB_TAG_NODE) == 0) { a_section_parent = crm_strdup(XML_CIB_TAG_NODES); } else if(strcmp(a_section, XML_CIB_TAG_STATE) == 0) { a_section_parent = crm_strdup(XML_CIB_TAG_STATUS); } else if(strcmp(a_section, XML_CIB_TAG_CONSTRAINT) == 0) { a_section_parent = crm_strdup(XML_CIB_TAG_CONSTRAINTS); } else if(strcmp(a_section, "rsc_location") == 0) { a_section_parent = crm_strdup(XML_CIB_TAG_CONSTRAINTS); } else if(strcmp(a_section, "rsc_dependancy") == 0) { a_section_parent = crm_strdup(XML_CIB_TAG_CONSTRAINTS); } else if(strcmp(a_section, "rsc_order") == 0) { a_section_parent = crm_strdup(XML_CIB_TAG_CONSTRAINTS); } else if(strcmp(a_section, XML_CIB_TAG_RESOURCE) == 0) { a_section_parent = crm_strdup(XML_CIB_TAG_RESOURCES); } else if(strcmp(a_section, XML_CIB_TAG_NVPAIR) == 0) { a_section_parent = crm_strdup(XML_CIB_TAG_CRMCONFIG); } else { crm_err("Unknown section %s", a_section); a_section_parent = crm_strdup("all"); } crm_verbose("Plural of %s is %s", crm_str(a_section), a_section_parent); return a_section_parent;}const char *cib_error2string(enum cib_errors return_code){ const char *error_msg = NULL; switch(return_code) { case cib_msg_field_add: error_msg = "failed adding field to cib message"; break; case cib_operation: error_msg = "invalid operation"; break; case cib_create_msg: error_msg = "couldnt create cib message"; break; case cib_client_gone: error_msg = "client left before we could send reply"; break; case cib_not_connected: error_msg = "not connected"; break; case cib_not_authorized: error_msg = "not authorized"; break; case cib_send_failed: error_msg = "send failed"; break; case cib_reply_failed: error_msg = "reply failed"; break; case cib_return_code: error_msg = "no return code"; break; case cib_output_ptr: error_msg = "nowhere to store output"; break; case cib_output_data: error_msg = "corrupt output data"; break; case cib_connection: error_msg = "connection failed"; break; case cib_callback_register: error_msg = "couldnt register callback channel"; break; case cib_authentication: error_msg = ""; break; case cib_registration_msg: error_msg = "invalid registration msg"; break; case cib_callback_token: error_msg = "callback token not found"; break; case cib_missing: error_msg = "cib object missing";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -