/*****************************************************************************\
 *  mysql_common.c - common functions for the mysql storage plugin.
 *****************************************************************************
 *  Copyright (C) 2004-2007 The Regents of the University of California.
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
 *  Written by Danny Auble <da@llnl.gov>
 *
 *  This file is part of Slurm, a resource management program.
 *  For details, see <https://slurm.schedmd.com/>.
 *  Please also read the included file: DISCLAIMER.
 *
 *  Slurm is free software; you can redistribute it and/or modify it under
 *  the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 2 of the License, or (at your option)
 *  any later version.
 *
 *  In addition, as a special exception, the copyright holders give permission
 *  to link the code of portions of this program with the OpenSSL library under
 *  certain conditions as described in each individual source file, and
 *  distribute linked combinations including the two. You must obey the GNU
 *  General Public License in all respects for all of the code used other than
 *  OpenSSL. If you modify file(s) with this exception, you may extend this
 *  exception to your version of the file(s), but you are not obligated to do
 *  so. If you do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source files in
 *  the program, then also delete it here.
 *
 *  Slurm is distributed in the hope that it will be useful, but WITHOUT ANY
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 *  details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with Slurm; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
 *
 *  This file is patterned after jobcomp_linux.c, written by Morris Jette and
 *  Copyright (C) 2002 The Regents of the University of California.
\*****************************************************************************/

#include "config.h"

#include "mysql_common.h"
#include "src/common/log.h"
#include "src/common/xstring.h"
#include "src/common/xmalloc.h"
#include "src/common/timers.h"
#include "src/common/slurm_protocol_api.h"
#include "src/common/read_config.h"
#include "src/slurmdbd/read_config.h"

#define MAX_DEADLOCK_ATTEMPTS 10

static char *table_defs_table = "table_defs_table";

typedef struct {
	char *name;
	char *columns;
	bool non_unique;
} db_key_t;

static void _destroy_db_key(void *arg)
{
	db_key_t *db_key = (db_key_t *)arg;

	if (db_key) {
		xfree(db_key->name);
		xfree(db_key->columns);
		xfree(db_key);
	}
}

static int _find_db_key(void *x, void *key)
{
	db_key_t * db_key = (db_key_t *) x;

	if (xstrcmp(db_key->name, (char *) key))
		return 0;
	return 1;
}

/* NOTE: Ensure that mysql_conn->lock is set on function entry */
static int _clear_results(MYSQL *db_conn)
{
	MYSQL_RES *result = NULL;
	int rc = 0;

	do {
		/* did current statement return data? */
		if ((result = mysql_store_result(db_conn)))
			mysql_free_result(result);

		/* more results? -1 = no, >0 = error, 0 = yes (keep looping) */
		if ((rc = mysql_next_result(db_conn)) > 0)
			error("Could not execute statement %d %s",
			      mysql_errno(db_conn),
			      mysql_error(db_conn));
	} while (rc == 0);

	if (rc > 0) {
		errno = rc;
		return SLURM_ERROR;
	}
	return SLURM_SUCCESS;
}

/* NOTE: Ensure that mysql_conn->lock is set on function entry */
static MYSQL_RES *_get_first_result(MYSQL *db_conn)
{
	MYSQL_RES *result = NULL;
	int rc = 0;
	do {
		/* did current statement return data? */
		if ((result = mysql_store_result(db_conn)))
			return result;

		/* more results? -1 = no, >0 = error, 0 = yes (keep looping) */
		if ((rc = mysql_next_result(db_conn)) > 0)
			debug3("error: Could not execute statement %d", rc);

	} while (rc == 0);

	return NULL;
}

/* NOTE: Ensure that mysql_conn->lock is set on function entry */
static MYSQL_RES *_get_last_result(MYSQL *db_conn)
{
	MYSQL_RES *result = NULL;
	MYSQL_RES *last_result = NULL;
	int rc = 0;
	do {
		/* did current statement return data? */
		if ((result = mysql_store_result(db_conn))) {
			if (last_result)
				mysql_free_result(last_result);
			last_result = result;
		}
		/* more results? -1 = no, >0 = error, 0 = yes (keep looping) */
		if ((rc = mysql_next_result(db_conn)) > 0)
			debug3("error: Could not execute statement %d", rc);
	} while (rc == 0);

	return last_result;
}

/* NOTE: Ensure that mysql_conn->lock is set on function entry */
static int _mysql_query_internal(MYSQL *db_conn, char *query)
{
	int rc = SLURM_SUCCESS;
	int deadlock_attempt = 0;

try_again:
	if (!db_conn)
		fatal("You haven't inited this storage yet.");

	/* clear out the old results so we don't get a 2014 error */
	_clear_results(db_conn);
	if (mysql_query(db_conn, query)) {
		const char *err_str = mysql_error(db_conn);
		errno = mysql_errno(db_conn);
		if (errno == ER_NO_SUCH_TABLE) {
			debug4("This could happen often and is expected.\n"
			       "mysql_query failed: %d %s\n%s",
			       errno, err_str, query);
			errno = 0;
			goto end_it;
		}
		if (errno == ER_LOCK_DEADLOCK) {
			/*
			 * Mysql detected a deadlock and we should retry
			 * a few times since this is mainly a race condition
			 */
			deadlock_attempt++;

			if (deadlock_attempt < MAX_DEADLOCK_ATTEMPTS) {
				error("%s: deadlock detected attempt %u/%u: %d %s",
				      __func__, deadlock_attempt,
				      MAX_DEADLOCK_ATTEMPTS, errno, err_str);
				goto try_again;
			} else {
				fatal("%s: unable to resolve deadlock with attempts %u/%u: %d %s\nPlease call 'show engine innodb status;' in MySQL/MariaDB and open a bug report with SchedMD.",
				      __func__, deadlock_attempt,
				      MAX_DEADLOCK_ATTEMPTS, errno, err_str);
			}
		} else if (errno == ER_LOCK_WAIT_TIMEOUT) {
			/* FIXME: If we get ER_LOCK_WAIT_TIMEOUT here we need
			 * to restart the connections, but it appears restarting
			 * the calling program is the only way to handle this.
			 * If anyone in the future figures out a way to handle
			 * this, super.  Until then we will need to restart the
			 * calling program if you ever get this error.
			 */
			fatal("mysql gave ER_LOCK_WAIT_TIMEOUT as an error. "
			      "The only way to fix this is restart the "
			      "calling program");
		} else if (errno == ER_HOST_IS_BLOCKED) {
			fatal("MySQL gave ER_HOST_IS_BLOCKED as an error. "
			      "You will need to call 'mysqladmin flush-hosts' "
			      "to regain connectivity.");
		}
		error("mysql_query failed: %d %s\n%s", errno, err_str, query);
		rc = SLURM_ERROR;
	}
end_it:
	/*
	 * Starting in MariaDB 10.2 many of the api commands started
	 * setting errno erroneously.
	 */
	if (!rc)
		errno = 0;

	return rc;
}

