14 #include <sys/types.h>
39 static int operations = 0;
69 if (rc > 0 && stat(path, &st) == 0) {
93 const char *agent,
const char *action,
int interval,
int timeout,
103 if (crm_strlen_zero(name)) {
104 crm_err(
"A service or resource action must have a name.");
108 if (crm_strlen_zero(standard)) {
109 crm_err(
"A service action must have a valid standard.");
113 if (!strcasecmp(standard,
"ocf") && crm_strlen_zero(provider)) {
114 crm_err(
"An OCF resource action must have a provider.");
118 if (crm_strlen_zero(agent)) {
119 crm_err(
"A service or resource action must have an agent.");
123 if (crm_strlen_zero(action)) {
124 crm_err(
"A service or resource action must specify an action.");
142 op->
rsc = strdup(name);
143 op->
action = strdup(action);
147 op->
agent = strdup(agent);
151 if (asprintf(&op->
id,
"%s_%s_%d", name, action, interval) == -1) {
155 if (strcasecmp(op->
standard,
"service") == 0) {
171 if (strcasecmp(op->
standard,
"ocf") == 0) {
177 crm_err(
"Internal error: cannot create agent path");
183 }
else if (strcasecmp(op->
standard,
"lsb") == 0) {
184 if (op->
agent[0] ==
'/') {
189 crm_err(
"Internal error: cannot create agent path");
195 #if SUPPORT_HEARTBEAT
196 }
else if (strcasecmp(op->
standard,
"heartbeat") == 0) {
202 if (op->
agent[0] ==
'/') {
206 }
else if (asprintf(&op->
opaque->
exec,
"%s/%s", HB_RA_DIR, op->
agent) == -1) {
207 crm_err(
"Internal error: cannot create agent path");
215 for (index = 1; index <=
MAX_ARGC - 3; index++ ) {
216 snprintf(buf_tmp,
sizeof(buf_tmp),
"%d", index);
217 value_tmp = g_hash_table_lookup(params, buf_tmp);
218 if (value_tmp == NULL) {
223 op->
opaque->
args[param_num++] = strdup(value_tmp);
232 }
else if (strcasecmp(op->
standard,
"systemd") == 0) {
236 }
else if (strcasecmp(op->
standard,
"upstart") == 0) {
239 }
else if (strcasecmp(op->
standard,
"service") == 0) {
246 }
else if (strcasecmp(op->
standard,
"nagios") == 0) {
249 if (op->
agent[0] ==
'/') {
255 crm_err(
"Internal error: cannot create agent path");
264 op->
opaque->
args[index] = strdup(
"--version");
271 static int args_size =
sizeof(op->
opaque->
args) /
sizeof(
char *);
273 g_hash_table_iter_init(&iter, params);
275 while (g_hash_table_iter_next(&iter, (gpointer *) & key, (gpointer *) & value) &&
276 index <= args_size - 3) {
278 char *long_opt = NULL;
285 long_opt = calloc(1, len);
286 sprintf(long_opt,
"--%s", key);
287 long_opt[len - 1] = 0;
304 g_hash_table_destroy(params);
310 g_hash_table_destroy(params);
321 unsigned int cur_arg;
323 op = calloc(1,
sizeof(*op));
329 for (cur_arg = 1; args && args[cur_arg - 1]; cur_arg++) {
330 op->
opaque->
args[cur_arg] = strdup(args[cur_arg - 1]);
333 crm_err(
"svc_action_t args list not long enough for '%s' execution request.", exec);
350 services_set_op_pending(
svc_action_t *op, DBusPendingCall *pending)
352 if (op->
opaque->pending && (op->
opaque->pending != pending)) {
358 dbus_pending_call_unref(op->
opaque->pending);
360 op->
opaque->pending = pending;
362 crm_trace(
"Updated pending %s DBus call (%p)", op->
id, pending);
377 if(op->
opaque->timerid != 0) {
379 g_source_remove(op->
opaque->timerid);
385 if(dbus_pending_call_get_completed(op->
opaque->pending)) {
388 dbus_pending_call_cancel(op->
opaque->pending);
389 dbus_pending_call_unref(op->
opaque->pending);
390 op->
opaque->pending = NULL;
440 g_hash_table_destroy(op->
params);
470 snprintf(
id,
sizeof(
id),
"%s_%s_%d", name, action, interval);
489 crm_info(
"Cancelling in-flight op: performing early termination of %s (pid=%d)",
id, op->
pid);
494 crm_err(
"Termination of %s (pid=%d) failed",
id, op->
pid);
508 if (asprintf(&
id,
"%s_%s_%d", name, action, interval) == -1) {
548 if (dup && (dup != op)) {
610 if (action_callback) {
615 if (handle_duplicate_recurring(op, action_callback) == TRUE) {
628 return action_async_helper(op);
632 static gboolean processing_blocked_ops = FALSE;
640 for (gIter =
inflight_ops; gIter != NULL; gIter = gIter->next) {
653 GList *executed_ops = NULL;
656 gboolean res = FALSE;
658 if (processing_blocked_ops) {
663 processing_blocked_ops = TRUE;
667 for (gIter =
blocked_ops; gIter != NULL; gIter = gIter->next) {
672 executed_ops = g_list_append(executed_ops, op);
673 res = action_async_helper(op);
682 for (gIter = executed_ops; gIter != NULL; gIter = gIter->next) {
686 g_list_free(executed_ops);
688 processing_blocked_ops = FALSE;
735 #if SUPPORT_HEARTBEAT
737 resources_os_list_hb_agents(
void)
746 GList *standards = NULL;
747 GList *agents = NULL;
749 standards = g_list_append(standards, strdup(
"ocf"));
750 standards = g_list_append(standards, strdup(
"lsb"));
751 standards = g_list_append(standards, strdup(
"service"));
756 standards = g_list_append(standards, strdup(
"systemd"));
757 g_list_free_full(agents, free);
764 standards = g_list_append(standards, strdup(
"upstart"));
765 g_list_free_full(agents, free);
772 standards = g_list_append(standards, strdup(
"nagios"));
773 g_list_free_full(agents, free);
777 #if SUPPORT_HEARTBEAT
778 standards = g_list_append(standards, strdup(
"heartbeat"));
787 if (strcasecmp(standard,
"ocf") == 0) {
797 if (standard == NULL || strcasecmp(standard,
"service") == 0) {
802 if (standard == NULL) {
806 result = g_list_concat(tmp1, tmp2);
813 result = g_list_concat(tmp1, tmp2);
821 result = g_list_concat(tmp1, tmp2);
827 }
else if (strcasecmp(standard,
"ocf") == 0) {
829 }
else if (strcasecmp(standard,
"lsb") == 0) {
831 #if SUPPORT_HEARTBEAT
832 }
else if (strcasecmp(standard,
"heartbeat") == 0) {
833 return resources_os_list_hb_agents();
836 }
else if (strcasecmp(standard,
"systemd") == 0) {
840 }
else if (strcasecmp(standard,
"upstart") == 0) {
844 }
else if (strcasecmp(standard,
"nagios") == 0) {
gboolean services_action_cancel(const char *name, const char *action, int interval)
GList * resources_list_providers(const char *standard)
Get a list of providers.
gboolean upstart_job_exists(const char *name)
gboolean mainloop_child_kill(pid_t pid)
svc_action_t * resources_action_create(const char *name, const char *standard, const char *provider, const char *agent, const char *action, int interval, int timeout, GHashTable *params, enum svc_action_flags flags)
Create a new resource action.
mainloop_io_t * stderr_gsource
GList * resources_os_list_ocf_agents(const char *provider)
GList * resources_os_list_ocf_providers(void)
gboolean recurring_action_timer(gpointer data)
GList * services_os_get_directory_list(const char *root, gboolean files, gboolean executable)
gboolean services_action_async(svc_action_t *op, void(*action_callback)(svc_action_t *))
gboolean is_op_blocked(const char *rsc)
Wrappers for and extensions to glib mainloop.
svc_action_t * services_action_create_generic(const char *exec, const char *args[])
GList * resources_os_list_lsb_agents(void)
gboolean upstart_job_exec(svc_action_t *op, gboolean synchronous)
enum svc_action_flags flags
gboolean services_os_action_execute(svc_action_t *op, gboolean synchronous)
#define crm_warn(fmt, args...)
GList * services_list(void)
gboolean cancel_recurring_action(svc_action_t *op)
svc_action_private_t * opaque
GList * upstart_job_listall(void)
#define crm_debug(fmt, args...)
gboolean operation_finalize(svc_action_t *op)
gboolean systemd_unit_exists(const char *name)
#define crm_trace(fmt, args...)
void(* callback)(svc_action_t *op)
gboolean services_action_sync(svc_action_t *op)
#define SUPPORT_HEARTBEAT
gboolean services_action_kick(const char *name, const char *action, int interval)
GList * systemd_unit_listall(void)
const char * resources_find_service_class(const char *agent)
GList * resources_list_agents(const char *standard, const char *provider)
Get a list of resource agents.
void services_add_inflight_op(svc_action_t *op)
GList * resources_list_standards(void)
GList * get_directory_list(const char *root, gboolean files, gboolean executable)
Get a list of files or directories in a given path.
#define NAGIOS_PLUGIN_DIR
#define crm_err(fmt, args...)
GList * resources_os_list_nagios_agents(void)
GHashTable * recurring_actions
mainloop_io_t * stdout_gsource
#define XML_ATTR_CRM_VERSION
void mainloop_del_fd(mainloop_io_t *client)
void services_action_cleanup(svc_action_t *op)
#define safe_str_eq(a, b)
void handle_blocked_ops(void)
void services_action_free(svc_action_t *op)
gboolean systemd_unit_exec(svc_action_t *op)
#define crm_info(fmt, args...)
svc_action_t * services_action_create(const char *name, const char *action, int interval, int timeout)