1#!/usr/local/bin/bash
2
3#######################################################################
4
5# Use runuser if available for SELinux.
6if [ -x /sbin/runuser ]; then
7	SU=runuser
8else
9	SU=su
10fi
11
12# Attempt to detect a default binary
13OCF_RESKEY_binary_default=$(which mysqld_safe 2> /dev/null)
14if [ "$OCF_RESKEY_binary_default" = "" ]; then
15	OCF_RESKEY_binary_default=$(which safe_mysqld 2> /dev/null)
16fi
17
18# Fill in some defaults if no values are specified
19HOSTOS=`uname`
20if [ "X${HOSTOS}" = "XOpenBSD" ];then
21	if [ "$OCF_RESKEY_binary_default" = "" ]; then
22		OCF_RESKEY_binary_default="/usr/local/bin/mysqld_safe"
23	fi
24	OCF_RESKEY_config_default="/etc/my.cnf"
25	OCF_RESKEY_datadir_default="/var/mysql"
26	OCF_RESKEY_user_default="_mysql"
27	OCF_RESKEY_group_default="_mysql"
28	OCF_RESKEY_log_default="/var/log/mysqld.log"
29	OCF_RESKEY_pid_default="/var/mysql/mysqld.pid"
30	OCF_RESKEY_socket_default="/var/run/mysql/mysql.sock"
31else
32	if [ "$OCF_RESKEY_binary_default" = "" ]; then
33		OCF_RESKEY_binary_default="/usr/bin/safe_mysqld"
34	fi
35	OCF_RESKEY_config_default="/etc/my.cnf"
36	OCF_RESKEY_datadir_default="/var/lib/mysql"
37	OCF_RESKEY_user_default="mysql"
38	OCF_RESKEY_group_default="mysql"
39	OCF_RESKEY_log_default="/var/log/mysqld.log"
40	OCF_RESKEY_pid_default="/var/run/mysql/mysqld.pid"
41	OCF_RESKEY_socket_default="/var/lib/mysql/mysql.sock"
42fi
43OCF_RESKEY_client_binary_default="mysql"
44OCF_RESKEY_test_user_default="root"
45OCF_RESKEY_test_table_default="mysql.user"
46OCF_RESKEY_test_passwd_default=""
47OCF_RESKEY_enable_creation_default=0
48OCF_RESKEY_additional_parameters_default=""
49OCF_RESKEY_replication_user_default="root"
50OCF_RESKEY_replication_passwd_default=""
51OCF_RESKEY_replication_port_default="3306"
52OCF_RESKEY_replication_require_ssl_default="false"
53OCF_RESKEY_replication_master_ssl_ca_default=""
54OCF_RESKEY_replication_master_ssl_cert_default=""
55OCF_RESKEY_replication_master_ssl_key_default=""
56OCF_RESKEY_max_slave_lag_default="3600"
57OCF_RESKEY_evict_outdated_slaves_default="false"
58OCF_RESKEY_reader_attribute_default="readable"
59
60: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}}
61MYSQL_BINDIR=`dirname ${OCF_RESKEY_binary}`
62
63: ${OCF_RESKEY_client_binary=${OCF_RESKEY_client_binary_default}}
64
65: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}}
66: ${OCF_RESKEY_datadir=${OCF_RESKEY_datadir_default}}
67
68: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}}
69: ${OCF_RESKEY_group=${OCF_RESKEY_group_default}}
70
71: ${OCF_RESKEY_log=${OCF_RESKEY_log_default}}
72: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}}
73: ${OCF_RESKEY_socket=${OCF_RESKEY_socket_default}}
74
75: ${OCF_RESKEY_test_user=${OCF_RESKEY_test_user_default}}
76: ${OCF_RESKEY_test_table=${OCF_RESKEY_test_table_default}}
77: ${OCF_RESKEY_test_passwd=${OCF_RESKEY_test_passwd_default}}
78
79: ${OCF_RESKEY_enable_creation=${OCF_RESKEY_enable_creation_default}}
80: ${OCF_RESKEY_additional_parameters=${OCF_RESKEY_additional_parameters_default}}
81
82: ${OCF_RESKEY_replication_user=${OCF_RESKEY_replication_user_default}}
83: ${OCF_RESKEY_replication_passwd=${OCF_RESKEY_replication_passwd_default}}
84: ${OCF_RESKEY_replication_port=${OCF_RESKEY_replication_port_default}}
85: ${OCF_RESKEY_replication_require_ssl=${OCF_RESKEY_replication_require_ssl_default}}
86: ${OCF_RESKEY_replication_master_ssl_ca=${OCF_RESKEY_replication_master_ssl_ca_default}}
87: ${OCF_RESKEY_replication_master_ssl_cert=${OCF_RESKEY_replication_master_ssl_cert_default}}
88: ${OCF_RESKEY_replication_master_ssl_key=${OCF_RESKEY_replication_master_ssl_key_default}}
89
90: ${OCF_RESKEY_max_slave_lag=${OCF_RESKEY_max_slave_lag_default}}
91: ${OCF_RESKEY_evict_outdated_slaves=${OCF_RESKEY_evict_outdated_slaves_default}}
92
93: ${OCF_RESKEY_reader_attribute=${OCF_RESKEY_reader_attribute_default}}
94
95#######################################################################
96# Convenience variables
97
98MYSQL=$OCF_RESKEY_client_binary
99if ocf_is_true "$OCF_RESKEY_replication_require_ssl"; then
100  MYSQL_OPTIONS_LOCAL_SSL_OPTIONS="--ssl"
101else
102  MYSQL_OPTIONS_LOCAL_SSL_OPTIONS=""
103fi
104MYSQL_OPTIONS_LOCAL="-S $OCF_RESKEY_socket"
105MYSQL_OPTIONS_REPL="$MYSQL_OPTIONS_LOCAL_SSL_OPTIONS $MYSQL_OPTIONS_LOCAL --user=$OCF_RESKEY_replication_user --password=$OCF_RESKEY_replication_passwd"
106MYSQL_OPTIONS_TEST="$MYSQL_OPTIONS_LOCAL --user=$OCF_RESKEY_test_user --password=$OCF_RESKEY_test_passwd"
107MYSQL_TOO_MANY_CONN_ERR=1040
108
109CRM_MASTER="${HA_SBIN_DIR}/crm_master -l reboot "
110NODENAME=$(ocf_local_nodename)
111CRM_ATTR="${HA_SBIN_DIR}/crm_attribute -N $NODENAME "
112INSTANCE_ATTR_NAME=`echo ${OCF_RESOURCE_INSTANCE}| awk -F : '{print $1}'`
113CRM_ATTR_REPL_INFO="${HA_SBIN_DIR}/crm_attribute --type crm_config --name ${INSTANCE_ATTR_NAME}_REPL_INFO -s mysql_replication"
114
115#######################################################################
116
117mysql_common_validate()
118{
119
120    if ! have_binary "$OCF_RESKEY_binary"; then
121        ocf_exit_reason "Setup problem: couldn't find command: $OCF_RESKEY_binary"
122        return $OCF_ERR_INSTALLED;
123    fi
124
125    if ! have_binary "$OCF_RESKEY_client_binary"; then
126        ocf_exit_reason "Setup problem: couldn't find command: $OCF_RESKEY_client_binary"
127        return $OCF_ERR_INSTALLED;
128    fi
129
130    if [ ! -f $OCF_RESKEY_config ]; then
131        ocf_exit_reason "Config $OCF_RESKEY_config doesn't exist";
132        return $OCF_ERR_INSTALLED;
133    fi
134
135    if [ ! -d $OCF_RESKEY_datadir ]; then
136        ocf_exit_reason "Datadir $OCF_RESKEY_datadir doesn't exist";
137        return $OCF_ERR_INSTALLED;
138    fi
139
140    getent passwd $OCF_RESKEY_user >/dev/null 2>&1
141    if [ ! $? -eq 0 ]; then
142        ocf_exit_reason "User $OCF_RESKEY_user doesn't exit";
143        return $OCF_ERR_INSTALLED;
144    fi
145
146    getent group $OCF_RESKEY_group >/dev/null 2>&1
147    if [ ! $? -eq 0 ]; then
148        ocf_exit_reason "Group $OCF_RESKEY_group doesn't exist";
149        return $OCF_ERR_INSTALLED;
150    fi
151
152    return $OCF_SUCCESS
153}
154
155mysql_common_check_pid() {
156    local pid=$1
157
158    if [ -d /proc -a -d /proc/1 ]; then
159        [ "u$pid" != "u" -a -d /proc/$pid ]
160    else
161        kill -s 0 $pid >/dev/null 2>&1
162    fi
163    return $?
164}
165
166mysql_common_status() {
167    local loglevel=$1
168    local pid=$2
169    if [ -z "$pid" ]; then
170        if [ ! -e $OCF_RESKEY_pid ]; then
171            ocf_log $loglevel "MySQL is not running"
172            return $OCF_NOT_RUNNING;
173        fi
174
175        pid=`cat $OCF_RESKEY_pid`;
176    fi
177
178    mysql_common_check_pid $pid
179
180
181    if [ $? -eq 0 ]; then
182        return $OCF_SUCCESS;
183    else
184        if [ -e $OCF_RESKEY_pid ]; then
185            ocf_log $loglevel "MySQL not running: removing old PID file"
186            rm -f $OCF_RESKEY_pid
187        fi
188        return $OCF_NOT_RUNNING;
189    fi
190}
191
192mysql_common_prepare_dirs()
193{
194    local rc
195
196    touch $OCF_RESKEY_log
197    chown $OCF_RESKEY_user:$OCF_RESKEY_group $OCF_RESKEY_log
198    chmod 0640 $OCF_RESKEY_log
199    [ -x /sbin/restorecon ] && /sbin/restorecon $OCF_RESKEY_log
200
201    if ocf_is_true "$OCF_RESKEY_enable_creation" && [ ! -d $OCF_RESKEY_datadir/mysql ] ; then
202        ocf_log info "Initializing MySQL database: "
203        $MYSQL_BINDIR/mysql_install_db --datadir=$OCF_RESKEY_datadir
204        rc=$?
205        if [ $rc -ne 0 ] ; then
206            ocf_exit_reason "Initialization failed: $rc";
207            exit $OCF_ERR_GENERIC
208        fi
209        chown -R $OCF_RESKEY_user:$OCF_RESKEY_group $OCF_RESKEY_datadir
210    fi
211
212    pid_dir=`dirname $OCF_RESKEY_pid`
213    if [ ! -d $pid_dir ] ; then
214        ocf_log info "Creating PID dir: $pid_dir"
215        mkdir -p $pid_dir
216        chown $OCF_RESKEY_user:$OCF_RESKEY_group $pid_dir
217    fi
218
219    socket_dir=`dirname $OCF_RESKEY_socket`
220    if [ ! -d $socket_dir ] ; then
221        ocf_log info "Creating socket dir: $socket_dir"
222        mkdir -p $socket_dir
223        chown $OCF_RESKEY_user:$OCF_RESKEY_group $socket_dir
224    fi
225
226    # Regardless of whether we just created the directory or it
227    # already existed, check whether it is writable by the configured
228    # user
229    for dir in $pid_dir $socket_dir $OCF_RESKEY_datadir; do
230        if ! $SU -s /bin/sh - $OCF_RESKEY_user -c "test -w $dir"; then
231            ocf_exit_reason "Directory $dir is not writable by $OCF_RESKEY_user"
232            exit $OCF_ERR_PERM;
233        fi
234    done
235}
236
237mysql_common_start()
238{
239    local mysql_extra_params="$1"
240    local pid
241
242    $SU - $OCF_RESKEY_user -s /bin/sh -c \
243    "${OCF_RESKEY_binary} --defaults-file=$OCF_RESKEY_config \
244    --pid-file=$OCF_RESKEY_pid \
245    --socket=$OCF_RESKEY_socket \
246    --datadir=$OCF_RESKEY_datadir \
247    --log-error=$OCF_RESKEY_log \
248    $OCF_RESKEY_additional_parameters \
249    $mysql_extra_params >/dev/null 2>&1" &
250    pid=$!
251
252    # Spin waiting for the server to come up.
253    # Let the CRM/LRM time us out if required.
254    start_wait=1
255    while [ $start_wait = 1 ]; do
256        if ! ps $pid > /dev/null 2>&1; then
257            wait $pid
258            ocf_exit_reason "MySQL server failed to start (pid=$pid) (rc=$?), please check your installation"
259            return $OCF_ERR_GENERIC
260        fi
261        mysql_common_status info
262        rc=$?
263        if [ $rc = $OCF_SUCCESS ]; then
264            start_wait=0
265        elif [ $rc != $OCF_NOT_RUNNING ]; then
266            ocf_log info "MySQL start failed: $rc"
267            return $rc
268        fi
269        sleep 2
270    done
271
272    return $OCF_SUCCESS
273}
274
275mysql_common_stop()
276{
277    local pid
278    local rc
279
280    if [ ! -f $OCF_RESKEY_pid ]; then
281        ocf_log info "MySQL is not running"
282        return $OCF_SUCCESS
283    fi
284
285    pid=`cat $OCF_RESKEY_pid 2> /dev/null `
286
287    mysql_common_check_pid $pid
288    if [ $? -ne 0 ]; then
289        rm -f $OCF_RESKEY_pid
290        ocf_log info "MySQL is already stopped"
291        return $OCF_SUCCESS;
292    fi
293
294    /bin/kill $pid > /dev/null
295    rc=$?
296    if [ $rc != 0 ]; then
297        ocf_exit_reason "MySQL couldn't be stopped"
298        return $OCF_ERR_GENERIC
299    fi
300    # stop waiting
301    shutdown_timeout=15
302    if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then
303        shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5))
304    fi
305    count=0
306    while [ $count -lt $shutdown_timeout ]
307    do
308        mysql_common_status info $pid
309        rc=$?
310        if [ $rc = $OCF_NOT_RUNNING ]; then
311            break
312        fi
313        count=`expr $count + 1`
314        sleep 1
315        ocf_log debug "MySQL still hasn't stopped yet. Waiting..."
316    done
317
318    mysql_common_status info $pid
319    if [ $? != $OCF_NOT_RUNNING ]; then
320        ocf_log info "MySQL failed to stop after ${shutdown_timeout}s using SIGTERM. Trying SIGKILL..."
321        /bin/kill -KILL $pid > /dev/null
322    fi
323
324    ocf_log info "MySQL stopped";
325    rm -f /var/lock/subsys/mysqld
326    rm -f $OCF_RESKEY_socket
327    return $OCF_SUCCESS
328
329}
330