root/lib/fencing/st_output.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. time_t_string
  2. PCMK__OUTPUT_ARGS
  3. PCMK__OUTPUT_ARGS
  4. PCMK__OUTPUT_ARGS
  5. PCMK__OUTPUT_ARGS
  6. PCMK__OUTPUT_ARGS
  7. PCMK__OUTPUT_ARGS
  8. PCMK__OUTPUT_ARGS
  9. PCMK__OUTPUT_ARGS
  10. PCMK__OUTPUT_ARGS
  11. PCMK__OUTPUT_ARGS
  12. PCMK__OUTPUT_ARGS
  13. PCMK__OUTPUT_ARGS
  14. PCMK__OUTPUT_ARGS
  15. PCMK__OUTPUT_ARGS
  16. stonith__register_messages

   1 /*
   2  * Copyright 2019-2020 the Pacemaker project contributors
   3  *
   4  * The version control history for this file may have further details.
   5  *
   6  * This source code is licensed under the GNU Lesser General Public License
   7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
   8  */
   9 
  10 #include <crm_internal.h>
  11 #include <stdarg.h>
  12 
  13 #include <crm/stonith-ng.h>
  14 #include <crm/common/iso8601.h>
  15 #include <crm/common/util.h>
  16 #include <crm/common/xml.h>
  17 #include <crm/common/output_internal.h>
  18 #include <crm/fencing/internal.h>
  19 #include <crm/pengine/internal.h>
  20 
  21 static char *
  22 time_t_string(time_t when) {
     /* [previous][next][first][last][top][bottom][index][help] */
  23     crm_time_t *crm_when = crm_time_new(NULL);
  24     char *buf = NULL;
  25 
  26     crm_time_set_timet(crm_when, &when);
  27     buf = crm_time_as_string(crm_when, crm_time_log_date | crm_time_log_timeofday | crm_time_log_with_timezone);
  28     crm_time_free(crm_when);
  29     return buf;
  30 }
  31 
  32 PCMK__OUTPUT_ARGS("failed-fencing-history", "stonith_history_t *", "GListPtr", "gboolean", "gboolean")
     /* [previous][next][first][last][top][bottom][index][help] */
  33 int
  34 stonith__failed_history(pcmk__output_t *out, va_list args) {
  35     stonith_history_t *history = va_arg(args, stonith_history_t *);
  36     GListPtr only_node = va_arg(args, GListPtr);
  37     gboolean full_history = va_arg(args, gboolean);
  38     gboolean print_spacer = va_arg(args, gboolean);
  39 
  40     int rc = pcmk_rc_no_output;
  41 
  42     for (stonith_history_t *hp = history; hp; hp = hp->next) {
  43         if (hp->state != st_failed) {
  44             continue;
  45         }
  46 
  47         if (!pcmk__str_in_list(only_node, hp->target)) {
  48             continue;
  49         }
  50 
  51         PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, "Failed Fencing Actions");
  52         out->message(out, "stonith-event", hp, full_history, stonith__later_succeeded(hp, history));
  53         out->increment_list(out);
  54     }
  55 
  56     PCMK__OUTPUT_LIST_FOOTER(out, rc);
  57     return rc;
  58 }
  59 
  60 PCMK__OUTPUT_ARGS("fencing-history", "stonith_history_t *", "GListPtr", "gboolean", "gboolean")
     /* [previous][next][first][last][top][bottom][index][help] */
  61 int
  62 stonith__history(pcmk__output_t *out, va_list args) {
  63     stonith_history_t *history = va_arg(args, stonith_history_t *);
  64     GListPtr only_node = va_arg(args, GListPtr);
  65     gboolean full_history = va_arg(args, gboolean);
  66     gboolean print_spacer = va_arg(args, gboolean);
  67 
  68     int rc = pcmk_rc_no_output;
  69 
  70     for (stonith_history_t *hp = history; hp; hp = hp->next) {
  71         if (!pcmk__str_in_list(only_node, hp->target)) {
  72             continue;
  73         }
  74 
  75         if (hp->state != st_failed) {
  76             PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, "Fencing History");
  77             out->message(out, "stonith-event", hp, full_history, stonith__later_succeeded(hp, history));
  78             out->increment_list(out);
  79         }
  80     }
  81 
  82     PCMK__OUTPUT_LIST_FOOTER(out, rc);
  83     return rc;
  84 }
  85 
  86 PCMK__OUTPUT_ARGS("full-fencing-history", "crm_exit_t", "stonith_history_t *", "GListPtr", "gboolean", "gboolean")
     /* [previous][next][first][last][top][bottom][index][help] */
  87 int
  88 stonith__full_history(pcmk__output_t *out, va_list args) {
  89     crm_exit_t history_rc G_GNUC_UNUSED = va_arg(args, crm_exit_t);
  90     stonith_history_t *history = va_arg(args, stonith_history_t *);
  91     GListPtr only_node = va_arg(args, GListPtr);
  92     gboolean full_history = va_arg(args, gboolean);
  93     gboolean print_spacer = va_arg(args, gboolean);
  94 
  95     int rc = pcmk_rc_no_output;
  96 
  97     for (stonith_history_t *hp = history; hp; hp = hp->next) {
  98         if (!pcmk__str_in_list(only_node, hp->target)) {
  99             continue;
 100         }
 101 
 102         PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, "Fencing History");
 103         out->message(out, "stonith-event", hp, full_history, stonith__later_succeeded(hp, history));
 104         out->increment_list(out);
 105     }
 106 
 107     PCMK__OUTPUT_LIST_FOOTER(out, rc);
 108     return rc;
 109 }
 110  
 111 PCMK__OUTPUT_ARGS("full-fencing-history", "crm_exit_t", "stonith_history_t *", "GListPtr", "gboolean", "gboolean")
     /* [previous][next][first][last][top][bottom][index][help] */
 112 int
 113 stonith__full_history_xml(pcmk__output_t *out, va_list args) {
 114     crm_exit_t history_rc = va_arg(args, crm_exit_t);
 115     stonith_history_t *history = va_arg(args, stonith_history_t *);
 116     GListPtr only_node = va_arg(args, GListPtr);
 117     gboolean full_history = va_arg(args, gboolean);
 118     gboolean print_spacer G_GNUC_UNUSED = va_arg(args, gboolean);
 119 
 120     int rc = pcmk_rc_no_output;
 121 
 122     if (history_rc == 0) {
 123         for (stonith_history_t *hp = history; hp; hp = hp->next) {
 124             if (!pcmk__str_in_list(only_node, hp->target)) {
 125                 continue;
 126             }
 127 
 128             PCMK__OUTPUT_LIST_HEADER(out, FALSE, rc, "Fencing History");
 129             out->message(out, "stonith-event", hp, full_history, stonith__later_succeeded(hp, history));
 130             out->increment_list(out);
 131         }
 132 
 133         PCMK__OUTPUT_LIST_FOOTER(out, rc);
 134     } else {
 135         xmlNodePtr node = pcmk__output_create_xml_node(out, "fence_history");
 136         char *rc_s = crm_itoa(history_rc);
 137 
 138         xmlSetProp(node, (pcmkXmlStr) "status", (pcmkXmlStr) rc_s);
 139         free(rc_s);
 140 
 141         rc = pcmk_rc_ok;
 142     }
 143 
 144     return rc;
 145 }
 146 
 147 PCMK__OUTPUT_ARGS("last-fenced", "const char *", "time_t")
     /* [previous][next][first][last][top][bottom][index][help] */
 148 int
 149 stonith__last_fenced_html(pcmk__output_t *out, va_list args) {
 150     const char *target = va_arg(args, const char *);
 151     time_t when = va_arg(args, time_t);
 152 
 153     if (when) {
 154         char *buf = crm_strdup_printf("Node %s last fenced at: %s", target, ctime(&when));
 155         pcmk__output_create_html_node(out, "div", NULL, NULL, buf);
 156         free(buf);
 157         return pcmk_rc_ok;
 158     } else {
 159         return pcmk_rc_no_output;
 160     }
 161 }
 162 
 163 PCMK__OUTPUT_ARGS("last-fenced", "const char *", "time_t")
     /* [previous][next][first][last][top][bottom][index][help] */
 164 int
 165 stonith__last_fenced_text(pcmk__output_t *out, va_list args) {
 166     const char *target = va_arg(args, const char *);
 167     time_t when = va_arg(args, time_t);
 168 
 169     if (when) {
 170         pcmk__indented_printf(out, "Node %s last fenced at: %s", target, ctime(&when));
 171     } else {
 172         pcmk__indented_printf(out, "Node %s has never been fenced\n", target);
 173     }
 174 
 175     return pcmk_rc_ok;
 176 }
 177 
 178 PCMK__OUTPUT_ARGS("last-fenced", "const char *", "time_t")
     /* [previous][next][first][last][top][bottom][index][help] */
 179 int
 180 stonith__last_fenced_xml(pcmk__output_t *out, va_list args) {
 181     const char *target = va_arg(args, const char *);
 182     time_t when = va_arg(args, time_t);
 183 
 184     if (when) {
 185         xmlNodePtr node = pcmk__output_create_xml_node(out, "last-fenced");
 186         char *buf = time_t_string(when);
 187 
 188         xmlSetProp(node, (pcmkXmlStr) "target", (pcmkXmlStr) target);
 189         xmlSetProp(node, (pcmkXmlStr) "when", (pcmkXmlStr) buf);
 190 
 191         free(buf);
 192         return pcmk_rc_ok;
 193     } else {
 194         return pcmk_rc_no_output;
 195     }
 196 }
 197 
 198 PCMK__OUTPUT_ARGS("pending-fencing-actions", "stonith_history_t *", "GListPtr", "gboolean", "gboolean")
     /* [previous][next][first][last][top][bottom][index][help] */
 199 int
 200 stonith__pending_actions(pcmk__output_t *out, va_list args) {
 201     stonith_history_t *history = va_arg(args, stonith_history_t *);
 202     GListPtr only_node = va_arg(args, GListPtr);
 203     gboolean full_history = va_arg(args, gboolean);
 204     gboolean print_spacer = va_arg(args, gboolean);
 205 
 206     int rc = pcmk_rc_no_output;
 207 
 208     for (stonith_history_t *hp = history; hp; hp = hp->next) {
 209         if (!pcmk__str_in_list(only_node, hp->target)) {
 210             continue;
 211         }
 212 
 213         /* Skip the rest of the history after we see a failed/done action */
 214         if ((hp->state == st_failed) || (hp->state == st_done)) {
 215             break;
 216         }
 217 
 218         PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, "Pending Fencing Actions");
 219         out->message(out, "stonith-event", hp, full_history, stonith__later_succeeded(hp, history));
 220         out->increment_list(out);
 221     }
 222 
 223     PCMK__OUTPUT_LIST_FOOTER(out, rc);
 224     return rc;
 225 }
 226 
 227 PCMK__OUTPUT_ARGS("stonith-event", "stonith_history_t *", "gboolean", "gboolean")
     /* [previous][next][first][last][top][bottom][index][help] */
 228 int
 229 stonith__event_html(pcmk__output_t *out, va_list args) {
 230     stonith_history_t *event = va_arg(args, stonith_history_t *);
 231     gboolean full_history = va_arg(args, gboolean);
 232     gboolean later_succeeded = va_arg(args, gboolean);
 233 
 234     switch(event->state) {
 235         case st_done: {
 236             char *completed_s = time_t_string(event->completed);
 237 
 238             out->list_item(out, "successful-stonith-event",
 239                            "%s of %s successful: delegate=%s, client=%s, origin=%s, %s='%s'",
 240                            stonith_action_str(event->action), event->target,
 241                            event->delegate ? event->delegate : "",
 242                            event->client, event->origin,
 243                            full_history ? "completed" : "last-successful",
 244                            completed_s);
 245             free(completed_s);
 246             break;
 247         }
 248 
 249         case st_failed: {
 250             char *failed_s = time_t_string(event->completed);
 251 
 252             out->list_item(out, "failed-stonith-event",
 253                            "%s of %s failed : delegate=%s, client=%s, origin=%s, %s='%s' %s",
 254                            stonith_action_str(event->action), event->target,
 255                            event->delegate ? event->delegate : "",
 256                            event->client, event->origin,
 257                            full_history ? "completed" : "last-failed",
 258                            failed_s,
 259                            later_succeeded ? "(a later attempt succeeded)" : "");
 260             free(failed_s);
 261             break;
 262         }
 263 
 264         default:
 265             out->list_item(out, "pending-stonith-event",
 266                            "%s of %s pending: client=%s, origin=%s",
 267                            stonith_action_str(event->action), event->target,
 268                            event->client, event->origin);
 269             break;
 270     }
 271 
 272     return pcmk_rc_ok;
 273 }
 274 
 275 PCMK__OUTPUT_ARGS("stonith-event", "stonith_history_t *", "gboolean", "gboolean")
     /* [previous][next][first][last][top][bottom][index][help] */
 276 int
 277 stonith__event_text(pcmk__output_t *out, va_list args) {
 278     stonith_history_t *event = va_arg(args, stonith_history_t *);
 279     gboolean full_history = va_arg(args, gboolean);
 280     gboolean later_succeeded = va_arg(args, gboolean);
 281 
 282     char *buf = time_t_string(event->completed);
 283 
 284     switch (event->state) {
 285         case st_failed:
 286             pcmk__indented_printf(out, "%s of %s failed: delegate=%s, client=%s, origin=%s, %s='%s' %s\n",
 287                                   stonith_action_str(event->action), event->target,
 288                                   event->delegate ? event->delegate : "",
 289                                   event->client, event->origin,
 290                                   full_history ? "completed" : "last-failed", buf,
 291                                   later_succeeded ? "(a later attempt succeeded)" : "");
 292             break;
 293 
 294         case st_done:
 295             pcmk__indented_printf(out, "%s of %s successful: delegate=%s, client=%s, origin=%s, %s='%s'\n",
 296                                   stonith_action_str(event->action), event->target,
 297                                   event->delegate ? event->delegate : "",
 298                                   event->client, event->origin,
 299                                   full_history ? "completed" : "last-successful", buf);
 300             break;
 301 
 302         default:
 303             pcmk__indented_printf(out, "%s of %s pending: client=%s, origin=%s\n",
 304                                   stonith_action_str(event->action), event->target,
 305                                   event->client, event->origin);
 306             break;
 307     }
 308 
 309     free(buf);
 310     return pcmk_rc_ok;
 311 }
 312 
 313 PCMK__OUTPUT_ARGS("stonith-event", "stonith_history_t *", "gboolean", "gboolean")
     /* [previous][next][first][last][top][bottom][index][help] */
 314 int
 315 stonith__event_xml(pcmk__output_t *out, va_list args) {
 316     xmlNodePtr node = pcmk__output_create_xml_node(out, "fence_event");
 317     stonith_history_t *event = va_arg(args, stonith_history_t *);
 318     gboolean full_history G_GNUC_UNUSED = va_arg(args, gboolean);
 319     gboolean later_succeeded G_GNUC_UNUSED = va_arg(args, gboolean);
 320 
 321     char *buf = NULL;
 322 
 323     switch (event->state) {
 324         case st_failed:
 325             xmlSetProp(node, (pcmkXmlStr) "status", (pcmkXmlStr) "failed");
 326             break;
 327 
 328         case st_done:
 329             xmlSetProp(node, (pcmkXmlStr) "status", (pcmkXmlStr) "success");
 330             break;
 331 
 332         default: {
 333             char *state = crm_itoa(event->state);
 334             xmlSetProp(node, (pcmkXmlStr) "status", (pcmkXmlStr) "pending");
 335             xmlSetProp(node, (pcmkXmlStr) "extended-status", (pcmkXmlStr) state);
 336             free(state);
 337             break;
 338         }
 339     }
 340 
 341     if (event->delegate != NULL) {
 342         xmlSetProp(node, (pcmkXmlStr) "delegate", (pcmkXmlStr) event->delegate);
 343     }
 344 
 345     xmlSetProp(node, (pcmkXmlStr) "action", (pcmkXmlStr) event->action);
 346     xmlSetProp(node, (pcmkXmlStr) "target", (pcmkXmlStr) event->target);
 347     xmlSetProp(node, (pcmkXmlStr) "client", (pcmkXmlStr) event->client);
 348     xmlSetProp(node, (pcmkXmlStr) "origin", (pcmkXmlStr) event->origin);
 349 
 350     if (event->state == st_failed || event->state == st_done) {
 351         buf = time_t_string(event->completed);
 352         xmlSetProp(node, (pcmkXmlStr) "completed", (pcmkXmlStr) buf);
 353         free(buf);
 354     }
 355 
 356     return pcmk_rc_ok;
 357 }
 358 
 359 PCMK__OUTPUT_ARGS("validate", "const char *", "const char *", "char *", "char *", "int")
     /* [previous][next][first][last][top][bottom][index][help] */
 360 int
 361 stonith__validate_agent_html(pcmk__output_t *out, va_list args) {
 362     const char *agent = va_arg(args, const char *);
 363     const char *device = va_arg(args, const char *);
 364     char *output = va_arg(args, char *);
 365     char *error_output = va_arg(args, char *);
 366     int rc = va_arg(args, int);
 367 
 368     if (device) {
 369         char *buf = crm_strdup_printf("Validation of %s on %s %s", agent, device,
 370                                       rc ? "failed" : "succeeded");
 371         pcmk__output_create_html_node(out, "div", NULL, NULL, buf);
 372         free(buf);
 373     } else {
 374         char *buf = crm_strdup_printf("Validation of %s %s", agent,
 375                                       rc ? "failed" : "succeeded");
 376         pcmk__output_create_html_node(out, "div", NULL, NULL, buf);
 377         free(buf);
 378     }
 379 
 380     out->subprocess_output(out, rc, output, error_output);
 381     return rc;
 382 }
 383 
 384 PCMK__OUTPUT_ARGS("validate", "const char *", "const char *", "char *", "char *", "int")
     /* [previous][next][first][last][top][bottom][index][help] */
 385 int
 386 stonith__validate_agent_text(pcmk__output_t *out, va_list args) {
 387     const char *agent = va_arg(args, const char *);
 388     const char *device = va_arg(args, const char *);
 389     char *output = va_arg(args, char *);
 390     char *error_output = va_arg(args, char *);
 391     int rc = va_arg(args, int);
 392 
 393     if (device) {
 394         pcmk__indented_printf(out, "Validation of %s on %s %s\n", agent, device,
 395                               rc ? "failed" : "succeeded");
 396     } else {
 397         pcmk__indented_printf(out, "Validation of %s %s\n", agent,
 398                               rc ? "failed" : "succeeded");
 399     }
 400 
 401     if (output) {
 402         puts(output);
 403     }
 404 
 405     if (error_output) {
 406         puts(error_output);
 407     }
 408 
 409     return rc;
 410 }
 411 
 412 PCMK__OUTPUT_ARGS("validate", "const char *", "const char *", "char *", "char *", "int")
     /* [previous][next][first][last][top][bottom][index][help] */
 413 int
 414 stonith__validate_agent_xml(pcmk__output_t *out, va_list args) {
 415     xmlNodePtr node = pcmk__output_create_xml_node(out, "validate");
 416 
 417     const char *agent = va_arg(args, const char *);
 418     const char *device = va_arg(args, const char *);
 419     char *output = va_arg(args, char *);
 420     char *error_output = va_arg(args, char *);
 421     int rc = va_arg(args, int);
 422 
 423     xmlSetProp(node, (pcmkXmlStr) "agent", (pcmkXmlStr) agent);
 424     if (device != NULL) {
 425         xmlSetProp(node, (pcmkXmlStr) "device", (pcmkXmlStr) device);
 426     }
 427     xmlSetProp(node, (pcmkXmlStr) "valid", (pcmkXmlStr) pcmk__btoa(rc));
 428 
 429     pcmk__output_xml_push_parent(out, node);
 430     out->subprocess_output(out, rc, output, error_output);
 431     pcmk__output_xml_pop_parent(out);
 432 
 433     return rc;
 434 }
 435 
 436 static pcmk__message_entry_t fmt_functions[] = {
 437     { "failed-fencing-history", "default", stonith__failed_history },
 438     { "fencing-history", "default", stonith__history },
 439     { "full-fencing-history", "default", stonith__full_history },
 440     { "full-fencing-history", "xml", stonith__full_history_xml },
 441     { "last-fenced", "html", stonith__last_fenced_html },
 442     { "last-fenced", "log", stonith__last_fenced_text },
 443     { "last-fenced", "text", stonith__last_fenced_text },
 444     { "last-fenced", "xml", stonith__last_fenced_xml },
 445     { "pending-fencing-actions", "default", stonith__pending_actions },
 446     { "stonith-event", "html", stonith__event_html },
 447     { "stonith-event", "log", stonith__event_text },
 448     { "stonith-event", "text", stonith__event_text },
 449     { "stonith-event", "xml", stonith__event_xml },
 450     { "validate", "html", stonith__validate_agent_html },
 451     { "validate", "log", stonith__validate_agent_text },
 452     { "validate", "text", stonith__validate_agent_text },
 453     { "validate", "xml", stonith__validate_agent_xml },
 454 
 455     { NULL, NULL, NULL }
 456 };
 457 
 458 void
 459 stonith__register_messages(pcmk__output_t *out) {
     /* [previous][next][first][last][top][bottom][index][help] */
 460     pcmk__register_messages(out, fmt_functions);
 461 }

/* [previous][next][first][last][top][bottom][index][help] */