pacemaker  2.1.7-0f7f88312f
Scalable High-Availability cluster resource manager
upstart.c
Go to the documentation of this file.
1 /*
2  * Original copyright 2010 Senko Rasic <senko.rasic@dobarkod.hr>
3  * and Ante Karamatic <ivoks@init.hr>
4  * Later changes copyright 2012-2023 the Pacemaker project contributors
5  *
6  * The version control history for this file may have further details.
7  *
8  * This source code is licensed under the GNU Lesser General Public License
9  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
10  */
11 
12 #include <crm_internal.h>
13 
14 #include <stdio.h>
15 
16 #include <crm/crm.h>
17 #include <crm/services.h>
18 #include <crm/common/mainloop.h>
19 
20 #include <services_private.h>
21 #include <upstart.h>
22 #include <dbus/dbus.h>
23 #include <pcmk-dbus.h>
24 
25 #include <glib.h>
26 #include <gio/gio.h>
27 
28 #define BUS_NAME "com.ubuntu.Upstart"
29 #define BUS_PATH "/com/ubuntu/Upstart"
30 
31 #define UPSTART_06_API BUS_NAME"0_6"
32 #define UPSTART_JOB_IFACE UPSTART_06_API".Job"
33 #define BUS_PROPERTY_IFACE "org.freedesktop.DBus.Properties"
34 
35 /*
36  http://upstart.ubuntu.com/wiki/DBusInterface
37 */
38 static DBusConnection *upstart_proxy = NULL;
39 
48 int
50 {
51  op->opaque->exec = strdup("upstart-dbus");
52  if (op->opaque->exec == NULL) {
53  return ENOMEM;
54  }
55  return pcmk_rc_ok;
56 }
57 
66 enum ocf_exitcode
67 services__upstart2ocf(int exit_status)
68 {
69  // This library uses OCF codes for Upstart actions
70  return (enum ocf_exitcode) exit_status;
71 }
72 
73 static gboolean
74 upstart_init(void)
75 {
76  static int need_init = 1;
77 
78  if (need_init) {
79  need_init = 0;
80  upstart_proxy = pcmk_dbus_connect();
81  }
82  if (upstart_proxy == NULL) {
83  return FALSE;
84  }
85  return TRUE;
86 }
87 
88 void
90 {
91  if (upstart_proxy) {
92  pcmk_dbus_disconnect(upstart_proxy);
93  upstart_proxy = NULL;
94  }
95 }
96 
108 static bool
109 object_path_for_job(const gchar *arg_name, char **path, int timeout)
110 {
111  /*
112  com.ubuntu.Upstart0_6.GetJobByName (in String name, out ObjectPath job)
113  */
114  DBusError error;
115  DBusMessage *msg;
116  DBusMessage *reply = NULL;
117  bool rc = false;
118 
119  if (path != NULL) {
120  *path = NULL;
121  }
122 
123  if (!upstart_init()) {
124  return false;
125  }
126  msg = dbus_message_new_method_call(BUS_NAME, // target for the method call
127  BUS_PATH, // object to call on
128  UPSTART_06_API, // interface to call on
129  "GetJobByName"); // method name
130 
131  dbus_error_init(&error);
132  CRM_LOG_ASSERT(dbus_message_append_args(msg, DBUS_TYPE_STRING, &arg_name,
133  DBUS_TYPE_INVALID));
134  reply = pcmk_dbus_send_recv(msg, upstart_proxy, &error, timeout);
135  dbus_message_unref(msg);
136 
137  if (dbus_error_is_set(&error)) {
138  crm_err("Could not get DBus object path for %s: %s",
139  arg_name, error.message);
140  dbus_error_free(&error);
141 
142  } else if (!pcmk_dbus_type_check(reply, NULL, DBUS_TYPE_OBJECT_PATH,
143  __func__, __LINE__)) {
144  crm_err("Could not get DBus object path for %s: Invalid return type",
145  arg_name);
146 
147  } else {
148  if (path != NULL) {
149  dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, path,
150  DBUS_TYPE_INVALID);
151  if (*path != NULL) {
152  *path = strdup(*path);
153  }
154  }
155  rc = true;
156  }
157 
158  if (reply != NULL) {
159  dbus_message_unref(reply);
160  }
161  return rc;
162 }
163 
164 static void
165 fix(char *input, const char *search, char replace)
166 {
167  char *match = NULL;
168  int shuffle = strlen(search) - 1;
169 
170  while (TRUE) {
171  int len, lpc;
172 
173  match = strstr(input, search);
174  if (match == NULL) {
175  break;
176  }
177  crm_trace("Found: %s", match);
178  match[0] = replace;
179  len = strlen(match) - shuffle;
180  for (lpc = 1; lpc <= len; lpc++) {
181  match[lpc] = match[lpc + shuffle];
182  }
183  }
184 }
185 
186 static char *
187 fix_upstart_name(const char *input)
188 {
189  char *output = strdup(input);
190 
191  fix(output, "_2b", '+');
192  fix(output, "_2c", ',');
193  fix(output, "_2d", '-');
194  fix(output, "_2e", '.');
195  fix(output, "_40", '@');
196  fix(output, "_5f", '_');
197  return output;
198 }
199 
200 GList *
202 {
203  GList *units = NULL;
204  DBusMessageIter args;
205  DBusMessageIter unit;
206  DBusMessage *msg = NULL;
207  DBusMessage *reply = NULL;
208  const char *method = "GetAllJobs";
209  DBusError error;
210  int lpc = 0;
211 
212  if (upstart_init() == FALSE) {
213  return NULL;
214  }
215 
216 /*
217  com.ubuntu.Upstart0_6.GetAllJobs (out <Array of ObjectPath> jobs)
218 */
219 
220  dbus_error_init(&error);
221  msg = dbus_message_new_method_call(BUS_NAME, // target for the method call
222  BUS_PATH, // object to call on
223  UPSTART_06_API, // interface to call on
224  method); // method name
225  CRM_ASSERT(msg != NULL);
226 
227  reply = pcmk_dbus_send_recv(msg, upstart_proxy, &error, DBUS_TIMEOUT_USE_DEFAULT);
228  dbus_message_unref(msg);
229 
230  if (dbus_error_is_set(&error)) {
231  crm_err("Call to %s failed: %s", method, error.message);
232  dbus_error_free(&error);
233  return NULL;
234 
235  } else if (!dbus_message_iter_init(reply, &args)) {
236  crm_err("Call to %s failed: Message has no arguments", method);
237  dbus_message_unref(reply);
238  return NULL;
239  }
240 
241  if(!pcmk_dbus_type_check(reply, &args, DBUS_TYPE_ARRAY, __func__, __LINE__)) {
242  crm_err("Call to %s failed: Message has invalid arguments", method);
243  dbus_message_unref(reply);
244  return NULL;
245  }
246 
247  dbus_message_iter_recurse(&args, &unit);
248  while (dbus_message_iter_get_arg_type (&unit) != DBUS_TYPE_INVALID) {
249  DBusBasicValue value;
250  const char *job = NULL;
251  char *path = NULL;
252 
253  if(!pcmk_dbus_type_check(reply, &unit, DBUS_TYPE_OBJECT_PATH, __func__, __LINE__)) {
254  crm_warn("Skipping Upstart reply argument with unexpected type");
255  continue;
256  }
257 
258  dbus_message_iter_get_basic(&unit, &value);
259 
260  if(value.str) {
261  int llpc = 0;
262  path = value.str;
263  job = value.str;
264  while (path[llpc] != 0) {
265  if (path[llpc] == '/') {
266  job = path + llpc + 1;
267  }
268  llpc++;
269  }
270  lpc++;
271  crm_trace("%s -> %s", path, job);
272  units = g_list_append(units, fix_upstart_name(job));
273  }
274  dbus_message_iter_next (&unit);
275  }
276 
277  dbus_message_unref(reply);
278  crm_trace("Found %d upstart jobs", lpc);
279  return units;
280 }
281 
282 gboolean
284 {
285  return object_path_for_job(name, NULL, DBUS_TIMEOUT_USE_DEFAULT);
286 }
287 
288 static char *
289 get_first_instance(const gchar * job, int timeout)
290 {
291  char *instance = NULL;
292  const char *method = "GetAllInstances";
293  DBusError error;
294  DBusMessage *msg;
295  DBusMessage *reply;
296  DBusMessageIter args;
297  DBusMessageIter unit;
298 
299  dbus_error_init(&error);
300  msg = dbus_message_new_method_call(BUS_NAME, // target for the method call
301  job, // object to call on
302  UPSTART_JOB_IFACE, // interface to call on
303  method); // method name
304  CRM_ASSERT(msg != NULL);
305 
306  dbus_message_append_args(msg, DBUS_TYPE_INVALID);
307  reply = pcmk_dbus_send_recv(msg, upstart_proxy, &error, timeout);
308  dbus_message_unref(msg);
309 
310  if (dbus_error_is_set(&error)) {
311  crm_info("Call to %s failed: %s", method, error.message);
312  dbus_error_free(&error);
313  goto done;
314 
315  } else if(reply == NULL) {
316  crm_info("Call to %s failed: no reply", method);
317  goto done;
318 
319  } else if (!dbus_message_iter_init(reply, &args)) {
320  crm_info("Call to %s failed: Message has no arguments", method);
321  goto done;
322  }
323 
324  if(!pcmk_dbus_type_check(reply, &args, DBUS_TYPE_ARRAY, __func__, __LINE__)) {
325  crm_info("Call to %s failed: Message has invalid arguments", method);
326  goto done;
327  }
328 
329  dbus_message_iter_recurse(&args, &unit);
330  if(pcmk_dbus_type_check(reply, &unit, DBUS_TYPE_OBJECT_PATH, __func__, __LINE__)) {
331  DBusBasicValue value;
332 
333  dbus_message_iter_get_basic(&unit, &value);
334 
335  if(value.str) {
336  instance = strdup(value.str);
337  crm_trace("Result: %s", instance);
338  }
339  }
340 
341  done:
342  if(reply) {
343  dbus_message_unref(reply);
344  }
345  return instance;
346 }
347 
356 static void
357 parse_status_result(const char *name, const char *state, void *userdata)
358 {
359  svc_action_t *op = userdata;
360 
361  if (pcmk__str_eq(state, "running", pcmk__str_none)) {
363  } else {
365  }
366 
367  if (!(op->synchronous)) {
368  services_set_op_pending(op, NULL);
370  }
371 }
372 
373 #define METADATA_FORMAT \
374  "<?xml version=\"1.0\"?>\n" \
375  "<!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n" \
376  "<resource-agent name=\"%s\" version=\"" PCMK_DEFAULT_AGENT_VERSION "\">\n" \
377  " <version>1.1</version>\n" \
378  " <longdesc lang=\"en\">\n" \
379  " Upstart agent for controlling the system %s service\n" \
380  " </longdesc>\n" \
381  " <shortdesc lang=\"en\">Upstart job for %s</shortdesc>\n" \
382  " <parameters/>\n" \
383  " <actions>\n" \
384  " <action name=\"start\" timeout=\"15\" />\n" \
385  " <action name=\"stop\" timeout=\"15\" />\n" \
386  " <action name=\"status\" timeout=\"15\" />\n" \
387  " <action name=\"restart\" timeout=\"15\" />\n" \
388  " <action name=\"monitor\" timeout=\"15\" interval=\"15\" start-delay=\"15\" />\n" \
389  " <action name=\"meta-data\" timeout=\"5\" />\n" \
390  " </actions>\n" \
391  " <special tag=\"upstart\"/>\n" \
392  "</resource-agent>\n"
393 
394 static char *
395 upstart_job_metadata(const char *name)
396 {
398 }
399 
407 static void
408 set_result_from_method_error(svc_action_t *op, const DBusError *error)
409 {
411  "Unable to invoke Upstart DBus method");
412 
413  if (strstr(error->name, UPSTART_06_API ".Error.UnknownInstance")) {
414 
415  if (pcmk__str_eq(op->action, PCMK_ACTION_STOP, pcmk__str_casei)) {
416  crm_trace("Masking stop failure (%s) for %s "
417  "because unknown service can be considered stopped",
418  error->name, pcmk__s(op->rsc, "unknown resource"));
420  return;
421  }
422 
424  PCMK_EXEC_NOT_INSTALLED, "Upstart job not found");
425 
426  } else if (pcmk__str_eq(op->action, PCMK_ACTION_START, pcmk__str_casei)
427  && strstr(error->name, UPSTART_06_API ".Error.AlreadyStarted")) {
428  crm_trace("Masking start failure (%s) for %s "
429  "because already started resource is OK",
430  error->name, pcmk__s(op->rsc, "unknown resource"));
432  return;
433  }
434 
435  crm_info("DBus request for %s of Upstart job %s for resource %s failed: %s",
436  op->action, op->agent, pcmk__s(op->rsc, "with unknown name"),
437  error->message);
438 }
439 
447 static void
448 job_method_complete(DBusPendingCall *pending, void *user_data)
449 {
450  DBusError error;
451  DBusMessage *reply = NULL;
452  svc_action_t *op = user_data;
453 
454  // Grab the reply
455  if (pending != NULL) {
456  reply = dbus_pending_call_steal_reply(pending);
457  }
458 
459  // Determine result
460  dbus_error_init(&error);
461  if (pcmk_dbus_find_error(pending, reply, &error)) {
462  set_result_from_method_error(op, &error);
463  dbus_error_free(&error);
464 
465  } else if (pcmk__str_eq(op->action, PCMK_ACTION_STOP, pcmk__str_none)) {
466  // Call has no return value
467  crm_debug("DBus request for stop of %s succeeded",
468  pcmk__s(op->rsc, "unknown resource"));
470 
471  } else if (!pcmk_dbus_type_check(reply, NULL, DBUS_TYPE_OBJECT_PATH,
472  __func__, __LINE__)) {
473  crm_info("DBus request for %s of %s succeeded but "
474  "return type was unexpected", op->action,
475  pcmk__s(op->rsc, "unknown resource"));
477 
478  } else {
479  const char *path = NULL;
480 
481  dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, &path,
482  DBUS_TYPE_INVALID);
483  crm_debug("DBus request for %s of %s using %s succeeded",
484  op->action, pcmk__s(op->rsc, "unknown resource"), path);
486  }
487 
488  // The call is no longer pending
489  CRM_LOG_ASSERT(pending == op->opaque->pending);
490  services_set_op_pending(op, NULL);
491 
492  // Finalize action
494  if (reply != NULL) {
495  dbus_message_unref(reply);
496  }
497 }
498 
515 int
517 {
518  char *job = NULL;
519  int arg_wait = TRUE;
520  const char *arg_env = "pacemaker=1";
521  const char *action = op->action;
522 
523  DBusError error;
524  DBusMessage *msg = NULL;
525  DBusMessage *reply = NULL;
526  DBusMessageIter iter, array_iter;
527 
528  CRM_ASSERT(op != NULL);
529 
530  if ((op->action == NULL) || (op->agent == NULL)) {
532  "Bug in action caller");
533  goto cleanup;
534  }
535 
536  if (!upstart_init()) {
538  "No DBus connection");
539  goto cleanup;
540  }
541 
542  if (pcmk__str_eq(op->action, PCMK_ACTION_META_DATA, pcmk__str_casei)) {
543  op->stdout_data = upstart_job_metadata(op->agent);
545  goto cleanup;
546  }
547 
548  if (!object_path_for_job(op->agent, &job, op->timeout)) {
549  if (pcmk__str_eq(action, PCMK_ACTION_STOP, pcmk__str_none)) {
551  } else {
554  "Upstart job not found");
555  }
556  goto cleanup;
557  }
558 
559  if (job == NULL) {
560  // Shouldn't normally be possible -- maybe a memory error
562  op->status = PCMK_EXEC_ERROR;
563  goto cleanup;
564  }
565 
567  PCMK_ACTION_STATUS, NULL)) {
568  DBusPendingCall *pending = NULL;
569  char *state = NULL;
570  char *path = get_first_instance(job, op->timeout);
571 
573  "No Upstart job instances found");
574  if (path == NULL) {
575  goto cleanup;
576  }
577  state = pcmk_dbus_get_property(upstart_proxy, BUS_NAME, path,
578  UPSTART_06_API ".Instance", "state",
579  op->synchronous? NULL : parse_status_result,
580  op,
581  op->synchronous? NULL : &pending,
582  op->timeout);
583  free(path);
584 
585  if (op->synchronous) {
586  parse_status_result("state", state, op);
587  free(state);
588 
589  } else if (pending == NULL) {
591  "Could not get job state from DBus");
592 
593  } else { // Successfully initiated async op
594  free(job);
595  services_set_op_pending(op, pending);
597  return pcmk_rc_ok;
598  }
599 
600  goto cleanup;
601 
602  } else if (pcmk__str_eq(action, PCMK_ACTION_START, pcmk__str_none)) {
603  action = "Start";
604 
605  } else if (pcmk__str_eq(action, PCMK_ACTION_STOP, pcmk__str_none)) {
606  action = "Stop";
607 
608  } else if (pcmk__str_eq(action, "restart", pcmk__str_none)) {
609  action = "Restart";
610 
611  } else {
614  "Action not implemented for Upstart resources");
615  goto cleanup;
616  }
617 
618  // Initialize rc/status in case called functions don't set them
620  "Bug in service library");
621 
622  crm_debug("Calling %s for %s on %s",
623  action, pcmk__s(op->rsc, "unknown resource"), job);
624 
625  msg = dbus_message_new_method_call(BUS_NAME, // target for the method call
626  job, // object to call on
627  UPSTART_JOB_IFACE, // interface to call on
628  action); // method name
629  CRM_ASSERT(msg != NULL);
630 
631  dbus_message_iter_init_append (msg, &iter);
632  CRM_LOG_ASSERT(dbus_message_iter_open_container(&iter,
633  DBUS_TYPE_ARRAY,
634  DBUS_TYPE_STRING_AS_STRING,
635  &array_iter));
636  CRM_LOG_ASSERT(dbus_message_iter_append_basic(&array_iter,
637  DBUS_TYPE_STRING, &arg_env));
638  CRM_LOG_ASSERT(dbus_message_iter_close_container(&iter, &array_iter));
639  CRM_LOG_ASSERT(dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &arg_wait,
640  DBUS_TYPE_INVALID));
641 
642  if (!(op->synchronous)) {
643  DBusPendingCall *pending = pcmk_dbus_send(msg, upstart_proxy,
644  job_method_complete, op,
645  op->timeout);
646 
647  if (pending == NULL) {
649  "Unable to send DBus message");
650  goto cleanup;
651 
652  } else { // Successfully initiated async op
653  free(job);
654  services_set_op_pending(op, pending);
656  return pcmk_rc_ok;
657  }
658  }
659 
660  // Synchronous call
661 
662  dbus_error_init(&error);
663  reply = pcmk_dbus_send_recv(msg, upstart_proxy, &error, op->timeout);
664 
665  if (dbus_error_is_set(&error)) {
666  set_result_from_method_error(op, &error);
667  dbus_error_free(&error);
668 
669  } else if (pcmk__str_eq(op->action, PCMK_ACTION_STOP, pcmk__str_none)) {
670  // DBus call does not return a value
672 
673  } else if (!pcmk_dbus_type_check(reply, NULL, DBUS_TYPE_OBJECT_PATH,
674  __func__, __LINE__)) {
675  crm_info("Call to %s passed but return type was unexpected",
676  op->action);
678 
679  } else {
680  const char *path = NULL;
681 
682  dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, &path,
683  DBUS_TYPE_INVALID);
684  crm_debug("Call to %s passed: %s", op->action, path);
686  }
687 
688 cleanup:
689  free(job);
690  if (msg != NULL) {
691  dbus_message_unref(msg);
692  }
693  if (reply != NULL) {
694  dbus_message_unref(reply);
695  }
696 
697  if (op->synchronous) {
698  return (op->rc == PCMK_OCF_OK)? pcmk_rc_ok : pcmk_rc_error;
699  } else {
700  return services__finalize_async_op(op);
701  }
702 }
Services API.
int rc
Exit status of action (set by library upon completion)
Definition: services.h:150
A dumping ground.
ocf_exitcode
Exit status codes for resource agents.
Definition: results.h:169
const char * name
Definition: cib.c:26
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:933
gboolean upstart_job_exists(const char *name)
Definition: upstart.c:283
enum ocf_exitcode services__upstart2ocf(int exit_status)
Definition: upstart.c:67
void pcmk_dbus_disconnect(DBusConnection *connection)
Definition: dbus.c:295
#define DBUS_TIMEOUT_USE_DEFAULT
Definition: pcmk-dbus.h:16
#define PCMK_ACTION_META_DATA
Definition: actions.h:56
#define PCMK_ACTION_MONITOR
Definition: actions.h:59
Service safely stopped.
Definition: results.h:177
char * rsc
XML ID of resource being executed for resource actions, otherwise NULL.
Definition: services.h:124
#define CRM_LOG_ASSERT(expr)
Definition: logging.h:222
int timeout
Action timeout (in milliseconds)
Definition: services.h:141
Execution failed, do not retry on node.
Definition: results.h:323
void upstart_cleanup(void)
Definition: upstart.c:89
Wrappers for and extensions to glib mainloop.
const char * action
Definition: pcmk_fence.c:30
#define PCMK_ACTION_STATUS
Definition: actions.h:72
#define crm_warn(fmt, args...)
Definition: logging.h:382
svc_action_private_t * opaque
This field should be treated as internal to Pacemaker.
Definition: services.h:177
GList * upstart_job_listall(void)
Definition: upstart.c:201
#define crm_debug(fmt, args...)
Definition: logging.h:386
char * stdout_data
Action stdout (set by library)
Definition: services.h:173
Parameter invalid (inherently)
Definition: results.h:176
#define crm_trace(fmt, args...)
Definition: logging.h:387
int services__finalize_async_op(svc_action_t *op)
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
Object for executing external actions.
Definition: services.h:117
#define PCMK_ACTION_START
Definition: actions.h:71
char * agent
Resource agent name for resource actions, otherwise NULL.
Definition: services.h:139
void services__set_result(svc_action_t *action, int agent_status, enum pcmk_exec_status exec_status, const char *exit_reason)
Definition: services.c:1271
int synchronous
Definition: services.h:168
Action completed, result is known.
Definition: results.h:318
#define PCMK_ACTION_STOP
Definition: actions.h:74
Execution failed, do not retry anywhere.
Definition: results.h:324
#define BUS_PATH
Definition: upstart.c:29
Dependencies not available locally.
Definition: results.h:175
int services__upstart_prepare(svc_action_t *op)
Definition: upstart.c:49
int services__execute_upstart(svc_action_t *op)
Definition: upstart.c:516
Unspecified error.
Definition: results.h:171
DBusPendingCall * pcmk_dbus_send(DBusMessage *msg, DBusConnection *connection, void(*done)(DBusPendingCall *pending, void *user_data), void *user_data, int timeout)
Definition: dbus.c:476
DBusConnection * pcmk_dbus_connect(void)
Definition: dbus.c:259
void services_add_inflight_op(svc_action_t *op)
Definition: services.c:835
Requested action not implemented.
Definition: results.h:173
char * action
Name of action being executed for resource actions, otherwise NULL.
Definition: services.h:127
const char * path
Definition: cib.c:28
#define crm_err(fmt, args...)
Definition: logging.h:381
#define CRM_ASSERT(expr)
Definition: results.h:42
Success.
Definition: results.h:170
xmlNode * input
int status
Execution status (enum pcmk_exec_status set by library)
Definition: services.h:158
#define UPSTART_JOB_IFACE
Definition: upstart.c:32
bool pcmk_dbus_type_check(DBusMessage *msg, DBusMessageIter *field, int expected, const char *function, int line)
Definition: dbus.c:516
Agent or dependency not available locally.
Definition: results.h:325
bool pcmk_dbus_find_error(const DBusPendingCall *pending, DBusMessage *reply, DBusError *ret)
Definition: dbus.c:330
#define UPSTART_06_API
Definition: upstart.c:31
char * pcmk_dbus_get_property(DBusConnection *connection, const char *target, const char *obj, const gchar *iface, const char *name, property_callback_func callback, void *userdata, DBusPendingCall **pending, int timeout)
Definition: dbus.c:695
unsigned int timeout
Definition: pcmk_fence.c:32
DBusMessage * pcmk_dbus_send_recv(DBusMessage *msg, DBusConnection *connection, DBusError *error, int timeout)
Definition: dbus.c:412
Execution failed, may be retried.
Definition: results.h:322
#define crm_info(fmt, args...)
Definition: logging.h:384
#define BUS_NAME
Definition: upstart.c:28
#define METADATA_FORMAT
Definition: upstart.c:373