From 7c628580a6ecaad9b044191dc24661fc291fb42e Mon Sep 17 00:00:00 2001 From: Michal Hrusecky Date: Mon, 12 Oct 2020 10:50:51 +0200 Subject: [PATCH 1/4] mariadb: Use defaults and change default datadir Use /srv/mysql as default datadir as /var/lib/mysql is in tmpfs. This doesn't affect any existing setup as up till now it had to be always specified in configuration. That is addressed in the second part of this commit - init script now uses even defaults as compiled in MariaDB so not everything has to be specified in configuration file. Signed-off-by: Michal Hrusecky --- utils/mariadb/Makefile | 2 +- utils/mariadb/files/mysqld.init | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/utils/mariadb/Makefile b/utils/mariadb/Makefile index 321ee70a9..162b0860a 100644 --- a/utils/mariadb/Makefile +++ b/utils/mariadb/Makefile @@ -380,7 +380,7 @@ CMAKE_OPTIONS += \ -DINSTALL_SQLBENCHDIR="" \ -DINSTALL_SUPPORTFILESDIR=share/mariadb \ -DINSTALL_UNIX_ADDRDIR=$(MARIADB_SOCKET) \ - -DMYSQL_DATADIR=/var/lib/mysql \ + -DMYSQL_DATADIR=/srv/mysql \ -DMYSQL_UNIX_ADDR=$(MARIADB_SOCKET) \ -DSKIP_TESTS=ON \ -DWITH_DEBUG=OFF \ diff --git a/utils/mariadb/files/mysqld.init b/utils/mariadb/files/mysqld.init index 3e3538907..4f23a01de 100644 --- a/utils/mariadb/files/mysqld.init +++ b/utils/mariadb/files/mysqld.init @@ -22,11 +22,7 @@ export HOME="/etc/mysql" cd / mysqld_get_param() { - $MYSQLD --print-defaults \ - | tr " " "\n" \ - | grep -- "--$1" \ - | tail -n 1 \ - | cut -d= -f2 + /usr/bin/mysqld --help --verbose | sed -n 's|^'"$1"'[[:blank:]]\+||p' } # Checks if a server is running and accessible. From a01637ddf01a93d3012c5f2d11fe489063212731 Mon Sep 17 00:00:00 2001 From: Michal Hrusecky Date: Mon, 12 Oct 2020 12:52:42 +0200 Subject: [PATCH 2/4] mariadb: Do not use mysqladmin in init Rewrite init script as mysqladmin requires access to the MySQL which is hard to guarantee. Use standard signals instead. Signed-off-by: Michal Hrusecky --- utils/mariadb/files/mysqld.init | 52 +++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/utils/mariadb/files/mysqld.init b/utils/mariadb/files/mysqld.init index 4f23a01de..f1d775404 100644 --- a/utils/mariadb/files/mysqld.init +++ b/utils/mariadb/files/mysqld.init @@ -11,10 +11,11 @@ NAME=mysqld LOGGER="/usr/bin/logger -p user.err -s -t $NAME --" [ -x "$LOGGER" ] || LOGGER="echo" -MYSQLADMIN="/usr/bin/mysqladmin" MYSQLD="/usr/bin/$NAME" MYSQLDSAFE="/usr/bin/mysqld_safe" +pidfile="" + # mysqladmin likes to read /root/.my.cnf which could cause issues. export HOME="/etc/mysql" @@ -22,31 +23,39 @@ export HOME="/etc/mysql" cd / mysqld_get_param() { - /usr/bin/mysqld --help --verbose | sed -n 's|^'"$1"'[[:blank:]]\+||p' + "$MYSQLD" --help --verbose | sed -n 's|^'"$1"'[[:blank:]]\+||p' +} + +# Send kill signal to MariaDB process +# +# Usage: boolean mysqld_kill signal +mysql_kill() { + [ -n "$pidfile" ] || pidfile="$(mysqld_get_param pid-file)" + [ -f "$pidfile" ] || return 1 + pid="$(cat $pidfile)" + [ -n "$pid" ] || return 2 + kill "$1" "$pid" } # Checks if a server is running and accessible. # -# check_alive insists on a pingable server -# check_dead also fails if there is a lost mysqld in the process list +# Supported modes are 'check_alive' and 'check_dead'. +# Both check for pidfile and whether the specified process is running and is +# indeed mysqld. We could use mysqladmin for the check, but to be able to do +# so, mysqladmin requires access to the database, which sounds like overkill +# and potential security issue. # # Usage: boolean mysqld_status [check_alive|check_dead] mysqld_status() { - if $MYSQLADMIN ping >/dev/null 2>&1; then - ping_alive=1 - else - ping_alive=0 - fi - ps_alive=0 pidfile="$(mysqld_get_param pid-file)" - if [ -f "$pidfile" ] && kill -0 "$(cat "$pidfile")" >/dev/null 2>&1; then + if [ -f "$pidfile" ] && mysql_kill -0 2> /dev/null && \ + [ "$(readlink "/proc/$(cat "$pidfile")/exe")" = "$MYSQLD" ]; then ps_alive=1 fi - if { [ "$1" = check_alive ] && [ $ping_alive = 1 ]; } || \ - { [ "$1" = check_dead ] && [ $ping_alive = 0 ] \ - && [ $ps_alive = 0 ]; } + if { [ "$1" = check_alive ] && [ $ps_alive = 1 ]; } || \ + { [ "$1" = check_dead ] && [ $ps_alive = 0 ]; } then return 0 # EXIT_SUCCESS else @@ -60,8 +69,8 @@ start() { rundir=/var/run/mysqld hint="please fix your server configuration in /etc/mysql/" - - for i in "$MYSQLD" "$MYSQLADMIN" "$MYSQLDSAFE"; do + + for i in "$MYSQLD" "$MYSQLDSAFE"; do if [ ! -x "$i" ]; then $LOGGER "$i is missing" exit 1 @@ -133,14 +142,21 @@ start() { } stop() { + timeout="0" + while mysqld_status check_alive && [ "$timeout" -lt 60 ]; do + mysql_kill -TERM + sleep 1 + timeout="$(($timeout + 1))" + done if ! mysqld_status check_dead; then - "$MYSQLADMIN" shutdown + $LOGGER "server is failing to stop" + mysql_kill -KILL fi } reload() { if mysqld_status check_alive; then - "$MYSQLADMIN" reload + mysql_kill -HUP else $LOGGER "server is not running" fi From 595f0f1a2d6ee6ff5b777930ac42a3821c211b36 Mon Sep 17 00:00:00 2001 From: Michal Hrusecky Date: Tue, 13 Oct 2020 08:52:42 +0200 Subject: [PATCH 3/4] mariadb: Use procd and run as user Drop mysqld_safe and use procd instead. Also run as a user. Signed-off-by: Michal Hrusecky --- utils/mariadb/files/mysqld.init | 89 ++++++++++++++++----------------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/utils/mariadb/files/mysqld.init b/utils/mariadb/files/mysqld.init index f1d775404..d502e2baf 100644 --- a/utils/mariadb/files/mysqld.init +++ b/utils/mariadb/files/mysqld.init @@ -5,14 +5,17 @@ START=95 # shellcheck disable=SC2034 STOP=10 +# shellcheck disable=SC2034 +USE_PROCD=1 NAME=mysqld +my_user="mariadb" +my_group="mariadb" LOGGER="/usr/bin/logger -p user.err -s -t $NAME --" [ -x "$LOGGER" ] || LOGGER="echo" MYSQLD="/usr/bin/$NAME" -MYSQLDSAFE="/usr/bin/mysqld_safe" pidfile="" @@ -63,25 +66,28 @@ mysqld_status() { fi } -start() { +start_service() { conf=/etc/mysql/my.cnf logdir=/var/log/mysql rundir=/var/run/mysqld hint="please fix your server configuration in /etc/mysql/" - for i in "$MYSQLD" "$MYSQLDSAFE"; do - if [ ! -x "$i" ]; then - $LOGGER "$i is missing" - exit 1 - fi - done + if [ ! -x "$MYSQLD" ]; then + $LOGGER "$MYSQLD is missing" + exit 1 + fi if [ ! -r "$conf" ]; then $LOGGER "$conf cannot be read" exit 1 fi + if mysqld_status check_alive; then + $LOGGER "server is already running" + exit 0 + fi + config_load "$NAME" config_get_bool enabled general enabled 0 @@ -116,48 +122,39 @@ start() { $LOGGER "Cannot detect privileges table. You might need to run" $LOGGER "'mysql_install_db \"$args\"'" $LOGGER "to initialize the system tables." + $LOGGER "Then hand it ower to MariaDB user" + $LOGGER "'chown -Rh \"$my_user:$my_group\" \"$datadir\"'" exit 1 fi - # Start daemon - if mysqld_status check_alive; then - $LOGGER "server is already running" - else - for i in "$logdir" "$rundir"; do - opts="-m 0750" - if ! [ -e "$i" ]; then - # $rundir needs to be accessible for - # clients - if [ "$i" = "$rundir" ]; then - opts= - fi - # shellcheck disable=SC2086 - mkdir -p $opts "$i" - [ -d "$i" ] && chown mariadb:mariadb "$i" + for i in "$logdir" "$rundir" "$tmpdir" "$datadir"; do + opts="-m 0750" + if ! [ -e "$i" ]; then + # $rundir needs to be accessible for + # clients + if [ "$i" = "$rundir" ]; then + opts= fi - done - # shellcheck disable=SC2154,SC2086 - "$MYSQLDSAFE" $options >/dev/null 2>&1 & - fi -} - -stop() { - timeout="0" - while mysqld_status check_alive && [ "$timeout" -lt 60 ]; do - mysql_kill -TERM - sleep 1 - timeout="$(($timeout + 1))" + # shellcheck disable=SC2086 + mkdir -p $opts "$i" + [ -d "$i" ] && chown -Rh "$my_user:$my_group" "$i" + fi done - if ! mysqld_status check_dead; then - $LOGGER "server is failing to stop" - mysql_kill -KILL - fi -} -reload() { - if mysqld_status check_alive; then - mysql_kill -HUP - else - $LOGGER "server is not running" - fi + # Start daemon + procd_open_instance + + # shellcheck disable=SC2086 + procd_set_param command "$MYSQLD" $options + procd_set_param respawn "${respawn_threshold:-3600}" "${respawn_timeout:-5}" "${respawn_retry:-5}" + # run as user + procd_set_param user "$my_user" + # forward stderr to logd + procd_set_param stderr 1 + # use HUP to reload + procd_set_param reload_signal HUP + # terminate using signals + procd_set_param term_timeout 60 + + procd_close_instance } From c11f3948b8e91aff0d1cc170fd2118401c6a2832 Mon Sep 17 00:00:00 2001 From: Michal Hrusecky Date: Tue, 13 Oct 2020 08:55:36 +0200 Subject: [PATCH 4/4] mariadb: Cleanup and bump Remove few no longer needed bits - like checking that datadir is defined or mysqld_safe from server package and bumping revision after all the init script cleanups. Signed-off-by: Michal Hrusecky --- utils/mariadb/Makefile | 4 ++-- utils/mariadb/files/mysqld.init | 16 ++-------------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/utils/mariadb/Makefile b/utils/mariadb/Makefile index 162b0860a..7dfd96f5e 100644 --- a/utils/mariadb/Makefile +++ b/utils/mariadb/Makefile @@ -137,8 +137,7 @@ MARIADB_SERVER := \ mysql_install_db \ mysql_upgrade \ mysqladmin \ - mysqld \ - mysqld_safe + mysqld MARIADB_SERVER_EXTRA := \ aria_chk \ @@ -157,6 +156,7 @@ MARIADB_SERVER_EXTRA := \ mysql_setpermission \ mysql_tzinfo_to_sql \ mysqld_multi \ + mysqld_safe \ mysqld_safe_helper \ mysqldumpslow \ mysqlhotcopy \ diff --git a/utils/mariadb/files/mysqld.init b/utils/mariadb/files/mysqld.init index d502e2baf..bf0d86827 100644 --- a/utils/mariadb/files/mysqld.init +++ b/utils/mariadb/files/mysqld.init @@ -35,7 +35,7 @@ mysqld_get_param() { mysql_kill() { [ -n "$pidfile" ] || pidfile="$(mysqld_get_param pid-file)" [ -f "$pidfile" ] || return 1 - pid="$(cat $pidfile)" + pid="$(cat "$pidfile")" [ -n "$pid" ] || return 2 kill "$1" "$pid" } @@ -102,18 +102,6 @@ start_service() { datadir="$(mysqld_get_param datadir)" tmpdir="$(mysqld_get_param tmpdir)" - if [ -z "$datadir" ]; then - $LOGGER "datadir is not set" - $LOGGER "$hint" - exit 1 - fi - - if [ -z "$tmpdir" ]; then - $LOGGER "tmpdir is not set" - $LOGGER "$hint" - exit 1 - fi - if [ ! -f "$datadir/mysql/tables_priv.MAD" ]; then args="--force" basedir="$(mysqld_get_param basedir)" @@ -144,7 +132,7 @@ start_service() { # Start daemon procd_open_instance - # shellcheck disable=SC2086 + # shellcheck disable=SC2154 disable=SC2086 procd_set_param command "$MYSQLD" $options procd_set_param respawn "${respawn_threshold:-3600}" "${respawn_timeout:-5}" "${respawn_retry:-5}" # run as user