blob: 52def2d3c5e2c52ba0a86fc454ed2748e06dde4d [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001#!/bin/sh /etc/rc.common
2# Copyright (C) 2010-2018 OpenWrt.org
3
4# shellcheck disable=SC2034
5START=95
6# shellcheck disable=SC2034
7STOP=10
8# shellcheck disable=SC2034
9USE_PROCD=1
10
11NAME=mysqld
12
13LOGGER="/usr/bin/logger -p user.err -s -t $NAME --"
14[ -x "$LOGGER" ] || LOGGER="echo"
15
16MYSQLD="/usr/bin/$NAME"
17
18pidfile=""
19
20# mysqladmin likes to read /root/.my.cnf which could cause issues.
21export HOME="/etc/mysql"
22
23# Safeguard (relative paths, core dumps...)
24cd /
25
26mysqld_get_param() {
27 "$MYSQLD" --help --verbose | sed -n 's|^'"$1"'[[:blank:]]\+||p'
28}
29
30# Send kill signal to MariaDB process
31#
32# Usage: boolean mysqld_kill signal
33mysql_kill() {
34 [ -n "$pidfile" ] || pidfile="$(mysqld_get_param pid-file)"
35 [ -f "$pidfile" ] || return 1
36 pid="$(cat "$pidfile")"
37 [ -n "$pid" ] || return 2
38 kill "$1" "$pid"
39}
40
41# Checks if a server is running and accessible.
42#
43# Supported modes are 'check_alive' and 'check_dead'.
44# Both check for pidfile and whether the specified process is running and is
45# indeed mysqld. We could use mysqladmin for the check, but to be able to do
46# so, mysqladmin requires access to the database, which sounds like overkill
47# and potential security issue.
48#
49# Usage: boolean mysqld_status [check_alive|check_dead]
50mysqld_status() {
51 ps_alive=0
52 pidfile="$(mysqld_get_param pid-file)"
53 if [ -f "$pidfile" ] && mysql_kill -0 2> /dev/null && \
54 [ "$(readlink "/proc/$(cat "$pidfile")/exe")" = "$MYSQLD" ]; then
55 ps_alive=1
56 fi
57
58 if { [ "$1" = check_alive ] && [ $ps_alive = 1 ]; } || \
59 { [ "$1" = check_dead ] && [ $ps_alive = 0 ]; }
60 then
61 return 0 # EXIT_SUCCESS
62 else
63 return 1 # EXIT_FAILURE
64 fi
65}
66
67start_service() {
68 conf=/etc/mysql/my.cnf
69 logdir=/var/log/mysql
70 version="$(mysqld --version | sed -n 's|.*Ver[[:blank:]]*\([0-9.]*\)-.*|\1|p')"
71
72 # Few basic checks
73 if [ ! -x "$MYSQLD" ]; then
74 $LOGGER "$MYSQLD is missing"
75 exit 1
76 fi
77
78 if [ -z "$version" ]; then
79 $LOGGER "Can't get MariaDB version, something is seriously wrong"
80 exit 1
81 fi
82
83 if [ ! -r "$conf" ]; then
84 $LOGGER "$conf cannot be read"
85 exit 1
86 fi
87
88 if mysqld_status check_alive; then
89 $LOGGER "server is already running"
90 exit 0
91 fi
92
93 # Get various config options
94 config_load "$NAME"
95 config_get my_user general user "mariadb"
96 config_get my_group general group "mariadb"
97 config_get_bool enabled general enabled 0
98 config_get_bool init_db general init 1
99 config_get_bool autoupgrade general upgrade 1
100 config_get options general options
101
102 # shellcheck disable=SC2154
103 if [ "$enabled" -eq 0 ]; then
104 $LOGGER "service not enabled in /etc/config/$NAME"
105 exit 1
106 fi
107
108 datadir="$(mysqld_get_param datadir)"
109 tmpdir="$(mysqld_get_param tmpdir)"
110 sockdir="$(dirname "$(mysqld_get_param socket)")"
111
112 # Make sure we have a working database in datadir
113 if [ ! -f "$datadir/mysql/tables_priv.MAD" ]; then
114 args="--force"
115 basedir="$(mysqld_get_param basedir)"
116 [ -n "$basedir" ] && args="$args --basedir=$basedir"
117
118 # shellcheck disable=SC2154
119 if [ "$init_db" -gt 0 ]; then
120 # shellcheck disable=SC2154
121 mysql_install_db $args --skip-name-resolve --skip-test-db --datadir="$datadir" || exit 1
122 echo "$version" > "$datadir"/.version
123 chown -Rh "$my_user:$my_group" "$datadir"
124 else
125 $LOGGER "Cannot detect privileges table. You might need to run"
126 $LOGGER "'mysql_install_db \"$args\"'"
127 $LOGGER "to initialize the system tables."
128 $LOGGER "Then hand it ower to MariaDB user"
129 # shellcheck disable=SC2154
130 $LOGGER "'chown -Rh \"$my_user:$my_group\" \"$datadir\"'"
131 exit 1
132 fi
133 fi
134
135 # Make sure all required directories exists and have correct rights
136 for i in "$logdir" "$sockdir"; do
137 opts="-m 0750"
138 if ! [ -e "$i" ]; then
139 # $sockdir needs to be accessible for clients
140 [ "$i" = "$sockdir" ] && opts="-m 0755"
141 # shellcheck disable=SC2086
142 mkdir -p $opts "$i"
143 fi
144 # shellcheck disable=SC2154
145 [ -d "$i" ] && chown -Rh "$my_user:$my_group" "$i"
146 done
147
148 # Migration from old versions
149 # shellcheck disable=SC2154
150 if [ "$(cat "$datadir"/.version 2> /dev/null)" \!= "$version" ] && [ "$autoupgrade" -gt 0 ]; then
151 # Check for correct owner
152 local owner="$(stat --format %U:%G "$datadir" 2> /dev/null)"
153 if [ -n "$owner" ] && [ "$owner" != "$my_user:$my_group" ]; then
154 chown -Rh "$my_user:$my_group" "$datadir"
155 fi
156
157 # Start upgrade instance without credentials
158 sudo -u "$my_user" mysqld --skip-networking --skip-grant-tables --socket=/tmp/mysql_upgrade.sock &
159 PID="$!"
160 i=0
161 # Wait for upgrade instance of db to start
162 while [ "$i" -lt 15 ] && test \! -S /tmp/mysql_upgrade.sock; do
163 sleep 1
164 i="$((i + 1))"
165 done
166 [ -S /tmp/mysql_upgrade.sock ] || {
167 $LOGGER "Failed to start upgrading instance of MariaDB."
168 exit 1
169 }
170 # Upgrade the database
171 mysql_upgrade --upgrade-system-tables --socket=/tmp/mysql_upgrade.sock
172 echo "$version" > "$datadir"/.version
173 # Stop the upgrade instance
174 kill "$PID"
175 i=0
176 while [ "$i" -lt 60 ] && grep -q mysql "/proc/$PID/cmdline"; do
177 sleep 1
178 [ "$i" -lt 30 ] || kill "$PID"
179 i="$((i + 1))"
180 done
181 # Use force
182 if grep -q mysql "/proc/$PID/cmdline"; then
183 kill -9 "$PID"
184 fi
185 fi
186
187 # Start daemon
188 procd_open_instance
189
190 # shellcheck disable=SC2154 disable=SC2086
191 procd_set_param command "$MYSQLD" $options
192 procd_set_param respawn "${respawn_threshold:-3600}" "${respawn_timeout:-5}" "${respawn_retry:-5}"
193 # run as user
194 procd_set_param user "$my_user"
195 # forward stderr to logd
196 procd_set_param stderr 1
197 # use HUP to reload
198 procd_set_param reload_signal HUP
199 # terminate using signals
200 procd_set_param term_timeout 60
201
202 procd_close_instance
203}