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

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