diff --git a/lib/plugins/lrm/raexechb.c b/lib/plugins/lrm/raexechb.c index 48dd6e1ed9..3f146c6aba 100644 --- a/lib/plugins/lrm/raexechb.c +++ b/lib/plugins/lrm/raexechb.c @@ -1,267 +1,263 @@ /* * 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: raexechb.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 #define PIL_PLUGINTYPE RA_EXEC_TYPE #define PIL_PLUGIN heartbeat #define PIL_PLUGINTYPE_S "RAExec" #define PIL_PLUGIN_S "heartbeat" #define PIL_PLUGINLICENSE LICENSE_PUBDOM #define PIL_PLUGINLICENSEURL URL_PUBDOM static const char * RA_PATH = HB_RA_DIR; /* The begin of exported function list */ static int execra(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 */ #define MAX_PARAMETER_NUM 40 typedef char * RA_ARGV[MAX_PARAMETER_NUM]; static int prepare_cmd_parameters(const char * rsc_type, const char * op_type, GHashTable * params, RA_ARGV params_argv); static void params_hash_to_argv(gpointer key, gpointer value, gpointer user_data); /* 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 }; /* * The following two functions are only exported to the plugin infrastructure. */ /* * raexec_closepi is called as part of shutting down the plugin. * If there was any global data allocated, or file descriptors opened, etc. * which is associated with the plugin, and not a single interface * in particular, here's our chance to clean it up. */ static void raexec_closepi(PILPlugin *pi) { } /* * raexec_close_intf called as part of shutting down the md5 HBauth interface. * If there was any global data allocated, or file descriptors opened, etc. * which is associated with the md5 implementation, here's our chance * to clean it up. */ static PIL_rc raexec_closeintf(PILInterface *pi, void *pd) { return PIL_OK; } PIL_PLUGIN_BOILERPLATE("1.0", Debug, raexec_closepi); 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; /* 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, raexec_closeintf, &OurInterface, &OurImports, interfprivate); } /* * Real work starts here ;-) */ static int execra( const char * rsc_type, const char * provider, const char * op_type, GHashTable * params) { RA_ARGV params_argv; char ra_pathname[RA_MAX_NAME_LENGTH]; uniform_ret_execra_t exit_value; GString * debug_info; int index_tmp = 0; /* Prepare the call parameter */ if (0 > prepare_cmd_parameters(rsc_type, op_type, params, params_argv)) { cl_log(LOG_ERR, "HB RA: Error of preparing parameters"); return -1; } - get_ra_pathname(RA_PATH, rsc_type, provider, ra_pathname); + get_ra_pathname(RA_PATH, rsc_type, NULL, ra_pathname); debug_info = g_string_new(""); do { g_string_append(debug_info, params_argv[index_tmp]); g_string_append(debug_info, " "); } while (params_argv[++index_tmp] != NULL); debug_info->str[debug_info->len-1] = '\0'; cl_log(LOG_DEBUG, "Will execute a heartbeat RA: %s", debug_info->str); g_string_free(debug_info, TRUE); if ( execv(ra_pathname, params_argv) < 0 ) { cl_log(LOG_ERR, "execl error when to execute RA %s.", rsc_type); } 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 int prepare_cmd_parameters(const char * rsc_type, const char * op_type, GHashTable * params_ht, RA_ARGV params_argv) { /* For heartbeat scripts, no corresponding definite specification * Maybe not need this function? */ int tmp_len; int ht_size = 0; if (params_ht) { ht_size = g_hash_table_size(params_ht); } if ( ht_size+3 > MAX_PARAMETER_NUM ) { cl_log(LOG_ERR, "Too many parameters"); return -1; } tmp_len = strnlen(rsc_type, 160) + 1; params_argv[0] = g_new(char, tmp_len); strncpy(params_argv[0], rsc_type, tmp_len); tmp_len = strnlen(op_type, 160) + 1; params_argv[ht_size+1] = g_new(char, tmp_len); strncpy(params_argv[ht_size+1], op_type, tmp_len); params_argv[ht_size+2] = NULL; if (params_ht) { g_hash_table_foreach(params_ht, params_hash_to_argv, params_argv); } return 0; } static uniform_ret_execra_t map_ra_retvalue(int ret_execra, const char * op_type) { /* Now there is no related specification for Heartbeat standard. * Temporarily deal as below. */ return ret_execra; } static int get_resource_list(GList ** rsc_info) { - return get_ra_list(RA_PATH, rsc_info); + return get_runnable_list(RA_PATH, rsc_info); } static void params_hash_to_argv(gpointer key, gpointer value, gpointer user_data) { int param_index; char** ra_argv = (char** ) user_data; if (ra_argv == NULL ) { return; } /* the parameter index start from 1 */ /* and start from 2 in argv array */ param_index = atoi( (char*) key ); ra_argv[param_index] = g_strdup((char*)value); } static char* get_resource_meta(const char* rsc_type, const char* provider) { return strdup(rsc_type); } 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 Heartbeat RA plugin"); - } - return ret; + *providers = NULL; + return 0; } diff --git a/lib/plugins/lrm/raexeclsb.c b/lib/plugins/lrm/raexeclsb.c index a22c7b1de9..157d25acb5 100644 --- a/lib/plugins/lrm/raexeclsb.c +++ b/lib/plugins/lrm/raexeclsb.c @@ -1,292 +1,288 @@ /* * 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: raexeclsb.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 /* Add it for compiling on OSX */ #include #include #include #include #include #define PIL_PLUGINTYPE RA_EXEC_TYPE #define PIL_PLUGIN lsb #define PIL_PLUGINTYPE_S "RAExec" #define PIL_PLUGIN_S "lsb" #define PIL_PLUGINLICENSE LICENSE_PUBDOM #define PIL_PLUGINLICENSEURL URL_PUBDOM /* * Are there multiple paths? Now according to LSB init scripts, the answer * is 'no', but should be 'yes' for lsb none-init scripts? */ static const char * RA_PATH = LSB_RA_DIR; static const int status_op_exitcode_map[] = { 0, 11, 12, 13, 14 }; /* The begin of exported function list */ static int execra(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 char* get_resource_meta(const char* rsc_type, const char* provider); static int get_resource_list(GList ** rsc_info); 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 */ #define MAX_PARAMETER_NUM 40 typedef char * RA_ARGV[MAX_PARAMETER_NUM]; static int prepare_cmd_parameters(const char * rsc_type, const char * op_type, GHashTable * params, RA_ARGV params_argv); static void params_hash_to_argv(gpointer key, gpointer value, gpointer user_data); /* 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 }; /* * The following two functions are only exported to the plugin infrastructure. */ /* * raexec_closepi is called as part of shutting down the plugin. * If there was any global data allocated, or file descriptors opened, etc. * which is associated with the plugin, and not a single interface * in particular, here's our chance to clean it up. */ static void raexec_closepi(PILPlugin *pi) { } /* * raexec_close_intf called as part of shutting down the md5 HBauth interface. * If there was any global data allocated, or file descriptors opened, etc. * which is associated with the md5 implementation, here's our chance * to clean it up. */ static PIL_rc raexec_closeintf(PILInterface *pi, void *pd) { return PIL_OK; } PIL_PLUGIN_BOILERPLATE("1.0", Debug, raexec_closepi); 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; /* 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, raexec_closeintf, &OurInterface, &OurImports, interfprivate); } /* * Real work starts here ;-) */ static int execra( const char * rsc_type, const char * provider, const char * op_type, GHashTable * params) { uniform_ret_execra_t exit_value; RA_ARGV params_argv; char ra_pathname[RA_MAX_NAME_LENGTH]; GString * debug_info; int index_tmp = 0; /* Prepare the call parameter */ if (0 > prepare_cmd_parameters(rsc_type, op_type, params, params_argv)) { cl_log(LOG_ERR, "lsb RA: Error of preparing parameters"); return -1; } - get_ra_pathname(RA_PATH, rsc_type, provider, ra_pathname); + get_ra_pathname(RA_PATH, rsc_type, NULL, ra_pathname); debug_info = g_string_new(""); do { g_string_append(debug_info, params_argv[index_tmp]); g_string_append(debug_info, " "); } while (params_argv[++index_tmp] != NULL); debug_info->str[debug_info->len-1] = '\0'; cl_log(LOG_DEBUG, "Will execute a lsb RA: %s", debug_info->str); g_string_free(debug_info, TRUE); execv(ra_pathname, params_argv); 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_t map_ra_retvalue(int ret_execra, const char * op_type) { /* Except op_type equals 'status', the UNIFORM_RET_EXECRA is compatible with LSB standard. */ if ( strncmp(op_type, "status", 6) == 0 ) { if (ret_execra < 0 || ret_execra > 4 ) { ret_execra = 4; } return status_op_exitcode_map[ret_execra]; } else { return ret_execra; } } static int get_resource_list(GList ** rsc_info) { - return get_ra_list(RA_PATH, rsc_info); + return get_runnable_list(RA_PATH, rsc_info); } static int prepare_cmd_parameters(const char * rsc_type, const char * op_type, GHashTable * params_ht, RA_ARGV params_argv) { /* For lsb init scripts, no corresponding definite specification * But for lsb none-init scripts, maybe need it. */ int tmp_len; int ht_size = 0; if (params_ht) { ht_size = g_hash_table_size(params_ht); } if ( ht_size+3 > MAX_PARAMETER_NUM ) { cl_log(LOG_ERR, "Too many parameters"); return -1; } tmp_len = strnlen(rsc_type, 160) + 1; params_argv[0] = g_new(gchar, tmp_len); strncpy(params_argv[0], rsc_type, tmp_len); tmp_len = strnlen(op_type, 160) + 1; params_argv[1] = g_new(gchar, tmp_len); strncpy(params_argv[1], op_type, tmp_len); params_argv[ht_size+2] = NULL; if (params_ht) { g_hash_table_foreach(params_ht, params_hash_to_argv, params_argv); } return 0; } static void params_hash_to_argv(gpointer key, gpointer value, gpointer user_data) { RA_ARGV * ra_argv = user_data; int param_index; if (user_data == NULL) { return; } if (*ra_argv == NULL ) { return; } /* the parameter index start from 1 */ /* and start from 2 in argv array */ param_index = atoi((char *)key); (*ra_argv)[param_index + 1] = g_new(gchar, 21); *((*ra_argv)[param_index + 1] + 20) = '\0'; strncpy((*ra_argv)[param_index +1], (char*)value, strnlen((char*)value, 20)); } static char* get_resource_meta(const char* rsc_type, const char* provider) { return strdup(rsc_type); } 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 LSB RA plugin"); - } - return ret; + *providers = NULL; + return 0; } diff --git a/lib/plugins/lrm/raexecocf.c b/lib/plugins/lrm/raexecocf.c index d0d2420a6d..922212fe6e 100644 --- a/lib/plugins/lrm/raexecocf.c +++ b/lib/plugins/lrm/raexecocf.c @@ -1,330 +1,437 @@ /* * 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 # define PIL_PLUGINTYPE RA_EXEC_TYPE # define PIL_PLUGINTYPE_S "RAExec" # define PIL_PLUGINLICENSE LICENSE_PUBDOM # define PIL_PLUGINLICENSEURL URL_PUBDOM #ifndef COMPILE_AS_STONITH # 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; #else # define PIL_PLUGIN stonith # define PIL_PLUGIN_S "stonith" /* * Are there multiple paths? Now according to OCF spec, the answer is 'no'. * But actually or for future? */ static const char * RA_PATH = STONITH_RA_DIR; #endif /* The begin of exported function list */ static int execra(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 void add_OCF_prefix(GHashTable * params, GHashTable * new_params); 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 g_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 }; /* * The following two functions are only exported to the plugin infrastructure. */ /* * raexec_closepi is called as part of shutting down the plugin. * If there was any global data allocated, or file descriptors opened, etc. * which is associated with the plugin, and not a single interface * in particular, here's our chance to clean it up. */ static void raexec_closepi(PILPlugin *pi) { } /* * raexec_close_intf called as part of shutting down the md5 HBauth interface. * If there was any global data allocated, or file descriptors opened, etc. * which is associated with the md5 implementation, here's our chance * to clean it up. */ static PIL_rc raexec_closeintf(PILInterface *pi, void *pd) { return PIL_OK; } PIL_PLUGIN_BOILERPLATE("1.0", Debug, raexec_closepi); 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; /* 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, raexec_closeintf, &OurInterface, &OurImports, interfprivate); } /* * Real work starts here ;-) */ - static int execra(const char * rsc_type, const char * provider, const char * op_type, 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); /* LRM team: Please cross-check before enabling. */ #if 0 g_hash_table_insert(tmp_for_setenv, "OCF_RA_VERSION_MAJOR", "1"); g_hash_table_insert(tmp_for_setenv, "OCF_RA_VERSION_MINOR", "0"); g_hash_table_insert(tmp_for_setenv, "OCF_ROOT", "/usr/lib/ocf"); /* TODO: This is not passed in currently. */ g_hash_table_insert(tmp_for_setenv, "OCF_RESOURCE_INSTANCE", "FIXME"); g_hash_table_insert(tmp_for_setenv, "OCF_RESOURCE_TYPE", rsc_type); g_hash_table_insert(tmp_for_setenv, "OCF_RESOURCE_PROVIDER", provider); #endif 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_t map_ra_retvalue(int ret_execra, const char * op_type) { /* Because the UNIFORM_RET_EXECRA is compatible with OCF standard */ return ret_execra; } +gint +g_compare_str(gconstpointer a, gconstpointer b) +{ + return strncmp(a,b,RA_MAX_NAME_LENGTH); +} static int get_resource_list(GList ** rsc_info) { - return get_ra_list(RA_PATH, rsc_info); -} + struct dirent **namelist; + GList* item; + int file_num; + + 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; + } + char subdir[FILENAME_MAX+1]; + while (file_num--) { + GList* ra_subdir = NULL; + if (DT_DIR != namelist[file_num]->d_type) { + free(namelist[file_num]); + continue; + } + + if ('.' == 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(ra_subdir, item->data); + g_free(item->data); + g_list_free(item); + } + + free(namelist[file_num]); + } + free(namelist); + + return 0; +} +void +merge_string_list(GList** old, GList* new) +{ + GList* item = NULL; + for( item=g_list_first(new); NULL!=item; item=g_list_next(item)){ + if (!g_list_find_custom(*old, item->data,g_compare_str)){ + char* newitem = strndup(item->data,RA_MAX_NAME_LENGTH); + *old = g_list_append(*old, newitem); + } + } +} 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 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; get_ra_pathname(RA_PATH, rsc_type, provider, ra_pathname); strncat(ra_pathname, " meta-data",RA_MAX_NAME_LENGTH); 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 (0len+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 void add_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, strdup(value)); } static gboolean let_remove_eachitem(gpointer key, gpointer value, gpointer user_data) { g_free(key); g_free(value); return TRUE; } int raexec_setenv(GHashTable * env_params) { /* For lsb init scripts, no corresponding definite specification * But for lsb none-init scripts, maybe need it. */ if (env_params) { g_hash_table_foreach(env_params, set_env, NULL); } return 0; } static void set_env(gpointer key, gpointer value, gpointer user_data) { if (setenv(key, value, 1) != 0) { cl_log(LOG_ERR, "setenv failed in raexecocf."); } /*Need to free the memory to which key and value point?*/ } +int +get_providers(const char* class_path, const char* op_type, GList ** providers) +{ + struct dirent **namelist; + int file_num; + + if ( providers == NULL ) { + return -2; + } + + if ( *providers != NULL ) { + *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) { + free(namelist[file_num]); + continue; + } + if ('.' == 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); +}