root/lib/fencing/st_output.c

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

DEFINITIONS

This source file includes following definitions.
  1. timespec_string
  2. state_str
  3. stonith__history_description
  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. PCMK__OUTPUT_ARGS
  17. PCMK__OUTPUT_ARGS
  18. stonith__register_messages

   1 /*
   2  * Copyright 2019-2022 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 #include <stdint.h>
  13 
  14 #include <crm/stonith-ng.h>
  15 #include <crm/msg_xml.h>
  16 #include <crm/common/iso8601.h>
  17 #include <crm/common/util.h>
  18 #include <crm/common/xml.h>
  19 #include <crm/common/output.h>
  20 #include <crm/common/output_internal.h>
  21 #include <crm/common/xml_internal.h>
  22 #include <crm/fencing/internal.h>
  23 #include <crm/pengine/internal.h>
  24 
  25 /*!
  26  * \internal
  27  * \brief Convert seconds and nanoseconds to a date/time/time-zone string
  28  *
  29  * \param[in] sec        Seconds
  30  * \param[in] nsec       Nanoseconds
  31  * \param[in] show_usec  Whether to show time in microseconds resolution (if
  32  *                       false, use seconds resolution)
  33  *
  34  * \return A string representation of \p sec and \nsec
  35  *
  36  * \note The caller is responsible for freeing the return value using \p free().
  37  */
  38 static char *
  39 timespec_string(time_t sec, long nsec, bool show_usec) {
     /* [previous][next][first][last][top][bottom][index][help] */
  40     const struct timespec ts = {
  41         .tv_sec = sec,
  42         .tv_nsec = nsec,
  43     };
  44 
  45     return pcmk__timespec2str(&ts,
  46                               crm_time_log_date
  47                               |crm_time_log_timeofday
  48                               |crm_time_log_with_timezone
  49                               |(show_usec? crm_time_usecs : 0));
  50 }
  51 
  52 /*!
  53  * \internal
  54  * \brief Return a status-friendly description of fence history entry state
  55  *
  56  * \param[in] history  Fence history entry to describe
  57  *
  58  * \return One-word description of history entry state
  59  * \note This is similar to stonith_op_state_str() except user-oriented (i.e.
  60  *       for cluster status) instead of developer-oriented (for debug logs).
  61  */
  62 static const char *
  63 state_str(const stonith_history_t *history)
     /* [previous][next][first][last][top][bottom][index][help] */
  64 {
  65     switch (history->state) {
  66         case st_failed: return "failed";
  67         case st_done:   return "successful";
  68         default:        return "pending";
  69     }
  70 }
  71 
  72 /*!
  73  * \internal
  74  * \brief Create a description of a fencing history entry for status displays
  75  *
  76  * \param[in] history          Fencing history entry to describe
  77  * \param[in] full_history     Whether this is for full or condensed history
  78  * \param[in] later_succeeded  Node that a later equivalent attempt succeeded
  79  *                             from, or NULL if none
  80  * \param[in] show_opts        Flag group of pcmk_show_opt_e
  81  *
  82  * \return Newly created string with fencing history entry description
  83  *
  84  * \note The caller is responsible for freeing the return value with g_free().
  85  * \note This is similar to stonith__event_description(), except this is used
  86  *       for history entries (stonith_history_t) in status displays rather than
  87  *       event notifications (stonith_event_t) in log messages.
  88  */
  89 gchar *
  90 stonith__history_description(const stonith_history_t *history,
     /* [previous][next][first][last][top][bottom][index][help] */
  91                              bool full_history, const char *later_succeeded,
  92                              uint32_t show_opts)
  93 {
  94     GString *str = g_string_sized_new(256); // Generous starting size
  95     char *completed_time_s = NULL;
  96 
  97     if ((history->state == st_failed) || (history->state == st_done)) {
  98         completed_time_s = timespec_string(history->completed,
  99                                            history->completed_nsec, true);
 100     }
 101 
 102     pcmk__g_strcat(str,
 103                    stonith_action_str(history->action), " of ", history->target,
 104                    NULL);
 105 
 106     if (!pcmk_is_set(show_opts, pcmk_show_failed_detail)) {
 107         // More human-friendly
 108         if (((history->state == st_failed) || (history->state == st_done))
 109             && (history->delegate != NULL)) {
 110 
 111             pcmk__g_strcat(str, " by ", history->delegate, NULL);
 112         }
 113         pcmk__g_strcat(str, " for ", history->client, "@", history->origin,
 114                        NULL);
 115         if (!full_history) {
 116             g_string_append(str, " last"); // For example, "last failed at ..."
 117         }
 118     }
 119 
 120     pcmk__add_word(&str, 0, state_str(history));
 121 
 122     // For failed actions, add exit reason if available
 123     if ((history->state == st_failed) && (history->exit_reason != NULL)) {
 124         pcmk__g_strcat(str, " (", history->exit_reason, ")", NULL);
 125     }
 126 
 127     if (pcmk_is_set(show_opts, pcmk_show_failed_detail)) {
 128         // More technical
 129         g_string_append(str, ": ");
 130 
 131         // For completed actions, add delegate if available
 132         if (((history->state == st_failed) || (history->state == st_done))
 133             && (history->delegate != NULL)) {
 134 
 135             pcmk__g_strcat(str, "delegate=", history->delegate, ", ", NULL);
 136         }
 137 
 138         // Add information about originator
 139         pcmk__g_strcat(str,
 140                        "client=", history->client, ", origin=", history->origin,
 141                        NULL);
 142 
 143         // For completed actions, add completion time
 144         if (completed_time_s != NULL) {
 145             if (full_history) {
 146                 g_string_append(str, ", completed");
 147             } else if (history->state == st_failed) {
 148                 g_string_append(str, ", last-failed");
 149             } else {
 150                 g_string_append(str, ", last-successful");
 151             }
 152             pcmk__g_strcat(str, "='", completed_time_s, "'", NULL);
 153         }
 154     } else if (completed_time_s != NULL) {
 155         // More human-friendly
 156         pcmk__g_strcat(str, " at ", completed_time_s, NULL);
 157     }
 158 
 159     if ((history->state == st_failed) && (later_succeeded != NULL)) {
 160         pcmk__g_strcat(str,
 161                        " (a later attempt from ", later_succeeded,
 162                        " succeeded)", NULL);
 163     }
 164 
 165     free(completed_time_s);
 166     return g_string_free(str, FALSE);
 167 }
 168 
 169 PCMK__OUTPUT_ARGS("failed-fencing-list", "stonith_history_t *", "GList *",
     /* [previous][next][first][last][top][bottom][index][help] */
 170                   "uint32_t", "uint32_t", "bool")
 171 static int
 172 failed_history(pcmk__output_t *out, va_list args)
 173 {
 174     stonith_history_t *history = va_arg(args, stonith_history_t *);
 175     GList *only_node = va_arg(args, GList *);
 176     uint32_t section_opts = va_arg(args, uint32_t);
 177     uint32_t show_opts = va_arg(args, uint32_t);
 178     bool print_spacer = va_arg(args, int);
 179 
 180     int rc = pcmk_rc_no_output;
 181 
 182     for (stonith_history_t *hp = history; hp; hp = hp->next) {
 183         if (hp->state != st_failed) {
 184             continue;
 185         }
 186 
 187         if (!pcmk__str_in_list(hp->target, only_node, pcmk__str_star_matches|pcmk__str_casei)) {
 188             continue;
 189         }
 190 
 191         PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, "Failed Fencing Actions");
 192         out->message(out, "stonith-event", hp,
 193                      pcmk_all_flags_set(section_opts, pcmk_section_fencing_all),
 194                      false, stonith__later_succeeded(hp, history), show_opts);
 195         out->increment_list(out);
 196     }
 197 
 198     PCMK__OUTPUT_LIST_FOOTER(out, rc);
 199     return rc;
 200 }
 201 
 202 PCMK__OUTPUT_ARGS("fencing-list", "stonith_history_t *", "GList *", "uint32_t",
     /* [previous][next][first][last][top][bottom][index][help] */
 203                   "uint32_t", "bool")
 204 static int
 205 stonith_history(pcmk__output_t *out, va_list args)
 206 {
 207     stonith_history_t *history = va_arg(args, stonith_history_t *);
 208     GList *only_node = va_arg(args, GList *);
 209     uint32_t section_opts = va_arg(args, uint32_t);
 210     uint32_t show_opts = va_arg(args, uint32_t);
 211     bool print_spacer = va_arg(args, int);
 212 
 213     int rc = pcmk_rc_no_output;
 214 
 215     for (stonith_history_t *hp = history; hp; hp = hp->next) {
 216         if (!pcmk__str_in_list(hp->target, only_node, pcmk__str_star_matches|pcmk__str_casei)) {
 217             continue;
 218         }
 219 
 220         if (hp->state != st_failed) {
 221             PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, "Fencing History");
 222             out->message(out, "stonith-event", hp,
 223                          pcmk_all_flags_set(section_opts,
 224                                             pcmk_section_fencing_all),
 225                          false, stonith__later_succeeded(hp, history), show_opts);
 226             out->increment_list(out);
 227         }
 228     }
 229 
 230     PCMK__OUTPUT_LIST_FOOTER(out, rc);
 231     return rc;
 232 }
 233 
 234 PCMK__OUTPUT_ARGS("full-fencing-list", "crm_exit_t", "stonith_history_t *",
     /* [previous][next][first][last][top][bottom][index][help] */
 235                   "GList *", "uint32_t", "uint32_t", "bool")
 236 static int
 237 full_history(pcmk__output_t *out, va_list args)
 238 {
 239     crm_exit_t history_rc G_GNUC_UNUSED = va_arg(args, crm_exit_t);
 240     stonith_history_t *history = va_arg(args, stonith_history_t *);
 241     GList *only_node = va_arg(args, GList *);
 242     uint32_t section_opts = va_arg(args, uint32_t);
 243     uint32_t show_opts = va_arg(args, uint32_t);
 244     bool print_spacer = va_arg(args, int);
 245 
 246     int rc = pcmk_rc_no_output;
 247 
 248     for (stonith_history_t *hp = history; hp; hp = hp->next) {
 249         if (!pcmk__str_in_list(hp->target, only_node, pcmk__str_star_matches|pcmk__str_casei)) {
 250             continue;
 251         }
 252 
 253         PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, "Fencing History");
 254         out->message(out, "stonith-event", hp,
 255                      pcmk_all_flags_set(section_opts, pcmk_section_fencing_all),
 256                      false, stonith__later_succeeded(hp, history), show_opts);
 257         out->increment_list(out);
 258     }
 259 
 260     PCMK__OUTPUT_LIST_FOOTER(out, rc);
 261     return rc;
 262 }
 263 
 264 PCMK__OUTPUT_ARGS("full-fencing-list", "crm_exit_t", "stonith_history_t *",
     /* [previous][next][first][last][top][bottom][index][help] */
 265                   "GList *", "uint32_t", "uint32_t", "bool")
 266 static int
 267 full_history_xml(pcmk__output_t *out, va_list args)
 268 {
 269     crm_exit_t history_rc = va_arg(args, crm_exit_t);
 270     stonith_history_t *history = va_arg(args, stonith_history_t *);
 271     GList *only_node = va_arg(args, GList *);
 272     uint32_t section_opts = va_arg(args, uint32_t);
 273     uint32_t show_opts = va_arg(args, uint32_t);
 274     bool print_spacer G_GNUC_UNUSED = va_arg(args, int);
 275 
 276     int rc = pcmk_rc_no_output;
 277 
 278     if (history_rc == 0) {
 279         for (stonith_history_t *hp = history; hp; hp = hp->next) {
 280             if (!pcmk__str_in_list(hp->target, only_node, pcmk__str_star_matches|pcmk__str_casei)) {
 281                 continue;
 282             }
 283 
 284             PCMK__OUTPUT_LIST_HEADER(out, false, rc, "Fencing History");
 285             out->message(out, "stonith-event", hp,
 286                          pcmk_all_flags_set(section_opts,
 287                                             pcmk_section_fencing_all),
 288                          false, stonith__later_succeeded(hp, history), show_opts);
 289             out->increment_list(out);
 290         }
 291 
 292         PCMK__OUTPUT_LIST_FOOTER(out, rc);
 293     } else {
 294         char *rc_s = pcmk__itoa(history_rc);
 295 
 296         pcmk__output_create_xml_node(out, "fence_history",
 297                                      "status", rc_s,
 298                                      NULL);
 299         free(rc_s);
 300 
 301         rc = pcmk_rc_ok;
 302     }
 303 
 304     return rc;
 305 }
 306 
 307 PCMK__OUTPUT_ARGS("last-fenced", "const char *", "time_t")
     /* [previous][next][first][last][top][bottom][index][help] */
 308 static int
 309 last_fenced_html(pcmk__output_t *out, va_list args) {
 310     const char *target = va_arg(args, const char *);
 311     time_t when = va_arg(args, time_t);
 312 
 313     if (when) {
 314         char *buf = crm_strdup_printf("Node %s last fenced at: %s", target, ctime(&when));
 315         pcmk__output_create_html_node(out, "div", NULL, NULL, buf);
 316         free(buf);
 317         return pcmk_rc_ok;
 318     } else {
 319         return pcmk_rc_no_output;
 320     }
 321 }
 322 
 323 PCMK__OUTPUT_ARGS("last-fenced", "const char *", "time_t")
     /* [previous][next][first][last][top][bottom][index][help] */
 324 static int
 325 last_fenced_text(pcmk__output_t *out, va_list args) {
 326     const char *target = va_arg(args, const char *);
 327     time_t when = va_arg(args, time_t);
 328 
 329     if (when) {
 330         pcmk__indented_printf(out, "Node %s last fenced at: %s", target, ctime(&when));
 331     } else {
 332         pcmk__indented_printf(out, "Node %s has never been fenced\n", target);
 333     }
 334 
 335     return pcmk_rc_ok;
 336 }
 337 
 338 PCMK__OUTPUT_ARGS("last-fenced", "const char *", "time_t")
     /* [previous][next][first][last][top][bottom][index][help] */
 339 static int
 340 last_fenced_xml(pcmk__output_t *out, va_list args) {
 341     const char *target = va_arg(args, const char *);
 342     time_t when = va_arg(args, time_t);
 343 
 344     if (when) {
 345         char *buf = timespec_string(when, 0, false);
 346 
 347         pcmk__output_create_xml_node(out, "last-fenced",
 348                                      "target", target,
 349                                      "when", buf,
 350                                      NULL);
 351 
 352         free(buf);
 353         return pcmk_rc_ok;
 354     } else {
 355         return pcmk_rc_no_output;
 356     }
 357 }
 358 
 359 PCMK__OUTPUT_ARGS("pending-fencing-list", "stonith_history_t *", "GList *",
     /* [previous][next][first][last][top][bottom][index][help] */
 360                   "uint32_t", "uint32_t", "bool")
 361 static int
 362 pending_actions(pcmk__output_t *out, va_list args)
 363 {
 364     stonith_history_t *history = va_arg(args, stonith_history_t *);
 365     GList *only_node = va_arg(args, GList *);
 366     uint32_t section_opts = va_arg(args, uint32_t);
 367     uint32_t show_opts = va_arg(args, uint32_t);
 368     bool print_spacer = va_arg(args, int);
 369 
 370     int rc = pcmk_rc_no_output;
 371 
 372     for (stonith_history_t *hp = history; hp; hp = hp->next) {
 373         if (!pcmk__str_in_list(hp->target, only_node, pcmk__str_star_matches|pcmk__str_casei)) {
 374             continue;
 375         }
 376 
 377         /* Skip the rest of the history after we see a failed/done action */
 378         if ((hp->state == st_failed) || (hp->state == st_done)) {
 379             break;
 380         }
 381 
 382         PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, "Pending Fencing Actions");
 383         out->message(out, "stonith-event", hp,
 384                      pcmk_all_flags_set(section_opts, pcmk_section_fencing_all),
 385                      false, stonith__later_succeeded(hp, history), show_opts);
 386         out->increment_list(out);
 387     }
 388 
 389     PCMK__OUTPUT_LIST_FOOTER(out, rc);
 390     return rc;
 391 }
 392 
 393 PCMK__OUTPUT_ARGS("stonith-event", "stonith_history_t *", "bool", "bool",
     /* [previous][next][first][last][top][bottom][index][help] */
 394                   "const char *", "uint32_t")
 395 static int
 396 stonith_event_html(pcmk__output_t *out, va_list args)
 397 {
 398     stonith_history_t *event = va_arg(args, stonith_history_t *);
 399     bool full_history = va_arg(args, int);
 400     bool completed_only G_GNUC_UNUSED = va_arg(args, int);
 401     const char *succeeded = va_arg(args, const char *);
 402     uint32_t show_opts = va_arg(args, uint32_t);
 403 
 404     gchar *desc = stonith__history_description(event, full_history, succeeded,
 405                                                show_opts);
 406 
 407     switch(event->state) {
 408         case st_done:
 409             out->list_item(out, "successful-stonith-event", "%s", desc);
 410             break;
 411 
 412         case st_failed:
 413             out->list_item(out, "failed-stonith-event", "%s", desc);
 414             break;
 415 
 416         default:
 417             out->list_item(out, "pending-stonith-event", "%s", desc);
 418             break;
 419     }
 420     g_free(desc);
 421     return pcmk_rc_ok;
 422 }
 423 
 424 PCMK__OUTPUT_ARGS("stonith-event", "stonith_history_t *", "bool", "bool",
     /* [previous][next][first][last][top][bottom][index][help] */
 425                   "const char *", "uint32_t")
 426 static int
 427 stonith_event_text(pcmk__output_t *out, va_list args)
 428 {
 429     stonith_history_t *event = va_arg(args, stonith_history_t *);
 430     bool full_history = va_arg(args, int);
 431     bool completed_only = va_arg(args, int);
 432     const char *succeeded = va_arg(args, const char *);
 433     uint32_t show_opts = va_arg(args, uint32_t);
 434 
 435     if (completed_only) {
 436         pcmk__formatted_printf(out, "%lld\n", (long long) event->completed);
 437     } else {
 438         gchar *desc = stonith__history_description(event, full_history, succeeded,
 439                                                    show_opts);
 440 
 441         pcmk__indented_printf(out, "%s\n", desc);
 442         g_free(desc);
 443     }
 444 
 445     return pcmk_rc_ok;
 446 }
 447 
 448 PCMK__OUTPUT_ARGS("stonith-event", "stonith_history_t *", "bool", "bool",
     /* [previous][next][first][last][top][bottom][index][help] */
 449                   "const char *", "uint32_t")
 450 static int
 451 stonith_event_xml(pcmk__output_t *out, va_list args)
 452 {
 453     stonith_history_t *event = va_arg(args, stonith_history_t *);
 454     bool full_history G_GNUC_UNUSED = va_arg(args, int);
 455     bool completed_only G_GNUC_UNUSED = va_arg(args, int);
 456     const char *succeeded G_GNUC_UNUSED = va_arg(args, const char *);
 457     uint32_t show_opts G_GNUC_UNUSED = va_arg(args, uint32_t);
 458 
 459     xmlNodePtr node = pcmk__output_create_xml_node(out, "fence_event",
 460                                                    "action", event->action,
 461                                                    "target", event->target,
 462                                                    "client", event->client,
 463                                                    "origin", event->origin,
 464                                                    NULL);
 465 
 466     switch (event->state) {
 467         case st_failed:
 468             pcmk__xe_set_props(node, "status", "failed",
 469                                XML_LRM_ATTR_EXIT_REASON, event->exit_reason,
 470                                NULL);
 471             break;
 472 
 473         case st_done:
 474             crm_xml_add(node, "status", "success");
 475             break;
 476 
 477         default: {
 478             char *state = pcmk__itoa(event->state);
 479             pcmk__xe_set_props(node, "status", "pending",
 480                                "extended-status", state,
 481                                NULL);
 482             free(state);
 483             break;
 484         }
 485     }
 486 
 487     if (event->delegate != NULL) {
 488         crm_xml_add(node, "delegate", event->delegate);
 489     }
 490 
 491     if ((event->state == st_failed) || (event->state == st_done)) {
 492         char *time_s = timespec_string(event->completed, event->completed_nsec,
 493                                        true);
 494 
 495         crm_xml_add(node, "completed", time_s);
 496         free(time_s);
 497     }
 498 
 499     return pcmk_rc_ok;
 500 }
 501 
 502 PCMK__OUTPUT_ARGS("validate", "const char *", "const char *", "const char *",
     /* [previous][next][first][last][top][bottom][index][help] */
 503                   "const char *", "int")
 504 static int
 505 validate_agent_html(pcmk__output_t *out, va_list args) {
 506     const char *agent = va_arg(args, const char *);
 507     const char *device = va_arg(args, const char *);
 508     const char *output = va_arg(args, const char *);
 509     const char *error_output = va_arg(args, const char *);
 510     int rc = va_arg(args, int);
 511 
 512     if (device) {
 513         char *buf = crm_strdup_printf("Validation of %s on %s %s", agent, device,
 514                                       rc ? "failed" : "succeeded");
 515         pcmk__output_create_html_node(out, "div", NULL, NULL, buf);
 516         free(buf);
 517     } else {
 518         char *buf = crm_strdup_printf("Validation of %s %s", agent,
 519                                       rc ? "failed" : "succeeded");
 520         pcmk__output_create_html_node(out, "div", NULL, NULL, buf);
 521         free(buf);
 522     }
 523 
 524     out->subprocess_output(out, rc, output, error_output);
 525     return rc;
 526 }
 527 
 528 PCMK__OUTPUT_ARGS("validate", "const char *", "const char *", "const char *",
     /* [previous][next][first][last][top][bottom][index][help] */
 529                   "const char *", "int")
 530 static int
 531 validate_agent_text(pcmk__output_t *out, va_list args) {
 532     const char *agent = va_arg(args, const char *);
 533     const char *device = va_arg(args, const char *);
 534     const char *output = va_arg(args, const char *);
 535     const char *error_output = va_arg(args, const char *);
 536     int rc = va_arg(args, int);
 537 
 538     if (device) {
 539         pcmk__indented_printf(out, "Validation of %s on %s %s\n", agent, device,
 540                               rc ? "failed" : "succeeded");
 541     } else {
 542         pcmk__indented_printf(out, "Validation of %s %s\n", agent,
 543                               rc ? "failed" : "succeeded");
 544     }
 545 
 546     out->subprocess_output(out, rc, output, error_output);
 547     return rc;
 548 }
 549 
 550 PCMK__OUTPUT_ARGS("validate", "const char *", "const char *", "const char *",
     /* [previous][next][first][last][top][bottom][index][help] */
 551                   "const char *", "int")
 552 static int
 553 validate_agent_xml(pcmk__output_t *out, va_list args) {
 554     const char *agent = va_arg(args, const char *);
 555     const char *device = va_arg(args, const char *);
 556     const char *output = va_arg(args, const char *);
 557     const char *error_output = va_arg(args, const char *);
 558     int rc = va_arg(args, int);
 559 
 560     xmlNodePtr node = pcmk__output_create_xml_node(
 561         out, "validate", "agent", agent, "valid", pcmk__btoa(rc == pcmk_ok),
 562         NULL);
 563 
 564     if (device != NULL) {
 565         crm_xml_add(node, "device", device);
 566     }
 567 
 568     pcmk__output_xml_push_parent(out, node);
 569     out->subprocess_output(out, rc, output, error_output);
 570     pcmk__output_xml_pop_parent(out);
 571 
 572     return rc;
 573 }
 574 
 575 static pcmk__message_entry_t fmt_functions[] = {
 576     { "failed-fencing-list", "default", failed_history },
 577     { "fencing-list", "default", stonith_history },
 578     { "full-fencing-list", "default", full_history },
 579     { "full-fencing-list", "xml", full_history_xml },
 580     { "last-fenced", "html", last_fenced_html },
 581     { "last-fenced", "log", last_fenced_text },
 582     { "last-fenced", "text", last_fenced_text },
 583     { "last-fenced", "xml", last_fenced_xml },
 584     { "pending-fencing-list", "default", pending_actions },
 585     { "stonith-event", "html", stonith_event_html },
 586     { "stonith-event", "log", stonith_event_text },
 587     { "stonith-event", "text", stonith_event_text },
 588     { "stonith-event", "xml", stonith_event_xml },
 589     { "validate", "html", validate_agent_html },
 590     { "validate", "log", validate_agent_text },
 591     { "validate", "text", validate_agent_text },
 592     { "validate", "xml", validate_agent_xml },
 593 
 594     { NULL, NULL, NULL }
 595 };
 596 
 597 void
 598 stonith__register_messages(pcmk__output_t *out) {
     /* [previous][next][first][last][top][bottom][index][help] */
 599     pcmk__register_messages(out, fmt_functions);
 600 }

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