/*
 * Determine if a database server upgrade has taken place and if so, check to
 * see if the candidate table alteration query should be used to alter the table
 * to its expected settings. Returns true if so.
 *
 * Background:
 *
 * From the MariaDB docs:
 *  Before MariaDB 10.2.1, BLOB and TEXT columns could not be assigned a DEFAULT
 *  value. This restriction was lifted in MariaDB 10.2.1.
 *
 * If a site begins using MariaDB >= 10.2.1 and is either using an existing
 * Slurm database from an earlier version or has restored one from a dump from
 * an earlier version or from any version of MySQL, some text/blob default
 * values will need to be altered to avoid failures from subsequent queries from
 * slurmdbd that set affected fields to DEFAULT (see bug#13606).
 *
 * Note that only one column from one table ('preempt' from qos_table) is
 * checked to determine if an upgrade has taken place with the assumption that
 * if its default value is not correct then the same is true for similar
 * text/blob columns from other tables and they will also need to be altered.
 *
 * The qos_table has been chosen for this check because it is the last table
 * with condition to be created. If that condition changes this should be
 * re-evaluated.
 */
static bool _alter_table_after_upgrade(mysql_conn_t *mysql_conn,
				       char *table_alter_query)
{
	static bool have_value = false, upgraded = false;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;

	/* check to see if upgrade has happened */
	if (!have_value) {
		const char *tmp_char;
		char *query;
		/*
		 * confirm MariaDB is being used to avoid any ambiguity with
		 * MySQL versions
		 */
		tmp_char = mysql_get_server_info(mysql_conn->db_conn);
		if (xstrcasestr(tmp_char, "mariadb") &&
		    (mysql_get_server_version(mysql_conn->db_conn) >= 100201)) {
			query = "show columns from `qos_table` like 'preempt'";
			result = mysql_db_query_ret(mysql_conn, query, 0);
			if (result) {
				/*
				 * row[4] holds the column's default value and
				 * if it's not empty ('') then it will need to
				 * be altered and an upgrade is assumed
				 */
				if ((row = mysql_fetch_row(result)) &&
				    !xstrcasecmp(row[1], "text") &&
				    xstrcmp(row[4], "''"))
					upgraded = true;
				mysql_free_result(result);
			}
		}
		have_value = true;
	}

	/*
	 * If upgrade detected and the table alter query string contains an
	 * empty string default then the query should be executed. The latter
	 * check avoids unnecessary table alterations.
	 */
	if (upgraded && xstrcasestr(table_alter_query, "default ''"))
		return true;

	return false;
}

