diff --git a/lib/plugins/lrm/Makefile.am b/lib/plugins/lrm/Makefile.am index 6943031d37..ad1f65a483 100644 --- a/lib/plugins/lrm/Makefile.am +++ b/lib/plugins/lrm/Makefile.am @@ -1,50 +1,50 @@ # # Author: Sun Jiang Dong # Copyright (c) 2004 International Business Machines # # 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 # of the License, or (at your option) any later version. # # This program 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 program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in LRM_DIR = lrm INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_builddir)/linux-ha -I$(top_srcdir)/linux-ha \ -I$(top_builddir)/libltdl -I$(top_srcdir)/libltdl halibdir = $(libdir)/@HB_PKG@ havarlibdir = $(localstatedir)/lib/@HB_PKG@ COMMONLIBS = $(top_builddir)/lib/clplumbing/libplumb.la \ $(GLIBLIB) lrmdir = $(HA_VARLIBDIR)/$(HB_PKG)/$(LRM_DIR) plugindir = $(halibdir)/plugins/RAExec plugin_LTLIBRARIES = lsb.la ocf.la heartbeat.la stonith.la lsb_la_SOURCES = raexeclsb.c racommon.c lsb_la_LDFLAGS = -L$(top_builddir)/lib/pils -lpils -export-dynamic -module -avoid-version ocf_la_SOURCES = raexecocf.c racommon.c ocf_la_LDFLAGS = -L$(top_builddir)/lib/pils -lpils -export-dynamic -module -avoid-version -stonith_la_SOURCES = raexecocf.c racommon.c -stonith_la_LDFLAGS = -L$(top_builddir)/lib/pils -lpils -export-dynamic -module -avoid-version -stonith_la_CFLAGS = -DCOMPILE_AS_STONITH +stonith_la_SOURCES = raexecstonith.c racommon.c +stonith_la_LDFLAGS = -L$(top_builddir)/lib/pils -lpils -export-dynamic -module -avoid-version \ + -L$(top_builddir)/lib/fencing -lstonithd heartbeat_la_SOURCES = raexechb.c racommon.c heartbeat_la_LDFLAGS = -L$(top_builddir)/lib/pils -lpils -export-dynamic -module -avoid-version install-exec-local: $(mkinstalldirs) $(DESTDIR)$(lrmdir) -chgrp $(apigid) $(DESTDIR)/$(lrmdir) chmod 770 $(DESTDIR)/$(lrmdir) diff --git a/lib/plugins/lrm/raexecstonith.c b/lib/plugins/lrm/raexecstonith.c new file mode 100644 index 0000000000..780d2d2258 --- /dev/null +++ b/lib/plugins/lrm/raexecstonith.c @@ -0,0 +1,351 @@ +/* + * 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 + * + * File: raexecocf.c + * Author: Sun Jiang Dong + * Copyright (c) 2004 International Business Machines + * + * This code implements the Resource Agent Plugin Module for LSB style. + * It's a part of Local Resource Manager. Currently it's used by lrmd only. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* Add it for compiling on OSX */ +#include + +#include +#include + +# define PIL_PLUGINTYPE RA_EXEC_TYPE +# define PIL_PLUGINTYPE_S "RAExec" +# define PIL_PLUGINLICENSE LICENSE_PUBDOM +# define PIL_PLUGINLICENSEURL URL_PUBDOM + +# define PIL_PLUGIN stonith +# define PIL_PLUGIN_S "stonith" + +static PIL_rc close_stonithRA(PILInterface*, void* ud_interface); + +/* static const char * RA_PATH = STONITH_RA_DIR; */ +/* Temporarily use it */ +static const char * RA_PATH = "/usr/lib/stonith/plugins/stonith/"; + +/* The begin of exported function list */ +static int execra(const char * rsc_id, + const char * rsc_type, + const char * provider, + const char * op_type, + GHashTable * params); +static uniform_ret_execra_t map_ra_retvalue(int ret_execra, + const char * op_type); +static int get_resource_list(GList ** rsc_info); +static char* get_resource_meta(const char* rsc_type, const char* provider); +static int get_provider_list(const char* op_type, GList ** providers); + +/* The end of exported function list */ + +/* The begin of internal used function & data list */ +static int get_providers(const char* class_path, const char* op_type, + GList ** providers); +static void stonithRA_ops_callback(stonithRA_ops_t * op, void * private_data); +static int exit_value; +static gboolean signoned_to_stonithd = FALSE; +/* The end of internal function & data list */ + +/* Rource agent execution plugin operations */ +static struct RAExecOps raops = +{ execra, + map_ra_retvalue, + get_resource_list, + get_provider_list, + get_resource_meta +}; + +static const char * meta_data1 = "\n" +"\n" +"\n" +"\n" +" 1.0\n" +" \n" +" \n" +" \n" +" Config string for a stonith resource -- one type of stonith devices\n" +" \n" +" Config string\n" +" \n" +" \n" +" \n" +" \n" +" Config file for a stonith resource -- one type of stonithd devices.\n" +" \n" +" Config file\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" 2.0\n" +" \n" +"\n"; + +PIL_PLUGIN_BOILERPLATE2("1.0", Debug); + +static const PILPluginImports* PluginImports; +static PILPlugin* OurPlugin; +static PILInterface* OurInterface; +static void* OurImports; +static void* interfprivate; + +/* + * Our plugin initialization and registration function + * It gets called when the plugin gets loaded. + */ +PIL_rc +PIL_PLUGIN_INIT(PILPlugin * us, const PILPluginImports* imports); + +PIL_rc +PIL_PLUGIN_INIT(PILPlugin * us, const PILPluginImports* imports) +{ + /* Force the compiler to do a little type checking */ + (void)(PILPluginInitFun)PIL_PLUGIN_INIT; + + PluginImports = imports; + OurPlugin = us; + + if (ST_OK != stonithd_signon("STONITH_RA")) { + signoned_to_stonithd = TRUE; + cl_log(LOG_ERR, "Can not signon to the stonithd."); + return PIL_OOPS; /* Should add a new type for this */ + } + + /* Register ourself as a plugin */ + imports->register_plugin(us, &OurPIExports); + + /* Register our interfaces */ + return imports->register_interface(us, PIL_PLUGINTYPE_S, PIL_PLUGIN_S, + &raops, close_stonithRA, &OurInterface, &OurImports, + interfprivate); +} + +static PIL_rc +close_stonithRA(PILInterface* pif, void* ud_interface) +{ + stonithd_signoff(); + return PIL_OK; +} + +/* + * Most of the oprations will be sent to sotnithd directly, such as 'start', + * 'stop', 'monitor'. And others like 'meta-data' will be handled by itself + * locally. + * Some of important parameters' name: + * config_file + * config_string + */ +static int +execra(const char * rsc_id, const char * rsc_type, const char * provider, + const char * op_type, GHashTable * params) +{ + stonithRA_ops_t * op; + int call_id = -1; + + if (signoned_to_stonithd == FALSE) { + if (ST_OK != stonithd_signon("STONITH_RA")) { + cl_log(LOG_ERR, "Can not signon to the stonithd."); + exit(EXECRA_UNKNOWN_ERROR); + } else { + signoned_to_stonithd = TRUE; + } + } + + if (strncmp(op_type, "meta-data", strlen("meta-data")) == 0) { + char * tmp; + tmp = get_resource_meta(rsc_type, provider); + printf("%s", tmp); + g_free(tmp); + exit(0); + } + + stonithd_set_stonithRA_ops_callback(stonithRA_ops_callback, &call_id); + + /* Temporarily donnot use it, but how to deal with the global OCF + * variables. This is a important thing to think about and do. + */ + /* send the RA operation to stonithd to simulate a RA's actions */ + cl_log(LOG_DEBUG, "Will send the stonith RA operation to stonithd: " \ + "%s %s", rsc_type, op_type); + + op = g_new(stonithRA_ops_t, 1); + op->ra_name = g_strdup(rsc_type); + op->op_type = g_strdup(op_type); + op->params = params; + op->rsc_id = g_strdup(rsc_id); + if (ST_FAIL == stonithd_virtual_stonithRA_ops(op, &call_id)) { + cl_log(LOG_DEBUG, "sending stonithRA op to stonithd failed."); + /* Need to improve the granularity for error return code */ + exit(EXECRA_EXEC_UNKNOWN_ERROR); + } + + cl_log(LOG_DEBUG, "Waiting until the final result returned."); + /* May be redundant */ + while (stonithd_op_result_ready() != TRUE) { + ; + } + cl_log(LOG_DEBUG, "Will call stonithd_receive_ops_result."); + stonithd_receive_ops_result(TRUE); + + /* exit_value will be setted by the callback function */ + g_free(op->ra_name); + g_free(op->op_type); + g_free(op->rsc_id); + g_free(op); + cl_log(LOG_DEBUG, "stonithRA orignal exit code=%d", exit_value); + exit(map_ra_retvalue(exit_value, op_type)); +} + +static void +stonithRA_ops_callback(stonithRA_ops_t * op, void * private_data) +{ + cl_log(LOG_DEBUG, "setting exit code=%d", exit_value); + exit_value = op->op_result; +} + +static uniform_ret_execra_t +map_ra_retvalue(int ret_execra, const char * op_type) +{ + /* Because the UNIFORM_RET_EXECRA is compatible with OCF standard */ + return ret_execra; +} + +static int +get_resource_list(GList ** rsc_info) +{ + cl_log(LOG_ERR, "get_resource_list: begin."); + + if ( rsc_info == NULL ) { + cl_log(LOG_ERR, "Parameter error: get_resource_list"); + return -2; + } + + if ( *rsc_info != NULL ) { + cl_log(LOG_ERR, "Parameter error: get_resource_list."\ + "will cause memory leak."); + *rsc_info = NULL; + } + + if (signoned_to_stonithd == FALSE) { + if (ST_OK != stonithd_signon("STONITH_RA")) { + cl_log(LOG_ERR, "Can not signon to the stonithd."); + return -1; + } else { + signoned_to_stonithd = TRUE; + } + } + + return stonithd_list_stonith_types(rsc_info); +} + +static int +get_provider_list(const char* op_type, GList ** providers) +{ + int ret; + ret = get_providers(RA_PATH, op_type, providers); + if (0>ret) { + cl_log(LOG_ERR, "scandir failed in stonith RA plugin"); + } + return ret; +} + +static char * +get_resource_meta(const char* rsc_type, const char* provider) +{ + char * buffer; + buffer = g_new(char, strlen(meta_data1)+strlen(meta_data2)+40); + + sprintf(buffer, "%s%s%s", meta_data1, rsc_type, meta_data2); + + return buffer; +} + +/* + * Currently should return *providers = NULL, but rmain the old code for + * possible unsing in the future + */ +static int +get_providers(const char* class_path, const char* op_type, GList ** providers) +{ + + if ( providers == NULL ) { + cl_log(LOG_ERR, "Parameter error: get_providers"); + return -2; + } + + if ( *providers != NULL ) { + cl_log(LOG_ERR, "Parameter error: get_providers."\ + "will cause memory leak."); + *providers = NULL; + } + + return 0; +#if 0 + struct dirent **namelist; + int file_num; + file_num = scandir(class_path, &namelist, 0, alphasort); + if (file_num < 0) { + return -2; + }else{ + char tmp_buffer[FILENAME_MAX+1]; + while (file_num--) { + if ((DT_DIR != namelist[file_num]->d_type) || + ('.' == namelist[file_num]->d_name[0])) { + free(namelist[file_num]); + continue; + } + + snprintf(tmp_buffer,FILENAME_MAX,"%s/%s/%s", + class_path, namelist[file_num]->d_name, op_type); + + if ( filtered(tmp_buffer) == TRUE ) { + *providers = g_list_append(*providers, + g_strdup(namelist[file_num]->d_name)); + } + free(namelist[file_num]); + } + free(namelist); + } + return g_list_length(*providers); +#endif +}