Beispiel #1
0
/*
 * pgsql_modify_common - modify the entity table and insert a txn record
 *
 * IN pg_conn: database connection
 * IN type: modification action type
 * IN now: current time
 * IN cluster: which cluster is modified, "" for shared tables
 * IN user_name: user performing the modify operation
 * IN table: name of the table to modify
 * IN name_char: which entities to modify
 *    FORMAT: "(name=val1 OR name=val2...)"
 * IN vals: values of new attributes of the entities
 *    FORMAT: ", field1=val1,field2=val2..."
 *    NOTE the leading ", "
 * RET: error code
 */
extern int
pgsql_modify_common(pgsql_conn_t *pg_conn, uint16_t type, time_t now,
		    char *cluster, char *user_name, char *table,
		    char *name_char, char *vals)
{
	char *query = NULL;
	int rc = SLURM_SUCCESS;

	query = xstrdup_printf("UPDATE %s SET mod_time=%ld %s "
			       "WHERE deleted=0 AND %s;",
			       table, now, vals, name_char);
	rc = DEF_QUERY_RET_RC;
	if (rc == SLURM_SUCCESS)
		rc = add_txn(pg_conn, now, cluster, type, name_char,
			     user_name, (vals+2));

	if (rc != SLURM_SUCCESS) {
		reset_pgsql_conn(pg_conn);
		return SLURM_ERROR;
	}
	return SLURM_SUCCESS;
}
Beispiel #2
0
/*
 * as_pg_remove_accts - remove accounts
 *
 * IN pg_conn: database connection
 * IN uid: user performing the remove operation
 * IN acct_cond: accounts to remove
 * RET: list of accounts removed
 */
extern List
as_pg_remove_accts(pgsql_conn_t *pg_conn, uint32_t uid,
		   slurmdb_account_cond_t *acct_cond)
{
	DEF_VARS;
	List ret_list = NULL, tmp_list = NULL;
	char *user_name = NULL, *cond = NULL, *name_char = NULL,
		*assoc_char = NULL;
	time_t now = time(NULL);
	int rc = SLURM_SUCCESS, has_jobs;

	if(!acct_cond) {
		error("as/pg: remove_accts: we need something to remove");
		return NULL;
	}
	if (check_db_connection(pg_conn) != SLURM_SUCCESS)
		return NULL;

	if(acct_cond->assoc_cond)
		concat_cond_list(acct_cond->assoc_cond->acct_list,
				 NULL, "name", &cond);
	concat_cond_list(acct_cond->description_list,
			 NULL, "description", &cond);
	concat_cond_list(acct_cond->organization_list,
			 NULL, "organization", &cond);
	if(!cond) {
		error("as/pg: remove_accts: nothing to remove");
		return NULL;
	}

	query = xstrdup_printf(
		"SELECT name FROM %s WHERE deleted=0 %s;",
		acct_table, cond);
	xfree(cond);
	result = DEF_QUERY_RET;
	if(!result)
		return NULL;

	rc = 0;
	ret_list = list_create(slurm_destroy_char);
	FOR_EACH_ROW {
		char *object = xstrdup(ROW(0));
		list_append(ret_list, object);
		if(!rc) {
			xstrfmtcat(name_char, "name='%s'", object);
			xstrfmtcat(assoc_char, "t2.acct='%s'", object);
			rc = 1;
		} else  {
			xstrfmtcat(name_char, " OR name='%s'", object);
			xstrfmtcat(assoc_char, " OR t2.acct='%s'", object);
		}
	} END_EACH_ROW;
	PQclear(result);

	if(!list_count(ret_list)) {
		errno = SLURM_NO_CHANGE_IN_DATA;
		debug3("as/pg: remove_accts: didn't effect anything");
		return ret_list;
	}

	/* remove these accounts from the coord's that have it */
	tmp_list = acct_storage_p_remove_coord(pg_conn, uid, ret_list, NULL);
	if(tmp_list)
		list_destroy(tmp_list);

	/* if there are running jobs of the accounts, return the jobs */
	tmp_list = _get_acct_running_jobs(pg_conn, assoc_char);
	if (tmp_list) {
		errno = ESLURM_JOBS_RUNNING_ON_ASSOC;
		list_destroy(ret_list);
		reset_pgsql_conn(pg_conn);
		return tmp_list;
	}

	/* delete recently added accounts */
	has_jobs = _acct_has_jobs(pg_conn, assoc_char);
	if (! has_jobs ) {
		query = xstrdup_printf(
			"DELETE FROM %s WHERE creation_time>%d AND (%s);",
			acct_table, (int)(now - DELETE_SEC_BACK), name_char);
	}
	/* mark others as deleted */
	xstrfmtcat(query, "UPDATE %s SET mod_time=%ld, deleted=1 "
		   "WHERE deleted=0 "
		   "AND (%s);", acct_table, (long)now, name_char);
	user_name = uid_to_string((uid_t) uid);
	xstrfmtcat(query, "INSERT INTO %s (timestamp, action, name, actor) "
		   "VALUES (%ld, %d, $$%s$$, '%s');", txn_table, (long)now,
		   DBD_REMOVE_ACCOUNTS, name_char, user_name);
	xfree(user_name);
	rc = DEF_QUERY_RET_RC;
	if (rc != SLURM_SUCCESS) {
		reset_pgsql_conn(pg_conn);
		list_destroy(ret_list);
		ret_list = NULL;
		goto out;
	}

	/* TODO: this may leave sub-accts without assoc */
	/* handle associations */
	FOR_EACH_CLUSTER(NULL) {
		rc = _cluster_remove_acct_assoc(pg_conn, cluster_name,
						now, assoc_char, has_jobs);
		if (rc != SLURM_SUCCESS)
			break;
	} END_EACH_CLUSTER;

	if (rc != SLURM_SUCCESS) {
		reset_pgsql_conn(pg_conn);
		list_destroy(ret_list);
		ret_list = NULL;
	}

out:
	xfree(name_char);
	xfree(assoc_char);
	return ret_list;
}
Beispiel #3
0
/*
 * handle related associations:
 * 1. mark assoc usages as deleted
 * 2. delete assocs that does not has job
 * 3. mark other assocs as deleted
 * assoc_cond format: "t2.acct=name OR t2.acct=name..."
 */
static int
_cluster_remove_acct_assoc(pgsql_conn_t *pg_conn, char *cluster,
			   time_t now, char *assoc_cond, int has_jobs)
{
	DEF_VARS;
	slurmdb_association_rec_t *rem_assoc = NULL;
	char *assoc_char = NULL;
	int rc = SLURM_SUCCESS;
	uint32_t smallest_lft = 0xFFFFFFFF, lft;

	query = xstrdup_printf (
		"SELECT DISTINCT t1.id_assoc,t1.lft FROM %s.%s AS t1, %s.%s AS t2 "
		"WHERE t1.deleted=0 AND t2.deleted=0 AND (%s) AND "
		"t1.creation_time>%d "
		"AND (t1.lft BETWEEN t2.lft AND t2.rgt);",
		cluster, assoc_table, cluster, assoc_table, assoc_cond,
		(int)(now - DELETE_SEC_BACK));
	result = DEF_QUERY_RET;
	if (!result)
		return SLURM_ERROR;

	if (PQntuples(result) == 0) {
		PQclear(result);
		return SLURM_SUCCESS;
	}

	FOR_EACH_ROW {
		if (assoc_char)
			xstrfmtcat(assoc_char, " OR id_assoc=%s", ROW(0));
		else
			xstrfmtcat(assoc_char, "id_assoc=%s", ROW(0));

		lft = atoi(ROW(1));
		if (lft < smallest_lft)
			smallest_lft = lft;

		rem_assoc = xmalloc(sizeof(slurmdb_association_rec_t));
		rem_assoc->id = atoi(ROW(0));
		rem_assoc->cluster = xstrdup(cluster);
		if (addto_update_list(pg_conn->update_list,
				      SLURMDB_REMOVE_ASSOC,
				      rem_assoc) != SLURM_SUCCESS)
			error("could not add to the update list");
		if (! has_jobs) {
			xstrfmtcat(query, "SELECT %s.remove_assoc(%s);",
				   cluster, ROW(0));
		}
	} END_EACH_ROW;
	PQclear(result);

	/* mark usages as deleted */
	cluster_delete_assoc_usage(pg_conn, cluster, now, assoc_char);

	if (!has_jobs && query) {
		rc = DEF_QUERY_RET_RC;
		if (rc != SLURM_SUCCESS) {
			error("failed to remove account assoc");
		}
	}

	if(rc == SLURM_SUCCESS)
		rc = pgsql_get_modified_lfts(pg_conn,
					     cluster, smallest_lft);
	if (rc != SLURM_SUCCESS) {
		reset_pgsql_conn(pg_conn);
		return rc;
	}

	/* update associations to clear the limits */
	query = xstrdup_printf(
		"UPDATE %s.%s SET mod_time=%d, deleted=1, def_qos_id=NULL, "
		"shares=1, max_jobs=NULL, max_nodes_pj=NULL, max_wall_pj=NULL, "
		"max_cpu_mins_pj=NULL WHERE (%s);", cluster, assoc_table,
		(int)now, assoc_char);
	xfree(assoc_char);
	rc = DEF_QUERY_RET_RC;

	return rc;
}
Beispiel #4
0
/*
 * as_pg_remove_clusters - remove clusters
 *
 * IN pg_conn: database connection
 * IN uid: user performing the remove operation
 * IN cluster_cond: clusters to remove
 * RET: list of clusters removed
 */
extern List
as_pg_remove_clusters(pgsql_conn_t *pg_conn, uint32_t uid,
		      slurmdb_cluster_cond_t *cluster_cond)
{
	DEF_VARS;
	List ret_list = NULL, job_list = NULL;
	int rc = SLURM_SUCCESS, has_jobs;
	char *cond = NULL, *user_name = NULL;
	time_t now = time(NULL);

	if(!cluster_cond) {
		error("as/pg: remove_clusters: we need something to remove");
		return NULL;
	}
	if(check_db_connection(pg_conn) != SLURM_SUCCESS)
		return NULL;

	concat_cond_list(cluster_cond->cluster_list, NULL, "name", &cond);
	if(!cond) {
		error("as/pg: remove_clusters: nothing to remove");
		return NULL;
	}
	query = xstrdup_printf("SELECT name FROM %s WHERE deleted=0 %s;",
			       cluster_table, cond);
	xfree(cond);
	result = DEF_QUERY_RET;
	if (!result) {
		error("as/pg: remove_clusters: failed to get cluster names");
		return NULL;
	}

	ret_list = list_create(slurm_destroy_char);
	if (PQntuples(result) == 0) {
		PQclear(result);
		errno = SLURM_NO_CHANGE_IN_DATA;
		debug3("didn't effect anything");
		/* XXX: if we return NULL, test21.27 will fail to execute */
		return ret_list;
	}

	user_name = uid_to_string((uid_t)uid);
	rc = 0;
	FOR_EACH_ROW {
		char *cluster = ROW(0);

		job_list = _get_cluster_running_jobs(pg_conn, cluster);
		if (job_list)
			break;

		has_jobs = _cluster_has_jobs(pg_conn, cluster);

		if (!has_jobs)
			query = xstrdup_printf(
				"DELETE FROM %s WHERE creation_time>%ld AND "
				"name='%s';", cluster_table,
				(now - DELETE_SEC_BACK), cluster);
		xstrfmtcat(query,
			   "UPDATE %s SET mod_time=%ld, deleted=1 WHERE "
			   "deleted=0 AND name='%s';", cluster_table, now,
			   cluster);
		xstrfmtcat(query,
			   "INSERT INTO %s (timestamp, action, name, actor) "
			   "VALUES (%ld, %d, '%s', '%s');", txn_table, now,
			   (int)DBD_REMOVE_CLUSTERS, cluster, user_name);

		rc = DEF_QUERY_RET_RC;
		if (rc != SLURM_SUCCESS)
			break;

		rc = _remove_cluster_tables(pg_conn, cluster);
		if (rc != SLURM_SUCCESS)
			break;

		list_append(ret_list, xstrdup(cluster));
		addto_update_list(pg_conn->update_list, SLURMDB_REMOVE_CLUSTER,
				  xstrdup(cluster));
		pg_conn->cluster_changed = 1;
	} END_EACH_ROW;
	PQclear(result);

	if (job_list) {
		reset_pgsql_conn(pg_conn);
		list_destroy(ret_list);
		error("as/pg: remove_clusters: jobs running on cluster");
		errno = ESLURM_JOBS_RUNNING_ON_ASSOC;
		return job_list;
	}
	if (rc != SLURM_SUCCESS) {
		reset_pgsql_conn(pg_conn);
		list_destroy(ret_list);
		ret_list = NULL;
	}
	return ret_list;
}
Beispiel #5
0
/*
 * as_pg_add_clusters - add clusters
 *
 * IN pg_conn: database connection
 * IN uid: user performing the add operation
 * IN cluster_list: clusters to add
 * RET: error code
 */
extern int
as_pg_add_clusters(pgsql_conn_t *pg_conn, uint32_t uid,
		   List cluster_list)
{
	ListIterator itr = NULL;
	int rc = SLURM_SUCCESS, added = 0;
	slurmdb_cluster_rec_t *object = NULL;
	time_t now = time(NULL);
	List assoc_list = NULL;
	slurmdb_association_rec_t *assoc = NULL;
	char *txn_info = NULL, *query = NULL, *user_name = NULL;

	if (check_db_connection(pg_conn) != SLURM_SUCCESS)
		return ESLURM_DB_CONNECTION;

	assoc_list = list_create(slurmdb_destroy_association_rec);
	user_name = uid_to_string((uid_t) uid);
	itr = list_iterator_create(cluster_list);
	while((object = list_next(itr))) {
		if(!object->name) {
			error("as/pg: add_clusters: We need a cluster "
			      "name to add.");
			rc = SLURM_ERROR;
			continue;
		}
		if (strchr(object->name, '.')) {
			error("as/pg: add_clusters: invalid cluster name %s",
			      object->name);
			rc = SLURM_ERROR;
			continue;
		}
		if (cluster_in_db(pg_conn, object->name)) {
			error("cluster %s already added", object->name);
			rc = SLURM_ERROR;
			continue;
		}

		query = xstrdup_printf(
			"SELECT public.add_cluster("
			"(%ld, %ld, 0, '%s', '', 0, 0, %u, 1, 0, 0));",
			(long)now, (long)now, object->name,
			object->classification);
		rc = DEF_QUERY_RET_RC;
		if(rc != SLURM_SUCCESS) {
			error("Couldn't add cluster %s", object->name);
			added = 0; /* rollback modification to DB */
			break;
		}

		rc = _create_cluster_tables(pg_conn, object->name);
		if (rc != SLURM_SUCCESS) {
			error("Failed creating cluster tables for %s",
			      object->name);
			added = 0;
			break;
		}

		/* add root account assoc: <'cluster', 'root', '', ''> */
		if (add_cluster_root_assoc(pg_conn, now, object, &txn_info)
		    != SLURM_SUCCESS) {
			added = 0;
			break;
		}

		if (add_txn(pg_conn, now, "", DBD_ADD_CLUSTERS, object->name,
			    user_name, txn_info) != SLURM_SUCCESS) {
			error("as/pg: add_cluster: couldn't add txn");
		} else {
			added ++;
		}
		xfree(txn_info);

		/* Add user root by default to run from the root
		 * association.  This gets popped off so we need to
		 * read it every time here.
		 */
		assoc = xmalloc(sizeof(slurmdb_association_rec_t));
		slurmdb_init_association_rec(assoc, 0);
		list_append(assoc_list, assoc);
		assoc->cluster = xstrdup(object->name);
		assoc->user = xstrdup("root");
		assoc->acct = xstrdup("root");
		if(acct_storage_p_add_associations(pg_conn, uid, assoc_list)
		   == SLURM_ERROR) {
			error("Problem adding root user association");
			rc = SLURM_ERROR;
		}
		list_flush(assoc_list); /* do not add it again, in case not popped */
	}
	list_iterator_destroy(itr);
	xfree(user_name);
	list_destroy(assoc_list);

	if (!added) {
		reset_pgsql_conn(pg_conn);
	} else {
		/* when loading sacctmgr cfg file,
		   get_assoc will be called before commit
		*/
		pg_conn->cluster_changed = 1;
	}

	return rc;
}