# HG changeset patch # Parent 7eacbb51c894acea7a42b7b3199fba6ae8404adc Medium: stonith: Remove Glib data types from the API arguments This is the first step towards purging Glib from the API so that low level consumers don't need to explicitly use or link against Glib which is considered "heavy". diff -r 7eacbb51c894 fencing/admin.c --- a/fencing/admin.c Tue Feb 22 17:21:51 2011 +0800 +++ b/fencing/admin.c Fri Apr 29 11:51:01 2011 -0400 @@ -72,11 +72,6 @@ crm_log_xml_notice(msg, event); } - -extern void cleanup_calculations(pe_working_set_t *data_set); -extern gboolean unpack_nodes(xmlNode * xml_nodes, pe_working_set_t *data_set); - - int main(int argc, char ** argv) { @@ -93,7 +88,7 @@ char action = 0; stonith_t *st = NULL; - GHashTable *hash = g_hash_table_new(crm_str_hash, g_str_equal); + stonith_key_value_t *params = NULL; crm_log_init(NULL, LOG_INFO, TRUE, TRUE, argc, argv); crm_set_options("V?$LQ:R:D:o:a:l:e:F:U:M", "mode [options]", long_options, @@ -146,7 +141,7 @@ ++argerr; } else { crm_info("Got: '%s'='%s'", name, value); - g_hash_table_insert(hash, crm_strdup(name), crm_strdup(value)); + stonith_key_value_add(params, crm_strdup(name), crm_strdup(value)); } break; case 'e': @@ -159,7 +154,8 @@ ++argerr; } else { crm_info("Got: '%s'='%s'", optarg, env); - g_hash_table_insert(hash, crm_strdup(optarg), crm_strdup(env)); + stonith_key_value_add( params, crm_strdup(optarg), + crm_strdup(env)); } } break; @@ -177,13 +173,6 @@ crm_help('?', LSB_EXIT_GENERIC); } -#if 0 - g_hash_table_insert(hash, crm_strdup("ipaddr"), crm_strdup("localhost")); - g_hash_table_insert(hash, crm_strdup("pcmk-portmap"), crm_strdup("some-host=pcmk-1 pcmk-3=3,4")); - g_hash_table_insert(hash, crm_strdup("login"), crm_strdup("root")); - g_hash_table_insert(hash, crm_strdup("identity_file"), crm_strdup("/root/.ssh/id_dsa")); -#endif - crm_debug("Create"); st = stonith_api_new(); @@ -198,17 +187,16 @@ { case 'L': { - GListPtr devices = NULL; + stonith_key_value_t *devices = NULL; rc = st->cmds->query(st, st_opts, target, &devices, 10); if(rc == 0) { fprintf(stderr, "No devices found\n"); } else if(rc > 0) { - GListPtr lpc = NULL; fprintf(stderr, "%d devices found\n", rc); - for(lpc = devices; lpc != NULL; lpc = lpc->next) { - char *device = (char*)lpc->data; - fprintf(stdout, " %s\n", device); + + for( ; devices; devices = devices->next ) { + fprintf( stdout, " %s\n", devices->value ); } rc = 0; } @@ -221,7 +209,8 @@ } break; case 'R': - rc = st->cmds->register_device(st, st_opts, device, "stonith-ng", agent, hash); + rc = st->cmds->register_device(st, st_opts, device, "stonith-ng", + agent, params); break; case 'D': rc = st->cmds->remove_device(st, st_opts, device); diff -r 7eacbb51c894 fencing/commands.c --- a/fencing/commands.c Tue Feb 22 17:21:51 2011 +0800 +++ b/fencing/commands.c Fri Apr 29 11:51:01 2011 -0400 @@ -37,6 +37,7 @@ #include #include +#include #include #include #include diff -r 7eacbb51c894 fencing/main.c --- a/fencing/main.c Tue Feb 22 17:21:51 2011 +0800 +++ b/fencing/main.c Fri Apr 29 11:51:01 2011 -0400 @@ -35,6 +35,7 @@ #include #include +#include #include #include diff -r 7eacbb51c894 fencing/remote.c --- a/fencing/remote.c Tue Feb 22 17:21:51 2011 +0800 +++ b/fencing/remote.c Fri Apr 29 11:51:01 2011 -0400 @@ -37,6 +37,7 @@ #include #include +#include #include #include #include diff -r 7eacbb51c894 fencing/test.c --- a/fencing/test.c Tue Feb 22 17:21:51 2011 +0800 +++ b/fencing/test.c Fri Apr 29 11:51:01 2011 -0400 @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -70,8 +71,8 @@ int option_index = 0; stonith_t *st = NULL; - GHashTable *hash = NULL; + stonith_key_value_t *params = NULL; gboolean passive_mode = FALSE; crm_log_init(NULL, LOG_INFO, TRUE, TRUE, argc, argv); @@ -79,6 +80,11 @@ "Provides a summary of cluster's current state." "\n\nOutputs varying levels of detail in a number of different formats.\n"); + params = stonith_key_value_add(params, "ipaddr", "localhost"); + params = stonith_key_value_add(params, "pcmk-portmal", "some-host=pcmk-1 pcmk-3=3,4"); + params = stonith_key_value_add(params, "login", "root"); + params = stonith_key_value_add(params, "identity_file","/root/.ssh/id_dsa"); + while (1) { flag = crm_get_option(argc, argv, &option_index); if (flag == -1) @@ -110,12 +116,6 @@ crm_help('?', LSB_EXIT_GENERIC); } - hash = g_hash_table_new(crm_str_hash, g_str_equal); - g_hash_table_insert(hash, crm_strdup("ipaddr"), crm_strdup("localhost")); - g_hash_table_insert(hash, crm_strdup("pcmk-portmap"), crm_strdup("some-host=pcmk-1 pcmk-3=3,4")); - g_hash_table_insert(hash, crm_strdup("login"), crm_strdup("root")); - g_hash_table_insert(hash, crm_strdup("identity_file"), crm_strdup("/root/.ssh/id_dsa")); - crm_debug("Create"); st = stonith_api_new(); @@ -137,7 +137,7 @@ g_main_run(mainloop); } else { - rc = st->cmds->register_device(st, st_opts, "test-id", "stonith-ng", "fence_virsh", hash); + rc = st->cmds->register_device(st, st_opts, "test-id", "stonith-ng", "fence_virsh", params); crm_debug("Register: %d", rc); rc = st->cmds->call(st, st_opts, "test-id", "list", NULL, 10); diff -r 7eacbb51c894 include/crm/crm.h --- a/include/crm/crm.h Tue Feb 22 17:21:51 2011 +0800 +++ b/include/crm/crm.h Fri Apr 29 11:51:01 2011 -0400 @@ -21,6 +21,7 @@ #include #include #include +#include #undef MIN #undef MAX diff -r 7eacbb51c894 include/crm/stonith-ng-internal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/crm/stonith-ng-internal.h Fri Apr 29 11:51:01 2011 -0400 @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 Andrew Beekhof + * + * 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 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef STONITH_NG_INTERNAL__H +#define STONITH_NG_INTERNAL__H + + +/* internal details - move elsewhere */ + +typedef struct async_command_s +{ + + int id; + int stdout; + int options; + int timeout; + + char *op; + char *origin; + char *client; + char *remote; + + char *victim; + char *action; + char *device; + + GListPtr device_list; + GListPtr device_next; + + ProcTrack_ops *pt_ops; + GHashTable *node_attrs; + ProcTrackKillInfo killseq[3]; + +} async_command_t; + + +extern int run_stonith_agent( + const char *agent, GHashTable *dev_hash, GHashTable *node_hash, const char *action, const char *victim, + int *agent_result, char **output, async_command_t *track); + +extern gboolean is_redhat_agent(const char *agent); + +#endif diff -r 7eacbb51c894 include/crm/stonith-ng.h --- a/include/crm/stonith-ng.h Tue Feb 22 17:21:51 2011 +0800 +++ b/include/crm/stonith-ng.h Fri Apr 29 11:51:01 2011 -0400 @@ -25,7 +25,7 @@ enum stonith_state { stonith_connected_command, stonith_connected_query, - stonith_disconnected + stonith_disconnected, }; enum stonith_call_options { @@ -105,6 +105,12 @@ #define stonith_channel "st_command" #define stonith_channel_callback "st_callback" +typedef struct stonith_key_value_s { + const char *key; + const char *value; + struct stonith_key_value_s *next; +} stonith_key_value_t; + typedef struct stonith_s stonith_t; typedef struct stonith_api_operations_s @@ -117,15 +123,17 @@ stonith_t *st, int options, const char *name); int (*register_device)( stonith_t *st, int options, const char *id, - const char *namespace, const char *agent, GHashTable *parameters); + const char *namespace, const char *agent, stonith_key_value_t *params); int (*metadata)(stonith_t *st, int options, const char *device, const char *namespace, char **output, int timeout); int (*call)(stonith_t *st, int options, const char *id, const char *action, const char *port, int timeout); - int (*query)(stonith_t *st, int options, const char *node, GListPtr *devices, int timeout); - int (*fence)(stonith_t *st, int options, const char *node, const char *action, int timeout); + int (*query)(stonith_t *st, int options, const char *node, + stonith_key_value_t **devices, int timeout); + int (*fence)(stonith_t *st, int options, const char *node, const char *action, + int timeout); int (*confirm)(stonith_t *st, int options, const char *node); int (*register_notification)( @@ -134,10 +142,10 @@ int (*remove_notification)(stonith_t *st, const char *event); int (*register_callback)( - stonith_t *st, int call_id, int timeout, gboolean only_success, + stonith_t *st, int call_id, int timeout, bool only_success, void *userdata, const char *callback_name, void (*callback)(stonith_t *st, const xmlNode *msg, int call, int rc, xmlNode *output, void *userdata)); - int (*remove_callback)(stonith_t *st, int call_id, gboolean all_callbacks); + int (*remove_callback)(stonith_t *st, int call_id, bool all_callbacks); } stonith_api_operations_t; @@ -149,8 +157,6 @@ int call_timeout; void *private; - GList *notify_list; - stonith_api_operations_t *cmds; }; @@ -161,40 +167,11 @@ extern const char *stonith_error2string(enum stonith_errors return_code); extern void stonith_dump_pending_callbacks(stonith_t *st); -/* internal details - move elsewhere */ +extern const char *get_stonith_provider(const char *agent, const char *provider); -typedef struct async_command_s -{ - - int id; - int stdout; - int options; - int timeout; - - char *op; - char *origin; - char *client; - char *remote; - - char *victim; - char *action; - char *device; - - GListPtr device_list; - GListPtr device_next; - - ProcTrack_ops *pt_ops; - GHashTable *node_attrs; - ProcTrackKillInfo killseq[3]; - -} async_command_t; - -extern int run_stonith_agent( - const char *agent, GHashTable *dev_hash, GHashTable *node_hash, const char *action, const char *victim, - int *agent_result, char **output, async_command_t *track); - -extern gboolean is_redhat_agent(const char *agent); -extern const char *get_stonith_provider(const char *agent, const char *provider); +extern stonith_key_value_t *stonith_key_value_add(stonith_key_value_t *kvp, + const char *key, const char *value); +extern void stonith_key_value_freeall(stonith_key_value_t *kvp); #endif diff -r 7eacbb51c894 lib/fencing/st_client.c --- a/lib/fencing/st_client.c Tue Feb 22 17:21:51 2011 +0800 +++ b/lib/fencing/st_client.c Fri Apr 29 11:51:01 2011 -0400 @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -42,11 +43,12 @@ typedef struct stonith_private_s { - char *token; + char *token; IPC_Channel *command_channel; IPC_Channel *callback_channel; GCHSource *callback_source; GHashTable *stonith_op_callback_table; + GList *notify_list; void (*op_callback)( stonith_t *st, const xmlNode *msg, int call, int rc, xmlNode *output, void *userdata); @@ -121,6 +123,10 @@ stonith_t *stonith, const char *op, xmlNode *data, xmlNode **output_data, int call_options, int timeout); +stonith_key_value_t *stonith_key_value_add(stonith_key_value_t *kvp, + const char *key, const char *value); +void stonith_key_value_freeall(stonith_key_value_t *kvp); + static void stonith_connection_destroy(gpointer user_data); static void stonith_send_notification(gpointer data, gpointer user_data); @@ -131,7 +137,7 @@ struct notify_blob_s blob; blob.stonith = stonith; - blob.xml = create_xml_node(NULL, "notify");; + blob.xml = create_xml_node(NULL, "notify"); native = stonith->private; native->callback_source = NULL; @@ -140,13 +146,14 @@ crm_xml_add(blob.xml, F_TYPE, T_STONITH_NOTIFY); crm_xml_add(blob.xml, F_SUBTYPE, T_STONITH_NOTIFY_DISCONNECT); - g_list_foreach(stonith->notify_list, stonith_send_notification, &blob); + g_list_foreach(native->notify_list, stonith_send_notification, &blob); free_xml(blob.xml); } static int stonith_api_register_device( stonith_t *stonith, int call_options, - const char *id, const char *namespace, const char *agent, GHashTable *params) + const char *id, const char *namespace, const char *agent, + stonith_key_value_t *params) { int rc = 0; xmlNode *data = create_xml_node(NULL, F_STONITH_DEVICE); @@ -157,8 +164,10 @@ crm_xml_add(data, "agent", agent); crm_xml_add(data, "namespace", namespace); - g_hash_table_foreach(params, hash2field, args); - + for( ; params; params = params->next ) { + hash2field( (gpointer)params->key, (gpointer)params->value, args ); + } + rc = stonith_send_command(stonith, STONITH_OP_DEVICE_ADD, data, NULL, call_options, 0); free_xml(data); @@ -591,13 +600,15 @@ } static int stonith_api_query( - stonith_t *stonith, int call_options, const char *target, GListPtr *devices, int timeout) + stonith_t *stonith, int call_options, const char *target, + stonith_key_value_t **devices, int timeout) { int rc = 0, lpc = 0, max = 0; xmlNode *data = NULL; xmlNode *output = NULL; xmlXPathObjectPtr xpathObj = NULL; + crm_malloc( *devices, sizeof(char *)); CRM_CHECK(devices != NULL, return st_err_missing); @@ -619,7 +630,8 @@ CRM_CHECK(match != NULL, continue); crm_info("%s[%d] = %s", "//@agent", lpc, xmlGetNodePath(match)); - *devices = g_list_append(*devices, crm_element_value_copy(match, XML_ATTR_ID)); + stonith_key_value_add(*devices, NULL, + crm_element_value_copy(match, XML_ATTR_ID)); } } @@ -1039,16 +1051,18 @@ { GList *list_item = NULL; stonith_notify_client_t *new_client = NULL; + stonith_private_t *private = NULL; + private = stonith->private; crm_debug_2("Adding callback for %s events (%d)", - event, g_list_length(stonith->notify_list)); + event, g_list_length(private->notify_list)); crm_malloc0(new_client, sizeof(stonith_notify_client_t)); new_client->event = event; new_client->notify = callback; list_item = g_list_find_custom( - stonith->notify_list, new_client, stonithlib_GCompareFunc); + private->notify_list, new_client, stonithlib_GCompareFunc); if(list_item != NULL) { crm_warn("Callback already present"); @@ -1056,12 +1070,11 @@ return st_err_exists; } else { - stonith->notify_list = g_list_append( - stonith->notify_list, new_client); + private->notify_list = g_list_append(private->notify_list, new_client); stonith_set_notification(stonith, event, 1); - crm_debug_3("Callback added (%d)", g_list_length(stonith->notify_list)); + crm_debug_3("Callback added (%d)", g_list_length(private->notify_list)); } return stonith_ok; } @@ -1071,22 +1084,24 @@ { GList *list_item = NULL; stonith_notify_client_t *new_client = NULL; + stonith_private_t *private = NULL; crm_debug("Removing callback for %s events", event); + private = stonith->private; crm_malloc0(new_client, sizeof(stonith_notify_client_t)); new_client->event = event; new_client->notify = NULL; list_item = g_list_find_custom( - stonith->notify_list, new_client, stonithlib_GCompareFunc); + private->notify_list, new_client, stonithlib_GCompareFunc); stonith_set_notification(stonith, event, 0); if(list_item != NULL) { stonith_notify_client_t *list_client = list_item->data; - stonith->notify_list = - g_list_remove(stonith->notify_list, list_client); + private->notify_list = + g_list_remove(private->notify_list, list_client); crm_free(list_client); crm_debug_3("Removed callback"); @@ -1111,7 +1126,7 @@ } static int stonith_api_add_callback( - stonith_t *stonith, int call_id, int timeout, gboolean only_success, + stonith_t *stonith, int call_id, int timeout, bool only_success, void *user_data, const char *callback_name, void (*callback)( stonith_t *st, const xmlNode *msg, int call, int rc, xmlNode *output, void *userdata)) @@ -1158,7 +1173,7 @@ return TRUE; } -static int stonith_api_del_callback(stonith_t *stonith, int call_id, gboolean all_callbacks) +static int stonith_api_del_callback(stonith_t *stonith, int call_id, bool all_callbacks) { stonith_private_t *private = stonith->private; @@ -1498,7 +1513,7 @@ stonith_perform_callback(stonith, blob.xml, 0, 0); } else if(safe_str_eq(type, T_STONITH_NOTIFY)) { - g_list_foreach(stonith->notify_list, stonith_send_notification, &blob); + g_list_foreach(private->notify_list, stonith_send_notification, &blob); } else { crm_err("Unknown message type: %s", type); @@ -1574,7 +1589,8 @@ void stonith_api_delete(stonith_t *stonith) { - GList *list = stonith->notify_list; + stonith_private_t* private = stonith->private; + GList *list = private->notify_list; while(list != NULL) { stonith_notify_client_t *client = g_list_nth_data(list, 0); list = g_list_remove(list, client); @@ -1596,9 +1612,9 @@ private->stonith_op_callback_table = g_hash_table_new_full( g_direct_hash, g_direct_equal, NULL, stonith_destroy_op_callback); + private->notify_list = NULL; new_stonith->call_id = 1; - new_stonith->notify_list = NULL; new_stonith->state = stonith_disconnected; crm_malloc0(new_stonith->cmds, sizeof(stonith_api_operations_t)); @@ -1624,3 +1640,23 @@ return new_stonith; } +stonith_key_value_t *stonith_key_value_add(stonith_key_value_t *kvp, + const char *key, const char *value) { + stonith_key_value_t *p; + + crm_malloc(p, sizeof(stonith_key_value_t)); + p->next = kvp; + p->key = key; + p->value = value; + return( p ); +} + +void stonith_key_value_freeall(stonith_key_value_t *kvp) { + stonith_key_value_t *p; + + while(kvp) { + p = kvp->next; + free(kvp); + kvp = p; + } +} diff -r 7eacbb51c894 lib/plugins/lrm/raexecstonith.c --- a/lib/plugins/lrm/raexecstonith.c Tue Feb 22 17:21:51 2011 +0800 +++ b/lib/plugins/lrm/raexecstonith.c Fri Apr 29 11:51:01 2011 -0400 @@ -129,8 +129,11 @@ execra(const char *rsc_id, const char *rsc_type, const char *provider, const char *op_type, const int timeout, GHashTable *params) { - int rc = 0; + int i, num, rc = 0; + GHashTableIter ihash; + stonith_key_value_t *device_params = NULL; stonith_t *stonith_api = NULL; + provider = get_stonith_provider(rsc_type, provider); crm_log_init("lrm-stonith", LOG_INFO, FALSE, FALSE, 0, NULL); @@ -158,9 +161,18 @@ agent = "fence_legacy"; g_hash_table_replace(params, strdup("plugin"), strdup(rsc_type)); } - + + num = g_hash_table_size( params ); + g_hash_table_iter_init( &ihash, params ); + for( i = 0; i < num; i++ ) { + char *key, *value; + g_hash_table_iter_next(&ihash, + (gpointer *)&key, (gpointer *)&value); + stonith_key_value_add(device_params, key, value); + } + rc = stonith_api->cmds->register_device( - stonith_api, st_opt_sync_call, rsc_id, provider, agent, params); + stonith_api, st_opt_sync_call, rsc_id, provider, agent, device_params); } else if ( 0 == STRNCMP_CONST(op_type, "stop") ) { rc = stonith_api->cmds->remove_device(