Purpose
ha_gs_n_phase_callback - A callback routine that the Group Services subsystem calls to deliver an n-phase notification to a GS client
Library
GSAPI Thread-Safe Library (libha_gs_r.a)
GSAPI Library (not thread-safe) (libha_gs.a)
Syntax
#include <ha_gs.h> void ha_gs_n_phase_callback( const ha_gs_n_phase_notification_t *notification)
Parameters
Description
The ha_gs_n_phase_callback subroutine defines a GS client's n-phase callback routine. The GS client uses it to handle n-phase notifications from the Group Services subsystem. The process provides the address of the n-phase callback routine to the Group Services subsystem on the ha_gs_join subroutine when it joins the group as a provider. The Group Services subsystem then calls the n-phase callback routine when it has an n-phase notification to deliver to the GS client. This occurs during each voting phase of an n-phase protocol.
On input, the n-phase callback routine receives information that specifies the proposed changes to the group, such as its membership or its state value, as well as other control information for the protocol, such as the phase number and the voting time limit.
In response to this notification, it is expected that the provider will vote on the proposal by calling the ha_gs_vote subroutine. The call to submit the vote may be made either before or after the callback routine returns. The notification contains an identifying token that must be passed on the call to the ha_gs_vote subroutine so that the Group Services subsystem can match the vote to the protocol.
On input, the n-phase callback routine receives a pointer to the n-phase notification block. The n-phase notification block has the following definition:
typedef struct { ha_gs_notification_type_t gs_notification_type; ha_gs_token_t gs_provider_token; ha_gs_request_t gs_protocol_type; ha_gs_summary_code_t gs_summary_code; ha_gs_time_limit_t gs_time_limit; ha_gs_proposal_t *gs_proposal; } ha_gs_n_phase_notification_t;
The gs_notification_type field contains the type of notification. For an n-phase notification, it contains a value of HA_GS_N_PHASE_NOTIFICATION.
The gs_provider_token field contains a token that identifies the caller as a provider of the group. This token was previously initialized when the provider joined the group by using the ha_gs_join subroutine.
The gs_protocol_type field contains the type of request for which this n-phase notification is being delivered.
The gs_summary_code field contains one or more flags that indicate whether any default votes were recorded during any previous voting phase. It can contain one or more of the following flags:
The gs_time_limit field contains the time limit, in seconds, within which the provider must submit its vote for this voting phase. If the field is set to a value of 0, no limit is enforced.
The gs_proposal field points to the proposal block for the proposal on which the vote is requested.
The proposal block is common to the notifications that carry proposal information for one-phase and n-phase protocols. It is provided on input to protocol callback functions and has the following definition:
typedef struct { ha_gs_phase_info_t gs_phase_info; ha_gs_provider_t gs_proposed_by; ha_gs_updates_t gs_whats_changed; ha_gs_membership_t *gs_current_providers; ha_gs_membership_t *gs_changing_providers; ha_gs_leave_array_t *gs_leave_info; ha_gs_expel_info_t *gs_expel_info; ha_gs_state_value_t *gs_current_state_value; ha_gs_state_value_t *gs_proposed_state_value; ha_gs_state_value_t *gs_source_state_value; ha_gs_provider_message_t *gs_provider_message; ha_gs_group_attributes_t *gs_new_group_attributes; } ha_gs_proposal_t;
The gs_phase_info field contains information about the type of protocol that is running and the phase number to which this notification applies. It has the following definition:
typedef struct { ha_gs_num_phases_t gs_num_phases; ha_gs_num_phases_t gs_phase_number; } ha_gs_phase_info_t;
The gs_num_phases field contains:
The gs_phase_number field contains the phase number to which this notification applies.
The gs_proposed_by field contains the provider information block that identifies the provider (or the Group Services subsystem itself) that initiated the executing proposal. The provider information block is defined later in this section.
On all join protocols, this field always contains the provider information block for the GS client that is running the callback rather than the provider that initiated the join. This allows each provider to capture its own provider information block. For protocols (such as the cast-out protocol) that are initiated by the Group Services subsystem itself, this field contains the values that so identify it. For more details, see the description of the provider information block later in this section.
The gs_whats_changed field contains one or more flags that indicate whether the membership or the state values contained in the proposal are changes from the base group values at the beginning of the protocol, and if the notification contains a provider-broadcast message. It can contain one or more of the following flags:
The gs_current_providers field points to a list of providers that currently belong to the group. It has the following definition:
typedef struct { unsigned int gs_count; ha_gs_provider_t *gs_providers; } ha_gs_membership_t;
The gs_count field contains the number of providers in the list.
The gs_providers field points to the list of providers. Each provider is described by a provider information block, which is defined later in this section.
The gs_changing_providers field points to a list of providers that are joining or leaving the group through this protocol. If none are joining or leaving, the field is null.
The gs_leave_info field points to an array that contains the reason codes for each provider specified in the gs_changing_providers field that is leaving the group. This leave information field, which is used for voluntary and failure leave protocols only, has the following definition:
typedef struct { unsigned int gs_count; ha_gs_leave_info_t *gs_leave_codes; } ha_gs_leave_array_t;
The gs_count field contains the number of providers that are leaving.
The gs_leave_codes field points to an entry for each provider that is leaving the group. This entry specifies whether it is a voluntary or failure leave, and the reason or reasons for the leave. The leave reason entries are in the same order in which the providers are listed in the gs_changing_providers list.
The leave reason entries have the following definition:
typedef struct { unsigned int gs_voluntary_or_failure; unsigned int gs_voluntary_leave_code; } ha_gs_leave_info_t;
The gs_voluntary_or_failure field contains one or more of the following flags:
The voluntary_leave_code field contains the application-defined leave code that was specified on input to the ha_gs_leave subroutine.
If the Group Services subsystem detected that the provider's process failed, and its node also failed before the process failure could be reported, this flag could be set with the HA_GS_HOST_FAILURE flag.
If this flag is set, the gs_voluntary_leave_code field is not used and is undefined.
If the Group Services subsystem detected that the provider's process failed, and its node also failed before the process failure could be reported, this flag could be set with the HA_GS_PROVIDER_FAILURE flag.
If this flag is set, the gs_voluntary_leave_code field is not used and is undefined.
If this flag is set, the gs_voluntary_leave_code field is not used and is undefined.
If this flag is set, the gs_voluntary_leave_code field is not used and is undefined.
The gs_expel_info field points to a structure that contains expel information. This expel information field, which is used for expel protocols only, has the following definition:
typedef struct { int gs_deactivate_phase; int gs_expel_flag_length; char *gs_expel_flag; } ha_gs_expel_info_t;
The gs_deactivate_phase field contains the phase number in which the deactivate script should be run against any providers that are being expelled. If this field contains 0, no deactivate script is invoked.
The gs_expel_flag_length field contains the length of the expel flag.
The gs_expel_flag field contains a flag that is to be passed to the deactivate script. It is a pointer to a null-terminated string with a maximum length of 256 bytes. If the pointer is null, no flag is passed to the deactivate script.
The gs_current_state_value field points to a buffer that contains the current state value of the group. This is the latest approved state value of the group, which is the state value as it was at the beginning of the protocol. For the definition of the group state value, see the ha_gs_change_state_value man page.
The gs_proposed_state_value field points to a buffer that contains the proposed new value for the group's state. The gs_whats_changed field contains a value of either HA_GS_PROPOSED_STATE_VALUE or HA_GS_ONGOING_STATE_VALUE. If there is no new state value for this protocol, this field is null. For the definition of the group state value, see the ha_gs_change_state_value man page.
The gs_source_state_value field points to a buffer that contains the updated state value of this group's source-group, if this proposal is the result of a change in the source-group. The gs_whats_changed field contains a value of HA_GS_REFLECTED_SOURCE_VALUE. Otherwise, this field is null. For the definition of the group state value, see the ha_gs_change_state_value man page.
The gs_provider_message field points to a buffer that contains the provider-broadcast message, if any. The gs_whats_changed field contains a value of HA_GS_UPDATED_PROVIDER_MESSAGE. Otherwise, the field is null. For information on the definition of the provider-broadcast message, see the ha_gs_send_message man page.
The provider information block identifies each provider to the other providers in a group. It contains an application-defined instance number and the number of the node on which the provider is running. It has the following definition:
const short HA_GS_node_number = -1; const short HA_GS_instance_number = -1; #define gs_node_number _gs_provider_info._gs_node_number #define gs_instance_number _gs_provider_info._gs_instance_number typedef union { struct { short _gs_instance_number; short _gs_node_number; } _gs_provider_info; int gs_provider_id; } ha_gs_provider_t;
The gs_instance_number field contains the instance number of the provider. This instance number is specified by the provider and must be unique for each provider on a single node within a group.
When Group Services itself is acting as a "provider," the gs_instance_number field contains a value of HA_GS_instance_number.
The gs_node_number field contains the node number of the provider. This node number is specified by the Group Services subsystem.
When Group Services itself is acting as a "provider," the gs_node_number field contains a value of HA_GS_node_number.
The gs_provider_id field contains the gs_instance_number and the gs_node_number in a single word.
Restrictions
The following discussion of multiprocessing considerations applies to all callback routines, not just those for handling n-phase notifications.
The Group Services subsystem presents all notifications to all providers in a single group in the same order. The providers should try to invoke the same callback routines in the same order.
However, only for n-phase protocols does the Group Services subsystem verify that all of the group's providers have reached the same execution point before continuing to the next notification. In other cases, the providers may not receive and react to the notifications at the same time. For example, a provider might not receive a notification immediately because it is busy and not reading the socket.
If GS clients are providers in multiple groups, there is no guarantee that every provider will receive the notifications from different groups in the same order.
For multi-threaded clients, it is assumed that the callback routines are thread-safe and reentrant. If the same callback routines are specified for multiple groups, a multi-threaded client can process notifications by invoking the callback routines for more than one group at a time. For single-threaded providers, if they are acting as providers for multiple groups, they must also be coded to handle simultaneously executing protocols in all groups.
In all cases where GS clients are acting as providers in multiple groups, it is the responsibility of the providers to ensure that they do not create deadlock situations across groups. An example of a deadlock that could occur is when one provider blocks before voting, waiting for another provider to take some action; and the second provider is blocked on another group protocol, waiting for the first provider to take some action.
All of that said, the Group Services subsystem invokes callback routines only on the same thread (or threads) that are used to call the ha_gs_dispatch subroutine.
Return Values
None.
Error Values
None.
Asynchronous Errors
None.
Files
ha_gs.h
Prerequisite Information
Related Information
Subroutines: ha_gs_init, ha_gs_join, ha_gs_change_state_value, ha_gs_send_message, ha_gs_leave, ha_gs_expel, ha_gs_change_attributes, ha_gs_goodbye