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

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