16 #include <sys/types.h>
41 static int operations = 0;
42 static GHashTable *recurring_actions = NULL;
46 static GList *blocked_ops = NULL;
49 static GList *inflight_ops = NULL;
51 static void handle_blocked_ops(
void);
86 init_recurring_actions(
void)
88 if (recurring_actions == NULL) {
89 recurring_actions = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
102 static inline gboolean
107 && (g_list_find(inflight_ops, op) != NULL);
123 expand_resource_class(
const char *rsc,
const char *standard,
const char *agent)
125 char *expanded_class = NULL;
131 crm_debug(
"Found %s agent %s for %s", found_class, agent, rsc);
132 expanded_class = strdup(found_class);
134 crm_info(
"Assuming resource class lsb for agent %s for %s",
139 expanded_class = strdup(standard);
142 return expanded_class;
154 dup_file_path(
const char *filename,
const char *dirname)
156 return (*filename ==
'/')? strdup(filename)
162 const char *provider,
const char *agent,
163 const char *action, guint interval_ms,
int timeout,
167 uint32_t ra_caps = 0;
174 if (crm_strlen_zero(name)) {
175 crm_err(
"Cannot create operation without resource name");
179 if (crm_strlen_zero(standard)) {
180 crm_err(
"Cannot create operation for %s without resource class", name);
186 crm_err(
"Cannot create operation for %s without provider", name);
190 if (crm_strlen_zero(agent)) {
191 crm_err(
"Cannot create operation for %s without agent name", name);
195 if (crm_strlen_zero(action)) {
196 crm_err(
"Cannot create operation for %s without operation name", name);
206 op->
rsc = strdup(name);
209 op->
standard = expand_resource_class(name, standard, agent);
210 op->
agent = strdup(agent);
216 op->
action = strdup(
"status");
218 op->
action = strdup(action);
263 static int args_size =
sizeof(op->
opaque->
args) /
sizeof(
char *);
265 g_hash_table_iter_init(&iter, op->
params);
267 while (g_hash_table_iter_next(&iter, (gpointer *) & key, (gpointer *) & value) &&
268 index <= args_size - 3) {
280 g_hash_table_destroy(op->
params);
290 g_hash_table_destroy(params);
296 g_hash_table_destroy(params);
307 unsigned int cur_arg;
309 op = calloc(1,
sizeof(*op));
315 for (cur_arg = 1; args && args[cur_arg - 1]; cur_arg++) {
316 op->
opaque->
args[cur_arg] = strdup(args[cur_arg - 1]);
319 crm_err(
"svc_action_t args list not long enough for '%s' execution request.", exec);
343 GHashTable *params,
int sequence,
void *cb_data)
349 action->
id = strdup(
id);
374 CRM_CHECK((op != NULL) && (user != NULL),
return -EINVAL);
406 services_set_op_pending(
svc_action_t *op, DBusPendingCall *pending)
408 if (op->
opaque->pending && (op->
opaque->pending != pending)) {
414 dbus_pending_call_unref(op->
opaque->pending);
416 op->
opaque->pending = pending;
418 crm_trace(
"Updated pending %s DBus call (%p)", op->
id, pending);
428 if ((op == NULL) || (op->
opaque == NULL)) {
433 if(op->
opaque->timerid != 0) {
435 g_source_remove(op->
opaque->timerid);
440 if (dbus_pending_call_get_completed(op->
opaque->pending)) {
442 crm_warn(
"Result of %s op %s was unhandled",
445 crm_debug(
"Will ignore any result of canceled %s op %s",
448 dbus_pending_call_cancel(op->
opaque->pending);
449 services_set_op_pending(op, NULL);
477 CRM_CHECK(g_list_find(inflight_ops, op) == NULL,
return);
478 CRM_CHECK(g_list_find(blocked_ops, op) == NULL,
return);
480 || (g_hash_table_lookup(recurring_actions, op->
id) == NULL),
509 g_hash_table_destroy(op->
params);
521 if (recurring_actions) {
522 g_hash_table_remove(recurring_actions, op->
id);
545 gboolean cancelled = FALSE;
550 init_recurring_actions();
551 op = g_hash_table_lookup(recurring_actions,
id);
569 crm_info(
"Terminating in-flight op %s[%d] early because it was cancelled",
572 if (cancelled == FALSE) {
573 crm_err(
"Termination of %s[%d] failed",
id, op->
pid);
580 if (inflight_systemd_or_upstart(op)) {
581 inflight_ops = g_list_remove(inflight_ops, op);
599 blocked_ops = g_list_remove(blocked_ops, op);
615 init_recurring_actions();
616 op = g_hash_table_lookup(recurring_actions,
id);
624 if (op->
pid || inflight_systemd_or_upstart(op)) {
651 dup = g_hash_table_lookup(recurring_actions, op->
id);
653 if (dup && (dup != op)) {
676 inline static gboolean
711 inflight_ops = g_list_append(inflight_ops, op);
725 inflight_ops = g_list_remove(inflight_ops, op);
726 blocked_ops = g_list_remove(blocked_ops, op);
729 handle_blocked_ops();
738 if (action_callback) {
741 if (action_fork_callback) {
746 init_recurring_actions();
747 if (handle_duplicate_recurring(op) == TRUE) {
752 g_hash_table_replace(recurring_actions, op->
id, op);
757 blocked_ops = g_list_append(blocked_ops, op);
761 return action_exec_helper(op);
771 static gboolean processing_blocked_ops = FALSE;
779 for (gIter = inflight_ops; gIter != NULL; gIter = gIter->next) {
790 handle_blocked_ops(
void)
792 GList *executed_ops = NULL;
795 gboolean res = FALSE;
797 if (processing_blocked_ops) {
802 processing_blocked_ops = TRUE;
806 for (gIter = blocked_ops; gIter != NULL; gIter = gIter->next) {
811 executed_ops = g_list_append(executed_ops, op);
812 res = action_exec_helper(op);
821 for (gIter = executed_ops; gIter != NULL; gIter = gIter->next) {
823 blocked_ops = g_list_remove(blocked_ops, op);
825 g_list_free(executed_ops);
827 processing_blocked_ops = FALSE;
832 nagios_get_metadata(
const char *
type,
char **output)
835 FILE *file_strm = NULL;
836 int start = 0, length = 0, read_len = 0;
840 file_strm = fopen(metadata_file,
"r");
841 if (file_strm == NULL) {
842 crm_err(
"Metadata file %s does not exist", metadata_file);
848 start = ftell(file_strm);
849 fseek(file_strm, 0L, SEEK_END);
850 length = ftell(file_strm);
851 fseek(file_strm, 0L, start);
857 crm_info(
"%s was not valid", metadata_file);
863 crm_trace(
"Reading %d bytes from file", length);
864 *output = calloc(1, (length + 1));
865 read_len = fread(*output, 1, length, file_strm);
866 if (read_len != length) {
867 crm_err(
"Calculated and read bytes differ: %d vs. %d",
884 const char *
class = op->standard;
886 if (op->
agent == NULL) {
887 crm_err(
"meta-data requested without specifying agent");
892 crm_err(
"meta-data requested for agent %s without specifying class",
902 crm_err(
"meta-data requested for %s, but could not determine class",
917 return action_exec_helper(op);
940 rc = action_get_metadata(op);
942 rc = action_exec_helper(op);
964 GList *standards = NULL;
965 GList *agents = NULL;
974 standards = g_list_append(standards,
976 g_list_free_full(agents, free);
983 standards = g_list_append(standards,
985 g_list_free_full(agents, free);
992 standards = g_list_append(standards,
994 g_list_free_full(agents, free);
1014 if ((standard == NULL)
1021 if (standard == NULL) {
1025 result = g_list_concat(tmp1, tmp2);
1032 result = g_list_concat(tmp1, tmp2);
1040 result = g_list_concat(tmp1, tmp2);
1070 GList *standards = NULL;
1071 GList *providers = NULL;
1073 gboolean rc = FALSE;
1074 gboolean has_providers = FALSE;
1077 for (iter = standards; iter != NULL; iter = iter->next) {
1078 if (
crm_str_eq(iter->data, standard, TRUE)) {
1091 if (has_providers == TRUE && provider != NULL) {
1093 for (iter = providers; iter != NULL; iter = iter->next) {
1094 if (
crm_str_eq(iter->data, provider, TRUE)) {
1099 }
else if (has_providers == FALSE && provider == NULL) {
1149 g_list_free(standards);
1150 g_list_free(providers);