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

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