pacemaker  2.0.2-debe490
Scalable High-Availability cluster resource manager
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
st_output.c
Go to the documentation of this file.
1 /*
2  * Copyright 2019 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 <stdarg.h>
11 
12 #include <crm/stonith-ng.h>
13 #include <crm/common/iso8601.h>
14 #include <crm/common/output.h>
15 #include <crm/common/util.h>
16 #include <crm/common/xml.h>
17 #include <crm/fencing/internal.h>
18 
19 static int
20 fence_target_text(pcmk__output_t *out, va_list args) {
21  const char *hostname = va_arg(args, const char *);
22  const char *uuid = va_arg(args, const char *);
23  const char *status = va_arg(args, const char *);
24 
25  pcmk__indented_printf(out, "%s\t%s\t%s\n", hostname, uuid, status);
26  return 0;
27 }
28 
29 static int
30 fence_target_xml(pcmk__output_t *out, va_list args) {
31  xmlNodePtr node = NULL;
32  const char *hostname = va_arg(args, const char *);
33  const char *uuid = va_arg(args, const char *);
34  const char *status = va_arg(args, const char *);
35 
36  node = xmlNewNode(NULL, (pcmkXmlStr) "target");
37  xmlSetProp(node, (pcmkXmlStr) "hostname", (pcmkXmlStr) hostname);
38  xmlSetProp(node, (pcmkXmlStr) "uuid", (pcmkXmlStr) uuid);
39  xmlSetProp(node, (pcmkXmlStr) "status", (pcmkXmlStr) status);
40 
41  pcmk__xml_add_node(out, node);
42  return 0;
43 }
44 
45 static int
46 last_fenced_text(pcmk__output_t *out, va_list args) {
47  const char *target = va_arg(args, const char *);
48  time_t when = va_arg(args, time_t);
49 
50  if (when) {
51  pcmk__indented_printf(out, "Node %s last fenced at: %s", target, ctime(&when));
52  } else {
53  pcmk__indented_printf(out, "Node %s has never been fenced\n", target);
54  }
55 
56  return 0;
57 }
58 
59 static int
60 last_fenced_xml(pcmk__output_t *out, va_list args) {
61  const char *target = va_arg(args, const char *);
62  time_t when = va_arg(args, time_t);
63 
64  if (when) {
65  crm_time_t *crm_when = crm_time_new(NULL);
66  xmlNodePtr node = xmlNewNode(NULL, (pcmkXmlStr) "last-fenced");
67  char *buf = NULL;
68 
69  crm_time_set_timet(crm_when, &when);
71 
72  xmlSetProp(node, (pcmkXmlStr) "target", (pcmkXmlStr) target);
73  xmlSetProp(node, (pcmkXmlStr) "when", (pcmkXmlStr) buf);
74 
75  pcmk__xml_add_node(out, node);
76 
77  crm_time_free(crm_when);
78  free(buf);
79  }
80 
81  return 0;
82 }
83 
84 static int
85 stonith_event_text(pcmk__output_t *out, va_list args) {
86  stonith_history_t *event = va_arg(args, stonith_history_t *);
87 
88  switch (event->state) {
89  case st_failed:
90  pcmk__indented_printf(out, "%s failed %s node %s on behalf of %s from %s at %s",
91  event->delegate ? event->delegate : "We",
92  stonith_action_str(event->action), event->target,
93  event->client, event->origin, ctime(&event->completed));
94  break;
95 
96  case st_done:
97  pcmk__indented_printf(out, "%s succeeded %s node %s on behalf of %s from %s at %s",
98  event->delegate ? event->delegate : "This node",
99  stonith_action_str(event->action), event->target,
100  event->client, event->origin, ctime(&event->completed));
101  break;
102 
103  default:
104  /* ocf:pacemaker:controld depends on "wishes to" being
105  * in this output, when used with older versions of DLM
106  * that don't report stateful_merge_wait
107  */
108  pcmk__indented_printf(out, "%s at %s wishes to %s node %s - %d %lld\n",
109  event->client, event->origin, stonith_action_str(event->action),
110  event->target, event->state, (long long) event->completed);
111  break;
112  }
113 
114  return 0;
115 }
116 
117 static int
118 stonith_event_xml(pcmk__output_t *out, va_list args) {
119  xmlNodePtr node = NULL;
120  stonith_history_t *event = va_arg(args, stonith_history_t *);
121  crm_time_t *crm_when = crm_time_new(NULL);
122  char *buf = NULL;
123 
124  node = xmlNewNode(NULL, (pcmkXmlStr) "fence_event");
125 
126  switch (event->state) {
127  case st_failed:
128  xmlSetProp(node, (pcmkXmlStr) "status", (pcmkXmlStr) "failed");
129  break;
130 
131  case st_done:
132  xmlSetProp(node, (pcmkXmlStr) "status", (pcmkXmlStr) "success");
133  break;
134 
135  default: {
136  char *state = crm_itoa(event->state);
137  xmlSetProp(node, (pcmkXmlStr) "status", (pcmkXmlStr) "pending");
138  xmlSetProp(node, (pcmkXmlStr) "extended-status", (pcmkXmlStr) state);
139  free(state);
140  break;
141  }
142  }
143 
144  if (event->delegate != NULL) {
145  xmlSetProp(node, (pcmkXmlStr) "delegate", (pcmkXmlStr) event->delegate);
146  }
147 
148  xmlSetProp(node, (pcmkXmlStr) "action", (pcmkXmlStr) event->action);
149  xmlSetProp(node, (pcmkXmlStr) "target", (pcmkXmlStr) event->target);
150  xmlSetProp(node, (pcmkXmlStr) "client", (pcmkXmlStr) event->client);
151  xmlSetProp(node, (pcmkXmlStr) "origin", (pcmkXmlStr) event->origin);
152 
153  if (event->state == st_failed || event->state == st_done) {
154  crm_time_set_timet(crm_when, &event->completed);
156  xmlSetProp(node, (pcmkXmlStr) "completed", (pcmkXmlStr) buf);
157  free(buf);
158  }
159 
160  pcmk__xml_add_node(out, node);
161 
162  crm_time_free(crm_when);
163  return 0;
164 }
165 
166 static int
167 validate_agent_text(pcmk__output_t *out, va_list args) {
168  const char *agent = va_arg(args, const char *);
169  const char *device = va_arg(args, const char *);
170  const char *output = va_arg(args, const char *);
171  const char *error_output = va_arg(args, const char *);
172  int rc = va_arg(args, int);
173 
174  if (device) {
175  pcmk__indented_printf(out, "Validation of %s on %s %s\n", agent, device,
176  rc ? "failed" : "succeeded");
177  } else {
178  pcmk__indented_printf(out, "Validation of %s %s\n", agent,
179  rc ? "failed" : "succeeded");
180  }
181 
182  if (output) {
183  puts(output);
184  }
185 
186  if (error_output) {
187  puts(error_output);
188  }
189 
190  return rc;
191 }
192 
193 static int
194 validate_agent_xml(pcmk__output_t *out, va_list args) {
195  xmlNodePtr node = NULL;
196 
197  const char *agent = va_arg(args, const char *);
198  const char *device = va_arg(args, const char *);
199  const char *output = va_arg(args, const char *);
200  const char *error_output = va_arg(args, const char *);
201  int rc = va_arg(args, int);
202 
203  node = xmlNewNode(NULL, (pcmkXmlStr) "validate");
204  xmlSetProp(node, (pcmkXmlStr) "agent", (pcmkXmlStr) agent);
205  if (device != NULL) {
206  xmlSetProp(node, (pcmkXmlStr) "device", (pcmkXmlStr) device);
207  }
208  xmlSetProp(node, (pcmkXmlStr) "valid", (pcmkXmlStr) (rc ? "false" : "true"));
209 
210  pcmk__xml_push_parent(out, node);
211  out->subprocess_output(out, rc, output, error_output);
213 
214  pcmk__xml_add_node(out, node);
215  return rc;
216 }
217 
218 static pcmk__message_entry_t fmt_functions[] = {
219  { "fence-target", "text", fence_target_text },
220  { "fence-target", "xml", fence_target_xml },
221  { "last-fenced", "text", last_fenced_text },
222  { "last-fenced", "xml", last_fenced_xml },
223  { "stonith-event", "text", stonith_event_text },
224  { "stonith-event", "xml", stonith_event_xml },
225  { "validate", "text", validate_agent_text },
226  { "validate", "xml", validate_agent_xml },
227 
228  { NULL, NULL, NULL }
229 };
230 
231 void
233  static bool registered = FALSE;
234 
235  if (!registered) {
236  pcmk__register_messages(out, fmt_functions);
237  registered = TRUE;
238  }
239 }
void void pcmk__xml_add_node(pcmk__output_t *out, xmlNodePtr node)
Definition: output_xml.c:230
Definition: output.h:84
Formatted output for pacemaker tools.
void stonith__register_messages(pcmk__output_t *out)
Definition: st_output.c:232
#define crm_time_log_timeofday
Definition: iso8601.h:63
void pcmk__xml_push_parent(pcmk__output_t *out, xmlNodePtr node)
Definition: output_xml.c:240
struct crm_time_s crm_time_t
Definition: iso8601.h:32
void pcmk__xml_pop_parent(pcmk__output_t *out)
Definition: output_xml.c:250
const char * stonith_action_str(const char *action)
Turn stonith action into a more readable string.
Definition: st_client.c:2270
Utility functions.
void(* subprocess_output)(pcmk__output_t *out, int exit_status, const char *proc_stdout, const char *proc_stderr)
Definition: output.h:273
void crm_time_set_timet(crm_time_t *target, time_t *source)
Definition: iso8601.c:1028
Wrappers for and extensions to libxml2.
ISO_8601 Date handling.
#define crm_time_log_with_timezone
Definition: iso8601.h:64
void pcmk__register_messages(pcmk__output_t *out, pcmk__message_entry_t *table)
Definition: output.c:141
const xmlChar * pcmkXmlStr
Definition: xml.h:51
crm_time_t * crm_time_new(const char *string)
Definition: iso8601.c:84
void pcmk__indented_printf(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
Fencing aka. STONITH.
This structure contains everything that makes up a single output formatter.
Definition: output.h:124
char * crm_time_as_string(crm_time_t *dt, int flags)
Definition: iso8601.c:393
#define crm_time_log_date
Definition: iso8601.h:62
void crm_time_free(crm_time_t *dt)
Definition: iso8601.c:101