This file is indexed.

/usr/share/cluster/follow-service.sl is in rgmanager 3.1.8-1.2+b1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
% follow-service.sl
%
% Description:	Implements the "follow service" mechanism based on the Red Hat RIND event 
%               scripting mechanism.
%
% Author:       Marc Grimme, Mark Hlawatschek, October 2008
% Support:      support@atix.de
% License:      GNU General Public License (GPL), version 2 or later
% Copyright:    (c) 2008-2010 ATIX AG


debug("*** follow-service.sl");


%
% Returns a list of nodes for the given service that are online and in the failoverdomain.
%
define nodelist_online(service_name) {
   variable nodes, nofailback, restricted, ordered, node_list;
   nodes=nodes_online();
   
   (nofailback, restricted, ordered, node_list) = service_domain_info(service_name);
   
   return intersection(nodes, node_list);
}

%
% Idea: 
%   General purpose function of a construct when Service(svc1) and Service(svc2) 
%   should not be running on the same node even after failover.
%   There are to options to influence the behaviour. If both services have to be 
%   running on the same node (only one node is left in the failovergroup) what 
%   service is the master and should both services be running or only the master
%   service survives. If master is not svc1 or svc2 both service might run on the 
%   same node. If master is either svc1 or svc2 the specified one will be the 
%   surviving service.
%   If followslave is not 0 the svc1 always follows svc2. That means it will be 
%   started on on the same node as svc1. And if available svc2 will be relocated
%   to any other node.
%
define follow_service(svc1, svc2, master) %, followslave)
{
	variable state_svc1, state_svc2, owner_svc1, owner_svc2;
	variable nodes1, nodes2, allowed;

	debug("*** FOLLOW_SERVICE: follow_service(",svc1,", ",svc2,", ", master, ")");
	debug("*** FOLLOW_SERVICE: event_type: ", event_type, ", service_name: ", service_name, ", service_state: ", service_state);

	%
	% setup the master
	%
	if ((master != svc1) and (master != svc2)) {
		debug("*** FOLLOW_SERVICE: master=NULL");
		master=NULL;
	}

	% get infos we need to decide further
	(,,, owner_svc1, state_svc1) = service_status(svc1);
	(,,, owner_svc2, state_svc2) = service_status(svc2);
	nodes1 = nodelist_online(svc1);
	nodes2 = nodelist_online(svc2);
	debug("*** FOLLOW_SERVICE: service_status(",svc1,"): ", state_svc1);
	debug("*** FOLLOW_SERVICE: owner_svc1: ", owner_svc1, ", owner_svc2: ", owner_svc2, ", nodes1: ", nodes1, ", nodes2: ", nodes2);

	if (((event_type == EVENT_NODE)    and (owner_svc1 == node_id) and (node_state == NODE_OFFLINE) and (owner_svc2 >=0)) or 
		((event_type == EVENT_SERVICE) and (service_name == svc1)  and (service_state == "recovering" ) and (owner_svc2 >= 0))) {
		%
		% uh oh, the owner of the master server died.  Restart it
		% on the node running the slave server or if we should not 
		% follow the slave start it somewhere else.
		% We should end up here if svc1 has to be restarted

		%
		% If this was a service event, don't execute the default event
		% script trigger after this script completes.
		%
		if (event_type == EVENT_SERVICE) {
			stop_processing();
		}
		% were to start svc2
		allowed=subtract(nodes2, owner_svc2);
		if (length(allowed) > 1) {
			allowed=subtract(allowed, service_last_owner);
		}
		debug("*** FOLLOW SERVICE: service event triggered following svc2 to ",owner_svc2, " svc2 on : ",allowed);

		% either svc1 is the master or there are node were to start svc2
		if ((master == svc1) or (length(allowed) > 0)) {
			()=service_start(svc1, owner_svc2);
		}
		% either svc2 is the master or there are node were to start svc2
		if ((master == svc2) or (length(allowed) > 0)) {
			()=service_stop(svc2);
			()=service_start(svc2, allowed);
		} 
	}
	else if (((event_type == EVENT_NODE) and (owner_svc2 == node_id) and (node_state == NODE_OFFLINE) and (owner_svc2 >=0)) or 
		((event_type == EVENT_SERVICE) and (service_name == svc2) and (service_state == "recovering" ) and (owner_svc1 >= 0))) {
		%
		% uh oh, the owner of the svc2 died.  Restart it
		% on any other node but not the one running the svc1.
		% If svc1 is the only one left only start it there 
		% if master==svc2
		%
		% Just relocate svc2 or if svc2 is master stop svc1 and start svc2 on owner_svc1

		%
		% If this was a service event, don't execute the default event
		% script trigger after this script completes.
		%
	  
		if (event_type == EVENT_SERVICE) {
			stop_processing();
		}

		allowed=subtract(nodes2, owner_svc1);
		if (length(allowed) > 1) {
			allowed=subtract(allowed, service_last_owner);
		}

		debug("*** FOLLOW SERVICE: service event triggered relocating svc2 to ",allowed, " svc1 on : ",owner_svc1);

		if (length(allowed) > 0) {
			()=service_stop(svc2);
			()=service_start(svc2, allowed);
		} else if (master == svc2) {
			()=service_stop(svc1);
			()=service_start(svc2, owner_svc1);
		}
	}
	else if (((event_type == EVENT_SERVICE) and (service_state == "started") and (owner_svc2 == owner_svc1) and (owner_svc1 > 0) and (owner_svc2 > 0)) or
    		((event_type == EVENT_CONFIG) and (owner_svc2 == owner_svc1))) {
		allowed=subtract(nodes2, owner_svc1);
		debug("*** FOLLOW SERVICE: service event both running on same node triggered.", allowed);
		if (length(allowed) > 0) {
			%()=service_stop(svc1);
			%()=service_start(svc1, owner_svc2);
			()=service_stop(svc2);
			()=service_start(svc2, allowed);
		} else if ((master == svc2) and (owner_svc2 > 0)){
			debug("*** FOLLOW SERVICE: will stop service .", svc1); 
			()=service_stop(svc1);
		} else if ((master == svc1) and (owner_svc1 > 0)) {
			debug("*** FOLLOW SERVICE: will stop service .", svc2);
			()=service_stop(svc2);
		} else {
			debug("*** FOLLOW SERVICE: both services running on the same node or only one is running.", allowed, ", ", master);
		}
	}
	return;
}