Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F3686850
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/pengine/ptest.c b/pengine/ptest.c
index 8ecef45ca9..0ad3641ee0 100644
--- a/pengine/ptest.c
+++ b/pengine/ptest.c
@@ -1,479 +1,479 @@
/*
* Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
*
* 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 <crm_internal.h>
#include <crm/crm.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <crm/transition.h>
#include <crm/common/xml.h>
#include <crm/common/util.h>
#include <crm/msg_xml.h>
#include <crm/cib.h>
#include <glib.h>
#include <pengine.h>
#include <lib/pengine/utils.h>
#include <allocate.h>
#if HAVE_LIBXML2
# include <libxml/parser.h>
#endif
gboolean use_stdin = FALSE;
gboolean do_simulation = FALSE;
gboolean inhibit_exit = FALSE;
gboolean all_actions = FALSE;
extern xmlNode * do_calculations(
pe_working_set_t *data_set, xmlNode *xml_input, ha_time_t *now);
extern void cleanup_calculations(pe_working_set_t *data_set);
char *use_date = NULL;
FILE *dot_strm = NULL;
#define DOT_PREFIX "PE_DOT: "
/* #define DOT_PREFIX "" */
#define dot_write(fmt...) if(dot_strm != NULL) { \
fprintf(dot_strm, fmt); \
fprintf(dot_strm, "\n"); \
} else { \
crm_debug(DOT_PREFIX""fmt); \
}
static void
init_dotfile(void)
{
dot_write(" digraph \"g\" {");
/* dot_write(" size = \"30,30\""); */
/* dot_write(" graph ["); */
/* dot_write(" fontsize = \"12\""); */
/* dot_write(" fontname = \"Times-Roman\""); */
/* dot_write(" fontcolor = \"black\""); */
/* dot_write(" bb = \"0,0,398.922306,478.927856\""); */
/* dot_write(" color = \"black\""); */
/* dot_write(" ]"); */
/* dot_write(" node ["); */
/* dot_write(" fontsize = \"12\""); */
/* dot_write(" fontname = \"Times-Roman\""); */
/* dot_write(" fontcolor = \"black\""); */
/* dot_write(" shape = \"ellipse\""); */
/* dot_write(" color = \"black\""); */
/* dot_write(" ]"); */
/* dot_write(" edge ["); */
/* dot_write(" fontsize = \"12\""); */
/* dot_write(" fontname = \"Times-Roman\""); */
/* dot_write(" fontcolor = \"black\""); */
/* dot_write(" color = \"black\""); */
/* dot_write(" ]"); */
}
static char *
create_action_name(action_t *action)
{
char *action_name = NULL;
const char *action_host = NULL;
if(action->node) {
action_host = action->node->details->uname;
action_name = crm_concat(action->uuid, action_host, ' ');
} else if(action->pseudo) {
action_name = crm_strdup(action->uuid);
} else {
action_host = "<none>";
action_name = crm_concat(action->uuid, action_host, ' ');
}
if(safe_str_eq(action->task, RSC_CANCEL)) {
char *tmp_action_name = action_name;
action_name = crm_concat("Cancel", tmp_action_name, ' ');
crm_free(tmp_action_name);
}
return action_name;
}
gboolean USE_LIVE_CIB = FALSE;
static struct crm_option long_options[] = {
/* Top-level Options */
{"help", 0, 0, '?', "This text"},
- {"version", 0, 0, 'v', "Version information" },
+ {"version", 0, 0, '$', "Version information" },
{"verbose", 0, 0, 'V', "Increase debug output\n"},
{"show-scores", 0, 0, 's', "Display resource allocation scores"},
{"simulate", 0, 0, 'S', "Simulate the transition's execution to find invalid graphs\n"},
{"live-check", 0, 0, 'L', "Connect to the CIB and use the current contents as input"},
{"xml-text", 1, 0, 'X', "Retrieve XML from the supplied string"},
{"xml-file", 1, 0, 'x', "Retrieve XML from the named file"},
{"xml-pipe", 0, 0, 'p', "Retrieve XML from stdin\n"},
{"save-input", 1, 0, 'I', "\tSave the input to the named file"},
{"save-graph", 1, 0, 'G', "\tSave the transition graph (XML format) to the named file"},
{"save-dotfile",1, 0, 'D', "Save the transition graph (DOT format) to the named file\n"},
{0, 0, 0, 0}
};
int
main(int argc, char **argv)
{
gboolean process = TRUE;
gboolean all_good = TRUE;
enum transition_status graph_rc = -1;
crm_graph_t *transition = NULL;
ha_time_t *a_date = NULL;
cib_t * cib_conn = NULL;
xmlNode * cib_object = NULL;
int argerr = 0;
int flag;
char *msg_buffer = NULL;
gboolean optional = FALSE;
pe_working_set_t data_set;
const char *source = NULL;
const char *xml_file = NULL;
const char *dot_file = NULL;
const char *graph_file = NULL;
const char *input_file = NULL;
/* disable glib's fancy allocators that can't be free'd */
GMemVTable vtable;
vtable.malloc = malloc;
vtable.realloc = realloc;
vtable.free = free;
vtable.calloc = calloc;
vtable.try_malloc = malloc;
vtable.try_realloc = realloc;
g_mem_set_vtable(&vtable);
crm_log_init("ptest", LOG_CRIT, FALSE, FALSE, 0, NULL);
- crm_set_options("V?vXD:G:I:Lwx:d:aSs", "[-?Vv] -[Xxp] {other options}", long_options,
+ crm_set_options("V?$XD:G:I:Lwx:d:aSs", "[-?Vv] -[Xxp] {other options}", long_options,
"Calculate the cluster's response to the supplied cluster state\n");
cl_log_set_facility(LOG_USER);
while (1) {
int option_index = 0;
flag = crm_get_option(argc, argv, &option_index);
if (flag == -1)
break;
switch(flag) {
case 'S':
do_simulation = TRUE;
break;
case 'a':
all_actions = TRUE;
break;
case 'w':
inhibit_exit = TRUE;
break;
case 'X':
use_stdin = TRUE;
break;
case 's':
show_scores = TRUE;
break;
case 'x':
xml_file = optarg;
break;
case 'd':
use_date = optarg;
break;
case 'D':
dot_file = optarg;
break;
case 'G':
graph_file = optarg;
break;
case 'I':
input_file = optarg;
break;
case 'V':
cl_log_enable_stderr(TRUE);
alter_debug(DEBUG_INC);
break;
case 'L':
USE_LIVE_CIB = TRUE;
break;
- case 'v':
+ case '$':
case '?':
crm_help(flag, 0);
break;
default:
- printf("?? getopt returned character code 0%o ??\n", flag);
+ fprintf(stderr, "Option -%c is not yet supported\n", flag);
++argerr;
break;
}
}
if (optind < argc) {
printf("non-option ARGV-elements: ");
while (optind < argc) {
printf("%s ", argv[optind++]);
}
printf("\n");
}
if (optind > argc) {
++argerr;
}
if (argerr) {
crm_err("%d errors in option parsing", argerr);
crm_help('?', 1);
}
if(USE_LIVE_CIB) {
int rc = cib_ok;
source = "live cib";
cib_conn = cib_new();
rc = cib_conn->cmds->signon(cib_conn, "ptest", cib_command);
if(rc == cib_ok) {
crm_info("Reading XML from: live cluster");
cib_object = get_cib_copy(cib_conn);
} else {
fprintf(stderr, "Live CIB query failed: %s\n",
cib_error2string(rc));
return 3;
}
if(cib_object == NULL) {
fprintf(stderr, "Live CIB query failed: empty result\n");
return 3;
}
} else if(xml_file != NULL) {
source = xml_file;
cib_object = filename2xml(xml_file);
} else if(use_stdin) {
source = "stdin";
cib_object = filename2xml(NULL);
}
if(cib_object == NULL && source) {
fprintf(stderr, "Could not parse configuration input from: %s\n", source);
return 4;
} else if(cib_object == NULL) {
fprintf(stderr, "Not configuration specified\n");
crm_help('?', 1);
}
if(cli_config_update(&cib_object, NULL) == FALSE) {
free_xml(cib_object);
return cib_STALE;
}
if(validate_xml(cib_object, NULL, FALSE) != TRUE) {
free_xml(cib_object);
return cib_dtd_validation;
}
if(input_file != NULL) {
FILE *input_strm = fopen(input_file, "w");
if(input_strm == NULL) {
crm_perror(LOG_ERR,"Could not open %s for writing", input_file);
} else {
msg_buffer = dump_xml_formatted(cib_object);
if(fprintf(input_strm, "%s\n", msg_buffer) < 0) {
crm_perror(LOG_ERR,"Write to %s failed", input_file);
}
fflush(input_strm);
fclose(input_strm);
crm_free(msg_buffer);
}
}
if(use_date != NULL) {
a_date = parse_date(&use_date);
log_date(LOG_WARNING, "Set fake 'now' to",
a_date, ha_log_date|ha_log_time);
log_date(LOG_WARNING, "Set fake 'now' to (localtime)",
a_date, ha_log_date|ha_log_time|ha_log_local);
}
if(process) {
if(show_scores) {
fprintf(stdout, "Allocation scores:\n");
}
do_calculations(&data_set, cib_object, a_date);
}
msg_buffer = dump_xml_formatted(data_set.graph);
if(safe_str_eq(graph_file, "-")) {
fprintf(stdout, "%s\n", msg_buffer);
fflush(stdout);
} else if(graph_file != NULL) {
FILE *graph_strm = fopen(graph_file, "w");
if(graph_strm == NULL) {
crm_perror(LOG_ERR,"Could not open %s for writing", graph_file);
} else {
if(fprintf(graph_strm, "%s\n\n", msg_buffer) < 0) {
crm_perror(LOG_ERR,"Write to %s failed", graph_file);
}
fflush(graph_strm);
fclose(graph_strm);
}
}
crm_free(msg_buffer);
if(dot_file != NULL) {
dot_strm = fopen(dot_file, "w");
if(dot_strm == NULL) {
crm_perror(LOG_ERR,"Could not open %s for writing", dot_file);
}
}
if(dot_strm == NULL) {
goto simulate;
}
init_dotfile();
slist_iter(
action, action_t, data_set.actions, lpc,
const char *style = "filled";
const char *font = "black";
const char *color = "black";
const char *fill = NULL;
char *action_name = create_action_name(action);
crm_debug_3("Action %d: %p", action->id, action);
if(action->pseudo) {
font = "orange";
}
style = "dashed";
if(action->dumped) {
style = "bold";
color = "green";
} else if(action->rsc != NULL
&& is_not_set(action->rsc->flags, pe_rsc_managed)) {
color = "purple";
if(all_actions == FALSE) {
goto dont_write;
}
} else if(action->optional) {
color = "blue";
if(all_actions == FALSE) {
goto dont_write;
}
} else {
color = "red";
CRM_CHECK(action->runnable == FALSE, ;);
}
action->dumped = TRUE;
dot_write("\"%s\" [ style=%s color=\"%s\" fontcolor=\"%s\" %s%s]",
action_name, style, color, font, fill?"fillcolor=":"", fill?fill:"");
dont_write:
crm_free(action_name);
);
slist_iter(
action, action_t, data_set.actions, lpc,
slist_iter(
before, action_wrapper_t, action->actions_before, lpc2,
char *before_name = NULL;
char *after_name = NULL;
const char *style = "dashed";
optional = TRUE;
if(before->state == pe_link_dumped) {
optional = FALSE;
style = "bold";
} else if(action->pseudo
&& (before->type & pe_order_stonith_stop)) {
continue;
} else if(before->state == pe_link_dup) {
continue;
} else if(action->dumped && before->action->dumped) {
optional = FALSE;
}
if(all_actions || optional == FALSE) {
before_name = create_action_name(before->action);
after_name = create_action_name(action);
dot_write("\"%s\" -> \"%s\" [ style = %s]",
before_name, after_name, style);
crm_free(before_name);
crm_free(after_name);
}
);
);
dot_write("}");
if(dot_strm != NULL) {
fflush(dot_strm);
fclose(dot_strm);
}
simulate:
if(do_simulation == FALSE) {
goto cleanup;
}
transition = unpack_graph(data_set.graph, "ptest");
transition->batch_limit = 0;
print_graph(LOG_DEBUG, transition);
do {
graph_rc = run_graph(transition);
} while(graph_rc == transition_active);
if(graph_rc != transition_complete) {
crm_crit("Transition failed: %s", transition_status(graph_rc));
print_graph(LOG_ERR, transition);
}
destroy_graph(transition);
CRM_CHECK(graph_rc == transition_complete, all_good = FALSE; crm_err("An invalid transition was produced"));
cleanup:
cleanup_alloc_calculations(&data_set);
crm_log_deinit();
/* required for MallocDebug.app */
if(inhibit_exit) {
GMainLoop* mainloop = g_main_new(FALSE);
g_main_run(mainloop);
}
if(all_good) {
return 0;
}
return 5;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Apr 21, 6:07 PM (21 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1665074
Default Alt Text
(12 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment