/* File: lrmadmin.c
* Description: A adminstration tool for Local Resource Manager
*
* Author: Sun Jiang Dong <sunjd@cn.ibm.com>
* Copyright (c) 2004 International Business Machines
*
* Todo: security verification
*
* 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 <stdlib.h>
#ifndef __USE_GNU
#define __USE_GNU
/* For strnlen protype */
#include <string.h>
#undef __USE_GNU
#else
#include <string.h>
#endif
#include <errno.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif /* HAVE_GETOPT_H */
#include <uuid/uuid.h>
#include <uuid/uuid.h>
#include <clplumbing/cl_log.h>
#include <lrm/lrm_api.h>
/*
#include <clplumbing/lsb_exitcodes.h>
*/
const char * optstring = "AD:dEF:d:Msg:c:S:LI:Rh";
static struct option long_options[] = {
{"daemon", 0, 0, 'd'},
{"executera", 1, 0, 'E'},
{"flush",1,0,'F'},
{"monitor",0,0,'M'},
{"status",1,0,'S'},
{"listall",0,0,'L'},
{"information",1,0,'I'},
{"add",1,0,'A'},
{"delete",1,0,'D'},
{"rasupported",1,0,'R'},
{"help",0,0,'h'},
{0,0,0,0}
};
GMainLoop *mainloop = NULL;
const char * lrmadmin_name = "lrmadmin";
/* 20 is the length limit for a argv[x] */
const int ARGVI_MAX_LEN = 20;
typedef enum {
ERROR_OPTION = -1,
NULL_OP,
DAEMON_OP,
EXECUTE_RA,
FLUSH,
MONITOR,
MONITOR_SET,
MONITOR_GET,
MONITOR_CLS,
RSC_STATUS,
LIST_ALLRSC,
INF_RSC,
ADD_RSC,
DEL_RSC,
RATYPE_SUPPORTED,
HELP
} lrmadmin_cmd_t;
static const char * status_msg[5] = {
"Succeed", /* LRM_OP_DONE */
"Cancelled", /* LRM_OP_CANCELLED */
"Timeout", /* LRM_OP_TIMEOUT */
"Not Supported", /* LRM_OP_NOTSUPPORTED */
"Failed Due to a Error" /* LRM_OP_ERROR */
};
static gboolean QUIT_GETOPT = FALSE;
static lrmadmin_cmd_t lrmadmin_cmd = NULL_OP;
static gboolean ASYN_OPS = FALSE;
static int call_id = 0;
const char * simple_help_screen =
"lrmadmin {-d|--deamon}\n"\
" {-A|--add} <rscid> <ratype> <raname> [<rsc_params_list>]\n"\
" {-D|--delete} <rscid>\n"\
" {-F|--flush} <rscid>\n"\
" {-E|--execute} <rscid> <operator> <timeout> [<operator_parameters_"\
"list>]\n"\
" {-M|--monitor} -s <rscid> <operator> <timeout> <interval> "\
"[<operator_parameters_list>]\n"
" {-M|--monitor} {-g|-c} <rscid>\n"\
" {-S|--status} <rscid>\n"\
" {-L|--listall}\n"\
" {-I|--information} <rsc_id>\n"\
" {-R|--rasupported}\n"\
" {-h|--help}\n";
#define OPTION_OBSCURE_CHECK \
if ( lrmadmin_cmd != NULL_OP ) { \
cl_log(LOG_ERR,"Obscure options."); \
return -1; \
}
/* the begin of the internal used function list */
static int resource_operation(ll_lrm_t * lrmd, int argc, int optind,
char * argv[]);
static int add_resource(ll_lrm_t * lrmd, int argc, int optind, char * argv[]);
static int transfer_cmd_params(int amount, int start, char * argv[],
const char * ra_type, GHashTable ** params_ht);
static void g_ratype_supported(gpointer data, gpointer user_data);
static void g_print_ops(gpointer data, gpointer user_data);
static void g_get_rsc_description(gpointer data, gpointer user_data);
static void print_rsc_inf(lrm_rsc_t * lrmrsc);
static char * params_hashtable_to_str(const char * ra_type, GHashTable * ht);
static void free_stritem_of_hashtable(gpointer key, gpointer value,
gpointer user_data);
static void ocf_params_hash_to_str(gpointer key, gpointer value,
gpointer user_data);
static void normal_params_hash_to_str(gpointer key, gpointer value,
gpointer user_data);
static lrm_rsc_t * get_lrm_rsc(ll_lrm_t * lrmd, rsc_id_t rscid);
static void g_print_monitor(gpointer lrm_mon, gpointer user_data);
static int set_monitor(ll_lrm_t * lrmd, int argc, int optind, char * argv[]);
/* the end of the internal used function list */
static void lrm_op_done_callback(lrm_op_t* op);
static void lrm_monitor_callback(lrm_mon_t* mon);
static gboolean post_query_call_result(gpointer data);
int main(int argc, char **argv)
{
int option_char;
rsc_id_t rscid_arg_tmp;
int ret_value = 0;
ll_lrm_t* lrmd;
lrm_rsc_t * lrm_rsc;
GList *ratype, *rscid_list;
/* Prevent getopt_long to print error message on stderr isself */
/*opterr = 0; */
if (argc == 1) {
printf("%s",simple_help_screen);
return 0;
}
cl_log_set_entity(lrmadmin_name);
cl_log_enable_stderr(TRUE);
cl_log_set_facility(LOG_USER);
memset(rscid_arg_tmp, '\0', sizeof(rsc_id_t));
do {
option_char = getopt_long (argc, argv, optstring,
long_options, NULL);
if (option_char == -1) {
break;
}
switch (option_char) {
case 'd':
OPTION_OBSCURE_CHECK
lrmadmin_cmd = DAEMON_OP;
QUIT_GETOPT = TRUE;
break;
case 'A':
OPTION_OBSCURE_CHECK
lrmadmin_cmd = ADD_RSC;
break;
case 'D':
OPTION_OBSCURE_CHECK
lrmadmin_cmd = DEL_RSC;
if (optarg) {
uuid_parse(optarg, rscid_arg_tmp);
}
break;
case 'R':
OPTION_OBSCURE_CHECK
lrmadmin_cmd = RATYPE_SUPPORTED;
break;
case 'F':
OPTION_OBSCURE_CHECK
lrmadmin_cmd = FLUSH;
if (optarg) {
uuid_parse(optarg, rscid_arg_tmp);
}
break;
case 'E':
OPTION_OBSCURE_CHECK
lrmadmin_cmd = EXECUTE_RA;
break;
case 'M':
OPTION_OBSCURE_CHECK
lrmadmin_cmd = MONITOR;
break;
case 's':
if (lrmadmin_cmd != MONITOR) {
cl_log(LOG_ERR,"Option error.");
return -1;
}
lrmadmin_cmd = MONITOR_SET;
break;
case 'g':
if (lrmadmin_cmd != MONITOR) {
cl_log(LOG_ERR,"Option error.");
return -1;
}
lrmadmin_cmd = MONITOR_GET;
if (optarg) {
uuid_parse(optarg, rscid_arg_tmp);
}
break;
case 'c':
if (lrmadmin_cmd != MONITOR) {
cl_log(LOG_ERR,"Option error.");
return -1;
}
lrmadmin_cmd = MONITOR_CLS;
if (optarg) {
uuid_parse(optarg, rscid_arg_tmp);
}
break;
case 'S':
OPTION_OBSCURE_CHECK
lrmadmin_cmd = RSC_STATUS;
if (optarg) {
uuid_parse(optarg, rscid_arg_tmp);
}
break;
case 'L':
OPTION_OBSCURE_CHECK
lrmadmin_cmd = LIST_ALLRSC;
break;
case 'I':
OPTION_OBSCURE_CHECK
if (optarg) {
uuid_parse(optarg, rscid_arg_tmp);
}
lrmadmin_cmd = INF_RSC;
break;
case 'h':
OPTION_OBSCURE_CHECK
/* print detailed help screen? */
printf("%s",simple_help_screen);
return 0;
case '?':
/* cl_log(LOG_ERR,"There is a unrecognized
option %s", optarg);
*/
printf("%s", simple_help_screen);
return -1;
default:
cl_log(LOG_ERR,"Error:getopt returned character"\
" code %c.", option_char);
return -1;
}
} while (!QUIT_GETOPT);
lrmd = ll_lrm_new("lrm");
if (NULL == lrmd) {
cl_log(LOG_ERR,"ll_lrn_new return null.");
return -2;
}
if (lrmd->lrm_ops->signon(lrmd, lrmadmin_name) != 1) { /* != HA_OK */
if (lrmadmin_cmd == DAEMON_OP) {
printf("lrmd daemon is not running.\n");
return 0;
} else {
cl_log(LOG_ERR,"Can't connect to lrmd, quit!");
return -2;
}
}
if (lrmadmin_cmd == DAEMON_OP) {
printf("lrmd daemon is running.\n");
lrmd->lrm_ops->signoff(lrmd);
return 0;
}
switch (lrmadmin_cmd) {
case EXECUTE_RA:
call_id = resource_operation(lrmd, argc, optind, argv);
if (call_id < 0) {
if ( call_id == -2 ) {
cl_log(LOG_ERR, "Failed to operate "\
"resource %s due to parameter error."
, argv[optind]);
ret_value = -3;
}
if ( call_id == -1 ) {
cl_log(LOG_ERR, "Failed! no this "\
"resource %s.", argv[optind]);
ret_value = -2;
}
cl_log(LOG_ERR, "Failed to operate "\
"resource %s due to unknown error."
, argv[optind]);
ret_value = -3;
ASYN_OPS = FALSE;
} else {
/* Return value: HA_OK = 1 Or HA_FAIL = 0 */
if ( call_id == 0 ) {
cl_log(LOG_ERR, "Resource operation "\
"Failed." );
ret_value = -3;
ASYN_OPS = FALSE;
} else {
ASYN_OPS = TRUE;
}
}
break;
case ADD_RSC:
if (add_resource(lrmd, argc, optind, argv) == 0) {
printf("Succeeded in adding this resource.\n");
} else {
printf("Failed to add this resource.\n");
ret_value = -3;
}
ASYN_OPS = FALSE;
break;
case DEL_RSC:
/* Return value: HA_OK = 1 Or HA_FAIL = 0 */
if (lrmd->lrm_ops->delete_rsc(lrmd, rscid_arg_tmp)==1) {
printf("Succeeded in delete this resource.\n");
} else {
printf("Failed to delete this resource.\n");
ret_value = -3;
}
ASYN_OPS = FALSE;
break;
case FLUSH:
lrm_rsc = get_lrm_rsc(lrmd, rscid_arg_tmp);
if (!(lrm_rsc)) {
ret_value = -3;
} else {
/* Return value: HA_OK = 1 Or HA_FAIL = 0 */
if (lrm_rsc->ops->flush_ops(lrm_rsc) == 1 ) {
printf("Succeeded in flushing.\n");
} else {
printf("Falied to flush.\n");
ret_value = -3;
}
}
ASYN_OPS = FALSE;
break;
case RATYPE_SUPPORTED:
ratype = lrmd->lrm_ops->get_ra_supported(lrmd);
printf("List size: %d\n", g_list_length(ratype));
if (ratype) {
g_list_foreach(ratype, g_ratype_supported, NULL);
g_list_free(ratype);
} else {
printf("No resource agency is supported\n");
}
ASYN_OPS = FALSE;
break;
case LIST_ALLRSC:
rscid_list = lrmd->lrm_ops->get_all_rscs(lrmd);
if (rscid_list) {
g_list_foreach(rscid_list, g_get_rsc_description
, lrmd);
g_list_free(rscid_list);
} else
printf("Currently no resource is managed by "\
"LRM.\n");
ASYN_OPS = FALSE;
break;
case INF_RSC:
lrm_rsc = get_lrm_rsc(lrmd, rscid_arg_tmp);
if (!(lrm_rsc)) {
ret_value = -3;
} else {
print_rsc_inf(lrm_rsc);
g_free(lrm_rsc);
}
ASYN_OPS = FALSE;
break;
case RSC_STATUS:
lrm_rsc = get_lrm_rsc(lrmd, rscid_arg_tmp);
if (!(lrm_rsc)) {
ret_value = -3;
} else {
state_flag_t cur_state;
GList * ops_queue;
ops_queue = lrm_rsc->ops->get_cur_state(lrm_rsc,
&cur_state);
if (!ops_queue) {
cl_log(LOG_ERR, "Operation queue "\
"pointer is null when try to get the"\
" operation status on a RA.");
ret_value = -3;
} else {
if (cur_state == LRM_RSC_IDLE) {
printf("No operation is doing"\
"on the resource, and the "\
"operation is the last one "\
"executed on the resource.\n");
} else {
printf("The following "\
"operations are those in the "\
"queue, and the first one is "\
"running now.\n");
}
g_list_foreach(ops_queue, g_print_ops,
NULL);
g_list_free(ops_queue);
}
}
ASYN_OPS = FALSE;
break;
case MONITOR:
fprintf(stderr, "Need one more definite option.\n");
ret_value = -1;
ASYN_OPS = FALSE;
break;
/* Don't finished ops */
case MONITOR_SET:
call_id = set_monitor(lrmd, argc, optind, argv);
if (call_id < 0) {
cl_log(LOG_ERR, "There are invalid parameters");
ret_value = -3;
ASYN_OPS = FALSE;
} else {
/* Return value: HA_OK = 1 Or HA_FAIL = 0 */
if ( call_id == 0 ) {
cl_log(LOG_ERR, "Monitor settting "\
"Failed." );
ret_value = -3;
ASYN_OPS = FALSE;
} else {
ASYN_OPS = TRUE;
}
}
break;
case MONITOR_GET:
lrm_rsc = get_lrm_rsc(lrmd, rscid_arg_tmp);
if (!(lrm_rsc)) {
ret_value = -3;
} else {
GList* monitor_list = NULL;
monitor_list =
lrm_rsc->ops->get_monitors(lrm_rsc);
if ( monitor_list == NULL) {
printf("No monitor on this resource.\n");
} else {
printf("Monitors on this resource:\n");
g_list_foreach(monitor_list,
g_print_monitor, NULL);
g_list_free(monitor_list);
}
}
ASYN_OPS = FALSE;
break;
case MONITOR_CLS:
lrm_rsc = get_lrm_rsc(lrmd, rscid_arg_tmp);
if (!(lrm_rsc)) {
ret_value = -3;
} else {
lrm_mon_t mon_ops;
mon_ops.mode = LRM_MONITOR_CLEAR;
if (lrm_rsc->ops->set_monitor(lrm_rsc, &mon_ops)
== 1 ) { /* HA_OK */
printf("Be trying to clearing all "\
"monitors on this resource.\n");
ASYN_OPS = TRUE;
} else {
fprintf(stderr, "Failed to clear all "\
"monitors on this resource.\n");
ret_value = -1;
ASYN_OPS = FALSE;
}
}
break;
default:
fprintf(stderr, "This option is not supported yet.\n");
ret_value = -1;
ASYN_OPS = FALSE;
break;
}
if (ASYN_OPS) {
lrmd->lrm_ops->set_lrm_callback(lrmd, lrm_op_done_callback,
lrm_monitor_callback);
mainloop = g_main_new(FALSE);
cl_log(LOG_DEBUG, "%s waiting for calling result from the lrmd.",
lrmadmin_name);
g_idle_add(post_query_call_result, lrmd);
g_main_run(mainloop);
}
lrmd->lrm_ops->signoff(lrmd);
return ret_value;
}
static void
lrm_op_done_callback(lrm_op_t* op)
{
char * tmp = NULL;
if (!op) {
cl_log(LOG_ERR, "In callback function, op is NULL pointer.");
return;
}
printf("Operation result: %s\n", status_msg[op->status-LRM_OP_DONE]);
printf("Operation type: %s\n", op->op_type);
tmp = params_hashtable_to_str(op->rsc->ra_type, op->params);
printf("Opration parameters: %s\n", tmp);
g_free(tmp);
printf("\nThe corresponding resource description as below\n");
print_rsc_inf(op->rsc);
/* Don't need ?
* g_free(op->rsc);
* g_free(op);
*/
}
static void
lrm_monitor_callback(lrm_mon_t* mon)
{
if (mon) {
g_print_monitor(mon, NULL);
}
}
static gboolean
post_query_call_result(gpointer data)
{
ll_lrm_t * lrmd = (ll_lrm_t *) data;
if (!(lrmd->lrm_ops->msgready(lrmd)) ) {
return TRUE;
}
if (0 > lrmd->lrm_ops->rcvmsg(lrmd, TRUE)) {
cl_log(LOG_ERR, "Error when post query calling result.");
}
g_main_quit(mainloop);
return FALSE;
}
static int
resource_operation(ll_lrm_t * lrmd, int argc, int optind, char * argv[])
{
int call_id;
rsc_id_t rsc_id;
GHashTable * params_ht = NULL;
lrm_op_t op;
lrm_rsc_t * lrm_rsc;
if ((argc - optind) < 3) {
cl_log(LOG_ERR,"No enough parameters.");
return -2;
}
uuid_parse(argv[optind], rsc_id);
lrm_rsc = lrmd->lrm_ops->get_rsc(lrmd, rsc_id);
if (!lrm_rsc) {
return -1;
}
op.op_type = argv[optind+1];
op.timeout = atoi(argv[optind+2]);
if ((argc - optind) > 3) {
if (0 > transfer_cmd_params(argc, optind+3, argv,
lrm_rsc->ra_type, ¶ms_ht) ) {
return -2;
}
}
op.params = params_ht;
call_id = lrm_rsc->ops->perform_op(lrm_rsc, &op);
/* g_free(lrm_rsc); don't need to free it ? */
if (params_ht) {
g_hash_table_foreach(params_ht, free_stritem_of_hashtable, NULL);
g_hash_table_destroy(params_ht);
}
return call_id;
}
static int
add_resource(ll_lrm_t * lrmd, int argc, int optind, char * argv[])
{
rsc_id_t rsc_id;
const char * ra_type = NULL;
const char * ra_name = NULL;
GHashTable * params_ht = NULL;
int tmp_ret = NULL;
if ((argc - optind) < 3) {
cl_log(LOG_ERR,"No enough parameters.");
return -2;
}
ra_type = argv[optind+1];
ra_name = argv[optind+2];
uuid_parse(argv[optind], rsc_id);
/* delete Hashtable */
if ((argc - optind) > 3) {
if ( 0 > transfer_cmd_params(argc, optind+3, argv, ra_type,
¶ms_ht) ) {
return -1;
}
}
tmp_ret = lrmd->lrm_ops->add_rsc(lrmd, rsc_id, ra_type,
ra_name, params_ht);
/*delete params_ht*/
if (params_ht) {
g_hash_table_foreach(params_ht, free_stritem_of_hashtable, NULL);
g_hash_table_destroy(params_ht);
}
return (tmp_ret ? 0 : -1); /* tmp_ret is HA_OK=1 or HA_FAIL=0 */
}
static int
transfer_cmd_params(int amount, int start, char * argv[], const char * ra_type,
GHashTable ** params_ht)
{
if (amount < start) {
return -1;
}
if (strncmp("ocf", ra_type, 4)==0) {
int i;
char * delimit, * key, * value;
*params_ht = g_hash_table_new(g_str_hash, g_str_equal);
for (i=start; i<amount; i++) {
int len_tmp;
delimit = strchr(argv[i], '=');
if (!delimit) {
cl_log(LOG_ERR, "parameter %s is invalid for " \
"OCF standard.", argv[i]);
goto error_return; /* Have to */
}
/* lack error handling for g_new. Exception ? */
len_tmp = strnlen(delimit+1, 80) + 1;
value = g_new(gchar, len_tmp);
strncpy(value, delimit+1, len_tmp);
len_tmp = strnlen(argv[i], 80) - strnlen(delimit, 80);
key = g_new(gchar, len_tmp+1);
key[len_tmp] = '\0';
strncpy(key, argv[i], len_tmp);
g_hash_table_insert(*params_ht, key, value);
}
} else if ( strncmp("lsb", ra_type, 4) == 0 ||
strncmp("heartbeat", ra_type, 10) == 0 ) {
int i;
char buffer[21];
/* Pay attention: for parameter ordring issue */
*params_ht = g_hash_table_new(g_str_hash, g_str_equal);
buffer[20] = '\0';
for (i=start; i<amount; i++) {
snprintf(buffer, 20, "%d", i-start+1);
g_hash_table_insert( *params_ht, g_strdup(buffer), g_strdup(argv[i]));
/*printf("index: %d value: %s \n", i-start+1, argv[i]); */
}
} else {
fprintf(stderr, "Not supported resource agency type.\n");
return -1;
}
return 0;
error_return:
if (*params_ht) {
g_hash_table_foreach(*params_ht, free_stritem_of_hashtable, NULL);
g_hash_table_destroy(*params_ht);
*params_ht = NULL;
}
return -1;
}
static char *
params_hashtable_to_str(const char * ra_type, GHashTable * ht)
{
gchar * params_str = NULL;
GString * gstr_tmp;
if (!ht) {
return NULL;
}
if (strncmp("ocf", ra_type, 4)==0) {
gstr_tmp = g_string_new("");
g_hash_table_foreach(ht, ocf_params_hash_to_str, &gstr_tmp);
params_str = g_new(gchar, gstr_tmp->len+1);
strncpy(params_str, gstr_tmp->str, gstr_tmp->len+1);
g_string_free(gstr_tmp, TRUE);
} else if ( strncmp("lsb", ra_type, 4) == 0 ||
strncmp("heartbeat", ra_type, 10) == 0 ) {
int i;
int ht_size = g_hash_table_size(ht);
gchar * tmp_str = g_new(gchar, ht_size*ARGVI_MAX_LEN);
memset(tmp_str, '\0', ht_size*ARGVI_MAX_LEN);
g_hash_table_foreach(ht, normal_params_hash_to_str, &tmp_str);
gstr_tmp = g_string_new("");
for (i=0; i< ht_size; i++) {
g_string_append(gstr_tmp, tmp_str + i*ARGVI_MAX_LEN );
}
params_str = g_new(gchar, gstr_tmp->len+1);
strncpy(params_str, gstr_tmp->str, gstr_tmp->len+1);
g_string_free(gstr_tmp, TRUE);
} else {
fprintf(stderr, "Not supported resource agency type.\n");
}
return params_str;
}
static void
g_ratype_supported(gpointer data, gpointer user_data)
{
printf("%s\n", (char*)data);
g_free(data); /* ? */
}
static void
g_print_ops(gpointer data, gpointer user_data)
{
printf("%s ", (char*)data);
g_free(data); /* ? */
}
static void
g_get_rsc_description(gpointer data, gpointer user_data)
{
ll_lrm_t* lrmd = NULL;
lrm_rsc_t * lrm_rsc;
rsc_id_t rsc_id_tmp;
if (!(user_data)) {
return;
}
lrmd = (ll_lrm_t *)user_data;
memset(rsc_id_tmp, '\0', sizeof(rsc_id_t));
strncpy(rsc_id_tmp, data, sizeof(rsc_id_t));
lrm_rsc = lrmd->lrm_ops->get_rsc(lrmd, rsc_id_tmp);
if (lrm_rsc) {
print_rsc_inf(lrm_rsc);
g_free(lrm_rsc); /* ? */
} else
cl_log(LOG_ERR, "There is a invalid resource id %s.",
rsc_id_tmp);
g_free(data); /* ? */
}
static void
print_rsc_inf(lrm_rsc_t * lrm_rsc)
{
char rscid_str_tmp[40];
char * tmp = NULL;
if (!lrm_rsc) {
return;
}
uuid_unparse(lrm_rsc->id, rscid_str_tmp);
printf("Resource ID: %s\n", rscid_str_tmp);
printf("Resource agency name: %s\n", lrm_rsc->name);
printf("Resource agency type: %s\n", lrm_rsc->ra_type);
if (lrm_rsc->params) {
tmp = params_hashtable_to_str(lrm_rsc->ra_type,
lrm_rsc->params);
}
printf("Resource agency parameters: %s\n", tmp);
g_free(tmp);
}
static void
free_stritem_of_hashtable(gpointer key, gpointer value, gpointer user_data)
{
/*printf("key=%s value=%s\n", (char *)key, (char *)value);*/
g_free(key);
g_free(value);
}
static void
ocf_params_hash_to_str(gpointer key, gpointer value, gpointer user_data)
{
GString * gstr_tmp = *(GString **)user_data;
g_string_append(gstr_tmp, (char*)key);
g_string_append(gstr_tmp, "=");
g_string_append(gstr_tmp, (char *)value);
g_string_append(gstr_tmp, "\n");
}
static void
normal_params_hash_to_str(gpointer key, gpointer value, gpointer user_data)
{
gchar * str_tmp = *(gchar **) user_data;
if (str_tmp == NULL ) {
return;
}
strncpy(str_tmp + *(gint *)key * ARGVI_MAX_LEN, (char*)value,
ARGVI_MAX_LEN - 1);
}
static lrm_rsc_t *
get_lrm_rsc(ll_lrm_t * lrmd, rsc_id_t rscid)
{
char uuid_str_tmp[40];
lrm_rsc_t * lrm_rsc;
lrm_rsc = lrmd->lrm_ops->get_rsc(lrmd, rscid);
if (!(lrm_rsc)) {
uuid_unparse(rscid, uuid_str_tmp);
cl_log(LOG_ERR,"No this resource %s.", uuid_str_tmp);
}
return lrm_rsc;
}
static void
g_print_monitor(gpointer data, gpointer user_data)
{
/* Don't need to free it */
lrm_mon_t * lrm_mon = (lrm_mon_t *) data;
if (lrm_mon) {
char * tmp;
printf("MONITOR:\n");
printf("Mode: %d\n", lrm_mon->mode);
printf("Interval: %d\n", lrm_mon->interval);
printf("Target: %d\n", lrm_mon->target);
printf("Operation type: %s\n", lrm_mon->op_type);
printf("Timeout: %d\n", lrm_mon->timeout);
tmp = params_hashtable_to_str(lrm_mon->rsc->ra_type,
lrm_mon->params);
printf("Parameters: %s\n", tmp);
g_free(tmp);
/* Other fields ? */
}
}
static int
set_monitor(ll_lrm_t * lrmd, int argc, int optind, char * argv[])
{
int call_id;
rsc_id_t rsc_id;
GHashTable * params_ht = NULL;
lrm_mon_t mon;
lrm_rsc_t * lrm_rsc;
if ((argc - optind) < 4) {
cl_log(LOG_ERR,"No enough parameters.");
return -2;
}
uuid_parse(argv[optind], rsc_id);
lrm_rsc = lrmd->lrm_ops->get_rsc(lrmd, rsc_id);
if (!lrm_rsc) {
return -1;
}
mon.mode = LRM_MONITOR_SET;
mon.op_type = argv[optind+1];
mon.timeout = atoi(argv[optind+2]);
mon.interval = atoi(argv[optind+3]);
if ((argc - optind) > 4) {
if ( 0 > transfer_cmd_params(argc, optind+4, argv,
lrm_rsc->ra_type, ¶ms_ht) ) {
return -1;
}
}
mon.params = params_ht;
call_id = lrm_rsc->ops->set_monitor(lrm_rsc, &mon);
/* g_free(lrm_rsc); Don't need to free it? */
if (params_ht) {
g_hash_table_foreach(params_ht, free_stritem_of_hashtable, NULL);
g_hash_table_destroy(params_ht);
}
return call_id;
}
syntax highlighted by Code2HTML, v. 0.9.1