action = custom_action(rsc, crm_strdup(id), task, NULL, TRUE, data_set);
action = custom_action(rsc, crm_strdup(id), task, NULL, TRUE, TRUE, data_set);
unpack_rsc_op(resource_t *rsc, node_t *node, crm_data_t *xml_op,	      int *max_call_id, pe_working_set_t *data_set) {	const char *id          = NULL;	const char *task        = NULL; 	const char *task_id     = NULL;	const char *task_status = NULL;	int task_id_i = -1;	int task_status_i = -2;	action_t *action = NULL;	gboolean is_stop_action = FALSE;		CRM_DEV_ASSERT(rsc    != NULL); if(crm_assert_failed) { return FALSE; }	CRM_DEV_ASSERT(node   != NULL); if(crm_assert_failed) { return FALSE; }	CRM_DEV_ASSERT(xml_op != NULL); if(crm_assert_failed) { return FALSE; }		id = ID(xml_op);	task        = crm_element_value(xml_op, XML_LRM_ATTR_TASK); 	task_id     = crm_element_value(xml_op, XML_LRM_ATTR_CALLID);	task_status = crm_element_value(xml_op, XML_LRM_ATTR_OPSTATUS);	CRM_DEV_ASSERT(id != NULL);        if(crm_assert_failed) { return FALSE; }		CRM_DEV_ASSERT(task != NULL);        if(crm_assert_failed) { return FALSE; }	CRM_DEV_ASSERT(task_status != NULL);	if(crm_assert_failed) { return FALSE; }	task_status_i = atoi(task_status);	CRM_DEV_ASSERT(task_status_i <= LRM_OP_ERROR);	if(crm_assert_failed) {return FALSE;}	CRM_DEV_ASSERT(task_status_i >= LRM_OP_PENDING);	if(crm_assert_failed) {return FALSE;}	if(safe_str_eq(task, CRMD_ACTION_NOTIFY)) {		/* safe to ignore these */		return TRUE;	}		crm_debug_2("Unpacking task %s/%s (call_id=%s, status=%s) on %s",		    rsc->id, task, task_id, task_status, node->details->uname);		if(safe_str_eq(task, CRMD_ACTION_STOP)) {		is_stop_action = TRUE;	}		if(task_status_i != LRM_OP_PENDING) {		task_id_i = crm_atoi(task_id, "-1");		CRM_DEV_ASSERT(task_id != NULL);		if(crm_assert_failed) { return FALSE; }		CRM_DEV_ASSERT(task_id_i >= 0);		if(crm_assert_failed) { return FALSE; }		if(task_id_i == *max_call_id) {			crm_debug_2("Already processed this call");			return TRUE;		}		CRM_DEV_ASSERT(task_id_i > *max_call_id);		if(crm_assert_failed) { return FALSE; }	}	if(*max_call_id < task_id_i) {		*max_call_id = task_id_i;	}		if(node->details->unclean) {		crm_debug_2("Node %s (where %s is running) is unclean."			  " Further action depends on the value of %s",			  node->details->uname, rsc->id, XML_RSC_ATTR_STOPFAIL);	}	if(task_status_i == LRM_OP_ERROR	   || task_status_i == LRM_OP_TIMEOUT	   || task_status_i == LRM_OP_NOTSUPPORTED) {		action = custom_action(rsc, crm_strdup(id), task, NULL, TRUE, data_set);		if(action->on_fail == action_fail_ignore) {			task_status_i = LRM_OP_DONE;		}	}		switch(task_status_i) {		case LRM_OP_PENDING:			/*			 * TODO: this may need some more thought			 * Some cases:			 * - PE reinvoked with pending action that will succeed			 * - PE reinvoked with pending action that will fail			 * - After DC election			 * - After startup			 *			 * pending start - required start			 * pending stop  - required stop			 * pending <any> on unavailable node - stonith			 *			 * For now this should do			 */			if(safe_str_eq(task, CRMD_ACTION_START)) {				rsc->state = rsc_state_starting;				rsc->role = RSC_ROLE_STARTED;						/* make sure it is re-issued but,				 * only if we have quorum				 */				if(data_set->have_quorum == TRUE				   || data_set->no_quorum_policy == no_quorum_ignore){					/* do not specify the node, we may want					 * to start it elsewhere					 */					start_action(rsc, NULL, FALSE);				}							} else if(safe_str_eq(task, CRMD_ACTION_PROMOTE)) {				CRM_DEV_ASSERT(rsc->state == rsc_state_active);				rsc->role = RSC_ROLE_MASTER;			} else if(rsc->state > rsc_state_starting) {				crm_debug_2("Re-issuing pending recurring task:"					    " %s for %s on %s",					    task, rsc->id, node->details->id);				/* do not specify the node, we may want				 * to start it elsewhere				 */				custom_action(rsc, crm_strdup(id),					      task, NULL, FALSE, data_set);			}			break;				case LRM_OP_DONE:			crm_debug_3("%s/%s completed on %s",				    rsc->id, task, node->details->uname);			if(is_stop_action) {				rsc->state = rsc_state_inactive;				rsc->role = RSC_ROLE_STOPPED;			} else if(safe_str_eq(task, CRMD_ACTION_START)) {				crm_debug_3("%s active on %s",					    rsc->id, node->details->uname);				rsc->state = rsc_state_active;				rsc->role = RSC_ROLE_STARTED;			} else if(safe_str_eq(task, CRMD_ACTION_PROMOTE)) {				CRM_DEV_ASSERT(rsc->state == rsc_state_active);				rsc->role = RSC_ROLE_MASTER;			} else if(safe_str_eq(task, CRMD_ACTION_DEMOTE)) {				CRM_DEV_ASSERT(rsc->state == rsc_state_active);				rsc->role = RSC_ROLE_SLAVE;							} else if(rsc->state > rsc_state_starting) {				/* make sure its already created and is optional				 *				 * creating it now tells create_recurring_actions() 				 *  that it can safely leave it optional				 */				custom_action(rsc, crm_strdup(id),					      task, NULL, TRUE, data_set);			}			break;		case LRM_OP_ERROR:		case LRM_OP_TIMEOUT:		case LRM_OP_NOTSUPPORTED:			crm_debug_2("Processing failed op (%s) for %s on %s",				  task, rsc->id, node->details->uname);			action = custom_action(				rsc, crm_strdup(id), task, NULL, TRUE, data_set);			if(task_status_i == LRM_OP_NOTSUPPORTED			   || is_stop_action			   || safe_str_eq(task, CRMD_ACTION_START) ) {				crm_warn("Handling failed %s for %s on %s",					 task, rsc->id, node->details->uname);				rsc2node_new("dont_run__failed_stopstart",					     rsc, -INFINITY, node, data_set);			}			if(safe_str_eq(task, CRMD_ACTION_PROMOTE)) {				CRM_DEV_ASSERT(rsc->state == rsc_state_active);				rsc->role = RSC_ROLE_MASTER;			}			rsc->state = rsc_state_failed;			if(node->details->unclean) {				rsc->state = rsc_state_failed;				stop_action(rsc, node, FALSE);			} else if(action->on_fail == action_fail_fence) {				/* treat it as if it is still running				 * but also mark the node as unclean				 */				rsc->state = rsc_state_failed;				node->details->unclean = TRUE;				stop_action(rsc, node, FALSE);							} else if(action->on_fail == action_fail_block) {				/* is_managed == FALSE will prevent any				 * actions being sent for the resource				 */				rsc->is_managed = FALSE;				rsc->state = rsc_state_failed;							} else if(action->on_fail == action_fail_migrate) {				rsc->state = rsc_state_failed; 				stop_action(rsc, node, FALSE);				/* make sure it comes up somewhere else				 * or not at all				 */				rsc2node_new("__action_migration_auto__",					     rsc, -INFINITY, node, data_set);							} else if(action->fail_role == RSC_ROLE_STOPPED) {				rsc->state = rsc_state_failed;				/* make sure it doesnt come up again */				native_assign_color(rsc, data_set->no_color);			} else if(action->fail_role != RSC_ROLE_STARTED) {				rsc->next_role = action->fail_role;			} else {				rsc->state = rsc_state_failed; 				stop_action(rsc, node, FALSE);			}						break;		case LRM_OP_CANCELLED:			/* do nothing?? */			pe_err("Dont know what to do for cancelled ops yet");			break;	}	return TRUE;}