⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cibio.c

📁 在LINUX下实现HA的源代码
💻 C
字号:
/* $Id: cibio.c,v 1.9.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 <sys/stat.h>#include <string.h>#include <stdlib.h>#include <errno.h>#include <fcntl.h>#include <crm/crm.h>#include <libxml/tree.h>#include <crm/cib.h>#include <cibio.h>#include <crm/common/msgutils.h> /*  for getNow() */#include <crm/msg_xml.h>#include <crm/common/xmlutils.h>#include <crm/dmalloc_wrapper.h>const char * local_resource_path[] ={	XML_CIB_TAG_STATUS,};const char * resource_path[] ={	XML_CIB_TAG_RESOURCES,};const char * node_path[] ={	XML_CIB_TAG_NODES,};const char * constraint_path[] ={	XML_CIB_TAG_CONSTRAINTS,};gboolean initialized = FALSE;xmlNodePtr the_cib = NULL;xmlNodePtr node_search = NULL;xmlNodePtr resource_search = NULL;xmlNodePtr constraint_search = NULL;xmlNodePtr status_search = NULL;/* * It is the callers responsibility to free both the new CIB (output) *     and the new CIB (input) */xmlNodePtrcreateEmptyCib(void){	xmlNodePtr cib_root = NULL, config = NULL, status = NULL;		cib_root = create_xml_node(NULL, XML_TAG_CIB);	config = create_xml_node(cib_root, XML_CIB_TAG_CONFIGURATION);	status = create_xml_node(cib_root, XML_CIB_TAG_STATUS);	set_node_tstamp(cib_root);	set_node_tstamp(config);	set_node_tstamp(status);		set_xml_property_copy(cib_root, "version", "1");	set_xml_property_copy(cib_root, "generated", "true");	create_xml_node(config, XML_CIB_TAG_NODES);	create_xml_node(config, XML_CIB_TAG_RESOURCES);	create_xml_node(config, XML_CIB_TAG_CONSTRAINTS);		if (verifyCibXml(cib_root)) {		FNRET(cib_root);	}	cl_log(LOG_CRIT,	       "The generated CIB did not pass integrity testing!!"	       "  All hope is lost.");	FNRET(NULL);}gbooleanverifyCibXml(xmlNodePtr cib){	gboolean is_valid = TRUE;	xmlNodePtr tmp_node = NULL;	FNIN();	if (cib == NULL) {		cl_log(LOG_ERR, "XML Buffer was empty.");		FNRET(FALSE);	}		tmp_node = get_object_root(XML_CIB_TAG_NODES, cib);	if (tmp_node == NULL) is_valid = FALSE;	tmp_node = get_object_root(XML_CIB_TAG_RESOURCES, cib);	if (tmp_node == NULL) is_valid = FALSE;	tmp_node = get_object_root(XML_CIB_TAG_CONSTRAINTS, cib);	if (tmp_node == NULL) is_valid = FALSE;	tmp_node = get_object_root(XML_CIB_TAG_STATUS, cib); 	if (tmp_node == NULL) is_valid = FALSE;	/*  more integrity tests */	FNRET(is_valid);}/* * It is the callers responsibility to free the output of this function */xmlNodePtrreadCibXml(char *buffer){	xmlNodePtr root = string2xml(buffer);	if (verifyCibXml(root) == FALSE) {		free_xml(root);		FNRET(createEmptyCib());	}	FNRET(root);}/* * It is the callers responsibility to free the output of this function */xmlNodePtrreadCibXmlFile(const char *filename){	int s_res = -1;	struct stat buf;	xmlNodePtr root = NULL;	FNIN();	if(filename != NULL) {		s_res = stat(filename, &buf);	}		if (s_res == 0) {		FILE *cib_file = fopen(filename, "r");		root = file2xml(cib_file);		set_xml_property_copy(root, "generated", "false");		fclose(cib_file);			} else {		cl_log(LOG_WARNING,		       "Stat of (%s) failed, file does not exist.",		       CIB_FILENAME);	}		if (verifyCibXml(root) == FALSE) {		free_xml(root);/* 		FNRET(createEmptyCib()); */		root = NULL;	}	FNRET(root);}/* * The caller should never free the return value */xmlNodePtrget_the_CIB(void){	FNIN();	FNRET(the_cib);}gbooleanuninitializeCib(void){	xmlNodePtr tmp_cib = the_cib;	FNIN();		if(tmp_cib == NULL) {		cl_log(LOG_ERR, "The CIB has already been deallocated.");		FNRET(FALSE);	}		initialized = FALSE;	the_cib = NULL;	node_search = NULL;	resource_search = NULL;	constraint_search = NULL;	status_search = NULL;	cl_log(LOG_WARNING, "Deallocating the CIB.");		free_xml(tmp_cib);	cl_log(LOG_WARNING, "The CIB has been deallocated.");		FNRET(TRUE);}/* * This method will not free the old CIB pointer or the new one. * We rely on the caller to have saved a pointer to the old CIB *   and to free the old/bad one depending on what is appropriate. */gbooleaninitializeCib(xmlNodePtr new_cib){	if (verifyCibXml(new_cib)) {		initialized = FALSE;		the_cib = new_cib;		/*  update search paths */		/* not used yet...		node_search =			get_object_root(XML_CIB_TAG_NODES, new_cib);		resource_search =			get_object_root(XML_CIB_TAG_RESOURCES, new_cib);		constraint_search =			get_object_root(XML_CIB_TAG_CONSTRAINTS, new_cib);		status_search =			get_object_root(XML_CIB_TAG_STATUS, new_cib);		*/		initialized = TRUE;		CRM_DEBUG("CIB initialized");		FNRET(TRUE);	}	else {		cl_log(LOG_ERR, "CIB Verification failed");	}		FNRET(FALSE);    }intmoveFile(const char *oldname,	 const char *newname,	 gboolean backup,	 char *ext){	/* move 'oldname' to 'newname' by creating a hard link to it	 *  and then removing the original hard link	 */	int res = 0;	struct stat tmp;	int s_res = stat(newname, &tmp);	FNIN();		cl_log(LOG_INFO, "Stat of %s (code: %d).", newname, s_res);	if (s_res >= 0)	{		if (backup == TRUE) {			char backname[1024];			static const char *back_ext = "bak";			if (ext != NULL) back_ext = (char*)ext;	    			snprintf(backname, sizeof(backname)-1,				 "%s.%s", newname, back_ext);			moveFile(newname, backname, FALSE, NULL);		} else {			res = unlink(newname);			if (res < 0) {				perror("Could not remove the current backup of Cib");				FNRET(-1);			}		}	}    	s_res = stat(oldname, &tmp);	cl_log(LOG_INFO, "Stat of %s (code: %d).", oldname, s_res);	if (s_res >= 0) {		res = link(oldname, newname);		if (res < 0) {			perror("Could not create backup of current Cib");			FNRET(-2);		}		res = unlink(oldname);		if (res < 0) {			perror("Could not unlink the current Cib");			FNRET(-3);		}	}    	FNRET(0);    }intactivateCibBuffer(char *buffer, const char *filename){	int result = -1;	xmlNodePtr local_cib = NULL;	FNIN();		local_cib = readCibXml(buffer);	result = activateCibXml(local_cib, filename);		FNRET(result);}/* * This method will free the old CIB pointer on success and the new one * on failure. */intactivateCibXml(xmlNodePtr new_cib, const char *filename){	int error_code = 0;	xmlNodePtr saved_cib = get_the_CIB();	const char *filename_bak = CIB_BACKUP; /*  calculate */	xmlDocPtr foo;	FNIN();			if (initializeCib(new_cib) == TRUE) {		int res = moveFile(filename, filename_bak, FALSE, NULL);			if (res  < 0) {			cl_log(LOG_INFO,			       "Could not make backup of the current Cib "			       "(code: %d)... aborting update.", res);			error_code = -1;		} else {			cl_log(LOG_INFO,			       "Writing CIB out to %s",			       CIB_FILENAME);	    			if (new_cib->doc == NULL) {				cl_log(LOG_INFO,				       "Writing of a node tree with a NULL "				       "document will fail, creating a new "				       "back link.");				foo = xmlNewDoc("1.0");				xmlDocSetRootElement(foo, new_cib);				xmlSetTreeDoc(new_cib,foo);			}	    			/* save it.			 * set arg 3 to 0 to disable line breaks,1 to enable			 * res == num bytes saved			 */			res = xmlSaveFormatFile(filename,						new_cib->doc,						1);						/* for some reason, reading back after saving with			 * line-breaks doesnt go real well 			 */			cl_log(LOG_INFO,			       "Saved %d bytes to the Cib as XML",			       res);	    			if (res < 0) {				/*  assume 0 is good */				if (moveFile(filename_bak,					     filename,					     FALSE,					     NULL) < -1) {					cl_log(LOG_CRIT,					       "Could not restore the "					       "backup of the current Cib "					       "(code: %d)... panic!",					       res);					error_code = -2;					/*  should probably exit here  */				} else if (initializeCib(saved_cib) == FALSE) {					/*  oh we are so dead  */					cl_log(LOG_CRIT,					       "Could not re-initialize "					       "with the old CIB.  "					       "Everything is about to go "					       "pear shaped");					error_code = -3;				} else {					cl_log(LOG_CRIT,					       "Update of Cib failed "					       "(code: %d)... reverted to "					       "last known valid version",					       res);										error_code = -4;				}			}		}	}	else	{		cl_log(LOG_INFO, "Ignoring invalid or NULL Cib");		error_code = -5;	}/*  Make sure memory is cleaned up appropriately */	if (error_code != 0) {/* 		CRM_DEBUG2("Freeing new CIB %p", new_cib); */		free_xml(new_cib);	} else {/* 		CRM_DEBUG2("Freeing saved CIB %p", saved_cib); */		free_xml(saved_cib);	}	FNRET(error_code);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -