16 #include <sys/types.h>
45 static int operations = 0;
46 static GHashTable *recurring_actions = NULL;
50 static GList *blocked_ops = NULL;
53 static GList *inflight_ops = NULL;
55 static void handle_blocked_ops(
void);
90 init_recurring_actions(
void)
92 if (recurring_actions == NULL) {
93 recurring_actions = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
106 static inline gboolean
111 && (g_list_find(inflight_ops, op) != NULL);
127 expand_resource_class(
const char *rsc,
const char *standard,
const char *agent)
129 char *expanded_class = NULL;
135 crm_debug(
"Found %s agent %s for %s", found_class, agent, rsc);
136 expanded_class = strdup(found_class);
138 crm_info(
"Assuming resource class lsb for agent %s for %s",
143 expanded_class = strdup(standard);
146 return expanded_class;
158 dup_file_path(
const char *filename,
const char *dirname)
160 return (*filename ==
'/')? strdup(filename)
166 const char *provider,
const char *agent,
171 uint32_t ra_caps = 0;
178 if (pcmk__str_empty(
name)) {
179 crm_err(
"Cannot create operation without resource name");
183 if (pcmk__str_empty(standard)) {
184 crm_err(
"Cannot create operation for %s without resource class",
name);
190 crm_err(
"Cannot create operation for %s without provider",
name);
194 if (pcmk__str_empty(agent)) {
195 crm_err(
"Cannot create operation for %s without agent name",
name);
199 if (pcmk__str_empty(
action)) {
200 crm_err(
"Cannot create operation for %s without operation name",
name);
213 op->
standard = expand_resource_class(
name, standard, agent);
214 op->
agent = strdup(agent);
220 op->
action = strdup(
"status");
267 static int args_size =
sizeof(op->
opaque->
args) /
sizeof(
char *);
269 g_hash_table_iter_init(&iter, op->
params);
271 while (g_hash_table_iter_next(&iter, (gpointer *) & key, (gpointer *) & value) &&
272 index <= args_size - 3) {
284 g_hash_table_destroy(op->
params);
294 g_hash_table_destroy(params);
300 g_hash_table_destroy(params);
311 unsigned int cur_arg;
313 op = calloc(1,
sizeof(*op));
319 for (cur_arg = 1; args && args[cur_arg - 1]; cur_arg++) {
320 op->
opaque->
args[cur_arg] = strdup(args[cur_arg - 1]);
323 crm_err(
"svc_action_t args list not long enough for '%s' execution request.", exec);
347 GHashTable *params,
int sequence,
void *cb_data)
355 action->sequence = sequence;
356 action->cb_data = cb_data;
378 CRM_CHECK((op != NULL) && (user != NULL),
return -EINVAL);
396 action->synchronous =
false;
397 action->opaque->callback = cb;
410 services_set_op_pending(
svc_action_t *op, DBusPendingCall *pending)
412 if (op->
opaque->pending && (op->
opaque->pending != pending)) {
418 dbus_pending_call_unref(op->
opaque->pending);
420 op->
opaque->pending = pending;
422 crm_trace(
"Updated pending %s DBus call (%p)", op->
id, pending);
432 if ((op == NULL) || (op->
opaque == NULL)) {
437 if(op->
opaque->timerid != 0) {
439 g_source_remove(op->
opaque->timerid);
444 if (dbus_pending_call_get_completed(op->
opaque->pending)) {
446 crm_warn(
"Result of %s op %s was unhandled",
449 crm_debug(
"Will ignore any result of canceled %s op %s",
452 dbus_pending_call_cancel(op->
opaque->pending);
453 services_set_op_pending(op, NULL);
481 CRM_CHECK(g_list_find(inflight_ops, op) == NULL,
return);
482 CRM_CHECK(g_list_find(blocked_ops, op) == NULL,
return);
484 || (g_hash_table_lookup(recurring_actions, op->
id) == NULL),
513 g_hash_table_destroy(op->
params);
525 if (recurring_actions) {
526 g_hash_table_remove(recurring_actions, op->
id);
549 gboolean cancelled = FALSE;
554 init_recurring_actions();
555 op = g_hash_table_lookup(recurring_actions,
id);
573 crm_info(
"Terminating in-flight op %s[%d] early because it was cancelled",
576 if (cancelled == FALSE) {
577 crm_err(
"Termination of %s[%d] failed",
id, op->
pid);
584 if (inflight_systemd_or_upstart(op)) {
585 inflight_ops = g_list_remove(inflight_ops, op);
603 blocked_ops = g_list_remove(blocked_ops, op);
619 init_recurring_actions();
620 op = g_hash_table_lookup(recurring_actions,
id);
628 if (op->
pid || inflight_systemd_or_upstart(op)) {
655 dup = g_hash_table_lookup(recurring_actions, op->
id);
657 if (dup && (dup != op)) {
680 inline static gboolean
715 inflight_ops = g_list_append(inflight_ops, op);
729 inflight_ops = g_list_remove(inflight_ops, op);
730 blocked_ops = g_list_remove(blocked_ops, op);
733 handle_blocked_ops();
742 if (action_callback) {
745 if (action_fork_callback) {
750 init_recurring_actions();
751 if (handle_duplicate_recurring(op) == TRUE) {
756 g_hash_table_replace(recurring_actions, op->
id, op);
761 blocked_ops = g_list_append(blocked_ops, op);
765 return action_exec_helper(op);
775 static gboolean processing_blocked_ops = FALSE;
783 for (gIter = inflight_ops; gIter != NULL; gIter = gIter->next) {
794 handle_blocked_ops(
void)
796 GList *executed_ops = NULL;
799 gboolean res = FALSE;
801 if (processing_blocked_ops) {
806 processing_blocked_ops = TRUE;
810 for (gIter = blocked_ops; gIter != NULL; gIter = gIter->next) {
815 executed_ops = g_list_append(executed_ops, op);
816 res = action_exec_helper(op);
825 for (gIter = executed_ops; gIter != NULL; gIter = gIter->next) {
827 blocked_ops = g_list_remove(blocked_ops, op);
829 g_list_free(executed_ops);
831 processing_blocked_ops = FALSE;
837 const char *
class = op->standard;
839 if (op->
agent == NULL) {
840 crm_err(
"meta-data requested without specifying agent");
845 crm_err(
"meta-data requested for agent %s without specifying class",
855 crm_err(
"meta-data requested for %s, but could not determine class",
870 return action_exec_helper(op);
893 rc = action_get_metadata(op);
895 rc = action_exec_helper(op);
917 GList *standards = NULL;
918 GList *agents = NULL;
927 standards = g_list_append(standards,
929 g_list_free_full(agents, free);
936 standards = g_list_append(standards,
938 g_list_free_full(agents, free);
945 standards = g_list_append(standards,
947 g_list_free_full(agents, free);
967 if ((standard == NULL)
974 if (standard == NULL) {
978 result = g_list_concat(tmp1, tmp2);
985 result = g_list_concat(tmp1, tmp2);
993 result = g_list_concat(tmp1, tmp2);
1023 GList *standards = NULL;
1024 GList *providers = NULL;
1026 gboolean
rc = FALSE;
1027 gboolean has_providers = FALSE;
1030 for (iter = standards; iter != NULL; iter = iter->next) {
1031 if (
crm_str_eq(iter->data, standard, TRUE)) {
1044 if (has_providers == TRUE && provider != NULL) {
1046 for (iter = providers; iter != NULL; iter = iter->next) {
1047 if (
crm_str_eq(iter->data, provider, TRUE)) {
1052 }
else if (has_providers == FALSE && provider == NULL) {
1102 g_list_free(standards);
1103 g_list_free(providers);