Ejemplo n.º 1
0
/*
 * as_pg_roll_usage - rollup usage information
 *
 * IN pg_conn: database connection
 * IN sent_start: start time
 * IN sent_end: end time
 * IN archive_data: whether to archive usage data
 * RET: error code
 */
extern int
as_pg_roll_usage(pgsql_conn_t *pg_conn,  time_t sent_start,
		 time_t sent_end, uint16_t archive_data)
{
	int rc = SLURM_SUCCESS;

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

	slurm_mutex_lock(&usage_rollup_lock);
	FOR_EACH_CLUSTER(NULL) {
		rc |= _cluster_rollup_usage(pg_conn, cluster_name, sent_start,
					   sent_end, archive_data);
	} END_EACH_CLUSTER;
	slurm_mutex_unlock(&usage_rollup_lock);
	
	return rc;
}
Ejemplo n.º 2
0
// Return 1 on success, 0 on failure
int add_achievement_progress(int achievement_id, int add_progress_count){
	if(achievement_system_disabled){ return ACHIEVEMENT_PUSH_FAILURE; }
	if(ACHIEVEMENT_DEBUG){pline("DEBUG: add_achievement_progress(%i, %i)", achievement_id, add_progress_count);}
	
	if(check_db_connection()){
		disable_achievements();
	}
	
	//Check if user exists
	if(!user_exists()){
		register_user();
	}
	//Calculate user's completion on this achievement
	int pre_achievement_progress = get_achievement_progress(achievement_id);
	int max_achievement_progress = get_achievement_max_progress(achievement_id);
	if(ACHIEVEMENT_DEBUG){pline("DEBUG: get_achievement_max_progress(%i)=%i", achievement_id, max_achievement_progress);}

	if(pre_achievement_progress < max_achievement_progress){ //user still needs achievement
		if(pre_achievement_progress + add_progress_count >= max_achievement_progress){ //Achievement fully achieved!
			if(push_achievement_progress(achievement_id, max_achievement_progress)){ //floor the value to max_progress
				char * achievement_name = get_achievement_name(achievement_id);
				pline("Congratulations! You've earned the achievement: %s", achievement_name);
				free(achievement_name);
				return ACHIEVEMENT_PUSH_SUCCESS;
			}
			else{
				pline("Er, oops. You got an achievement, but it can't be recorded.");
				return ACHIEVEMENT_PUSH_FAILURE;
			}
		}
		else{ //user stills needs achievement, but isn't quite there yet
			if(push_achievement_progress(achievement_id, pre_achievement_progress+add_progress_count)){
				return ACHIEVEMENT_PUSH_SUCCESS;
			}
			else{
				return ACHIEVEMENT_PUSH_FAILURE;
			}
		}
	}
	return ACHIEVEMENT_PUSH_SUCCESS;
}
Ejemplo n.º 3
0
/*
 * as_pg_get_accts - get accounts
 *
 * IN pg_conn: database connection
 * IN uid: user performing the get operation
 * IN acct_cond: accounts to get
 * RET: list of accounts
 */
extern List
as_pg_get_accts(pgsql_conn_t *pg_conn, uid_t uid,
		slurmdb_account_cond_t *acct_cond)
{
	DEF_VARS;
	char *cond = NULL;
	List acct_list = NULL;
	ListIterator itr = NULL;
	int set=0, is_admin=1;
	slurmdb_user_rec_t user;	/* no need to free lists */

	char *ga_fields = "name, description, organization";
	enum {
		F_NAME,
		F_DESC,
		F_ORG,
		F_COUNT
	};

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

	if (check_user_op(pg_conn, uid, PRIVATE_DATA_ACCOUNTS,
			  &is_admin, &user) != SLURM_SUCCESS) {
		error("as/pg: user(%u) not found in db", uid);
		errno = ESLURM_USER_ID_MISSING;
		return NULL;
	}

	if (!is_admin && ! is_user_any_coord(pg_conn, &user)) {
		errno = ESLURM_ACCESS_DENIED;
		return NULL;
	}

	if(!acct_cond) {
		xstrcat(cond, "WHERE deleted=0");
		goto empty;
	}

	if(acct_cond->with_deleted)
		xstrcat(cond, "WHERE (deleted=0 OR deleted=1)");
	else
		xstrcat(cond, "WHERE deleted=0");

	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);

empty:
	if(!is_admin) {
		slurmdb_coord_rec_t *coord = NULL;
		set = 0;
		itr = list_iterator_create(user.coord_accts);
		while((coord = list_next(itr))) {
			if(set) {
				xstrfmtcat(cond, " OR name='%s'",
					   coord->name);
			} else {
				set = 1;
				xstrfmtcat(cond, " AND (name='%s'",
					   coord->name);
			}
		}
		list_iterator_destroy(itr);
		if(set)
			xstrcat(cond,")");
	}

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

	acct_list = list_create(slurmdb_destroy_account_rec);

	if(acct_cond && acct_cond->with_assocs) {
		if(!acct_cond->assoc_cond)
			acct_cond->assoc_cond = xmalloc(
				sizeof(slurmdb_association_cond_t));
		else if(acct_cond->assoc_cond->acct_list)
			list_destroy(acct_cond->assoc_cond->acct_list);
		acct_cond->assoc_cond->acct_list = list_create(NULL);
	}

	FOR_EACH_ROW {
		slurmdb_account_rec_t *acct = xmalloc(sizeof(slurmdb_account_rec_t));
		list_append(acct_list, acct);

		acct->name =  xstrdup(ROW(F_NAME));
		acct->description = xstrdup(ROW(F_DESC));
		acct->organization = xstrdup(ROW(F_ORG));
		if(acct_cond && acct_cond->with_coords)
			_get_account_coords(pg_conn, acct);
		if(acct_cond && acct_cond->with_assocs) {
			list_append(acct_cond->assoc_cond->acct_list,
				    acct->name);
		}
	} END_EACH_ROW;
	PQclear(result);

	/* get associations */
	if(acct_cond && acct_cond->with_assocs &&
	   list_count(acct_cond->assoc_cond->acct_list)) {
		ListIterator assoc_itr = NULL;
		slurmdb_account_rec_t *acct = NULL;
		slurmdb_association_rec_t *assoc = NULL;
		List assoc_list = acct_storage_p_get_associations(
			pg_conn, uid, acct_cond->assoc_cond);

		if(!assoc_list) {
			error("as/pg: get_accounts: no associations");
			return acct_list;
		}

		itr = list_iterator_create(acct_list);
		assoc_itr = list_iterator_create(assoc_list);
		while((acct = list_next(itr))) {
			while((assoc = list_next(assoc_itr))) {
				if(strcmp(assoc->acct, acct->name))
					continue;

				if(!acct->assoc_list)
					acct->assoc_list = list_create(
						slurmdb_destroy_association_rec);
				list_append(acct->assoc_list, assoc);
				list_remove(assoc_itr);
			}
			list_iterator_reset(assoc_itr);
			if(!acct->assoc_list) /* problem acct */
				list_remove(itr);
		}
		list_iterator_destroy(itr);
		list_iterator_destroy(assoc_itr);
		list_destroy(assoc_list);
	}
	return acct_list;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
/*
 * as_pg_modify_accounts - modify accounts
 *
 * IN pg_conn: database connection
 * IN uid: user performing the modify operation
 * IN acct_cond: accounts to modify
 * IN acct: attribute of accounts after modification
 * RET: list of accounts modified
 */
extern List
as_pg_modify_accounts(pgsql_conn_t *pg_conn, uint32_t uid,
		      slurmdb_account_cond_t *acct_cond,
		      slurmdb_account_rec_t *acct)
{
	DEF_VARS;
	List ret_list = NULL;
	int rc = SLURM_SUCCESS;
	char *object = NULL, *user_name = NULL;
	char *vals = NULL, *cond = NULL, *name_char = NULL;
	time_t now = time(NULL);

	if(!acct_cond || !acct) {
		error("as/pg: modify_accounts: we need something to change");
		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) {
		errno = SLURM_NO_CHANGE_IN_DATA;
		error("as/pg: modify_accounts: no condition given");
		return NULL;
	}

	if(acct->description)
		xstrfmtcat(vals, ", description='%s'", acct->description);
	if(acct->organization)
		xstrfmtcat(vals, ", organization='%s'", acct->organization);
	if(!vals) {
		xfree(cond);
		errno = SLURM_NO_CHANGE_IN_DATA;
		error("as/pg: modify_accounts: no new values given");
		return NULL;
	}

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

	rc = 0;
	ret_list = list_create(slurm_destroy_char);
	FOR_EACH_ROW {
		object = xstrdup(ROW(0));
		list_append(ret_list, object);
		if(!rc) {
			xstrfmtcat(name_char, "(name='%s'", object);
			rc = 1;
		} else  {
			xstrfmtcat(name_char, " OR name='%s'", object);
		}

	} END_EACH_ROW;
	PQclear(result);

	if(!list_count(ret_list)) {
		errno = SLURM_NO_CHANGE_IN_DATA;
		debug3("as/pg: modify_accounts: didn't effect anything");
		xfree(vals);
		return ret_list;
	}
	xstrcat(name_char, ")");

	user_name = uid_to_string((uid_t) uid);
	rc = pgsql_modify_common(pg_conn, DBD_MODIFY_ACCOUNTS, now, "",
				 user_name, acct_table, name_char, vals);
	xfree(user_name);
	xfree(name_char);
	xfree(vals);

	if (rc == SLURM_ERROR) {
		error("as/pg: couldn't modify accounts");
		list_destroy(ret_list);
		errno = SLURM_ERROR;
		ret_list = NULL;
	}
	return ret_list;
}
Ejemplo n.º 6
0
/*
 * as_pg_add_accts - add accounts
 *
 * IN pg_conn: database connection
 * IN uid: user performing the add operation
 * IN acct_list: accounts to add
 * RET: error code
 */
