14 #include <sys/types.h>
38 static int operations = 0;
39 static GHashTable *recurring_actions = NULL;
43 static GList *blocked_ops = NULL;
46 static GList *inflight_ops = NULL;
48 static void handle_blocked_ops(
void);
83 init_recurring_actions(
void)
85 if (recurring_actions == NULL) {
86 recurring_actions = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
99 static inline gboolean
104 && (g_list_find(inflight_ops, op) != NULL);
120 expand_resource_class(
const char *rsc,
const char *standard,
const char *agent)
122 char *expanded_class = NULL;
128 crm_debug(
"Found %s agent %s for %s", found_class, agent, rsc);
129 expanded_class = strdup(found_class);
131 crm_info(
"Assuming resource class lsb for agent %s for %s",
136 expanded_class = strdup(standard);
139 return expanded_class;
151 dup_file_path(
const char *filename,
const char *dirname)
153 return (*filename ==
'/')? strdup(filename)
159 const char *provider,
const char *agent,
160 const char *action, guint interval_ms,
int timeout,
171 if (crm_strlen_zero(name)) {
172 crm_err(
"Cannot create operation without resource name");
176 if (crm_strlen_zero(standard)) {
177 crm_err(
"Cannot create operation for %s without resource class", name);
183 crm_err(
"Cannot create operation for %s without provider", name);
187 if (crm_strlen_zero(agent)) {
188 crm_err(
"Cannot create operation for %s without agent name", name);
192 if (crm_strlen_zero(action)) {
193 crm_err(
"Cannot create operation for %s without operation name", name);
203 op->
rsc = strdup(name);
206 op->
standard = expand_resource_class(name, standard, agent);
207 op->
agent = strdup(agent);
213 op->
action = strdup(
"status");
215 op->
action = strdup(action);
260 static int args_size =
sizeof(op->
opaque->
args) /
sizeof(
char *);
262 g_hash_table_iter_init(&iter, op->
params);
264 while (g_hash_table_iter_next(&iter, (gpointer *) & key, (gpointer *) & value) &&
265 index <= args_size - 3) {
277 g_hash_table_destroy(op->
params);
287 g_hash_table_destroy(params);
293 g_hash_table_destroy(params);
304 unsigned int cur_arg;
306 op = calloc(1,
sizeof(*op));
312 for (cur_arg = 1; args && args[cur_arg - 1]; cur_arg++) {
313 op->
opaque->
args[cur_arg] = strdup(args[cur_arg - 1]);
316 crm_err(
"svc_action_t args list not long enough for '%s' execution request.", exec);
340 GHashTable *params,
int sequence,
void *cb_data)
346 action->
id = strdup(
id);
371 CRM_CHECK((op != NULL) && (user != NULL),
return -EINVAL);
403 services_set_op_pending(
svc_action_t *op, DBusPendingCall *pending)
405 if (op->
opaque->pending && (op->
opaque->pending != pending)) {
411 dbus_pending_call_unref(op->
opaque->pending);
413 op->
opaque->pending = pending;
415 crm_trace(
"Updated pending %s DBus call (%p)", op->
id, pending);
425 if ((op == NULL) || (op->
opaque == NULL)) {
430 if(op->
opaque->timerid != 0) {
432 g_source_remove(op->
opaque->timerid);
437 if (dbus_pending_call_get_completed(op->
opaque->pending)) {
439 crm_warn(
"Result of %s op %s was unhandled",
442 crm_debug(
"Will ignore any result of canceled %s op %s",
445 dbus_pending_call_cancel(op->
opaque->pending);
446 services_set_op_pending(op, NULL);
474 CRM_CHECK(g_list_find(inflight_ops, op) == NULL,
return);
475 CRM_CHECK(g_list_find(blocked_ops, op) == NULL,
return);
477 || (g_hash_table_lookup(recurring_actions, op->
id) == NULL),
506 g_hash_table_destroy(op->
params);
518 if (recurring_actions) {
519 g_hash_table_remove(recurring_actions, op->
id);
542 gboolean cancelled = FALSE;
547 init_recurring_actions();
548 op = g_hash_table_lookup(recurring_actions,
id);
566 crm_info(
"Terminating in-flight op %s (pid %d) early because it was cancelled",
569 if (cancelled == FALSE) {
570 crm_err(
"Termination of %s (pid %d) failed",
id, op->
pid);
577 if (inflight_systemd_or_upstart(op)) {
578 inflight_ops = g_list_remove(inflight_ops, op);
596 blocked_ops = g_list_remove(blocked_ops, op);
612 init_recurring_actions();
613 op = g_hash_table_lookup(recurring_actions,
id);
621 if (op->
pid || inflight_systemd_or_upstart(op)) {
648 dup = g_hash_table_lookup(recurring_actions, op->
id);
650 if (dup && (dup != op)) {
673 inline static gboolean
708 inflight_ops = g_list_append(inflight_ops, op);
722 inflight_ops = g_list_remove(inflight_ops, op);
723 blocked_ops = g_list_remove(blocked_ops, op);
726 handle_blocked_ops();
733 if (action_callback) {
738 init_recurring_actions();
739 if (handle_duplicate_recurring(op) == TRUE) {
744 g_hash_table_replace(recurring_actions, op->
id, op);
748 blocked_ops = g_list_append(blocked_ops, op);
752 return action_exec_helper(op);
756 static gboolean processing_blocked_ops = FALSE;
764 for (gIter = inflight_ops; gIter != NULL; gIter = gIter->next) {
775 handle_blocked_ops(
void)
777 GList *executed_ops = NULL;
780 gboolean res = FALSE;
782 if (processing_blocked_ops) {
787 processing_blocked_ops = TRUE;
791 for (gIter = blocked_ops; gIter != NULL; gIter = gIter->next) {
796 executed_ops = g_list_append(executed_ops, op);
797 res = action_exec_helper(op);
806 for (gIter = executed_ops; gIter != NULL; gIter = gIter->next) {
808 blocked_ops = g_list_remove(blocked_ops, op);
810 g_list_free(executed_ops);
812 processing_blocked_ops = FALSE;
817 nagios_get_metadata(
const char *
type,
char **output)
820 FILE *file_strm = NULL;
821 int start = 0, length = 0, read_len = 0;
825 file_strm = fopen(metadata_file,
"r");
826 if (file_strm == NULL) {
827 crm_err(
"Metadata file %s does not exist", metadata_file);
833 start = ftell(file_strm);
834 fseek(file_strm, 0L, SEEK_END);
835 length = ftell(file_strm);
836 fseek(file_strm, 0L, start);
842 crm_info(
"%s was not valid", metadata_file);
848 crm_trace(
"Reading %d bytes from file", length);
849 *output = calloc(1, (length + 1));
850 read_len = fread(*output, 1, length, file_strm);
851 if (read_len != length) {
852 crm_err(
"Calculated and read bytes differ: %d vs. %d",
869 const char *
class = op->standard;
871 if (op->
agent == NULL) {
872 crm_err(
"meta-data requested without specifying agent");
877 crm_err(
"meta-data requested for agent %s without specifying class",
887 crm_err(
"meta-data requested for %s, but could not determine class",
902 return action_exec_helper(op);
925 rc = action_get_metadata(op);
927 rc = action_exec_helper(op);
949 GList *standards = NULL;
950 GList *agents = NULL;
959 standards = g_list_append(standards,
961 g_list_free_full(agents, free);
968 standards = g_list_append(standards,
970 g_list_free_full(agents, free);
977 standards = g_list_append(standards,
979 g_list_free_full(agents, free);
999 if ((standard == NULL)
1006 if (standard == NULL) {
1010 result = g_list_concat(tmp1, tmp2);
1017 result = g_list_concat(tmp1, tmp2);
1025 result = g_list_concat(tmp1, tmp2);