raexecocf.c
来自「linux集群服务器软件代码包」· C语言 代码 · 共 436 行
C
436 行
/* * 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 <sunjd@cn.ibm.com> * 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 <portability.h>#include <stdio.h> #include <string.h>#include <unistd.h>#include <stdlib.h>#include <libgen.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/stat.h>#include <errno.h>#include <glib.h>#include <clplumbing/cl_log.h>#include <pils/plugin.h>#include <dirent.h>#include <libgen.h> /* Add it for compiling on OSX */#include <config.h>#include <lrm/raexec.h># define PIL_PLUGINTYPE RA_EXEC_TYPE# define PIL_PLUGINTYPE_S "RAExec"# define PIL_PLUGINLICENSE LICENSE_PUBDOM# define PIL_PLUGINLICENSEURL URL_PUBDOM# define PIL_PLUGIN ocf# define PIL_PLUGIN_S "ocf"/* * Are there multiple paths? Now according to OCF spec, the answer is 'no'. * But actually or for future? */static const char * RA_PATH = OCF_RA_DIR;/* The begin of exported function list */static int execra(const char * rsc_id, const char * rsc_type, const char * provider, const char * op_type, const int timeout, 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* ra_type, GList ** providers);/* The end of exported function list *//* The begin of internal used function & data list */static void add_OCF_prefix(GHashTable * params, GHashTable * new_params);static void add_OCF_env_vars(GHashTable * env, const char * rsc_id, const char * rsc_type, const char * provider);static void add_prefix_foreach(gpointer key, gpointer value, gpointer user_data);static int raexec_setenv(GHashTable * env_params);static void set_env(gpointer key, gpointer value, gpointer user_data); static gboolean let_remove_eachitem(gpointer key, gpointer value, gpointer user_data);static int get_providers(const char* class_path, const char* op_type, GList ** providers);static void merge_string_list(GList** old, GList* new);static gint compare_str(gconstpointer a, gconstpointer b);/* 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};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_rcPIL_PLUGIN_INIT(PILPlugin * us, const PILPluginImports* imports);PIL_rcPIL_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; /* 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, NULL, &OurInterface, &OurImports, interfprivate);}/* * The function to execute a RA. */static intexecra(const char * rsc_id, const char * rsc_type, const char * provider, const char * op_type, const int timeout, GHashTable * params){ uniform_ret_execra_t exit_value; char ra_pathname[RA_MAX_NAME_LENGTH]; GHashTable * tmp_for_setenv; get_ra_pathname(RA_PATH, rsc_type, provider, ra_pathname); /* Setup environment correctly */ tmp_for_setenv = g_hash_table_new(g_str_hash, g_str_equal); add_OCF_prefix(params, tmp_for_setenv); add_OCF_env_vars(tmp_for_setenv, rsc_id, rsc_type, provider); raexec_setenv(tmp_for_setenv); g_hash_table_foreach_remove(tmp_for_setenv, let_remove_eachitem, NULL); g_hash_table_destroy(tmp_for_setenv); /* execute the RA */ cl_log(LOG_DEBUG, "Will execute OCF RA : %s %s", ra_pathname, op_type); execl(ra_pathname, ra_pathname, op_type, NULL); switch (errno) { case ENOENT: /* No such file or directory */ case EISDIR: /* Is a directory */ exit_value = EXECRA_NO_RA; break; default: exit_value = EXECRA_EXEC_UNKNOWN_ERROR; } cl_log(LOG_ERR, "execl error when to execute RA %s.", rsc_type); exit(exit_value);}static uniform_ret_execra_tmap_ra_retvalue(int ret_execra, const char * op_type){ /* Because the UNIFORM_RET_EXECRA is compatible with OCF standard */ return ret_execra;}static gintcompare_str(gconstpointer a, gconstpointer b){ return strncmp(a,b,RA_MAX_NAME_LENGTH);}static intget_resource_list(GList ** rsc_info){ struct dirent **namelist; GList* item; int file_num; char subdir[FILENAME_MAX+1]; 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; } file_num = scandir(RA_PATH, &namelist, 0, alphasort); if (file_num < 0) { return -2; } while (file_num--) { GList* ra_subdir = NULL; if ((DT_DIR != namelist[file_num]->d_type) || ('.' == namelist[file_num]->d_name[0])) { free(namelist[file_num]); continue; } snprintf(subdir,FILENAME_MAX,"%s/%s", RA_PATH, namelist[file_num]->d_name); get_runnable_list(subdir,&ra_subdir); merge_string_list(rsc_info,ra_subdir); while (NULL != (item = g_list_first(ra_subdir))) { ra_subdir = g_list_remove_link(ra_subdir, item); g_free(item->data); g_list_free_1(item); } free(namelist[file_num]); } free(namelist); return 0;}static voidmerge_string_list(GList** old, GList* new){ GList* item = NULL; char* newitem; for( item=g_list_first(new); NULL!=item; item=g_list_next(item)){ if (!g_list_find_custom(*old, item->data,compare_str)){ newitem = strndup(item->data,RA_MAX_NAME_LENGTH); *old = g_list_append(*old, newitem); } }}static intget_provider_list(const char* ra_type, GList ** providers){ int ret; ret = get_providers(RA_PATH, ra_type, providers); if (0>ret) { cl_log(LOG_ERR, "scandir failed in OCF RA plugin"); } return ret;}static char*get_resource_meta(const char* rsc_type, const char* provider){ const int BUFF_LEN=4096; int read_len = 0; char buff[BUFF_LEN]; char* data = NULL; GString* g_str_tmp = NULL; char ra_pathname[RA_MAX_NAME_LENGTH]; FILE* file = NULL; GHashTable * tmp_for_setenv; get_ra_pathname(RA_PATH, rsc_type, provider, ra_pathname); strncat(ra_pathname, " meta-data",RA_MAX_NAME_LENGTH); tmp_for_setenv = g_hash_table_new(g_str_hash, g_str_equal); add_OCF_env_vars(tmp_for_setenv, "DUMMY_INSTANCE", rsc_type, provider); raexec_setenv(tmp_for_setenv); g_hash_table_foreach_remove(tmp_for_setenv, let_remove_eachitem, NULL); g_hash_table_destroy(tmp_for_setenv); file = popen(ra_pathname, "r"); if (NULL==file) { return NULL; } g_str_tmp = g_string_new(""); while(!feof(file)) { memset(buff, 0, BUFF_LEN); read_len = fread(buff, 1, BUFF_LEN, file); if (0<read_len) { g_string_append(g_str_tmp, buff); } else { sleep(1); } } if (0 == g_str_tmp->len) { pclose(file); return NULL; } data = (char*)g_new(char, g_str_tmp->len+1); data[0] = data[g_str_tmp->len] = 0; strncpy(data, g_str_tmp->str, g_str_tmp->len); g_string_free(g_str_tmp, TRUE); pclose(file); return data; }static void add_OCF_prefix(GHashTable * env_params, GHashTable * new_env_params){ if (env_params) { g_hash_table_foreach(env_params, add_prefix_foreach, new_env_params); }}static voidadd_prefix_foreach(gpointer key, gpointer value, gpointer user_data){ const int MAX_LENGTH_OF_ENV = 50; int prefix = strlen("OCF_RESKEY_"); GHashTable * new_hashtable = (GHashTable *) user_data; char * newkey; int keylen = strnlen((char*)key, MAX_LENGTH_OF_ENV-prefix)+prefix; newkey = g_new(gchar, keylen); strncpy(newkey, "OCF_RESKEY_", keylen); strncat(newkey, key, keylen); g_hash_table_insert(new_hashtable, (gpointer)newkey, g_strdup(value));}static gbooleanlet_remove_eachitem(gpointer key, gpointer value, gpointer user_data){ g_free(key); g_free(value); return TRUE;}static intraexec_setenv(GHashTable * env_params){ if (env_params) { g_hash_table_foreach(env_params, set_env, NULL); } return 0;}static voidset_env(gpointer key, gpointer value, gpointer user_data){ if (setenv(key, value, 1) != 0) { cl_log(LOG_ERR, "setenv failed in raexecocf."); }}static intget_providers(const char* class_path, const char* ra_type, GList ** providers){ struct dirent **namelist; int file_num; 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; } 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, ra_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);}static voidadd_OCF_env_vars(GHashTable * env, const char * rsc_id, const char * rsc_type, const char * provider){ if ( env == NULL ) { cl_log(LOG_WARNING, "env should not be a NULL pointer."); return; } g_hash_table_insert(env, g_strdup("OCF_RA_VERSION_MAJOR"), g_strdup("1")); g_hash_table_insert(env, g_strdup("OCF_RA_VERSION_MINOR"), g_strdup("0")); g_hash_table_insert(env, g_strdup("OCF_ROOT"), g_strdup(OCF_ROOT_DIR)); if ( rsc_id != NULL ) { g_hash_table_insert(env, g_strdup("OCF_RESOURCE_INSTANCE"), g_strdup(rsc_id)); } /* Currently the rsc_type=="the filename of the RA script/executable", * It seems always correct even in the furture. ;-) */ if ( rsc_type != NULL ) { g_hash_table_insert(env, g_strdup("OCF_RESOURCE_TYPE"), g_strdup(rsc_type)); } /* Notes: this is not added to specification yet. Sept 10,2004 */ if ( provider != NULL ) { g_hash_table_insert(env, g_strdup("OCF_RESOURCE_PROVIDER"), g_strdup(provider)); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?