extern int
as_pg_add_accts(pgsql_conn_t *pg_conn, uint32_t uid, List acct_list)
{
	ListIterator itr = NULL;
	slurmdb_account_rec_t *object = NULL;
	List assoc_list = NULL;
	int rc = SLURM_SUCCESS;
	char *user_name = NULL, *query = NULL, *txn_query = NULL;
	char *rec = NULL, *info = NULL;
	time_t now = time(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(acct_list);
	while((object = list_next(itr))) {
		if(!object->name || !object->description
		   || !object->organization) {
			error("as/pg: add_accts: We need an account name, "
			      "description, and organization to add. %s %s %s",
			      object->name, object->description,
			      object->organization);
			rc = SLURM_ERROR;
			continue;
		}
		/* order of vals must match structure of acct_table */
		rec = xstrdup_printf("(%ld, %ld, 0, '%s', '%s', '%s')", now,
				     now, object->name, object->description,
				     object->organization);
		query = xstrdup_printf("SELECT public.add_acct(%s);", rec);
		xfree(rec);
		rc = DEF_QUERY_RET_RC;
		if(rc != SLURM_SUCCESS) {
			error("as/pg: couldn't add acct %s", object->name);
			continue;
		}

		info = xstrdup_printf("description='%s', organization='%s'",
				      object->description,
				      object->organization);
		if(txn_query)
			xstrfmtcat(txn_query,
				   ", (%ld, %u, '%s', '%s', $$%s$$)",
				   now, DBD_ADD_ACCOUNTS, object->name,
				   user_name, info);
		else
			xstrfmtcat(txn_query,
				   "INSERT INTO %s "
				   "(timestamp, action, name, actor, info) "
				   "VALUES (%ld, %u, '%s', '%s', $$%s$$)",
				   txn_table,
				   now, DBD_ADD_ACCOUNTS, object->name,
				   user_name, info);
		xfree(info);

		if(!object->assoc_list)
			continue;

		list_transfer(assoc_list, object->assoc_list);
	}
	list_iterator_destroy(itr);
	xfree(user_name);

	if(rc == SLURM_SUCCESS) {
		if(txn_query) {
			xstrcat(txn_query, ";");
			rc = pgsql_db_query(pg_conn->db_conn, txn_query);
			xfree(txn_query);
			if(rc != SLURM_SUCCESS) {
				error("as/pg: add_accts: couldn't add txn");
				rc = SLURM_SUCCESS;
			}
		}
	} else
		xfree(txn_query);

	if(rc == SLURM_SUCCESS && list_count(assoc_list)) {
		if(acct_storage_p_add_associations(pg_conn, uid, assoc_list)
		   != SLURM_SUCCESS) {
			error("as/pg: add_accts: problem adding account "
			      "associations");
			rc = SLURM_ERROR;
		}
	}
	list_destroy(assoc_list);

	return rc;
}
Ejemplo n.º 7
0
/*
 * as_pg_get_clusters -  get clusters
 *
 * IN pg_conn: database connection
 * IN uid: user performing the get operation
 * IN cluster_cond: which clusters to get
 * RET: the clusters
 */
extern List
as_pg_get_clusters(pgsql_conn_t *pg_conn, uid_t uid,
		   slurmdb_cluster_cond_t *cluster_cond)
{
	DEF_VARS;
	char *cond = NULL;
	slurmdb_association_cond_t assoc_cond;
	slurmdb_cluster_rec_t *cluster = NULL;
	slurmdb_association_rec_t *assoc = NULL;
	List cluster_list = NULL, assoc_list = NULL;
	ListIterator itr = NULL, assoc_itr = NULL;

	/* if this changes you will need to edit the corresponding enum */
	char *gc_fields = "name,classification,control_host,control_port,"
		"rpc_version,dimensions,flags,plugin_id_select";
	enum {
		F_NAME,
		F_CLASS,
		F_CH,
		F_CP,
		F_VERSION,
		F_DIMS,
		F_FLAGS,
		F_PI_SELECT,
		F_COUNT
	};

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

	if(!cluster_cond) {
		xstrcat(cond, "WHERE deleted=0");
		goto empty;
	}

	if(cluster_cond->with_deleted)
		xstrcat(cond, "WHERE (deleted=0 OR deleted=1)");
	else
		xstrcat(cond, "WHERE deleted=0");
	concat_cond_list(cluster_cond->cluster_list, NULL, "name", &cond);
empty:
	query = xstrdup_printf("SELECT %s FROM %s %s",
			       gc_fields, cluster_table, cond);
	xfree(cond);
	result = DEF_QUERY_RET;
	if (!result) {
		error("failed to get clusters");
		return NULL;
	}

	cluster_list = list_create(slurmdb_destroy_cluster_rec);
	memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t));
	if(cluster_cond) {
		/* I don't think we want the with_usage flag here.
		 * We do need the with_deleted though. */
		//assoc_cond.with_usage = cluster_cond->with_usage;
		assoc_cond.with_deleted = cluster_cond->with_deleted;
	}
	/* not destroyed, since owned by cluster record */
	assoc_cond.cluster_list = list_create(NULL);

	FOR_EACH_ROW {
		cluster = xmalloc(sizeof(slurmdb_cluster_rec_t));
		list_append(cluster_list, cluster);

		cluster->name = xstrdup(ROW(F_NAME));
		list_append(assoc_cond.cluster_list, cluster->name);

		/* get the usage if requested */
		if(cluster_cond && cluster_cond->with_usage) {
			as_pg_get_usage(pg_conn, uid, cluster,
				       DBD_GET_CLUSTER_USAGE,
				       cluster_cond->usage_start,
				       cluster_cond->usage_end);
		}

		cluster->classification = atoi(ROW(F_CLASS));
		cluster->control_host = xstrdup(ROW(F_CH));
		cluster->control_port = atoi(ROW(F_CP));
		cluster->rpc_version = atoi(ROW(F_VERSION));
		cluster->dimensions = atoi(ROW(F_DIMS));
		cluster->flags = atoi(ROW(F_FLAGS));
		cluster->plugin_id_select = atoi(ROW(F_PI_SELECT));

		get_cluster_cpu_nodes(pg_conn, cluster);
	} END_EACH_ROW;
	PQclear(result);

	if(!list_count(assoc_cond.cluster_list)) {
		list_destroy(assoc_cond.cluster_list);
		return cluster_list;
	}

	/* get root assoc: <cluster, root, '', ''> */
	assoc_cond.acct_list = list_create(NULL);
	list_append(assoc_cond.acct_list, "root");

	assoc_cond.user_list = list_create(NULL);
	list_append(assoc_cond.user_list, "");

	assoc_list = acct_storage_p_get_associations(pg_conn, uid, &assoc_cond);
	list_destroy(assoc_cond.cluster_list);
	list_destroy(assoc_cond.acct_list);
	list_destroy(assoc_cond.user_list);

	if(!assoc_list)
		return cluster_list;

	itr = list_iterator_create(cluster_list);
	assoc_itr = list_iterator_create(assoc_list);
	while((cluster = list_next(itr))) {
		while((assoc = list_next(assoc_itr))) {
			if(strcmp(assoc->cluster, cluster->name))
				continue;

			if(cluster->root_assoc) {
				debug("This cluster %s already has "
				      "an association.", cluster->name);
				continue;
			}
			cluster->root_assoc = assoc;
			list_remove(assoc_itr);
		}
		list_iterator_reset(assoc_itr);
	}
	list_iterator_destroy(itr);
	list_iterator_destroy(assoc_itr);
	if(list_count(assoc_list))
		error("I have %d left over associations",
		      list_count(assoc_list));
	list_destroy(assoc_list);
	return cluster_list;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
/*
 * as_pg_modify_clusters - modify clusters
 *   This is called by cs_p_register_ctld when ctld registers to dbd.
 *   Also called when modify classification of cluster.
 *   If you need to alter the default values of the cluster, use
 *   modify_associations to change root association of the cluster.
 *
 * IN pg_conn: database connection
 * IN uid: user performing the modify operation
 * IN cluster_cond: which clusters to modify
 * IN cluster: attribute of clusters after modification
 * RET: list of clusters modified
 */
extern List
as_pg_modify_clusters(pgsql_conn_t *pg_conn, uint32_t uid,
		      slurmdb_cluster_cond_t *cluster_cond,
		      slurmdb_cluster_rec_t *cluster)
{
	DEF_VARS;
	List ret_list = NULL;
	int rc = SLURM_SUCCESS, set = 0;
	char *object = NULL, *user_name = NULL,	*name_char = NULL;
	char *vals = NULL, *cond = NULL, *send_char = NULL;
	time_t now = time(NULL);
	bool clust_reg = false;

	if (!cluster_cond || !cluster) {
		error("as/pg: modify_clusters: we need something to change");
		return NULL;
	}

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

	if(!pg_conn->cluster_name
	   && cluster_cond->cluster_list
	   && list_count(cluster_cond->cluster_list))
		pg_conn->cluster_name =
			xstrdup(list_peek(cluster_cond->cluster_list));

	concat_cond_list(cluster_cond->cluster_list, NULL, "name", &cond);
	if(cluster_cond->classification) {
		xstrfmtcat(cond, " AND (classification & %u)",
			   cluster_cond->classification);
	}

	set = 0;
	if (cluster->control_host) {
		xstrfmtcat(vals, ", control_host='%s'", cluster->control_host);
		set++;
		clust_reg = true;
	}
	if (cluster->control_port) {
		xstrfmtcat(vals, ", control_port=%u", cluster->control_port);
		set++;
		clust_reg = true;
	}
	if (cluster->rpc_version) {
		xstrfmtcat(vals, ", rpc_version=%u", cluster->rpc_version);
		set++;
		clust_reg = true;
	}
	if (cluster->dimensions) {
		xstrfmtcat(vals, ", dimensions=%u", cluster->dimensions);
		clust_reg = true;
	}
	if (cluster->plugin_id_select) {
		xstrfmtcat(vals, ", plugin_id_select=%u",
			   cluster->plugin_id_select);
		clust_reg = true;
	}
	if (cluster->flags != NO_VAL) {
		xstrfmtcat(vals, ", flags=%u", cluster->flags);
		clust_reg = true;
	}
	if (cluster->classification) {
		xstrfmtcat(vals, ", classification=%u",
			   cluster->classification);
	}

	if(!vals) {
		xfree(cond);
		errno = SLURM_NO_CHANGE_IN_DATA;
		error("as/pg: modify_clusters: nothing to change");
		return NULL;
	} else if(clust_reg && (set != 3)) {
		xfree(vals);
		xfree(cond);
		errno = EFAULT;
		error("as/pg: modify_clusters: need control host, port and "
		      "rpc version to register a cluster");
		return NULL;
	}

	query = xstrdup_printf(
		"SELECT name, control_port FROM %s WHERE deleted=0 %s;",
		cluster_table, cond ?: "");
	xfree(cond);
	result = DEF_QUERY_RET;
	if (!result) {
		xfree(vals);
		error("as/pg: modify_clusters: no result given");
		return NULL;
	}

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

	if(!list_count(ret_list)) {
		errno = SLURM_NO_CHANGE_IN_DATA;
		debug3("as/pg: modify_cluster: nothing effected");
		xfree(vals);
		return ret_list;
	}

	if(vals) {
		send_char = xstrdup_printf("(%s)", name_char);
		user_name = uid_to_string((uid_t) uid);
		rc = pgsql_modify_common(pg_conn, DBD_MODIFY_CLUSTERS, now,
					 "", user_name, cluster_table,
					 send_char, vals);
		xfree(user_name);
		xfree(send_char);
		if (rc != SLURM_SUCCESS) {
			error("Couldn't modify cluster 1");
			list_destroy(ret_list);
			ret_list = NULL;
			goto end_it;
		}
	}
end_it:
	xfree(name_char);
	xfree(vals);
	return ret_list;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
0
/*
 * js_pg_job_start - load into the storage the start of a job
 *
 * IN pg_conn: database connection
 * IN cluster_name: cluster of the job
 * IN job_ptr: job just started
 * RET: error code
 */
extern int
js_pg_job_start(pgsql_conn_t *pg_conn,
		struct job_record *job_ptr)
{
	int rc=SLURM_SUCCESS, track_steps = 0, reinit = 0;
	char *jname = NULL, *nodes = NULL, *node_inx = NULL;
	char *block_id = NULL, *rec = NULL, *query = NULL;
	time_t begin_time, check_time, start_time, submit_time;
	int job_state, node_cnt = 0;
	uint32_t wckeyid = 0;

	if ((!job_ptr->details || !job_ptr->details->submit_time)
	    && !job_ptr->resize_time) {
		error("as/pg: job_start: Not inputing this job, "
		      "it has no submit time.");
		return SLURM_ERROR;
	}

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

	if (! cluster_in_db(pg_conn, pg_conn->cluster_name) ) {
		error("cluster %s not in db", pg_conn->cluster_name);
		return SLURM_ERROR;
	}

	debug3("as/pg: job_start() called");

	job_state = job_ptr->job_state;

	/* Since we need a new db_inx make sure the old db_inx
	 * removed. This is most likely the only time we are going to
	 * be notified of the change also so make the state without
	 * the resize. */
	if (IS_JOB_RESIZING(job_ptr)) {
		/* If we have a db_index lets end the previous record. */
		if (job_ptr->db_index)
			js_pg_job_complete(pg_conn, job_ptr);
		else
			error("We don't have a db_index for job %u, "
			      "this should never happen.", job_ptr->job_id);
		job_state &= (~JOB_RESIZING);
		job_ptr->db_index = 0;
	}

	job_state &= JOB_STATE_BASE;

	if (job_ptr->resize_time) {
		begin_time  = job_ptr->resize_time;
		submit_time = job_ptr->resize_time;
		start_time  = job_ptr->resize_time;
	} else {
		begin_time  = job_ptr->details->begin_time;
		submit_time = job_ptr->details->submit_time;
		start_time  = job_ptr->start_time;
	}

	/* See what we are hearing about here if no start time. If
	 * this job latest time is before the last roll up we will
	 * need to reset it to look at this job. */
	if (start_time)
		check_time = start_time;
	else if (begin_time)
		check_time = begin_time;
	else
		check_time = submit_time;

	slurm_mutex_lock(&usage_rollup_lock);
	if (check_time < global_last_rollup) {
		PGresult *result = NULL;
		/* check to see if we are hearing about this time for the
		 * first time.
		 */
		query = xstrdup_printf(
			"SELECT job_db_inx FROM %s.%s WHERE id_job=%u AND "
			"time_submit=%ld AND time_eligible=%ld AND time_start=%ld",
			pg_conn->cluster_name, job_table, job_ptr->job_id,
			submit_time, begin_time, start_time);
		result = DEF_QUERY_RET;
		if (!result) {
			 slurm_mutex_unlock(&usage_rollup_lock);
			return SLURM_ERROR;
		}
		if (PQntuples(result) != 0) {
			PQclear(result);
			debug4("revieved an update for a "
			       "job (%u) already known about",
			       job_ptr->job_id);
			 slurm_mutex_unlock(&usage_rollup_lock);
			goto no_rollup_change;
		}
		PQclear(result);

		if (job_ptr->start_time)
			debug("Need to reroll usage from %s Job %u "
			      "from %s started then and we are just "
			      "now hearing about it.",
			      ctime(&check_time),
			      job_ptr->job_id, pg_conn->cluster_name);
		else if (begin_time)
			debug("Need to reroll usage from %s Job %u "
			      "from %s became eligible then and we are just "
			      "now hearing about it.",
			      ctime(&check_time),
			      job_ptr->job_id, pg_conn->cluster_name);
		else
			debug("Need to reroll usage from %s Job %u "
			      "from %s was submitted then and we are just "
			      "now hearing about it.",
			      ctime(&check_time),
			      job_ptr->job_id, pg_conn->cluster_name);

		global_last_rollup = check_time;
		slurm_mutex_unlock(&usage_rollup_lock);

		query = xstrdup_printf("UPDATE %s.%s SET hourly_rollup=%ld, "
				       "daily_rollup=%ld, monthly_rollup=%ld",
				       pg_conn->cluster_name, last_ran_table,
				       check_time, check_time, check_time);
		rc = DEF_QUERY_RET_RC;
	} else
		slurm_mutex_unlock(&usage_rollup_lock);

no_rollup_change:

	if (job_ptr->name && job_ptr->name[0])
		jname = xstrdup(job_ptr->name);
	else {
		jname = xstrdup("allocation");
		track_steps = 1;
	}

	if (job_ptr->nodes && job_ptr->nodes[0])
		nodes = job_ptr->nodes;
	else
		nodes = "None assigned";

	if (job_ptr->batch_flag)
		track_steps = 1;

	if (slurmdbd_conf) {
		block_id = xstrdup(job_ptr->comment);
		node_cnt = job_ptr->total_nodes;
		node_inx = job_ptr->network;
	} else {
		char temp_bit[BUF_SIZE];

		if (job_ptr->node_bitmap) {
			node_inx = bit_fmt(temp_bit, sizeof(temp_bit),
					   job_ptr->node_bitmap);
		}
#ifdef HAVE_BG
		select_g_select_jobinfo_get(job_ptr->select_jobinfo,
					    SELECT_JOBDATA_BLOCK_ID,
					    &block_id);
		select_g_select_jobinfo_get(job_ptr->select_jobinfo,
					    SELECT_JOBDATA_NODE_CNT,
					    &node_cnt);
#else
		node_cnt = job_ptr->total_nodes;
#endif
	}

	/* If there is a start_time get the wckeyid.  If the job is
	 * cancelled before the job starts we also want to grab it. */
	if (job_ptr->assoc_id &&
	   (job_ptr->start_time || IS_JOB_CANCELLED(job_ptr)))
		wckeyid = get_wckeyid(pg_conn, &job_ptr->wckey,
				      job_ptr->user_id, pg_conn->cluster_name,
				      job_ptr->assoc_id);

	if (!job_ptr->db_index) {
		if (!begin_time)
			begin_time = submit_time;

		rec = xstrdup_printf(
			"(0, 0, '%s', '%s', %d, %d, 0, '%s', "
			"%d, '%s', %d, %d, %d, %d, %d, %d, 0, "
			"%d, %ld, %ld, %ld, 0, 0, "
			"%d, '%s', '%s', %d, %d, '%s', %d)",
			/* job_db_inx=0, not used */
			/* deleted=0 */
			job_ptr->account ?: "",     /* account */
			job_ptr->partition ?: "",   /* partition */
			(int)job_ptr->details->min_cpus, /* cpus_req */
			(int)job_ptr->total_cpus, /* cpus_alloc */
			/* exit_code=0 */
			jname,  /* job_name */

			(int)job_ptr->assoc_id, /* id_assoc */
			block_id ?: "", /* id_block */
			(int)job_ptr->job_id,   /* id_job */
			(int)job_ptr->qos_id,   /* id_qos */
			(int)job_ptr->resv_id,  /* id_resv */
			(int)wckeyid,           /* id_wckey */
			(int)job_ptr->user_id,  /* uid */
			(int)job_ptr->group_id, /* gid */
			/* kill_requid=0 */

			(int)job_ptr->time_limit, /* timelimit */
			submit_time,         /* time_submit */
			begin_time,          /* time_eligible */
			start_time,          /* time_start */
			/* time_end=0 */
			/* time_suspended=0 */

			(int)node_cnt, /* nodes_alloc */
			nodes ?: "",                    /* nodelist */
			node_inx ?: "",         /* node_inx */
			(int)job_ptr->priority, /* priority */
			(int)job_state,         /* state */
			job_ptr->wckey ?: "",   /* wckey */
			(int)track_steps);

		query = xstrdup_printf("SELECT %s.add_job_start(%s);",
				       pg_conn->cluster_name, rec);
		xfree(rec);

	try_again:
		DEBUG_QUERY;
		job_ptr->db_index = pgsql_query_ret_id(pg_conn->db_conn,
						       query);
		if (!job_ptr->db_index) {
			if (!reinit) {
				error("It looks like the storage has gone "
				      "away trying to reconnect");
				check_db_connection(pg_conn);
				reinit = 1;
				goto try_again;
			} else
				rc = SLURM_ERROR;
		}
		xfree(query);
	} else {