Need clarifications on a few lines of code in the mysqld_safe shell script
0
votes
1
answer
76
views
I'm trying to develop a tool to check MariaDB option files to identify potential errors. When I was going through the
mysqld_safe
shell script in order to understand how it works, I came across these lines (lines 505 to 536, to be exact):
MY_PWD=dirname $0
MY_PWD=cd "$MY_PWD"/.. && pwd
# Check for the directories we would expect from a binary release install
if test -n "$MY_BASEDIR_VERSION" -a -d "$MY_BASEDIR_VERSION"
then
# BASEDIR is already overridden on command line. Do not re-set.
# Use BASEDIR to discover le.
if test -x "$MY_BASEDIR_VERSION/libexec/mariadbd"
then
ledir="$MY_BASEDIR_VERSION/libexec"
elif test -x "$MY_BASEDIR_VERSION/sbin/mariadbd"
then
ledir="$MY_BASEDIR_VERSION/sbin"
else
ledir="$MY_BASEDIR_VERSION/bin"
fi
elif test -x "$MY_PWD/bin/mariadbd"
then
MY_BASEDIR_VERSION="$MY_PWD" # Where bin, share and data are
ledir="$MY_PWD/bin" # Where mysqld is
#Check for the directories we would expect from a source install
elif test -x "$MY_PWD/libexec/mariadbd"
then
MY_BASEDIR_VERSION="$MY_PWD" # Where libexec, share and var are
ledir="$MY_PWD/libexec" # Where mysqld is
elif test -x "$MY_PWD/sbin/mariadbd"
then
MY_BASEDIR_VERSION="$MY_PWD" # Where sbin, share and var are
ledir="$MY_PWD/sbin" # Where mysqld is
# Since we didn't find anything, used the compiled-in defaults
else
MY_BASEDIR_VERSION='/usr'
ledir='/usr/bin'
fi
What confuses me first and foremost is the comment # BASEDIR is already overriden on command line. Do not re-set
. *How* exactly is $MY_BASEDIR_VERSION
set before that line to begin with? The only way (as far as I can tell) for $MY_BASEDIR_VERSION
to be set to a user-provided value (either via command line options or an option file) is via the parse_arguments()
function defined in lines 293 to 384.
parse_arguments() {
for arg do
val=echo "$arg" | sed -e "s;--[^=]*=;;"
case "$arg" in
# these get passed explicitly to mysqld
--basedir=*) MY_BASEDIR_VERSION="$val" ;;
--datadir=*|--data=*) DATADIR="$val" ;;
--pid[-_]file=*) pid_file="$val" ;;
--plugin[-_]dir=*) PLUGIN_DIR="$val" ;;
--user=*) user="$val"; SET_USER=1 ;;
--group=*) group="$val"; SET_USER=1 ;;
--log[-_]basename=*|--hostname=*|--loose[-_]log[-_]basename=*)
pid_file="$val.pid";
err_log_base="$val";
;;
# these might have been set in a [mysqld_safe] section of my.cnf
# they are added to mysqld command line to override settings from my.cnf
--skip[-_]log[-_]error)
err_log=;
skip_err_log=1;
;;
--log[-_]error=*)
err_log="$val";
skip_err_log=0;
;;
--port=*) mysql_tcp_port="$val" ;;
--socket=*) mysql_unix_port="$val" ;;
# mysqld_safe-specific options - must be set in my.cnf ([mysqld_safe])!
--core[-_]file[-_]size=*) core_file_size="$val" ;;
--ledir=*) ledir="$val" ;;
--malloc[-_]lib=*) set_malloc_lib "$val" ;;
--crash[-_]script=*) crash_script="$val" ;;
--mysqld=*) MYSQLD="$val" ;;
--mysqld[-_]version=*)
if test -n "$val"
then
MYSQLD="mysqld-$val"
PLUGIN_VARIANT="/$val"
else
MYSQLD="mysqld"
fi
;;
--dry[-_]run) dry_run=1 ;;
--nice=*) niceness="$val" ;;
--nowatch|--no[-_]watch|--no[-_]auto[-_]restart) nowatch=1 ;;
--open[-_]files[-_]limit=*) open_files="$val" ;;
--skip[-_]kill[-_]mysqld*) KILL_MYSQLD=0 ;;
--syslog) want_syslog=1 ;;
--skip[-_]syslog) want_syslog=0 ;;
--syslog[-_]tag=*) syslog_tag="$val" ;;
--timezone=*) TZ="$val"; export TZ; ;;
--flush[-_]caches) flush_caches=1 ;;
--numa[-_]interleave) numa_interleave=1 ;;
--wsrep[-_]on)
wsrep_on=1
append_arg_to_args "$arg"
;;
--skip[-_]wsrep[-_]on)
wsrep_on=0
append_arg_to_args "$arg"
;;
--wsrep[-_]on=*)
if echo $val | grep -iq '\(ON\|1\)'; then
wsrep_on=1
else
wsrep_on=0
fi
append_arg_to_args "$arg"
;;
--wsrep[-_]urls=*) wsrep_urls="$val"; ;;
--wsrep[-_]provider=*)
if test -n "$val" && test "$val" != "none"
then
wsrep_restart=1
fi
append_arg_to_args "$arg"
;;
--defaults-group-suffix=*) defaults_group_suffix="$arg" ;;
--help) usage ;;
*)
case "$unrecognized_handling" in
collect) append_arg_to_args "$arg" ;;
complain) log_error "unknown option '$arg'" ;;
esac
esac
done
}
The problem is that parse_arguments()
is first called on line 583 (*after* the aforementioned conditional tests). So how is it possible for $MY_BASEDIR_VERSION
to get overriden on the command line before that?
To me, there are only three conceivable ways for this to occur:
1. mysqld_safe
is re-run somehow after it was first launched (this is possible, but what would be the point in doing so?)
2. The user set the MY_BASEDIR_VERSION
environment variable manually before launching the script.
3. The MY_BASEDIR_VERSION
environment variable is set during MariaDB's installation process.
Having said that, these three possibilities lead to more questions than answers. I have gone through mysqld_safe
's documentation but came up empty. I hope somebody here can provide me with the clarification that I need.
Any insight is much appreciated.
Asked by Anthony
(109 rep)
May 9, 2023, 01:06 AM
Last activity: May 9, 2023, 04:08 AM
Last activity: May 9, 2023, 04:08 AM