22 #include <dbus/dbus.h>    28 #define BUS_NAME "com.ubuntu.Upstart"    29 #define BUS_PATH "/com/ubuntu/Upstart"    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"    38 static DBusConnection *upstart_proxy = NULL;
    76     static int need_init = 1;
    82     if (upstart_proxy == NULL) {
   109 object_path_for_job(
const gchar *arg_name, 
char **
path, 
int timeout)
   116     DBusMessage *reply = NULL;
   123     if (!upstart_init()) {
   126     msg = dbus_message_new_method_call(
BUS_NAME, 
   131     dbus_error_init(&error);
   132     CRM_LOG_ASSERT(dbus_message_append_args(msg, DBUS_TYPE_STRING, &arg_name,
   135     dbus_message_unref(msg);
   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);
   143                                      __func__, __LINE__)) {
   144         crm_err(
"Could not get DBus object path for %s: Invalid return type",
   149             dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, 
path,
   159         dbus_message_unref(reply);
   165 fix(
char *
input, 
const char *search, 
char replace)
   168     int shuffle = strlen(search) - 1;
   173         match = strstr(
input, search);
   179         len = strlen(match) - shuffle;
   180         for (lpc = 1; lpc <= len; lpc++) {
   181             match[lpc] = match[lpc + shuffle];
   187 fix_upstart_name(
const char *
input)
   189     char *output = strdup(
input);
   191     fix(output, 
"_2b", 
'+');
   192     fix(output, 
"_2c", 
',');
   193     fix(output, 
"_2d", 
'-');
   194     fix(output, 
"_2e", 
'.');
   195     fix(output, 
"_40", 
'@');
   196     fix(output, 
"_5f", 
'_');
   204     DBusMessageIter args;
   205     DBusMessageIter unit;
   206     DBusMessage *msg = NULL;
   207     DBusMessage *reply = NULL;
   208     const char *method = 
"GetAllJobs";
   212     if (upstart_init() == FALSE) {
   220     dbus_error_init(&error);
   221     msg = dbus_message_new_method_call(
BUS_NAME, 
   228     dbus_message_unref(msg);
   230     if (dbus_error_is_set(&error)) {
   231         crm_err(
"Call to %s failed: %s", method, error.message);
   232         dbus_error_free(&error);
   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);
   242         crm_err(
"Call to %s failed: Message has invalid arguments", method);
   243         dbus_message_unref(reply);
   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;
   254             crm_warn(
"Skipping Upstart reply argument with unexpected type");
   258         dbus_message_iter_get_basic(&unit, &value);
   264             while (
path[llpc] != 0) {
   265                 if (
path[llpc] == 
'/') {
   266                     job = 
path + llpc + 1;
   272             units = g_list_append(units, fix_upstart_name(job));
   274         dbus_message_iter_next (&unit);
   277     dbus_message_unref(reply);
   289 get_first_instance(
const gchar * job, 
int timeout)
   291     char *instance = NULL;
   292     const char *method = 
"GetAllInstances";
   296     DBusMessageIter args;
   297     DBusMessageIter unit;
   299     dbus_error_init(&error);
   300     msg = dbus_message_new_method_call(
BUS_NAME, 
   306     dbus_message_append_args(msg, DBUS_TYPE_INVALID);
   308     dbus_message_unref(msg);
   310     if (dbus_error_is_set(&error)) {
   311         crm_info(
"Call to %s failed: %s", method, error.message);
   312         dbus_error_free(&error);
   315     } 
else if(reply == NULL) {
   316         crm_info(
"Call to %s failed: no reply", method);
   319     } 
else if (!dbus_message_iter_init(reply, &args)) {
   320         crm_info(
"Call to %s failed: Message has no arguments", method);
   325         crm_info(
"Call to %s failed: Message has invalid arguments", method);
   329     dbus_message_iter_recurse(&args, &unit);
   331         DBusBasicValue value;
   333         dbus_message_iter_get_basic(&unit, &value);
   336             instance = strdup(value.str);
   343         dbus_message_unref(reply);
   357 parse_status_result(
const char *
name, 
const char *state, 
void *userdata)
   368         services_set_op_pending(op, NULL);
   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"             \   381     "  <shortdesc lang=\"en\">Upstart job for %s</shortdesc>\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"                     \   391     "  <special tag=\"upstart\"/>\n"                                        \   392     "</resource-agent>\n"   395 upstart_job_metadata(
const char *
name)
   408 set_result_from_method_error(
svc_action_t *op, 
const DBusError *error)
   411                          "Unable to invoke Upstart DBus method");
   413     if (strstr(error->name, 
UPSTART_06_API ".Error.UnknownInstance")) {
   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"));
   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"));
   435     crm_info(
"DBus request for %s of Upstart job %s for resource %s failed: %s",
   448 job_method_complete(DBusPendingCall *pending, 
void *user_data)
   451     DBusMessage *reply = NULL;
   455     if (pending != NULL) {
   456         reply = dbus_pending_call_steal_reply(pending);
   460     dbus_error_init(&error);
   462         set_result_from_method_error(op, &error);
   463         dbus_error_free(&error);
   467         crm_debug(
"DBus request for stop of %s succeeded",
   468                   pcmk__s(op->
rsc, 
"unknown resource"));
   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"));
   479         const char *
path = NULL;
   481         dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, &
path,
   483         crm_debug(
"DBus request for %s of %s using %s succeeded",
   490     services_set_op_pending(op, NULL);
   495         dbus_message_unref(reply);
   520     const char *arg_env = 
"pacemaker=1";
   524     DBusMessage *msg = NULL;
   525     DBusMessage *reply = NULL;
   526     DBusMessageIter iter, array_iter;
   532                              "Bug in action caller");
   536     if (!upstart_init()) {
   538                              "No DBus connection");
   548     if (!object_path_for_job(op->
agent, &job, op->
timeout)) {
   554                                  "Upstart job not found");
   567         DBusPendingCall *pending = NULL;
   572                              "No Upstart job instances found");
   585             parse_status_result(
"state", state, op);
   588         } 
else if (pending == NULL) {
   590                                  "Could not get job state from DBus");
   594             services_set_op_pending(op, pending);
   613                              "Action not implemented for Upstart resources");
   619                          "Bug in service library");
   622               action, pcmk__s(op->
rsc, 
"unknown resource"), job);
   624     msg = dbus_message_new_method_call(
BUS_NAME, 
   630     dbus_message_iter_init_append (msg, &iter);
   633                                                     DBUS_TYPE_STRING_AS_STRING,
   636                                                   DBUS_TYPE_STRING, &arg_env));
   637     CRM_LOG_ASSERT(dbus_message_iter_close_container(&iter, &array_iter));
   638     CRM_LOG_ASSERT(dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &arg_wait,
   643                                                   job_method_complete, op,
   646         if (pending == NULL) {
   648                                  "Unable to send DBus message");
   653             services_set_op_pending(op, pending);
   661     dbus_error_init(&error);
   664     if (dbus_error_is_set(&error)) {
   665         set_result_from_method_error(op, &error);
   666         dbus_error_free(&error);
   673                                      __func__, __LINE__)) {
   674         crm_info(
"Call to %s passed but return type was unexpected",
   679         const char *
path = NULL;
   681         dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, &
path,
   690         dbus_message_unref(msg);
   693         dbus_message_unref(reply);
 
int rc
Exit status of action (set by library upon completion) 
 
ocf_exitcode
Exit status codes for resource agents. 
 
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
 
gboolean upstart_job_exists(const char *name)
 
enum ocf_exitcode services__upstart2ocf(int exit_status)
 
void pcmk_dbus_disconnect(DBusConnection *connection)
 
#define DBUS_TIMEOUT_USE_DEFAULT
 
char * rsc
XML ID of resource being executed for resource actions, otherwise NULL. 
 
#define CRM_LOG_ASSERT(expr)
 
int timeout
Action timeout (in milliseconds) 
 
Execution failed, do not retry on node. 
 
void upstart_cleanup(void)
 
Wrappers for and extensions to glib mainloop. 
 
#define crm_warn(fmt, args...)
 
svc_action_private_t * opaque
This field should be treated as internal to Pacemaker. 
 
GList * upstart_job_listall(void)
 
#define crm_debug(fmt, args...)
 
char * stdout_data
Action stdout (set by library) 
 
Parameter invalid (inherently) 
 
#define crm_trace(fmt, args...)
 
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. 
 
char * agent
Resource agent name for resource actions, otherwise NULL. 
 
void services__set_result(svc_action_t *action, int agent_status, enum pcmk_exec_status exec_status, const char *exit_reason)
 
Action completed, result is known. 
 
Execution failed, do not retry anywhere. 
 
Dependencies not available locally. 
 
int services__upstart_prepare(svc_action_t *op)
 
int services__execute_upstart(svc_action_t *op)
 
DBusPendingCall * pcmk_dbus_send(DBusMessage *msg, DBusConnection *connection, void(*done)(DBusPendingCall *pending, void *user_data), void *user_data, int timeout)
 
DBusConnection * pcmk_dbus_connect(void)
 
void services_add_inflight_op(svc_action_t *op)
 
Requested action not implemented. 
 
char * action
Name of action being executed for resource actions, otherwise NULL. 
 
#define crm_err(fmt, args...)
 
int status
Execution status (enum pcmk_exec_status set by library) 
 
#define UPSTART_JOB_IFACE
 
bool pcmk_dbus_type_check(DBusMessage *msg, DBusMessageIter *field, int expected, const char *function, int line)
 
Agent or dependency not available locally. 
 
bool pcmk_dbus_find_error(const DBusPendingCall *pending, DBusMessage *reply, DBusError *ret)
 
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)
 
DBusMessage * pcmk_dbus_send_recv(DBusMessage *msg, DBusConnection *connection, DBusError *error, int timeout)
 
Execution failed, may be retried. 
 
#define crm_info(fmt, args...)