/* NOTE: Ensure that mysql_conn->lock is NOT set on function entry */
static int _mysql_make_table_current(mysql_conn_t *mysql_conn, char *table_name,
				     storage_field_t *fields, char *ending)
{
	char *query = NULL;
	char *correct_query = NULL;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	int i = 0;
	list_t *columns = NULL;
	list_itr_t *itr = NULL;
	char *col = NULL;
	int adding = 0;
	int run_update = 0;
	char *primary_key = NULL;
	char *unique_index = NULL;
	int old_primary = 0;
	char *temp = NULL, *temp2 = NULL;
	list_t *keys_list = NULL;
	db_key_t *db_key = NULL;

	DEF_TIMERS;

	/* figure out the unique keys in the table */
	query = xstrdup_printf("show index from %s where non_unique=0",
			       table_name);
	if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
		xfree(query);
		return SLURM_ERROR;
	}
	xfree(query);

	keys_list = list_create(_destroy_db_key);
	while ((row = mysql_fetch_row(result))) {
		/*
		 * row[2] = key name
		 * row[4] = column name
		 */
		if (!xstrcasecmp(row[2], "PRIMARY")) {
			old_primary = 1;
			continue;
		}

		db_key = list_find_first(keys_list, _find_db_key, row[2]);

		if (db_key) {
			xstrfmtcat(db_key->columns, ", %s", row[4]);
		} else {
			db_key = xmalloc(sizeof(db_key_t));
			db_key->name = xstrdup(row[2]);
			db_key->columns = xstrdup(row[4]);
			db_key->non_unique = false;
			list_append(keys_list, db_key);
		}
	}
	mysql_free_result(result);

	/* figure out the non-unique keys in the table */
	query = xstrdup_printf("show index from %s where non_unique=1",
			       table_name);
	if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
		xfree(query);
		return SLURM_ERROR;
	}
	xfree(query);

	while ((row = mysql_fetch_row(result))) {
		db_key = list_find_first(keys_list, _find_db_key, row[2]);

		if (db_key) {
			xstrfmtcat(db_key->columns, ", %s", row[4]);
		} else {
			db_key = xmalloc(sizeof(db_key_t));
			db_key->name = xstrdup(row[2]); // name
			db_key->columns = xstrdup(row[4]); // column name
			db_key->non_unique = true;
			list_append(keys_list, db_key); // don't use list_push
		}
	}
	mysql_free_result(result);

	/* figure out the existing columns in the table */
	query = xstrdup_printf("show columns from %s", table_name);
	if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
		xfree(query);
		FREE_NULL_LIST(keys_list);
		return SLURM_ERROR;
	}
	xfree(query);
	columns = list_create(xfree_ptr);
	while ((row = mysql_fetch_row(result))) {
		col = xstrdup(row[0]); //Field
		list_append(columns, col);
	}
	mysql_free_result(result);


	itr = list_iterator_create(columns);
	/* In MySQL 5.7.4 we lost the ability to run 'alter ignore'.  This was
	 * needed when converting old tables to new schemas.  If people convert
	 * in the future from an older version of Slurm that needed the ignore
	 * to work they will have to downgrade mysql to <= 5.7.3 to make things
	 * work correctly or manually edit the database to get things to work.
	 */
	/*
	 * `query` is compared against the current table_defs_table.definition
	 * and run if they are different. `correct_query` is inserted into the
	 * table, so it must be what future `query` schemas will be.
	 * In other words, `query` transitions the table to the new schema,
	 * `correct_query` represents the new schema
	 */
	query = xstrdup_printf("alter table %s", table_name);
	correct_query = xstrdup(query);
	START_TIMER;
	while (fields[i].name) {
		int found = 0;

		list_iterator_reset(itr);
		while ((col = list_next(itr))) {
			if (!xstrcmp(col, fields[i].name)) {
				xstrfmtcat(query, " modify `%s` %s,",
					   fields[i].name,
					   fields[i].options);
				xstrfmtcat(correct_query, " modify `%s` %s,",
					   fields[i].name,
					   fields[i].options);
				list_delete_item(itr);
				found = 1;
				break;
			}
		}
		if (!found) {
			if (i) {
				info("adding column %s after %s in table %s",
				     fields[i].name,
				     fields[i-1].name,
				     table_name);
				xstrfmtcat(query, " add `%s` %s after %s,",
					   fields[i].name,
					   fields[i].options,
					   fields[i-1].name);
				xstrfmtcat(correct_query, " modify `%s` %s,",
					   fields[i].name,
					   fields[i].options);
			} else {
				info("adding column %s at the beginning "
				     "of table %s",
				     fields[i].name,
				     table_name);
				xstrfmtcat(query, " add `%s` %s first,",
					   fields[i].name,
					   fields[i].options);
				xstrfmtcat(correct_query, " modify `%s` %s,",
					   fields[i].name,
					   fields[i].options);
			}
			adding = 1;
		}

		i++;
	}

	list_iterator_reset(itr);
	while ((col = list_next(itr))) {
		adding = 1;
		info("dropping column %s from table %s", col, table_name);
		xstrfmtcat(query, " drop %s,", col);
	}

	list_iterator_destroy(itr);
	FREE_NULL_LIST(columns);

	if ((temp = strstr(ending, "primary key ("))) {
		int open = 0, close =0;
		int end = 0;
		while (temp[end++]) {
			if (temp[end] == '(')
				open++;
			else if (temp[end] == ')')
				close++;
			else
				continue;
			if (open == close)
				break;
		}
		if (temp[end]) {
			end++;
			primary_key = xstrndup(temp, end);
			if (old_primary)
				xstrcat(query, " drop primary key,");
			xstrcat(correct_query, " drop primary key,");
			xstrfmtcat(query, " add %s,",  primary_key);
			xstrfmtcat(correct_query, " add %s,",  primary_key);

			xfree(primary_key);
		}
	}

	if ((temp = strstr(ending, "unique index"))) {
		int open = 0, close = 0;
		/* sizeof includes NULL, and end should start 1 back */
		int end = sizeof("unique index") - 2;
		char *udex_name = NULL, *name_marker = NULL;
		while (temp[end++]) {
			/*
			 * Extracts the index name, which is given explicitly
			 * or is the name of the first field included in the
			 * index.
			 * "unique index indexname (field1, field2)"
			 * "unique index (indexname, field2)"
			 * indexname is started by the first non '(' or ' '
			 *     after "unique index"
			 * indexname is terminated by '(' ')' ' ' or ','
			 */
			if (name_marker) {
				if (!udex_name && (temp[end] == '(' ||
						   temp[end] == ')' ||
						   temp[end] == ' ' ||
						   temp[end] == ','))
					udex_name = xstrndup(name_marker,
						temp + end - name_marker);
			} else if (temp[end] != '(' && temp[end] != ' ') {
				name_marker = temp + end;
			}

			/* find the end of the parenthetical expression */
			if (temp[end] == '(')
				open++;
			else if (temp[end] == ')')
				close++;
			else
				continue;
			if (open == close)
				break;
		}
		if (temp[end]) {
			end++;
			unique_index = xstrndup(temp, end);

			db_key = list_remove_first(keys_list, _find_db_key,
						   udex_name);
			if (db_key) {
				xstrfmtcat(query,
					   " drop index %s,", db_key->name);
				_destroy_db_key(db_key);
			} else {
				info("adding %s to table %s",
				     unique_index, table_name);
			}
			xstrfmtcat(correct_query, " drop index %s,", udex_name);
			xstrfmtcat(query, " add %s,", unique_index);
			xstrfmtcat(correct_query, " add %s,", unique_index);
			xfree(unique_index);
		}
		xfree(udex_name);
	}

	temp2 = ending;
	while ((temp = strstr(temp2, ", key "))) {
		int open = 0, close = 0, name_end = 0;
		int end = 5;
		char *new_key_name = NULL, *new_key = NULL;
		while (temp[end++]) {
			if (!name_end && (temp[end] == ' ')) {
				name_end = end;
				continue;
			} else if (temp[end] == '(') {
				open++;
				if (!name_end)
					name_end = end;
			} else if (temp[end] == ')')
				close++;
			else
				continue;
			if (open == close)
				break;
		}
		if (temp[end]) {
			end++;
			new_key_name = xstrndup(temp+6, name_end-6);
			new_key = xstrndup(temp+2, end-2); // skip ', '

			db_key = list_remove_first(keys_list, _find_db_key,
						   new_key_name);
			if (db_key) {
				xstrfmtcat(query,
					   " drop key %s,", db_key->name);
				_destroy_db_key(db_key);
			} else
				info("adding %s to table %s",
				     new_key, table_name);
			xstrfmtcat(correct_query,
				   " drop key %s,", new_key_name);

			xstrfmtcat(query, " add %s,",  new_key);
			xstrfmtcat(correct_query, " add %s,",  new_key);

			xfree(new_key);
			xfree(new_key_name);
		}
		temp2 = temp + end;
	}

	/* flush extra (old) keys */
	itr = list_iterator_create(keys_list);
	while ((db_key = list_next(itr))) {
		if (!db_key->non_unique) {
			info("dropping unique index %s from table %s",
			     db_key->name, table_name);
			xstrfmtcat(query, " drop index %s,", db_key->name);
		} else {
			info("dropping key %s from table %s",
			     db_key->name, table_name);
			xstrfmtcat(query, " drop key %s,", db_key->name);
		}
	}
	list_iterator_destroy(itr);

	FREE_NULL_LIST(keys_list);

	query[strlen(query)-1] = ';';
	correct_query[strlen(correct_query)-1] = ';';
	//info("%d query\n%s", __LINE__, query);

	/* see if table needs to be altered after db server upgrade */
	if (!adding && _alter_table_after_upgrade(mysql_conn, query)) {
		run_update = 3;
	} else if (!adding && !run_update) {
		/* see if we have already done this definition */
		char *quoted = slurm_add_slash_to_quotes(query);
		char *query2 = xstrdup_printf("select table_name from "
					      "%s where definition='%s'",
					      table_defs_table, quoted);
		MYSQL_RES *result = NULL;
		MYSQL_ROW row;

		xfree(quoted);
		run_update = 1;
		if ((result = mysql_db_query_ret(mysql_conn, query2, 0))) {
			if ((row = mysql_fetch_row(result)))
				run_update = 0;
			mysql_free_result(result);
		}
		xfree(query2);
		if (run_update) {
			run_update = 2;
			query2 = xstrdup_printf("select table_name from "
						"%s where table_name='%s'",
						table_defs_table, table_name);
			if ((result = mysql_db_query_ret(
				     mysql_conn, query2, 0))) {
				if ((row = mysql_fetch_row(result)))
					run_update = 1;
				mysql_free_result(result);
			}
			xfree(query2);
		}
	}

	/* if something has changed run the alter line */
	if (run_update || adding) {
		time_t now = time(NULL);
		char *query2 = NULL;
		char *quoted = NULL;

		if (run_update == 2)
			debug4("Table %s doesn't exist, adding", table_name);
		else if (run_update == 3)
			info("MariaDB >= 10.2.1 in use with a table from an earlier version or from MySQL. Updating table %s...",
			      table_name);
		else
			debug("Table %s has changed.  Updating...", table_name);

		debug2("query\n%s", query);
		if (mysql_db_query(mysql_conn, query)) {
			xfree(query);
			return SLURM_ERROR;
		}
		quoted = slurm_add_slash_to_quotes(correct_query);
		query2 = xstrdup_printf("insert into %s (creation_time, "
					"mod_time, table_name, definition) "
					"values (%ld, %ld, '%s', '%s') "
					"on duplicate key update "
					"definition='%s', mod_time=%ld;",
					table_defs_table, now, now,
					table_name, quoted,
					quoted, now);
		xfree(quoted);
		debug3("query\n%s", query2);
		if (mysql_db_query(mysql_conn, query2)) {
			xfree(query2);
			return SLURM_ERROR;
		}
		xfree(query2);
	}

	xfree(query);
	xfree(correct_query);
	query = xstrdup_printf("make table current %s", table_name);
	END_TIMER2(query);
	xfree(query);
	return SLURM_SUCCESS;
}

void _set_mysql_ssl_opts(MYSQL *db_conn, const char *options)
{
	char *tmp_opts, *token, *save_ptr = NULL;
	const char *key = NULL, *cert = NULL, *ca = NULL, *ca_path = NULL;
	const char *cipher = NULL;

	if (!options)
		return;

	tmp_opts = xstrdup(options);
	token = strtok_r(tmp_opts, ",", &save_ptr);
	while (token) {
		char *opt_str, *val_str = NULL;

		opt_str = strtok_r(token, "=", &val_str);

		if (!opt_str || !val_str) {
			error("Invalid storage option/val");
			goto next;
		} else if (!xstrcasecmp(opt_str, "SSL_CERT"))
			cert = val_str;
		else if (!xstrcasecmp(opt_str, "SSL_CA"))
			ca = val_str;
		else if (!xstrcasecmp(opt_str, "SSL_CAPATH"))
			ca_path = val_str;
		else if (!xstrcasecmp(opt_str, "SSL_KEY"))
			key = val_str;
		else if (!xstrcasecmp(opt_str, "SSL_CIPHER"))
			cipher = val_str;
		else {
			error("Invalid storage option '%s'", opt_str);
			goto next;
		}
next:
		token = strtok_r(NULL, ",", &save_ptr);
	}

	mysql_ssl_set(db_conn, key, cert, ca, ca_path, cipher);

	xfree(tmp_opts);
}

/* NOTE: Ensure that mysql_conn->lock is set on function entry */
static int _create_db(char *db_name, mysql_db_info_t *db_info)
{
	MYSQL *mysql_db = NULL;
	int rc = SLURM_ERROR;

	MYSQL *db_ptr = NULL;
	char *db_host = NULL;

	while (rc == SLURM_ERROR) {
		rc = SLURM_SUCCESS;
		if (!(mysql_db = mysql_init(mysql_db)))
			fatal("mysql_init failed: %s", mysql_error(mysql_db));

		_set_mysql_ssl_opts(mysql_db, db_info->params);

		db_host = db_info->host;
		db_ptr = mysql_real_connect(mysql_db,
					    db_host, db_info->user,
					    db_info->pass, NULL,
					    db_info->port, NULL, 0);

		if (!db_ptr && db_info->backup) {
			info("Connection failed to host = %s "
			     "user = %s port = %u",
			     db_host, db_info->user,
			     db_info->port);
			db_host = db_info->backup;
			db_ptr = mysql_real_connect(mysql_db, db_host,
						    db_info->user,
						    db_info->pass, NULL,
						    db_info->port, NULL, 0);
		}

		if (db_ptr) {
			char *create_line = NULL;
			xstrfmtcat(create_line, "create database %s", db_name);
			if (mysql_query(mysql_db, create_line)) {
				fatal("mysql_query failed: %d %s\n%s",
				      mysql_errno(mysql_db),
				      mysql_error(mysql_db), create_line);
			}
			xfree(create_line);
			if (mysql_thread_safe())
				mysql_thread_end();
			mysql_close(mysql_db);
		} else {
			info("Connection failed to host = %s "
			     "user = %s port = %u",
			     db_host, db_info->user,
			     db_info->port);
			error("mysql_real_connect failed: %d %s",
			      mysql_errno(mysql_db),
			      mysql_error(mysql_db));
			rc = SLURM_ERROR;
		}
		if (rc == SLURM_ERROR)
			sleep(3);
	}
	return rc;
}

extern mysql_conn_t *create_mysql_conn(int conn_num, bool rollback,
				       char *cluster_name)
{
	mysql_conn_t *mysql_conn = xmalloc(sizeof(mysql_conn_t));

	if (rollback)
		mysql_conn->flags |= DB_CONN_FLAG_ROLLBACK;
	mysql_conn->conn = conn_num;
	mysql_conn->cluster_name = xstrdup(cluster_name);
	mysql_conn->wsrep_trx_fragment_size_orig = NO_VAL64;
	slurm_mutex_init(&mysql_conn->lock);
	mysql_conn->update_list = list_create(slurmdb_destroy_update_object);

	return mysql_conn;
}

extern int destroy_mysql_conn(mysql_conn_t *mysql_conn)
{
	if (mysql_conn) {
		mysql_db_close_db_connection(mysql_conn);
		xfree(mysql_conn->pre_commit_query);
		xfree(mysql_conn->cluster_name);
		slurm_mutex_destroy(&mysql_conn->lock);
		FREE_NULL_LIST(mysql_conn->update_list);
		xfree(mysql_conn->wsrep_trx_fragment_unit_orig);
		xfree(mysql_conn);
	}

	return SLURM_SUCCESS;
}

extern mysql_db_info_t *create_mysql_db_info(slurm_mysql_plugin_type_t type)
{
	mysql_db_info_t *db_info = xmalloc(sizeof(mysql_db_info_t));

	switch (type) {
	case SLURM_MYSQL_PLUGIN_AS:
		db_info->port = slurm_conf.accounting_storage_port;
		db_info->host = xstrdup(slurm_conf.accounting_storage_host);
		db_info->backup =
			xstrdup(slurm_conf.accounting_storage_backup_host);
		db_info->user = xstrdup(slurmdbd_conf->storage_user);
		db_info->pass = xstrdup(slurm_conf.accounting_storage_pass);
		db_info->params = xstrdup(slurm_conf.accounting_storage_params);
		break;
	case SLURM_MYSQL_PLUGIN_JC:
		if (!slurm_conf.job_comp_port)
			slurm_conf.job_comp_port = DEFAULT_MYSQL_PORT;
		db_info->port = slurm_conf.job_comp_port;
		db_info->host = xstrdup(slurm_conf.job_comp_host);
		db_info->user = xstrdup(slurm_conf.job_comp_user);
		db_info->pass = xstrdup(slurm_conf.job_comp_pass);
		db_info->params = xstrdup(slurm_conf.accounting_storage_params);
		break;
	default:
		xfree(db_info);
		fatal("Unknown mysql_db_info %d", type);
	}
	return db_info;
}

extern int destroy_mysql_db_info(mysql_db_info_t *db_info)
{
	if (db_info) {
		xfree(db_info->backup);
		xfree(db_info->host);
		xfree(db_info->user);
		xfree(db_info->pass);
		xfree(db_info);
	}
	return SLURM_SUCCESS;
}

extern int mysql_db_get_db_connection(mysql_conn_t *mysql_conn, char *db_name,
				      mysql_db_info_t *db_info)
{
	int rc = SLURM_SUCCESS;
	bool storage_init = false;
	char *db_host = db_info->host;
	unsigned int my_timeout = 30;

	xassert(mysql_conn);

	slurm_mutex_lock(&mysql_conn->lock);

	if (!(mysql_conn->db_conn = mysql_init(mysql_conn->db_conn))) {
		slurm_mutex_unlock(&mysql_conn->lock);
		fatal("mysql_init failed: %s",
		      mysql_error(mysql_conn->db_conn));
	}

	/*
	 * If this ever changes you will need to alter
	 * src/common/slurmdbd_defs.c function _send_init_msg to
	 * handle a different timeout when polling for the
	 * response.
	 */
	mysql_options(mysql_conn->db_conn, MYSQL_OPT_CONNECT_TIMEOUT,
		      (char *)&my_timeout);

	_set_mysql_ssl_opts(mysql_conn->db_conn, db_info->params);

	while (!storage_init) {
		debug2("Attempting to connect to %s:%d", db_host,
		       db_info->port);
		if (!mysql_real_connect(mysql_conn->db_conn, db_host,
					db_info->user, db_info->pass,
					db_name, db_info->port, NULL,
					CLIENT_MULTI_STATEMENTS)) {
			const char *err_str = NULL;
			int err = mysql_errno(mysql_conn->db_conn);

			if (err == ER_BAD_DB_ERROR) {
				debug("Database %s not created.  Creating",
				      db_name);
				rc = _create_db(db_name, db_info);

				/*
				 * When using ca, cert and key the next
				 * connect will fail. Setting the options again
				 * fixes it.
				 */
				_set_mysql_ssl_opts(mysql_conn->db_conn,
						    db_info->params);
				continue;
			}

			err_str = mysql_error(mysql_conn->db_conn);

			if ((db_host == db_info->host) && db_info->backup) {
				debug2("mysql_real_connect failed: %d %s",
				       err, err_str);
				db_host = db_info->backup;
				continue;
			}

			error("mysql_real_connect failed: %d %s",
			      err, err_str);
			rc = ESLURM_DB_CONNECTION;
			mysql_close(mysql_conn->db_conn);
			mysql_conn->db_conn = NULL;
			break;
		}

		storage_init = true;
		if (mysql_conn->flags & DB_CONN_FLAG_ROLLBACK)
			mysql_autocommit(mysql_conn->db_conn, 0);
		rc = _mysql_query_internal(mysql_conn->db_conn,
					   "SET session sql_mode='ANSI_QUOTES,"
					   "NO_ENGINE_SUBSTITUTION';");
	}
	slurm_mutex_unlock(&mysql_conn->lock);
	errno = rc;
	return rc;
}

extern int mysql_db_close_db_connection(mysql_conn_t *mysql_conn)
{
	slurm_mutex_lock(&mysql_conn->lock);
	if (mysql_conn && mysql_conn->db_conn) {
		if (mysql_thread_safe())
			mysql_thread_end();
		mysql_close(mysql_conn->db_conn);
		mysql_conn->db_conn = NULL;
	}
	slurm_mutex_unlock(&mysql_conn->lock);
	return SLURM_SUCCESS;
}

extern int mysql_db_cleanup(void)
{
	debug3("starting mysql cleaning up");

#ifdef mysql_library_end
	mysql_library_end();
#else
	mysql_server_end();
#endif
	debug3("finished mysql cleaning up");
	return SLURM_SUCCESS;
}

extern int mysql_db_query(mysql_conn_t *mysql_conn, char *query)
{
	int rc = SLURM_SUCCESS;

	if (!mysql_conn || !mysql_conn->db_conn) {
		fatal("You haven't inited this storage yet.");
		return 0;	/* For CLANG false positive */
	}
	slurm_mutex_lock(&mysql_conn->lock);
	rc = _mysql_query_internal(mysql_conn->db_conn, query);
	slurm_mutex_unlock(&mysql_conn->lock);
	return rc;
}

/*
 * Executes a single delete sql query.
 * Returns the number of deleted rows, <0 for failure.
 */
extern int mysql_db_delete_affected_rows(mysql_conn_t *mysql_conn, char *query)
{
	int rc = SLURM_SUCCESS;

	if (!mysql_conn || !mysql_conn->db_conn) {
		fatal("You haven't inited this storage yet.");
		return 0;	/* For CLANG false positive */
	}
	slurm_mutex_lock(&mysql_conn->lock);
	if (!(rc = _mysql_query_internal(mysql_conn->db_conn, query)))
		rc = mysql_affected_rows(mysql_conn->db_conn);
	slurm_mutex_unlock(&mysql_conn->lock);
	return rc;
}

extern int mysql_db_ping(mysql_conn_t *mysql_conn)
{
	int rc;

	if (!mysql_conn->db_conn)
		return -1;

	/* clear out the old results so we don't get a 2014 error */
	slurm_mutex_lock(&mysql_conn->lock);
	_clear_results(mysql_conn->db_conn);
	rc = mysql_ping(mysql_conn->db_conn);
	/*
	 * Starting in MariaDB 10.2 many of the api commands started
	 * setting errno erroneously.
	 */
	if (!rc)
		errno = 0;
	slurm_mutex_unlock(&mysql_conn->lock);
	return rc;
}

extern int mysql_db_commit(mysql_conn_t *mysql_conn)
{
	int rc = SLURM_SUCCESS;

	if (!mysql_conn->db_conn)
		return SLURM_ERROR;

	slurm_mutex_lock(&mysql_conn->lock);
	/* clear out the old results so we don't get a 2014 error */
	_clear_results(mysql_conn->db_conn);
	if (mysql_commit(mysql_conn->db_conn)) {
		error("mysql_commit failed: %d %s",
		      mysql_errno(mysql_conn->db_conn),
		      mysql_error(mysql_conn->db_conn));
		errno = mysql_errno(mysql_conn->db_conn);
		rc = SLURM_ERROR;
	}
	slurm_mutex_unlock(&mysql_conn->lock);
	return rc;
}

extern int mysql_db_rollback(mysql_conn_t *mysql_conn)
{
	int rc = SLURM_SUCCESS;

	if (!mysql_conn->db_conn)
		return SLURM_ERROR;

	slurm_mutex_lock(&mysql_conn->lock);
	/* clear out the old results so we don't get a 2014 error */
	_clear_results(mysql_conn->db_conn);
	if (mysql_rollback(mysql_conn->db_conn)) {
		error("mysql_commit failed: %d %s",
		      mysql_errno(mysql_conn->db_conn),
		      mysql_error(mysql_conn->db_conn));
		errno = mysql_errno(mysql_conn->db_conn);
		rc = SLURM_ERROR;
	} else {
		/*
		 * Starting in MariaDB 10.2 many of the api commands started
		 * setting errno erroneously.
		 */
		errno = 0;
	}
	slurm_mutex_unlock(&mysql_conn->lock);
	return rc;

}

extern MYSQL_RES *mysql_db_query_ret(mysql_conn_t *mysql_conn,
				     char *query, bool last)
{
	MYSQL_RES *result = NULL;

	slurm_mutex_lock(&mysql_conn->lock);
	if (_mysql_query_internal(mysql_conn->db_conn, query) != SLURM_ERROR)  {
		if (mysql_errno(mysql_conn->db_conn) == ER_NO_SUCH_TABLE)
			goto fini;
		else if (last)
			result = _get_last_result(mysql_conn->db_conn);
		else
			result = _get_first_result(mysql_conn->db_conn);
		/*
		 * Starting in MariaDB 10.2 many of the api commands started
		 * setting errno erroneously.
		 */
		errno = 0;
		if (!result && mysql_field_count(mysql_conn->db_conn)) {
			/* should have returned data */
			error("We should have gotten a result: '%m' '%s'",
			      mysql_error(mysql_conn->db_conn));
		}
	}

fini:
	slurm_mutex_unlock(&mysql_conn->lock);
	return result;
}

extern int mysql_db_query_check_after(mysql_conn_t *mysql_conn, char *query)
{
	int rc = SLURM_SUCCESS;

	slurm_mutex_lock(&mysql_conn->lock);
	if ((rc = _mysql_query_internal(
		     mysql_conn->db_conn, query)) != SLURM_ERROR)
		rc = _clear_results(mysql_conn->db_conn);
	slurm_mutex_unlock(&mysql_conn->lock);
	return rc;
}

extern uint64_t mysql_db_insert_ret_id(mysql_conn_t *mysql_conn, char *query)
{
	uint64_t new_id = 0;

	slurm_mutex_lock(&mysql_conn->lock);
	if (_mysql_query_internal(mysql_conn->db_conn, query) != SLURM_ERROR)  {
		new_id = mysql_insert_id(mysql_conn->db_conn);
		if (!new_id) {
			/* should have new id */
			error("%s: We should have gotten a new id: %s",
			      __func__, mysql_error(mysql_conn->db_conn));
		}
	}
	slurm_mutex_unlock(&mysql_conn->lock);
	return new_id;

}

extern int mysql_db_create_table(mysql_conn_t *mysql_conn, char *table_name,
				 storage_field_t *fields, char *ending)
{
	char *query = NULL;
	int rc;
	storage_field_t *first_field = fields;

	if (!fields || !fields->name) {
		error("Not creating an empty table");
		return SLURM_ERROR;
	}

	/* We have an internal table called table_defs_table which
	 * contains the definition of each table in the database.  To
	 * speed things up we just check against that to see if
	 * anything has changed.
	 */
	query = xstrdup_printf("create table if not exists %s "
			       "(creation_time int unsigned not null, "
			       "mod_time int unsigned default 0 not null, "
			       "table_name text not null, "
			       "definition text not null, "
			       "primary key (table_name(50))) engine='innodb'",
			       table_defs_table);
	if (mysql_db_query(mysql_conn, query) == SLURM_ERROR) {
		xfree(query);
		return SLURM_ERROR;
	}
	xfree(query);

	query = xstrdup_printf("create table if not exists %s (`%s` %s",
			       table_name, fields->name, fields->options);
	fields++;

	while (fields && fields->name) {
		xstrfmtcat(query, ", `%s` %s", fields->name, fields->options);
		fields++;
	}
	xstrcat(query, ending);

	/* make sure we can do a rollback */
	xstrcat(query, " engine='innodb'");

	if (mysql_db_query(mysql_conn, query) == SLURM_ERROR) {
		xfree(query);
		return SLURM_ERROR;
	}
	xfree(query);

	rc = _mysql_make_table_current(
		mysql_conn, table_name, first_field, ending);
	return rc;
}

extern int mysql_db_get_var_str(mysql_conn_t *mysql_conn,
				const char *variable_name,
				char **value)
{
	MYSQL_ROW row = NULL;
	MYSQL_RES *result = NULL;
	char *query;

	query = xstrdup_printf("select @@%s;", variable_name);
	result = mysql_db_query_ret(mysql_conn, query, 0);
	if (!result) {
		error("%s: null result from query `%s`", __func__, query);
		xfree(query);
		return SLURM_ERROR;
	}

	if (mysql_num_rows(result) != 1) {
		error("%s: invalid results from query `%s`", __func__, query);
		xfree(query);
		mysql_free_result(result);
		return SLURM_ERROR;
	}

	xfree(query);

	row = mysql_fetch_row(result);
	*value = xstrdup(row[0]);

	mysql_free_result(result);

	return SLURM_SUCCESS;
}

extern int mysql_db_get_var_u64(mysql_conn_t *mysql_conn,
				const char *variable_name,
				uint64_t *value)
{
	char *err_check = NULL, *var_str = NULL;

	if (mysql_db_get_var_str(mysql_conn, variable_name, &var_str)) {
		return SLURM_ERROR;
	}

	*value = strtoull(var_str, &err_check, 10);

	if (*err_check) {
		error("%s: error parsing string to int `%s`",
		      __func__, var_str);
		xfree(var_str);
		return SLURM_ERROR;
	}
	xfree(var_str);

	return SLURM_SUCCESS;
}

extern void mysql_db_enable_streaming_replication(mysql_conn_t *mysql_conn)
{
	int rc = SLURM_SUCCESS;
	char *query;
	uint64_t wsrep_on, wsrep_max_ws_size, fragment_size;

	/* if this errors, assume wsrep_on doesn't exist, so must be disabled */
	if (mysql_db_get_var_u64(mysql_conn, "wsrep_on", &wsrep_on)) {
		wsrep_on = 0;
		if (errno == ER_UNKNOWN_SYSTEM_VARIABLE)
			error("The prior error message regarding an undefined 'wsrep_on' variable is innocuous.  MySQL and MariaDB < 10.1 do not have this variable and Slurm will operate normally without it.");
	}

	debug2("wsrep_on=%"PRIu64, wsrep_on);

	if (!wsrep_on)
		return;

	/*
	 * wsrep_max_ws_size represents the maximum write set size in bytes.
	 * The fragment cannot exceed this value.
	 */
	rc = mysql_db_get_var_u64(mysql_conn, "wsrep_max_ws_size",
			          &wsrep_max_ws_size);
	if (rc) {
		error("Failed to get wsrep_max_ws_size");
		return;
	}

	/*
	 * Save the initial wsrep settings so they can be restored later.
	 * If these were set previously, don't set them again.
	 *
	 * If these variables don't exist, streaming replication isn't supported
	 * so don't turn it on.
	 */
	if (!mysql_conn->wsrep_trx_fragment_unit_orig) {
		rc = mysql_db_get_var_str(
			mysql_conn,
			"wsrep_trx_fragment_unit",
			&mysql_conn->wsrep_trx_fragment_unit_orig);
		if (rc) {
			if (errno == ER_UNKNOWN_SYSTEM_VARIABLE)
				error("This version of galera does not support streaming replication.");
			error("Unable to fetch wsrep_trx_fragment_unit.");
			return;
		}
	}
	if (mysql_conn->wsrep_trx_fragment_size_orig == NO_VAL64) {
		rc = mysql_db_get_var_u64(
			mysql_conn,
			"wsrep_trx_fragment_size",
			&mysql_conn->wsrep_trx_fragment_size_orig);
		if (rc) {
			if (errno == ER_UNKNOWN_SYSTEM_VARIABLE)
				error("This version of galera does not support streaming replication.");
			error("Unable to fetch wsrep_trx_fragment_size.");
			return;
		}
	}

	/*
	 * Force the wsrep_trx_fragment_unit to bytes. The default may change
	 * in the future, or may have been set by the site, so don't rely on it
	 * being a specific value.
	 */
	query = xstrdup("SET @@SESSION.wsrep_trx_fragment_unit=\'bytes\';");
	rc = _mysql_query_internal(mysql_conn->db_conn, query);
	xfree(query);
	if (rc) {
		error("Unable to set wsrep_trx_fragment_unit.");
		return;
	}

	/*
	 * Set the fragment size to 128MiB, or wsrep_max_ws_size if it has been
	 * set below that. Simply setting it to the max size does not strictly
	 * result in the best performance.
	 */
	fragment_size = MIN(wsrep_max_ws_size, 134217700);
	query = xstrdup_printf("SET @@SESSION.wsrep_trx_fragment_size=%"PRIu64";",
			       fragment_size);
	rc = _mysql_query_internal(mysql_conn->db_conn, query);
	xfree(query);
	if (rc)
		error("Failed to set wsrep_trx_fragment_size");
	else
		debug2("set wsrep_trx_fragment_size=%"PRIu64" bytes",
		       fragment_size);

	return;
}

extern void mysql_db_restore_streaming_replication(mysql_conn_t *mysql_conn)
{
	int rc;
	char *query;

	/*
	 * Check if the connection has saved streaming replication settings.  If
	 * not there is nothing to restore.
	 */
	if (!mysql_conn->wsrep_trx_fragment_unit_orig &&
	    (mysql_conn->wsrep_trx_fragment_size_orig == NO_VAL64)) {
		debug2("no streaming replication settings to restore");
		return;
	}

	if (mysql_conn->wsrep_trx_fragment_unit_orig) {
		query = xstrdup_printf(
				"SET @@SESSION.wsrep_trx_fragment_unit=\'%s\';",
				mysql_conn->wsrep_trx_fragment_unit_orig);
		rc = _mysql_query_internal(mysql_conn->db_conn, query);
		xfree(query);
		if (rc) {
			error("Unable to restore wsrep_trx_fragment_unit.");
		} else {
			debug2("Restored wsrep_trx_fragment_unit=%s",
			       mysql_conn->wsrep_trx_fragment_unit_orig);
			xfree(mysql_conn->wsrep_trx_fragment_unit_orig);
		}
	}
	if (mysql_conn->wsrep_trx_fragment_size_orig != NO_VAL64) {
		query = xstrdup_printf(
				"SET @@SESSION.wsrep_trx_fragment_size=%"PRIu64";",
				mysql_conn->wsrep_trx_fragment_size_orig);
		rc = _mysql_query_internal(mysql_conn->db_conn, query);
		xfree(query);
		if (rc) {
			error("Unable to restore wsrep_trx_fragment_size.");
		} else {
			debug2("Restored wsrep_trx_fragment_size=%"PRIu64,
			       mysql_conn->wsrep_trx_fragment_size_orig);
			mysql_conn->wsrep_trx_fragment_size_orig = NO_VAL64;
		}
	}

	return;
}
