blob: 45c6cb246117e6944488f4d3f284ded8617376de [file] [log] [blame]
/*****************************************************************************\
* as_mysql_problems.c - functions for finding out problems in the
* associations and other places in the database.
*****************************************************************************
* Copyright (C) 2009 Lawrence Livermore National Security.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Danny Auble <da@llnl.gov>
* CODE-OCEC-09-009. All rights reserved.
*
* 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.
\*****************************************************************************/
#include "as_mysql_problems.h"
#include "src/common/uid.h"
static int _setup_assoc_cond_limits(
slurmdb_assoc_cond_t *assoc_cond,
char **extra, bool user_query)
{
int set = 0;
list_itr_t *itr = NULL;
char *object = NULL;
xstrfmtcat(*extra, "where t1.deleted=0");
if (!assoc_cond)
return 0;
if (assoc_cond->acct_list && list_count(assoc_cond->acct_list)) {
set = 0;
xstrcat(*extra, " && (");
itr = list_iterator_create(assoc_cond->acct_list);
while ((object = list_next(itr))) {
if (set)
xstrcat(*extra, " || ");
xstrfmtcat(*extra, "t1.acct='%s'", object);
set = 1;
}
list_iterator_destroy(itr);
xstrcat(*extra, ")");
}
if (assoc_cond->user_list && list_count(assoc_cond->user_list)) {
set = 0;
xstrcat(*extra, " && (");
itr = list_iterator_create(assoc_cond->user_list);
while ((object = list_next(itr))) {
if (set)
xstrcat(*extra, " || ");
xstrfmtcat(*extra, "t1.user='%s'", object);
set = 1;
}
list_iterator_destroy(itr);
xstrcat(*extra, ")");
} else if (user_query) {
/* we want all the users, but no non-user associations */
set = 1;
xstrcat(*extra, " && (t1.user!='')");
}
if (assoc_cond->partition_list
&& list_count(assoc_cond->partition_list)) {
set = 0;
xstrcat(*extra, " && (");
itr = list_iterator_create(assoc_cond->partition_list);
while ((object = list_next(itr))) {
if (set)
xstrcat(*extra, " || ");
xstrfmtcat(*extra, "t1.`partition`='%s'", object);
set = 1;
}
list_iterator_destroy(itr);
xstrcat(*extra, ")");
}
return set;
}
extern int as_mysql_acct_no_assocs(mysql_conn_t *mysql_conn,
slurmdb_assoc_cond_t *assoc_cond,
list_t *ret_list)
{
int rc = SLURM_SUCCESS;
char *query = NULL;
MYSQL_RES *result = NULL;
MYSQL_ROW row;
list_t *use_cluster_list = NULL;
list_itr_t *itr = NULL;
char *cluster_name = NULL;
bool locked = false;
xassert(ret_list);
query = xstrdup_printf("select name from %s where deleted=0",
acct_table);
if (assoc_cond &&
assoc_cond->acct_list && list_count(assoc_cond->acct_list)) {
int set = 0;
list_itr_t *itr = NULL;
char *object = NULL;
xstrcat(query, " && (");
itr = list_iterator_create(assoc_cond->acct_list);
while ((object = list_next(itr))) {
if (set)
xstrcat(query, " || ");
xstrfmtcat(query, "name='%s'", object);
set = 1;
}
list_iterator_destroy(itr);
xstrcat(query, ")");
}
if (!(result = mysql_db_query_ret(
mysql_conn, query, 0))) {
xfree(query);
return ESLURM_BAD_SQL;
}
xfree(query);
if (assoc_cond &&
assoc_cond->cluster_list && list_count(assoc_cond->cluster_list))
use_cluster_list = assoc_cond->cluster_list;
else {
slurm_rwlock_rdlock(&as_mysql_cluster_list_lock);
use_cluster_list = list_shallow_copy(as_mysql_cluster_list);
locked = true;
}
itr = list_iterator_create(use_cluster_list);
while ((row = mysql_fetch_row(result))) {
MYSQL_RES *result2 = NULL;
int cnt = 0;
slurmdb_assoc_rec_t *assoc = NULL;
/* See if we have at least 1 association in the system */
while ((cluster_name = list_next(itr))) {
if (query)
xstrcat(query, " union ");
xstrfmtcat(query,
"select distinct id_assoc from \"%s_%s\" "
"where deleted=0 && "
"acct='%s'",
cluster_name, assoc_table, row[0]);
}
list_iterator_reset(itr);
if (query)
xstrcat(query, " limit 1");
if (!(result2 = mysql_db_query_ret(
mysql_conn, query, 0))) {
xfree(query);
rc = ESLURM_BAD_SQL;
break;
}
xfree(query);
cnt = mysql_num_rows(result2);
mysql_free_result(result2);
if (cnt)
continue;
assoc = xmalloc(sizeof(slurmdb_assoc_rec_t));
list_append(ret_list, assoc);
assoc->id = SLURMDB_PROBLEM_ACCT_NO_ASSOC;
assoc->acct = xstrdup(row[0]);
}
mysql_free_result(result);
list_iterator_destroy(itr);
if (locked) {
slurm_rwlock_unlock(&as_mysql_cluster_list_lock);
FREE_NULL_LIST(use_cluster_list);
}
return rc;
}
extern int as_mysql_acct_no_users(mysql_conn_t *mysql_conn,
slurmdb_assoc_cond_t *assoc_cond,
list_t *ret_list)
{
int rc = SLURM_SUCCESS;
char *query = NULL, *tmp = NULL;
char *extra = NULL;
int i = 0;
MYSQL_RES *result = NULL;
MYSQL_ROW row;
list_t *use_cluster_list = NULL;
list_itr_t *itr = NULL;
char *cluster_name;
bool locked = false;
xassert(ret_list);
_setup_assoc_cond_limits(assoc_cond, &extra, 0);
/* if this changes you will need to edit the corresponding enum */
char *assoc_req_inx[] = {
"id_assoc",
"user",
"acct",
"`partition`",
"parent_acct",
};
enum {
ASSOC_REQ_ID,
ASSOC_REQ_USER,
ASSOC_REQ_ACCT,
ASSOC_REQ_PART,
ASSOC_REQ_PARENT,
ASSOC_REQ_COUNT
};
xfree(tmp);
xstrfmtcat(tmp, "t1.%s", assoc_req_inx[i]);
for(i=1; i<ASSOC_REQ_COUNT; i++) {
xstrfmtcat(tmp, ", t1.%s", assoc_req_inx[i]);
}
if (assoc_cond &&
assoc_cond->cluster_list && list_count(assoc_cond->cluster_list))
use_cluster_list = assoc_cond->cluster_list;
else {
slurm_rwlock_rdlock(&as_mysql_cluster_list_lock);
use_cluster_list = as_mysql_cluster_list;
locked = true;
}
itr = list_iterator_create(use_cluster_list);
while ((cluster_name = list_next(itr))) {
/*
* Only get the account associations that don't have an
* associated row with a user in it
*/
if (query)
xstrcat(query, " union ");
xstrfmtcat(query, "select distinct %s, '%s' as cluster from \"%s_%s\" as t1 left join \"%s_%s\" as t2 on t2.lineage like concat(t1.lineage, '0-%%') %s && t1.user='' && t2.lineage is NULL",
tmp, cluster_name, cluster_name,
assoc_table, cluster_name,
assoc_table, extra);
}
list_iterator_destroy(itr);
if (locked)
slurm_rwlock_unlock(&as_mysql_cluster_list_lock);
if (query)
xstrcat(query, " order by cluster, acct;");
xfree(tmp);
xfree(extra);
DB_DEBUG(DB_QUERY, mysql_conn->conn, "query\n%s", query);
if (!(result = mysql_db_query_ret(
mysql_conn, query, 0))) {
xfree(query);
return ESLURM_BAD_SQL;
}
xfree(query);
while ((row = mysql_fetch_row(result))) {
slurmdb_assoc_rec_t *assoc =
xmalloc(sizeof(slurmdb_assoc_rec_t));
list_append(ret_list, assoc);
assoc->id = SLURMDB_PROBLEM_ACCT_NO_USERS;
if (row[ASSOC_REQ_USER][0])
assoc->user = xstrdup(row[ASSOC_REQ_USER]);
assoc->acct = xstrdup(row[ASSOC_REQ_ACCT]);
assoc->cluster = xstrdup(row[ASSOC_REQ_COUNT]);
if (row[ASSOC_REQ_PARENT][0])
assoc->parent_acct = xstrdup(row[ASSOC_REQ_PARENT]);
if (row[ASSOC_REQ_PART][0])
assoc->partition = xstrdup(row[ASSOC_REQ_PART]);
}
mysql_free_result(result);
return rc;
}
extern int as_mysql_user_no_assocs_or_no_uid(
mysql_conn_t *mysql_conn,
slurmdb_assoc_cond_t *assoc_cond,
list_t *ret_list)
{
int rc = SLURM_SUCCESS;
char *query = NULL;
MYSQL_RES *result = NULL;
MYSQL_ROW row;
list_t *use_cluster_list = NULL;
list_itr_t *itr = NULL;
char *cluster_name = NULL;
bool locked = false;
xassert(ret_list);
query = xstrdup_printf("select name from %s where deleted=0",
user_table);
if (assoc_cond &&
assoc_cond->user_list && list_count(assoc_cond->user_list)) {
int set = 0;
char *object = NULL;
xstrcat(query, " && (");
itr = list_iterator_create(assoc_cond->user_list);
while ((object = list_next(itr))) {
if (set)
xstrcat(query, " || ");
xstrfmtcat(query, "name='%s'", object);
set = 1;
}
list_iterator_destroy(itr);
xstrcat(query, ")");
}
if (!(result = mysql_db_query_ret(
mysql_conn, query, 0))) {
xfree(query);
return ESLURM_BAD_SQL;
}
xfree(query);
if (assoc_cond &&
assoc_cond->cluster_list && list_count(assoc_cond->cluster_list))
use_cluster_list = assoc_cond->cluster_list;
else {
slurm_rwlock_rdlock(&as_mysql_cluster_list_lock);
use_cluster_list = list_shallow_copy(as_mysql_cluster_list);
locked = true;
}
itr = list_iterator_create(use_cluster_list);
while ((row = mysql_fetch_row(result))) {
MYSQL_RES *result2 = NULL;
int cnt = 0;
slurmdb_assoc_rec_t *assoc = NULL;
uid_t pw_uid;
if (uid_from_string(row[0], &pw_uid) != SLURM_SUCCESS) {
assoc = xmalloc(sizeof(slurmdb_assoc_rec_t));
list_append(ret_list, assoc);
assoc->id = SLURMDB_PROBLEM_USER_NO_UID;
assoc->user = xstrdup(row[0]);
continue;
}
/* See if we have at least 1 association in the system */
while ((cluster_name = list_next(itr))) {
if (query)
xstrcat(query, " union ");
xstrfmtcat(query,
"select distinct id_assoc from \"%s_%s\" "
"where deleted=0 && "
"user='%s'",
cluster_name, assoc_table, row[0]);
}
list_iterator_reset(itr);
if (query)
xstrcat(query, " limit 1");
if (!(result2 = mysql_db_query_ret(
mysql_conn, query, 0))) {
xfree(query);
rc = ESLURM_BAD_SQL;
break;
}
xfree(query);
cnt = mysql_num_rows(result2);
mysql_free_result(result2);
if (cnt)
continue;
assoc = xmalloc(sizeof(slurmdb_assoc_rec_t));
list_append(ret_list, assoc);
assoc->id = SLURMDB_PROBLEM_USER_NO_ASSOC;
assoc->user = xstrdup(row[0]);
}
mysql_free_result(result);
list_iterator_destroy(itr);
if (locked) {
FREE_NULL_LIST(use_cluster_list);
slurm_rwlock_unlock(&as_mysql_cluster_list_lock);
}
return rc;
}