📄 cibprimatives.c
字号:
/* $Id: cibprimatives.c,v 1.10.2.2 2004/09/11 06:36:31 msoffen Exp $ *//* * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net> * * 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; either * version 2.1 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <portability.h>#include <stdio.h>#include <sys/types.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <fcntl.h>#include <crm/crm.h>#include <clplumbing/cl_log.h>#include <libxml/tree.h>#include <cibprimatives.h>#include <crm/msg_xml.h>#include <crm/common/xmlutils.h>#include <crm/cib.h>#include <crm/dmalloc_wrapper.h>/* * In case of confusion, this is the memory management policy for * all functions in this file. * * All add/modify functions use copies of supplied data. * It is therefore appropriate that the callers free the supplied data * at some point after the function has finished. * * All delete functions will handle the freeing of deleted data * but not the function arguments. */void update_node_state(xmlNodePtr existing_node, xmlNodePtr update);/* --- Resource */intaddResource(xmlNodePtr cib, xmlNodePtr anXmlNode){ const char *id = ID(anXmlNode); xmlNodePtr root; if (id == NULL || strlen(id) < 1) { return CIBRES_MISSING_ID; } CRM_DEBUG2("Adding " XML_CIB_TAG_RESOURCE " (%s)...", id); root = get_object_root(XML_CIB_TAG_RESOURCES, cib); return add_cib_object(root, anXmlNode);}xmlNodePtrfindResource(xmlNodePtr cib, const char *id){ xmlNodePtr root = NULL, ret = NULL; FNIN(); root = get_object_root(XML_CIB_TAG_RESOURCES, cib); ret = find_entity(root, XML_CIB_TAG_RESOURCE, id, FALSE); FNRET(ret);}intupdateResource(xmlNodePtr cib, xmlNodePtr anXmlNode){ const char *id = ID(anXmlNode); xmlNodePtr root; if (id == NULL || strlen(id) < 1) { return CIBRES_MISSING_ID; } CRM_DEBUG2("Updating " XML_CIB_TAG_RESOURCE " (%s)...", id); root = get_object_root(XML_CIB_TAG_RESOURCES, cib); return update_cib_object(root, anXmlNode, FALSE);}intdelResource(xmlNodePtr cib, xmlNodePtr delete_spec){ const char *id = ID(delete_spec); xmlNodePtr root; if(id == NULL || strlen(id) == 0) { return CIBRES_MISSING_ID; } CRM_DEBUG2("Deleting " XML_CIB_TAG_RESOURCE " (%s)...", id); root = get_object_root(XML_CIB_TAG_RESOURCES, cib); return delete_cib_object(root, delete_spec);}/* --- Constraint */intaddConstraint(xmlNodePtr cib, xmlNodePtr anXmlNode){ const char *id = ID(anXmlNode); xmlNodePtr root; if (id == NULL || strlen(id) < 1) { return CIBRES_MISSING_ID; } CRM_DEBUG2("Adding " XML_CIB_TAG_CONSTRAINT " (%s)...", id); root = get_object_root(XML_CIB_TAG_CONSTRAINTS, cib); return add_cib_object(root, anXmlNode);}xmlNodePtrfindConstraint(xmlNodePtr cib, const char *id){ xmlNodePtr root = NULL, ret = NULL; FNIN(); root = get_object_root(XML_CIB_TAG_CONSTRAINTS, cib); ret = find_entity(root, XML_CIB_TAG_CONSTRAINT, id, FALSE); FNRET(ret);}intupdateConstraint(xmlNodePtr cib, xmlNodePtr anXmlNode){ const char *id = ID(anXmlNode); xmlNodePtr root; if (id == NULL || strlen(id) < 1) { return CIBRES_MISSING_ID; } CRM_DEBUG2("Updating " XML_CIB_TAG_CONSTRAINT " (%s)...", id); root = get_object_root(XML_CIB_TAG_CONSTRAINTS, cib); return update_cib_object(root, anXmlNode, FALSE);}intdelConstraint(xmlNodePtr cib, xmlNodePtr delete_spec){ const char *id = ID(delete_spec); xmlNodePtr root; if(id == NULL || strlen(id) == 0) { return CIBRES_MISSING_ID; } CRM_DEBUG2("Deleting " XML_CIB_TAG_CONSTRAINT " (%s)...", id); root = get_object_root(XML_CIB_TAG_CONSTRAINTS, cib); return delete_cib_object(root, delete_spec);}/* --- HaNode */intaddHaNode(xmlNodePtr cib, xmlNodePtr anXmlNode){ const char *id = ID(anXmlNode); xmlNodePtr root; if (id == NULL || strlen(id) < 1) { return CIBRES_MISSING_ID; } CRM_DEBUG2("Adding " XML_CIB_TAG_NODE " (%s)...", id); root = get_object_root(XML_CIB_TAG_NODES, cib); return add_cib_object(root, anXmlNode);}xmlNodePtrfindHaNode(xmlNodePtr cib, const char *id){ xmlNodePtr root = NULL, ret = NULL; FNIN(); root = get_object_root(XML_CIB_TAG_NODES, cib); ret = find_entity(root, XML_CIB_TAG_NODE, id, FALSE); FNRET(ret);}intupdateHaNode(xmlNodePtr cib, cibHaNode *anXmlNode){ const char *id = ID(anXmlNode); xmlNodePtr root; if (id == NULL || strlen(id) < 1) { return CIBRES_MISSING_ID; } CRM_DEBUG2("Updating " XML_CIB_TAG_NODE " (%s)...", id); root = get_object_root(XML_CIB_TAG_NODES, cib); return update_cib_object(root, anXmlNode, FALSE);}intdelHaNode(xmlNodePtr cib, xmlNodePtr delete_spec){ const char *id = ID(delete_spec); xmlNodePtr root; if(id == NULL || strlen(id) == 0) { return CIBRES_MISSING_ID; } CRM_DEBUG2("Deleting " XML_CIB_TAG_NODE " (%s)...", id); root = get_object_root(XML_CIB_TAG_CONSTRAINTS, cib); return delete_cib_object(root, delete_spec);}/* --- Status */intaddStatus(xmlNodePtr cib, xmlNodePtr anXmlNode){ const char *id = ID(anXmlNode); xmlNodePtr root; if (id == NULL || strlen(id) < 1) { return CIBRES_MISSING_ID; } CRM_DEBUG2("Adding " XML_CIB_TAG_NODE " (%s)...", id); root = get_object_root(XML_CIB_TAG_STATUS, cib); return add_cib_object(root, anXmlNode);}xmlNodePtrfindStatus(xmlNodePtr cib, const char *id){ xmlNodePtr root = NULL, ret = NULL; root = get_object_root(XML_CIB_TAG_STATUS, cib); ret = find_entity(root, XML_CIB_TAG_STATE, id, FALSE); FNRET(ret);}intupdateStatus(xmlNodePtr cib, xmlNodePtr anXmlNode){ const char *id = ID(anXmlNode); xmlNodePtr root; if (id == NULL || strlen(id) < 1) { return CIBRES_MISSING_ID; } CRM_DEBUG2("Updating " XML_CIB_TAG_NODE " (%s)...", id); root = get_object_root(XML_CIB_TAG_STATUS, cib); return update_cib_object(root, anXmlNode, FALSE);}intdelStatus(xmlNodePtr cib, xmlNodePtr delete_spec){ const char *id = ID(delete_spec); xmlNodePtr root; if(id == NULL || strlen(id) == 0) { return CIBRES_MISSING_ID; } CRM_DEBUG2("Deleting " XML_CIB_TAG_STATE " (%s)...", id); root = get_object_root(XML_CIB_TAG_STATUS, cib); return delete_cib_object(root, delete_spec);}intdelete_cib_object(xmlNodePtr parent, xmlNodePtr delete_spec){ const char *object_name = NULL; const char *object_id = NULL; xmlNodePtr equiv_node = NULL; xmlNodePtr children = NULL; int result = CIBRES_OK; if(delete_spec == NULL) { return CIBRES_FAILED_NOOBJECT; } else if(parent == NULL) { return CIBRES_FAILED_NOPARENT; } object_name = delete_spec->name; object_id = xmlGetProp(delete_spec, XML_ATTR_ID); children = delete_spec->children; if(object_id == NULL) { /* placeholder object */ equiv_node = find_xml_node(parent, object_name); } else { equiv_node = find_entity(parent, object_name, object_id, FALSE); } if(equiv_node == NULL) { return CIBRES_FAILED_NOTEXISTS; } else if(children == NULL) { /* only leaves are deleted */ unlink_xml_node(equiv_node); free_xml(equiv_node); } else { while(children != NULL) { int tmp_result = delete_cib_object(equiv_node, children); /* only the first error is likely to be interesting */ if(tmp_result != CIBRES_OK && result == CIBRES_OK) { result = tmp_result; } children = children->next; } } return result;}intadd_cib_object(xmlNodePtr parent, xmlNodePtr new_obj){ const char *object_name = NULL; const char *object_id = NULL; xmlNodePtr equiv_node = NULL; xmlNodePtr children = NULL; if(new_obj == NULL) { return CIBRES_FAILED_NOOBJECT; } else if(parent == NULL) { return CIBRES_FAILED_NOPARENT; } object_name = new_obj->name; object_id = xmlGetProp(new_obj, XML_ATTR_ID); children = new_obj->children; if(object_id == NULL) { /* placeholder object */ equiv_node = find_xml_node(parent, object_name); } else { equiv_node = find_entity(parent, object_name, object_id, FALSE); } if(equiv_node != NULL) { return CIBRES_FAILED_EXISTS; } else if(add_node_copy(parent, new_obj) == NULL) { return CIBRES_FAILED_NODECOPY; } return CIBRES_OK;}intupdate_cib_object(xmlNodePtr parent, xmlNodePtr new_obj, gboolean force){ const char *object_name = NULL; const char *object_id = NULL; xmlNodePtr equiv_node = NULL; xmlNodePtr children = NULL; int result = CIBRES_OK; if(new_obj == NULL) { return CIBRES_FAILED_NOOBJECT; } else if(parent == NULL) { return CIBRES_FAILED_NOPARENT; } object_name = new_obj->name; object_id = xmlGetProp(new_obj, XML_ATTR_ID); children = new_obj->children; if(object_id == NULL) { /* placeholder object */ equiv_node = find_xml_node(parent, object_name); } else { equiv_node = find_entity(parent, object_name, object_id, FALSE); } if(equiv_node != NULL) { if(force == FALSE) { const char *ts_existing = NULL; const char *ts_new = NULL; /* default to false? * * that would mean every node would have to * carry a timestamp */ gboolean is_update = TRUE; ts_existing = TSTAMP(equiv_node); ts_new = TSTAMP(new_obj); if(ts_new != NULL && ts_existing != NULL) { is_update = (strcmp(ts_new, ts_existing) > 0); } if(is_update == FALSE) { cl_log(LOG_ERR, "Ignoring old update to <%s id=\"%s\">" "(%s vs. %s)", object_name, object_id, ts_new, ts_existing); return CIBRES_FAILED_STALE; } } if(safe_str_eq(XML_CIB_TAG_STATE, object_name)){ update_node_state(equiv_node, new_obj); } else { copy_in_properties(equiv_node, new_obj); } while(children != NULL) { int tmp_result = update_cib_object(equiv_node, children,force); /* only the first error is likely to be interesting */ if(tmp_result != CIBRES_OK && result == CIBRES_OK) { result = tmp_result; } children = children->next; } } else if(add_node_copy(parent, new_obj) == NULL) { return CIBRES_FAILED_NODECOPY; } return result;}voidupdate_node_state(xmlNodePtr target, xmlNodePtr update){ gboolean any_updates = FALSE; gboolean replace_lrm = FALSE; const char *old_state = xmlGetProp(target, "state"); const char *old_unclean = xmlGetProp(target, "unclean"); const char *source = NULL; const char *unclean = NULL; const char *exp_state = NULL; const char *state = NULL; xmlAttrPtr prop_iter = NULL; FNIN(); prop_iter = update->properties; while(prop_iter != NULL) { const char *local_prop_name = prop_iter->name; const char *local_prop_value = xmlGetProp(update, local_prop_name); if(local_prop_name == NULL) { /* error */ } else if(strcmp(local_prop_name, "replace_lrm") == 0) { replace_lrm = TRUE; any_updates = TRUE; } else if(strcmp(local_prop_name, "source") == 0) { source = local_prop_value; } else if(strcmp(local_prop_name, "state") == 0) { state = local_prop_value; } else { any_updates = TRUE; set_xml_property_copy(target, local_prop_name, local_prop_value); } prop_iter = prop_iter->next; } unclean = xmlGetProp(target, "unclean"); exp_state = xmlGetProp(target, "exp_state"); if(safe_str_eq(state, "in_ccm")) { if(safe_str_eq(old_state, "active")) { state = "active"; } else { any_updates = TRUE; } } else if(safe_str_eq(state, "down")) { any_updates = TRUE; if(safe_str_neq(exp_state, "down")) { /* TODO: Set the actual time */ /* TODO: Only if not set? */ if(old_unclean == NULL) { set_xml_property_copy(target, "unclean", "time"); } /* TODO: unset source? */ } } else if(state != NULL) { any_updates = TRUE; } if(replace_lrm) { xmlNodePtr lrm = find_xml_node(target, "lrm"); xmlUnlinkNode(lrm); free_xml(lrm); } set_xml_property_copy(target, "state", state); if(any_updates) { set_node_tstamp(target); set_xml_property_copy(target, "source", source); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -