| 1568 | } |
| 1569 | |
| 1570 | enum pe_graph_flags |
| 1571 | native_update_actions(action_t * first, action_t * then, node_t * node, enum pe_action_flags flags, |
| 1572 | enum pe_action_flags filter, enum pe_ordering type) |
| 1573 | { |
| 1574 | /* flags == get_action_flags(first, then_node) called from update_action() */ |
| 1575 | enum pe_graph_flags changed = pe_graph_none; |
| 1576 | enum pe_action_flags then_flags = then->flags; |
| 1577 | enum pe_action_flags first_flags = first->flags; |
| 1578 | |
| 1579 | if (type & pe_order_asymmetrical) { |
| 1580 | resource_t *then_rsc = then->rsc; |
| 1581 | enum rsc_role_e then_rsc_role = then_rsc ? then_rsc->fns->state(then_rsc, TRUE) : 0; |
| 1582 | |
| 1583 | if (!then_rsc) { |
| 1584 | /* ignore */ |
| 1585 | } else if ((then_rsc_role == RSC_ROLE_STOPPED) && safe_str_eq(then->task, RSC_STOP)) { |
| 1586 | /* ignore... if 'then' is supposed to be stopped after 'first', but |
| 1587 | * then is already stopped, there is nothing to be done when non-symmetrical. */ |
| 1588 | } else if ((then_rsc_role == RSC_ROLE_STARTED) && safe_str_eq(then->task, RSC_START)) { |
| 1589 | /* ignore... if 'then' is supposed to be started after 'first', but |
| 1590 | * then is already started, there is nothing to be done when non-symmetrical. */ |
| 1591 | } else if (!(first->flags & pe_action_runnable)) { |
| 1592 | /* prevent 'then' action from happening if 'first' is not runnable and |
| 1593 | * 'then' has not yet occurred. */ |
| 1594 | pe_clear_action_bit(then, pe_action_runnable); |
| 1595 | pe_clear_action_bit(then, pe_action_optional); |
| 1596 | pe_rsc_trace(then->rsc, "Unset optional and runnable on %s", then->uuid); |
| 1597 | } else { |
| 1598 | /* ignore... then is allowed to start/stop if it wants to. */ |
| 1599 | } |
| 1600 | } |
| 1601 | |
| 1602 | if (type & pe_order_implies_first) { |
| 1603 | if ((filter & pe_action_optional) && (flags & pe_action_optional) == 0) { |
| 1604 | pe_rsc_trace(first->rsc, "Unset optional on %s because of %s", first->uuid, then->uuid); |
| 1605 | pe_clear_action_bit(first, pe_action_optional); |
| 1606 | } |
| 1607 | } |
| 1608 | |
| 1609 | if (type & pe_order_implies_first_master) { |
| 1610 | if ((filter & pe_action_optional) && |
| 1611 | ((then->flags & pe_action_optional) == FALSE) && |
| 1612 | then->rsc && (then->rsc->role == RSC_ROLE_MASTER)) { |
| 1613 | clear_bit(first->flags, pe_action_optional); |
| 1614 | } |
| 1615 | } |
| 1616 | |
| 1617 | if (is_set(type, pe_order_runnable_left) |
| 1618 | && is_set(filter, pe_action_runnable) |
| 1619 | && is_set(then->flags, pe_action_runnable) |
| 1620 | && is_set(flags, pe_action_runnable) == FALSE) { |
| 1621 | pe_rsc_trace(then->rsc, "Unset runnable on %s because of %s", then->uuid, first->uuid); |
| 1622 | pe_clear_action_bit(then, pe_action_runnable); |
| 1623 | } |
| 1624 | |
| 1625 | if (is_set(type, pe_order_implies_then) |
| 1626 | && is_set(filter, pe_action_optional) |
| 1627 | && is_set(then->flags, pe_action_optional) |
no test coverage detected