b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | #!/bin/sh /etc/rc.common |
| 2 | # Copyright (C) 2010-2018 OpenWrt.org |
| 3 | |
| 4 | # shellcheck disable=SC2034 |
| 5 | START=95 |
| 6 | # shellcheck disable=SC2034 |
| 7 | STOP=10 |
| 8 | # shellcheck disable=SC2034 |
| 9 | USE_PROCD=1 |
| 10 | |
| 11 | NAME=mysqld |
| 12 | |
| 13 | LOGGER="/usr/bin/logger -p user.err -s -t $NAME --" |
| 14 | [ -x "$LOGGER" ] || LOGGER="echo" |
| 15 | |
| 16 | MYSQLD="/usr/bin/$NAME" |
| 17 | |
| 18 | pidfile="" |
| 19 | |
| 20 | # mysqladmin likes to read /root/.my.cnf which could cause issues. |
| 21 | export HOME="/etc/mysql" |
| 22 | |
| 23 | # Safeguard (relative paths, core dumps...) |
| 24 | cd / |
| 25 | |
| 26 | mysqld_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 |
| 33 | mysql_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] |
| 50 | mysqld_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 | |
| 67 | start_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 | } |