Sample Header Ad - 728x90

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