Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/tools/crm_mon.h b/tools/crm_mon.h
index 6e5b179638..0ebc3a1e20 100644
--- a/tools/crm_mon.h
+++ b/tools/crm_mon.h
@@ -1,130 +1,131 @@
/*
* Copyright 2019 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under the GNU General Public License version 2
* or later (GPLv2+) WITHOUT ANY WARRANTY.
*/
#include <glib.h>
#include <crm/common/output.h>
#include <crm/common/curses_internal.h>
#include <crm/pengine/pe_types.h>
#include <crm/stonith-ng.h>
/* Never display node attributes whose name starts with one of these prefixes */
#define FILTER_STR { CRM_FAIL_COUNT_PREFIX, CRM_LAST_FAILURE_PREFIX, \
"shutdown", "terminate", "standby", "probe_complete", \
"#", NULL }
/* Convenience macro for prettifying output (e.g. "node" vs "nodes") */
#define s_if_plural(i) (((i) == 1)? "" : "s")
#if CURSES_ENABLED
# define print_dot(output_format) if (output_format == mon_output_console) { \
printw("."); \
clrtoeol(); \
refresh(); \
} else { \
fprintf(stdout, "."); \
}
#else
# define print_dot(output_format) fprintf(stdout, ".");
#endif
#if CURSES_ENABLED
# define print_as(output_format, fmt, args...) if (output_format == mon_output_console) { \
printw(fmt, ##args); \
clrtoeol(); \
refresh(); \
} else { \
fprintf(stdout, fmt, ##args); \
}
#else
# define print_as(output_format, fmt, args...) fprintf(stdout, fmt, ##args);
#endif
typedef enum mon_output_format_e {
mon_output_unset,
mon_output_none,
mon_output_monitor,
mon_output_plain,
mon_output_console,
mon_output_xml,
mon_output_legacy_xml,
mon_output_html,
mon_output_cgi
} mon_output_format_t;
#define mon_show_times (0x0001U)
#define mon_show_stack (0x0002U)
#define mon_show_dc (0x0004U)
#define mon_show_count (0x0008U)
#define mon_show_nodes (0x0010U)
#define mon_show_resources (0x0020U)
#define mon_show_attributes (0x0040U)
#define mon_show_failcounts (0x0080U)
#define mon_show_operations (0x0100U)
#define mon_show_tickets (0x0200U)
#define mon_show_bans (0x0400U)
#define mon_show_fence_history (0x0800U)
#define mon_show_headers (mon_show_times | mon_show_stack | mon_show_dc \
| mon_show_count)
#define mon_show_default (mon_show_headers | mon_show_nodes \
| mon_show_resources)
#define mon_show_all (mon_show_default | mon_show_attributes \
| mon_show_failcounts | mon_show_operations \
| mon_show_tickets | mon_show_bans \
| mon_show_fence_history)
#define mon_op_group_by_node (0x0001U)
#define mon_op_inactive_resources (0x0002U)
#define mon_op_one_shot (0x0004U)
#define mon_op_has_warnings (0x0008U)
#define mon_op_print_timing (0x0010U)
#define mon_op_watch_fencing (0x0020U)
#define mon_op_fence_history (0x0040U)
#define mon_op_fence_full_history (0x0080U)
#define mon_op_fence_connect (0x0100U)
#define mon_op_print_brief (0x0200U)
#define mon_op_print_pending (0x0400U)
#define mon_op_print_clone_detail (0x0800U)
#define mon_op_default (mon_op_print_pending)
typedef struct {
FILE *stream;
mon_output_format_t output_format;
pcmk__output_t *out;
} mon_state_t;
void print_status(mon_state_t *state, pe_working_set_t *data_set,
stonith_history_t *stonith_history, unsigned int mon_ops,
unsigned int show, const char *prefix);
void print_xml_status(mon_state_t *state, pe_working_set_t *data_set,
stonith_history_t *stonith_history, unsigned int mon_ops,
unsigned int show, const char *prefix);
int print_html_status(mon_state_t *state, pe_working_set_t *data_set,
const char *filename, stonith_history_t *stonith_history,
unsigned int mon_ops, unsigned int show, const char *prefix,
unsigned int reconnect_msec);
GList *append_attr_list(GList *attr_list, char *name);
void blank_screen(void);
int count_resources(pe_working_set_t *data_set, resource_t *rsc);
void crm_mon_get_parameters(resource_t *rsc, pe_working_set_t *data_set);
const char *get_cluster_stack(pe_working_set_t *data_set);
char *get_node_display_name(node_t *node, unsigned int mon_ops);
int get_resource_display_options(unsigned int mon_ops,
mon_output_format_t output_format);
pcmk__output_t *crm_mon_mk_curses_output(char **argv);
void curses_indented_printf(pcmk__output_t *out, const char *format, ...) G_GNUC_PRINTF(2, 3);
+void curses_indented_vprintf(pcmk__output_t *out, const char *format, va_list args) G_GNUC_PRINTF(2, 0);
#if CURSES_ENABLED
extern GOptionEntry crm_mon_curses_output_entries[];
#define CRM_MON_SUPPORTED_FORMAT_CURSES { "console", crm_mon_mk_curses_output, crm_mon_curses_output_entries }
#endif
diff --git a/tools/crm_mon_curses.c b/tools/crm_mon_curses.c
index 7186afde41..7b69c8ad2d 100644
--- a/tools/crm_mon_curses.c
+++ b/tools/crm_mon_curses.c
@@ -1,260 +1,272 @@
/*
* Copyright 2019 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under the GNU Lesser General Public License
* version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
*/
#include <stdlib.h>
#include <crm/crm.h>
#include <crm/common/curses_internal.h>
#include <crm/common/output.h>
#include <glib.h>
#include "crm_mon.h"
#if CURSES_ENABLED
GOptionEntry crm_mon_curses_output_entries[] = {
{ NULL }
};
typedef struct curses_list_data_s {
unsigned int len;
char *singular_noun;
char *plural_noun;
} curses_list_data_t;
typedef struct private_data_s {
GQueue *parent_q;
} private_data_t;
static void
curses_free_priv(pcmk__output_t *out) {
private_data_t *priv = out->priv;
if (priv == NULL) {
return;
}
g_queue_free(priv->parent_q);
free(priv);
}
static bool
curses_init(pcmk__output_t *out) {
private_data_t *priv = NULL;
/* If curses_init was previously called on this output struct, just return. */
if (out->priv != NULL) {
return true;
} else {
out->priv = calloc(1, sizeof(private_data_t));
if (out->priv == NULL) {
return false;
}
priv = out->priv;
}
priv->parent_q = g_queue_new();
return true;
}
static void
curses_finish(pcmk__output_t *out, crm_exit_t exit_status, bool print, void **copy_dest) {
}
static void
curses_reset(pcmk__output_t *out) {
CRM_ASSERT(out->priv != NULL);
curses_free_priv(out);
curses_init(out);
}
static void
curses_subprocess_output(pcmk__output_t *out, int exit_status,
const char *proc_stdout, const char *proc_stderr) {
if (proc_stdout != NULL) {
printw("%s\n", proc_stdout);
}
if (proc_stderr != NULL) {
printw("%s\n", proc_stderr);
}
clrtoeol();
refresh();
}
/* curses_version is defined in curses.h, so we can't use that name here.
* Note that this function prints out via text, not with curses.
*/
static void
curses_ver(pcmk__output_t *out, bool extended) {
if (extended) {
printf("Pacemaker %s (Build: %s): %s\n", PACEMAKER_VERSION, BUILD_VERSION, CRM_FEATURES);
} else {
printf("Pacemaker %s\n", PACEMAKER_VERSION);
printf("Written by Andrew Beekhof\n");
}
}
G_GNUC_PRINTF(2, 3)
static void
curses_err_info(pcmk__output_t *out, const char *format, ...) {
va_list ap;
/* Informational output does not get indented, to separate it from other
* potentially indented list output.
*/
va_start(ap, format);
vw_printw(stdscr, format, ap);
va_end(ap);
/* Add a newline. */
addch('\n');
clrtoeol();
refresh();
}
static void
curses_output_xml(pcmk__output_t *out, const char *name, const char *buf) {
private_data_t *priv = out->priv;
CRM_ASSERT(priv != NULL);
curses_indented_printf(out, "%s", buf);
}
static void
curses_begin_list(pcmk__output_t *out, const char *name, const char *singular_noun,
const char *plural_noun) {
private_data_t *priv = out->priv;
curses_list_data_t *new_list = NULL;
CRM_ASSERT(priv != NULL);
curses_indented_printf(out, "%s:\n", name);
new_list = calloc(1, sizeof(curses_list_data_t));
new_list->len = 0;
new_list->singular_noun = singular_noun == NULL ? NULL : strdup(singular_noun);
new_list->plural_noun = plural_noun == NULL ? NULL : strdup(plural_noun);
g_queue_push_tail(priv->parent_q, new_list);
}
static void
curses_list_item(pcmk__output_t *out, const char *id, const char *content) {
private_data_t *priv = out->priv;
CRM_ASSERT(priv != NULL);
if (id != NULL) {
curses_indented_printf(out, "%s: %s\n", id, content);
} else {
curses_indented_printf(out, "%s\n", content);
}
((curses_list_data_t *) g_queue_peek_tail(priv->parent_q))->len++;
}
static void
curses_end_list(pcmk__output_t *out) {
private_data_t *priv = out->priv;
curses_list_data_t *node = NULL;
CRM_ASSERT(priv != NULL);
node = g_queue_pop_tail(priv->parent_q);
if (node->singular_noun != NULL && node->plural_noun != NULL) {
if (node->len == 1) {
curses_indented_printf(out, "%d %s found\n", node->len, node->singular_noun);
} else {
curses_indented_printf(out, "%d %s found\n", node->len, node->plural_noun);
}
}
free(node);
}
pcmk__output_t *
crm_mon_mk_curses_output(char **argv) {
pcmk__output_t *retval = calloc(1, sizeof(pcmk__output_t));
if (retval == NULL) {
return NULL;
}
retval->fmt_name = "console";
retval->request = g_strjoinv(" ", argv);
retval->supports_quiet = true;
retval->init = curses_init;
retval->free_priv = curses_free_priv;
retval->finish = curses_finish;
retval->reset = curses_reset;
retval->register_message = pcmk__register_message;
retval->message = pcmk__call_message;
retval->subprocess_output = curses_subprocess_output;
retval->version = curses_ver;
retval->err = curses_err_info;
retval->info = curses_err_info;
retval->output_xml = curses_output_xml;
retval->begin_list = curses_begin_list;
retval->list_item = curses_list_item;
retval->end_list = curses_end_list;
return retval;
}
-G_GNUC_PRINTF(2, 3)
+G_GNUC_PRINTF(2, 0)
void
-curses_indented_printf(pcmk__output_t *out, const char *format, ...) {
- va_list ap;
+curses_indented_vprintf(pcmk__output_t *out, const char *format, va_list args) {
int level = 0;
private_data_t *priv = out->priv;
CRM_ASSERT(priv != NULL);
level = g_queue_get_length(priv->parent_q);
for (int i = 0; i < level; i++) {
addch('\t');
}
if (level > 0) {
printw("* ");
}
- va_start(ap, format);
- vw_printw(stdscr, format, ap);
- va_end(ap);
+ vw_printw(stdscr, format, args);
clrtoeol();
refresh();
}
+G_GNUC_PRINTF(2, 3)
+void
+curses_indented_printf(pcmk__output_t *out, const char *format, ...) {
+ va_list ap;
+
+ va_start(ap, format);
+ curses_indented_vprintf(out, format, ap);
+ va_end(ap);
+}
#else
pcmk__output_t *
crm_mon_mk_curses_output(char **argv) {
/* curses was disabled in the build, so fall back to text. */
return pcmk__mk_text_output(argv);
}
+G_GNUC_PRINTF(2, 0)
+void
+curses_indented_vprintf(pcmk__output_t *out, const char *format, va_list args) {
+ return;
+}
+
G_GNUC_PRINTF(2, 3)
void
-curses_indented_printf(pcmk__output_t *out, const char *format, ...) {
+curses_indented_printf(pcmk__output_t *out, const char *format, va_list args) {
return;
}
#endif

File Metadata

Mime Type
text/x-diff
Expires
Thu, Oct 16, 12:19 AM (1 d, 20 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2530801
Default Alt Text
(12 KB)

Event Timeline