extern int as_mysql_fix_runaway_jobs(mysql_conn_t *mysql_conn, uint32_t uid,
				     List runaway_jobs)
{
	char *query = NULL, *job_ids = NULL;
	slurmdb_job_rec_t *job = NULL;
	ListIterator iter = NULL;
	int rc = SLURM_SUCCESS;
	slurmdb_job_rec_t *first_job;

	list_sort(runaway_jobs, _job_sort_by_start_time);
	first_job = list_peek(runaway_jobs);

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return ESLURM_DB_CONNECTION;

	if (!is_user_min_admin_level(mysql_conn, uid, SLURMDB_ADMIN_OPERATOR)) {
		slurmdb_user_rec_t user;

		memset(&user, 0, sizeof(slurmdb_user_rec_t));
		user.uid = uid;

		if (!is_user_any_coord(mysql_conn, &user)) {
			error("Only admins/operators/coordinators "
			      "can fix runaway jobs");
			return ESLURM_ACCESS_DENIED;
		}
	}

	iter = list_iterator_create(runaway_jobs);
	while ((job = list_next(iter))) {
		xstrfmtcat(job_ids, "%s%d", ((job_ids) ? "," : ""), job->jobid);
	}

	query = xstrdup_printf("UPDATE \"%s_%s\" SET time_end="
			       "GREATEST(time_start, time_eligible, time_submit), "
			       "state=%d WHERE id_job IN (%s);",
			       mysql_conn->cluster_name, job_table,
			       JOB_COMPLETE, job_ids);

	if (debug_flags & DEBUG_FLAG_DB_QUERY)
		DB_DEBUG(mysql_conn->conn, "query\n%s", query);
	mysql_db_query(mysql_conn, query);
	xfree(query);
	xfree(job_ids);

	/* Set rollup to the the last day of the previous month of the first
	 * runaway job */
	rc = _first_job_roll_up(mysql_conn, first_job->start);
	if (rc != SLURM_SUCCESS) {
		error("Failed to fix runaway jobs");
		return SLURM_ERROR;
	}

	return rc;
}
예제 #2
0
extern List as_mysql_get_accts(mysql_conn_t *mysql_conn, uid_t uid,
			       slurmdb_account_cond_t *acct_cond)
{
	char *query = NULL;
	char *extra = NULL;
	char *tmp = NULL;
	List acct_list = NULL;
	ListIterator itr = NULL;
	char *object = NULL;
	int set = 0;
	int i=0, is_admin=1;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	uint16_t private_data = 0;
	slurmdb_user_rec_t user;

	/* if this changes you will need to edit the corresponding enum */
	char *acct_req_inx[] = {
		"name",
		"description",
		"organization"
	};
	enum {
		SLURMDB_REQ_NAME,
		SLURMDB_REQ_DESC,
		SLURMDB_REQ_ORG,
		SLURMDB_REQ_COUNT
	};

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return NULL;

	memset(&user, 0, sizeof(slurmdb_user_rec_t));
	user.uid = uid;

	private_data = slurm_get_private_data();

	if (private_data & PRIVATE_DATA_ACCOUNTS) {
		if (!(is_admin = is_user_min_admin_level(
			      mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) {
			if (!is_user_any_coord(mysql_conn, &user)) {
				error("Only admins/coordinators "
				      "can look at account usage");
				errno = ESLURM_ACCESS_DENIED;
				return NULL;
			}
		}
	}

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

	if (acct_cond->with_deleted)
		xstrcat(extra, "where (deleted=0 || deleted=1)");
	else
		xstrcat(extra, "where deleted=0");

	if (acct_cond->assoc_cond
	    && acct_cond->assoc_cond->acct_list
	    && list_count(acct_cond->assoc_cond->acct_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(acct_cond->assoc_cond->acct_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "name='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (acct_cond->description_list
	    && list_count(acct_cond->description_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(acct_cond->description_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "description='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (acct_cond->organization_list
	    && list_count(acct_cond->organization_list)) {
		set = 0;
		xstrcat(extra, " && (");
		itr = list_iterator_create(acct_cond->organization_list);
		while ((object = list_next(itr))) {
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "organization='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

empty:

	xfree(tmp);
	xstrfmtcat(tmp, "%s", acct_req_inx[i]);
	for(i=1; i<SLURMDB_REQ_COUNT; i++) {
		xstrfmtcat(tmp, ", %s", acct_req_inx[i]);
	}

	/* This is here to make sure we are looking at only this user
	 * if this flag is set.  We also include any accounts they may be
	 * coordinator of.
	 */
	if (!is_admin && (private_data & PRIVATE_DATA_ACCOUNTS)) {
		slurmdb_coord_rec_t *coord = NULL;
		set = 0;
		itr = list_iterator_create(user.coord_accts);
		while ((coord = list_next(itr))) {
			if (set) {
				xstrfmtcat(extra, " || name='%s'",
					   coord->name);
			} else {
				set = 1;
				xstrfmtcat(extra, " && (name='%s'",
					   coord->name);
			}
		}
		list_iterator_destroy(itr);
		if (set)
			xstrcat(extra,")");
	}

	query = xstrdup_printf("select %s from %s %s", tmp, acct_table, extra);
	xfree(tmp);
	xfree(extra);

	if (debug_flags & DEBUG_FLAG_DB_ASSOC)
		DB_DEBUG(mysql_conn->conn, "query\n%s", query);
	if (!(result = mysql_db_query_ret(
		      mysql_conn, query, 0))) {
		xfree(query);
		return NULL;
	}
	xfree(query);

	acct_list = list_create(slurmdb_destroy_account_rec);

	if (acct_cond && acct_cond->assoc_cond && acct_cond->with_assocs) {
		/* We are going to be freeing the inners of
		   this list in the acct->name so we don't
		   free it here
		*/
		if (acct_cond->assoc_cond->acct_list)
			list_destroy(acct_cond->assoc_cond->acct_list);
		acct_cond->assoc_cond->acct_list = list_create(NULL);
		acct_cond->assoc_cond->with_deleted = acct_cond->with_deleted;
	}

	while ((row = mysql_fetch_row(result))) {
		slurmdb_account_rec_t *acct =
			xmalloc(sizeof(slurmdb_account_rec_t));
		list_append(acct_list, acct);

		acct->name =  xstrdup(row[SLURMDB_REQ_NAME]);
		acct->description = xstrdup(row[SLURMDB_REQ_DESC]);
		acct->organization = xstrdup(row[SLURMDB_REQ_ORG]);

		if (acct_cond && acct_cond->with_coords) {
			_get_account_coords(mysql_conn, acct);
		}

		if (acct_cond && acct_cond->with_assocs) {
			if (!acct_cond->assoc_cond) {
				acct_cond->assoc_cond = xmalloc(
					sizeof(slurmdb_association_cond_t));
			}

			list_append(acct_cond->assoc_cond->acct_list,
				    acct->name);
		}
	}
	mysql_free_result(result);

	if (acct_cond && acct_cond->with_assocs && acct_cond->assoc_cond
	    && 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 = as_mysql_get_assocs(
			mysql_conn, uid, acct_cond->assoc_cond);

		if (!assoc_list) {
			error("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)
				list_remove(itr);
		}
		list_iterator_destroy(itr);
		list_iterator_destroy(assoc_itr);

		list_destroy(assoc_list);
	}

	return acct_list;
}
예제 #3
0
파일: as_pg_acct.c 프로젝트: VURM/slurm
/*
 * 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;
}
예제 #4
0
extern List as_mysql_jobacct_process_get_jobs(mysql_conn_t *mysql_conn,
					      uid_t uid,
					      slurmdb_job_cond_t *job_cond)
{
	char *extra = NULL;
	char *tmp = NULL, *tmp2 = NULL;
	ListIterator itr = NULL;
	int is_admin=1;
	int i;
	List job_list = NULL;
	uint16_t private_data = 0;
	slurmdb_user_rec_t user;
	int only_pending = 0;
	List use_cluster_list = as_mysql_cluster_list;
	char *cluster_name;
	assoc_mgr_lock_t locks = { NO_LOCK, NO_LOCK, NO_LOCK, NO_LOCK,
				   READ_LOCK, NO_LOCK, NO_LOCK };

	memset(&user, 0, sizeof(slurmdb_user_rec_t));
	user.uid = uid;

	private_data = slurm_get_private_data();
	if (private_data & PRIVATE_DATA_JOBS) {
		if (!(is_admin = is_user_min_admin_level(
			      mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) {
			/* Only fill in the coordinator accounts here
			   we will check them later when we actually
			   try to get the jobs.
			*/
			is_user_any_coord(mysql_conn, &user);
		}
		if (!is_admin && !user.name) {
			debug("User %u has no assocations, and is not admin, "
			      "so not returning any jobs.", user.uid);
			return NULL;
		}
	}

	if (job_cond
	    && job_cond->state_list && (list_count(job_cond->state_list) == 1)
	    && (slurm_atoul(list_peek(job_cond->state_list)) == JOB_PENDING))
		only_pending = 1;

	setup_job_cond_limits(job_cond, &extra);

	xfree(tmp);
	xstrfmtcat(tmp, "%s", job_req_inx[0]);
	for(i=1; i<JOB_REQ_COUNT; i++) {
		xstrfmtcat(tmp, ", %s", job_req_inx[i]);
	}

	xfree(tmp2);
	xstrfmtcat(tmp2, "%s", step_req_inx[0]);
	for(i=1; i<STEP_REQ_COUNT; i++) {
		xstrfmtcat(tmp2, ", %s", step_req_inx[i]);
	}

	if (job_cond
	    && job_cond->cluster_list && list_count(job_cond->cluster_list))
		use_cluster_list = job_cond->cluster_list;
	else
		slurm_mutex_lock(&as_mysql_cluster_list_lock);

	assoc_mgr_lock(&locks);

	job_list = list_create(slurmdb_destroy_job_rec);
	itr = list_iterator_create(use_cluster_list);
	while ((cluster_name = list_next(itr))) {
		int rc;
		if ((rc = _cluster_get_jobs(mysql_conn, &user, job_cond,
					    cluster_name, tmp, tmp2, extra,
					    is_admin, only_pending, job_list))
		    != SLURM_SUCCESS)
			error("Problem getting jobs for cluster %s",
			      cluster_name);
	}
	list_iterator_destroy(itr);

	assoc_mgr_unlock(&locks);

	if (use_cluster_list == as_mysql_cluster_list)
		slurm_mutex_unlock(&as_mysql_cluster_list_lock);

	xfree(tmp);
	xfree(tmp2);
	xfree(extra);

	return job_list;
}
예제 #5
0
extern List as_mysql_remove_coord(mysql_conn_t *mysql_conn, uint32_t uid,
				  List acct_list,
				  slurmdb_user_cond_t *user_cond)
{
	char *query = NULL, *object = NULL, *extra = NULL, *last_user = NULL;
	char *user_name = NULL;
	time_t now = time(NULL);
	int set = 0, is_admin=0, rc = SLURM_SUCCESS;
	ListIterator itr = NULL;
	slurmdb_user_rec_t *user_rec = NULL;
	List ret_list = NULL;
	List user_list = NULL;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	slurmdb_user_rec_t user;

	if (!user_cond && !acct_list) {
		error("we need something to remove");
		return NULL;
	} else if (user_cond && user_cond->assoc_cond)
		user_list = user_cond->assoc_cond->user_list;

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return NULL;

	memset(&user, 0, sizeof(slurmdb_user_rec_t));
	user.uid = uid;

	if (!(is_admin = is_user_min_admin_level(
		      mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) {
		if (!is_user_any_coord(mysql_conn, &user)) {
			error("Only admins/coordinators can "
			      "remove coordinators");
			errno = ESLURM_ACCESS_DENIED;
			return NULL;
		}
	}

	/* Leave it this way since we are using extra below */

	if (user_list && list_count(user_list)) {
		set = 0;
		if (extra)
			xstrcat(extra, " && (");
		else
			xstrcat(extra, "(");

		itr = list_iterator_create(user_list);
		while ((object = list_next(itr))) {
			if (!object[0])
				continue;
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "user='******'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (acct_list && list_count(acct_list)) {
		set = 0;
		if (extra)
			xstrcat(extra, " && (");
		else
			xstrcat(extra, "(");

		itr = list_iterator_create(acct_list);
		while ((object = list_next(itr))) {
			if (!object[0])
				continue;
			if (set)
				xstrcat(extra, " || ");
			xstrfmtcat(extra, "acct='%s'", object);
			set = 1;
		}
		list_iterator_destroy(itr);
		xstrcat(extra, ")");
	}

	if (!extra) {
		errno = SLURM_ERROR;
		debug3("No conditions given");
		return NULL;
	}

	query = xstrdup_printf(
		"select user, acct from %s where deleted=0 && %s order by user",
		acct_coord_table, extra);

	debug3("%d(%s:%d) query\n%s",
	       mysql_conn->conn, THIS_FILE, __LINE__, query);
	if (!(result =
	      mysql_db_query_ret(mysql_conn, query, 0))) {
		xfree(query);
		xfree(extra);
		errno = SLURM_ERROR;
		return NULL;
	}
	xfree(query);
	ret_list = list_create(slurm_destroy_char);
	user_list = list_create(slurm_destroy_char);
	while ((row = mysql_fetch_row(result))) {
		if (!is_admin) {
			slurmdb_coord_rec_t *coord = NULL;
			if (!user.coord_accts) { // This should never
				// happen
				error("We are here with no coord accts");
				errno = ESLURM_ACCESS_DENIED;
				list_destroy(ret_list);
				list_destroy(user_list);
				xfree(extra);
				mysql_free_result(result);
				return NULL;
			}
			itr = list_iterator_create(user.coord_accts);
			while ((coord = list_next(itr))) {
				if (!strcasecmp(coord->name, row[1]))
					break;
			}
			list_iterator_destroy(itr);

			if (!coord) {
				error("User %s(%d) does not have the "
				      "ability to change this account (%s)",
				      user.name, user.uid, row[1]);
				errno = ESLURM_ACCESS_DENIED;
				list_destroy(ret_list);
				list_destroy(user_list);
				xfree(extra);
				mysql_free_result(result);
				return NULL;
			}
		}
		if (!last_user || strcasecmp(last_user, row[0])) {
			list_append(user_list, xstrdup(row[0]));
			last_user = row[0];
		}
		list_append(ret_list, xstrdup_printf("U = %-9s A = %-10s",
						     row[0], row[1]));
	}
	mysql_free_result(result);

	user_name = uid_to_string((uid_t) uid);
	rc = remove_common(mysql_conn, DBD_REMOVE_ACCOUNT_COORDS,
			   now, user_name, acct_coord_table,
			   extra, NULL, NULL, NULL, NULL);
	xfree(user_name);
	xfree(extra);
	if (rc == SLURM_ERROR) {
		list_destroy(ret_list);
		list_destroy(user_list);
		errno = SLURM_ERROR;
		return NULL;
	}

	/* get the update list set */
	itr = list_iterator_create(user_list);
	while ((last_user = list_next(itr))) {
		user_rec = xmalloc(sizeof(slurmdb_user_rec_t));
		user_rec->name = xstrdup(last_user);
		_get_user_coords(mysql_conn, user_rec);
		if (addto_update_list(mysql_conn->update_list,
				      SLURMDB_REMOVE_COORD, user_rec)
		    != SLURM_SUCCESS)
			slurmdb_destroy_user_rec(user_rec);
	}
	list_iterator_destroy(itr);
	list_destroy(user_list);

	return ret_list;
}
예제 #6
0
extern int as_mysql_add_accts(mysql_conn_t *mysql_conn, uint32_t uid,
			      List acct_list)
{
	ListIterator itr = NULL;
	int rc = SLURM_SUCCESS;
	slurmdb_account_rec_t *object = NULL;
	char *cols = NULL, *vals = NULL, *query = NULL, *txn_query = NULL;
	time_t now = time(NULL);
	char *user_name = NULL;
	char *extra = NULL, *tmp_extra = NULL;

	int affect_rows = 0;
	List assoc_list = list_create(slurmdb_destroy_assoc_rec);

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return ESLURM_DB_CONNECTION;

	if (!is_user_min_admin_level(mysql_conn, uid, SLURMDB_ADMIN_OPERATOR)) {
		slurmdb_user_rec_t user;

		memset(&user, 0, sizeof(slurmdb_user_rec_t));
		user.uid = uid;

		if (!is_user_any_coord(mysql_conn, &user)) {
			error("Only admins/operators/coordinators "
			      "can add accounts");
			return ESLURM_ACCESS_DENIED;
		}
		/* If the user is a coord of any acct they can add
		 * accounts they are only able to make associations to
		 * these accounts if they are coordinators of the
		 * parent they are trying to add to
		 */
	}

	user_name = uid_to_string((uid_t) uid);
	itr = list_iterator_create(acct_list);
	while ((object = list_next(itr))) {
		if (!object->name || !object->name[0]
		    || !object->description || !object->description[0]
		    || !object->organization || !object->organization[0]) {
			error("We need an account name, description, and "
			      "organization to add. %s %s %s",
			      object->name, object->description,
			      object->organization);
			rc = SLURM_ERROR;
			continue;
		}
		xstrcat(cols, "creation_time, mod_time, name, "
			"description, organization");
		xstrfmtcat(vals, "%ld, %ld, '%s', '%s', '%s'",
			   now, now, object->name,
			   object->description, object->organization);
		xstrfmtcat(extra, ", description='%s', organization='%s'",
			   object->description, object->organization);

		query = xstrdup_printf(
			"insert into %s (%s) values (%s) "
			"on duplicate key update deleted=0, mod_time=%ld %s;",
			acct_table, cols, vals,
			now, extra);
		if (debug_flags & DEBUG_FLAG_DB_ASSOC)
			DB_DEBUG(mysql_conn->conn, "query\n%s", query);
		rc = mysql_db_query(mysql_conn, query);
		xfree(cols);
		xfree(vals);
		xfree(query);
		if (rc != SLURM_SUCCESS) {
			error("Couldn't add acct");
			xfree(extra);
			continue;
		}
		affect_rows = last_affected_rows(mysql_conn);
		/* if (debug_flags & DEBUG_FLAG_DB_ASSOC) */
		/* 	DB_DEBUG(mysql_conn->conn, "affected %d", affect_rows); */

		if (!affect_rows) {
			if (debug_flags & DEBUG_FLAG_DB_ASSOC)
				DB_DEBUG(mysql_conn->conn, "nothing changed");
			xfree(extra);
			continue;
		}

		/* we always have a ', ' as the first 2 chars */
		tmp_extra = slurm_add_slash_to_quotes(extra+2);

		if (txn_query)
			xstrfmtcat(txn_query,
				   ", (%ld, %u, '%s', '%s', '%s')",
				   now, DBD_ADD_ACCOUNTS, object->name,
				   user_name, tmp_extra);
		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, tmp_extra);
		xfree(tmp_extra);
		xfree(extra);

		if (!object->assoc_list)
			continue;

		if (!assoc_list)
			assoc_list =
				list_create(slurmdb_destroy_assoc_rec);
		list_transfer(assoc_list, object->assoc_list);
	}
	list_iterator_destroy(itr);
	xfree(user_name);

	if (rc != SLURM_ERROR) {
		if (txn_query) {
			xstrcat(txn_query, ";");
			rc = mysql_db_query(mysql_conn,
					    txn_query);
			xfree(txn_query);
			if (rc != SLURM_SUCCESS) {
				error("Couldn't add txn");
				rc = SLURM_SUCCESS;
			}
		}
	} else
		xfree(txn_query);

	if (assoc_list && list_count(assoc_list)) {
		if ((rc = as_mysql_add_assocs(mysql_conn, uid, assoc_list))
		    != SLURM_SUCCESS)
			error("Problem adding accounts associations");
	}
	FREE_NULL_LIST(assoc_list);

	return rc;
}
예제 #7
0
extern int as_mysql_get_usage(mysql_conn_t *mysql_conn, uid_t uid,
			      void *in, slurmdbd_msg_type_t type,
			      time_t start, time_t end)
{
	int rc = SLURM_SUCCESS;
	int i=0, is_admin=1;
	MYSQL_RES *result = NULL;
	MYSQL_ROW row;
	char *tmp = NULL;
	char *my_usage_table = NULL;
	slurmdb_association_rec_t *slurmdb_assoc = in;
	slurmdb_wckey_rec_t *slurmdb_wckey = in;
	char *query = NULL;
	char *username = NULL;
	uint16_t private_data = 0;
	slurmdb_user_rec_t user;
	List *my_list;
	uint32_t id = NO_VAL;
	char *cluster_name = NULL;
	char **usage_req_inx = NULL;

	enum {
		USAGE_ID,
		USAGE_START,
		USAGE_ACPU,
		USAGE_COUNT,
		USAGE_ENERGY
	};

	switch (type) {
	case DBD_GET_ASSOC_USAGE:
	{
		char *temp_usage[] = {
			"t3.id_assoc",
			"t1.time_start",
			"t1.alloc_cpu_secs"
		};
		usage_req_inx = temp_usage;

		id = slurmdb_assoc->id;
		cluster_name = slurmdb_assoc->cluster;
		username = slurmdb_assoc->user;
		my_list = &slurmdb_assoc->accounting_list;
		my_usage_table = assoc_day_table;
		break;
	}
	case DBD_GET_WCKEY_USAGE:
	{
		char *temp_usage[] = {
			"id_wckey",
			"time_start",
			"alloc_cpu_secs"
		};
		usage_req_inx = temp_usage;

		id = slurmdb_wckey->id;
		cluster_name = slurmdb_wckey->cluster;
		username = slurmdb_wckey->user;
		my_list = &slurmdb_wckey->accounting_list;
		my_usage_table = wckey_day_table;
		break;
	}
	case DBD_GET_CLUSTER_USAGE:
	{
		return _get_cluster_usage(mysql_conn, uid, in,
					  type, start, end);
		break;
	}
	default:
		error("Unknown usage type %d", type);
		return SLURM_ERROR;
		break;
	}

	if (!id) {
		error("We need an id to set data for getting usage");
		return SLURM_ERROR;
	} else if (!cluster_name) {
		error("We need a cluster_name to set data for getting usage");
		return SLURM_ERROR;
	}

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return ESLURM_DB_CONNECTION;

	memset(&user, 0, sizeof(slurmdb_user_rec_t));
	user.uid = uid;

	private_data = slurm_get_private_data();
	if (private_data & PRIVATE_DATA_USAGE) {
		if (!(is_admin = is_user_min_admin_level(
			      mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) {
			ListIterator itr = NULL;
			slurmdb_coord_rec_t *coord = NULL;

			if (username && !strcmp(slurmdb_assoc->user, user.name))
				goto is_user;

			if (type != DBD_GET_ASSOC_USAGE)
				goto bad_user;

			if (!slurmdb_assoc->acct) {
				debug("No account name given "
				      "in association.");
				goto bad_user;
			}

			if (!is_user_any_coord(mysql_conn, &user)) {
				debug4("This user is not a coordinator.");
				goto bad_user;
			}

			/* Existance of user.coord_accts is checked in
			   is_user_any_coord.
			*/
			itr = list_iterator_create(user.coord_accts);
			while ((coord = list_next(itr)))
				if (!strcasecmp(coord->name,
						slurmdb_assoc->acct))
					break;
			list_iterator_destroy(itr);

			if (coord)
				goto is_user;

		bad_user:
			errno = ESLURM_ACCESS_DENIED;
			return SLURM_ERROR;
		}
	}
is_user:

	if (set_usage_information(&my_usage_table, type, &start, &end)
	    != SLURM_SUCCESS) {
		return SLURM_ERROR;
	}

	xfree(tmp);
	i=0;
	xstrfmtcat(tmp, "%s", usage_req_inx[i]);
	for(i=1; i<USAGE_COUNT; i++) {
		xstrfmtcat(tmp, ", %s", usage_req_inx[i]);
	}
	switch (type) {
	case DBD_GET_ASSOC_USAGE:
		query = xstrdup_printf(
			"select %s from \"%s_%s\" as t1, "
			"\"%s_%s\" as t2, \"%s_%s\" as t3 "
			"where (t1.time_start < %ld && t1.time_start >= %ld) "
			"&& t1.id_assoc=t2.id_assoc && t3.id_assoc=%d && "
			"t2.lft between t3.lft and t3.rgt "
			"order by t3.id_assoc, time_start;",
			tmp, cluster_name, my_usage_table,
			cluster_name, cluster_name, assoc_table, assoc_table,
			end, start, id);
		break;
	case DBD_GET_WCKEY_USAGE:
		query = xstrdup_printf(
			"select %s from \"%s_%s\" "
			"where (time_start < %ld && time_start >= %ld) "
			"&& id_wckey=%d order by id_wckey, time_start;",
			tmp, cluster_name, my_usage_table, end, start, id);
		break;
	default:
		error("Unknown usage type %d", type);
		return SLURM_ERROR;
		break;
	}

	xfree(tmp);
	debug4("%d(%s:%d) query\n%s",
	       mysql_conn->conn, THIS_FILE, __LINE__, query);
	if (!(result = mysql_db_query_ret(
		      mysql_conn, query, 0))) {
		xfree(query);
		return SLURM_ERROR;
	}
	xfree(query);

	if (!(*my_list))
		(*my_list) = list_create(slurmdb_destroy_accounting_rec);

	while ((row = mysql_fetch_row(result))) {
		slurmdb_accounting_rec_t *accounting_rec =
			xmalloc(sizeof(slurmdb_accounting_rec_t));
		accounting_rec->id = slurm_atoul(row[USAGE_ID]);
		accounting_rec->period_start = slurm_atoul(row[USAGE_START]);
		accounting_rec->alloc_secs = slurm_atoull(row[USAGE_ACPU]);
		accounting_rec->consumed_energy = slurm_atoull(row[USAGE_ENERGY]);
		list_append((*my_list), accounting_rec);
	}
	mysql_free_result(result);

	return rc;
}
예제 #8
0
extern int as_mysql_add_coord(mysql_conn_t *mysql_conn, uint32_t uid,
			      List acct_list, slurmdb_user_cond_t *user_cond)
{
	char *query = NULL, *user = NULL, *acct = NULL;
	char *user_name = NULL, *txn_query = NULL;
	ListIterator itr, itr2;
	time_t now = time(NULL);
	int rc = SLURM_SUCCESS;
	slurmdb_user_rec_t *user_rec = NULL;

	if (!user_cond || !user_cond->assoc_cond
	    || !user_cond->assoc_cond->user_list
	    || !list_count(user_cond->assoc_cond->user_list)
	    || !acct_list || !list_count(acct_list)) {
		error("we need something to add");
		return SLURM_ERROR;
	}

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return ESLURM_DB_CONNECTION;

	if (!is_user_min_admin_level(mysql_conn, uid, SLURMDB_ADMIN_OPERATOR)) {
		slurmdb_user_rec_t user;
		slurmdb_coord_rec_t *coord = NULL;
		char *acct = NULL;

		memset(&user, 0, sizeof(slurmdb_user_rec_t));
		user.uid = uid;

		if (!is_user_any_coord(mysql_conn, &user)) {
			error("Only admins/operators/coordinators "
			      "can add account coordinators");
			return ESLURM_ACCESS_DENIED;
		}

		itr = list_iterator_create(acct_list);
		itr2 = list_iterator_create(user.coord_accts);
		while ((acct = list_next(itr))) {
			while ((coord = list_next(itr2))) {
				if (!xstrcasecmp(coord->name, acct))
					break;
			}
			if (!coord)
				break;
			list_iterator_reset(itr2);
		}
		list_iterator_destroy(itr2);
		list_iterator_destroy(itr);

		if (!coord)  {
			error("Coordinator %s(%d) tried to add another "
			      "coordinator to an account they aren't "
			      "coordinator over.",
			      user.name, user.uid);
			return ESLURM_ACCESS_DENIED;
		}
	}

	user_name = uid_to_string((uid_t) uid);
	itr = list_iterator_create(user_cond->assoc_cond->user_list);
	itr2 = list_iterator_create(acct_list);
	while ((user = list_next(itr))) {
		if (!user[0])
			continue;
		while ((acct = list_next(itr2))) {
			if (!acct[0])
				continue;
			if (query)
				xstrfmtcat(query, ", (%ld, %ld, '%s', '%s')",
					   (long)now, (long)now, acct, user);
			else
				query = xstrdup_printf(
					"insert into %s (creation_time, "
					"mod_time, acct, user) values "
					"(%ld, %ld, '%s', '%s')",
					acct_coord_table,
					(long)now, (long)now, acct, user);

			if (txn_query)
				xstrfmtcat(txn_query,
					   ", (%ld, %u, '%s', '%s', '%s')",
					   (long)now, DBD_ADD_ACCOUNT_COORDS,
					   user, user_name, acct);
			else
				xstrfmtcat(txn_query,
					   "insert into %s "
					   "(timestamp, action, name, "
					   "actor, info) "
					   "values (%ld, %u, '%s', "
					   "'%s', '%s')",
					   txn_table,
					   (long)now, DBD_ADD_ACCOUNT_COORDS,
					   user,
					   user_name, acct);
		}
		list_iterator_reset(itr2);
	}
	xfree(user_name);
	list_iterator_destroy(itr);
	list_iterator_destroy(itr2);

	if (query) {
		xstrfmtcat(query,
			   " on duplicate key update mod_time=%ld, "
			   "deleted=0;%s",
			   (long)now, txn_query);
		if (debug_flags & DEBUG_FLAG_DB_ASSOC)
			DB_DEBUG(mysql_conn->conn, "query\n%s", query);
		rc = mysql_db_query(mysql_conn, query);
		xfree(query);
		xfree(txn_query);

		if (rc != SLURM_SUCCESS) {
			error("Couldn't add cluster hour rollup");
			return rc;
		}
		/* get the update list set */
		itr = list_iterator_create(user_cond->assoc_cond->user_list);
		while ((user = list_next(itr))) {
			user_rec = xmalloc(sizeof(slurmdb_user_rec_t));
			user_rec->name = xstrdup(user);
			_get_user_coords(mysql_conn, user_rec);
			if (addto_update_list(mysql_conn->update_list,
					      SLURMDB_ADD_COORD, user_rec)
			    != SLURM_SUCCESS)
				slurmdb_destroy_user_rec(user_rec);
		}
		list_iterator_destroy(itr);
	}

	return SLURM_SUCCESS;
}
예제 #9
0
extern int as_mysql_add_users(mysql_conn_t *mysql_conn, uint32_t uid,
			      List user_list)
{
	ListIterator itr = NULL;
	int rc = SLURM_SUCCESS;
	slurmdb_user_rec_t *object = NULL;
	char *cols = NULL, *vals = NULL, *query = NULL, *txn_query = NULL;
	time_t now = time(NULL);
	char *user_name = NULL;
	char *extra = NULL, *tmp_extra = NULL;
	int affect_rows = 0;
	List assoc_list = list_create(slurmdb_destroy_assoc_rec);
	List wckey_list = list_create(slurmdb_destroy_wckey_rec);

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return ESLURM_DB_CONNECTION;

	if (!is_user_min_admin_level(mysql_conn, uid, SLURMDB_ADMIN_OPERATOR)) {
		slurmdb_user_rec_t user;

		memset(&user, 0, sizeof(slurmdb_user_rec_t));
		user.uid = uid;

		if (!is_user_any_coord(mysql_conn, &user)) {
			error("Only admins/operators/coordinators "
			      "can add accounts");
			return ESLURM_ACCESS_DENIED;
		}
		/* If the user is a coord of any acct they can add
		 * accounts they are only able to make associations to
		 * these accounts if they are coordinators of the
		 * parent they are trying to add to
		 */
	}

	user_name = uid_to_string((uid_t) uid);
	itr = list_iterator_create(user_list);
	while ((object = list_next(itr))) {
		if (!object->name || !object->name[0]) {
			error("We need a user name and "
			      "default acct to add.");
			rc = SLURM_ERROR;
			continue;
		}
		xstrcat(cols, "creation_time, mod_time, name");
		xstrfmtcat(vals, "%ld, %ld, '%s'",
			   (long)now, (long)now, object->name);

		if (object->admin_level != SLURMDB_ADMIN_NOTSET) {
			xstrcat(cols, ", admin_level");
			xstrfmtcat(vals, ", %u", object->admin_level);
			xstrfmtcat(extra, ", admin_level=%u",
				   object->admin_level);
		} else
			xstrfmtcat(extra, ", admin_level=%u",
				   SLURMDB_ADMIN_NONE);

		query = xstrdup_printf(
			"insert into %s (%s) values (%s) "
			"on duplicate key update deleted=0, mod_time=%ld %s;",
			user_table, cols, vals,
			(long)now, extra);
		xfree(cols);
		xfree(vals);

		rc = mysql_db_query(mysql_conn, query);
		xfree(query);
		if (rc != SLURM_SUCCESS) {
			error("Couldn't add user %s", object->name);
			xfree(extra);
			continue;
		}

		affect_rows = last_affected_rows(mysql_conn);
		if (!affect_rows) {
			debug("nothing changed");
			xfree(extra);
			continue;
		}

		if (addto_update_list(mysql_conn->update_list, SLURMDB_ADD_USER,
				      object) == SLURM_SUCCESS)
			list_remove(itr);

		/* we always have a ', ' as the first 2 chars */
		tmp_extra = slurm_add_slash_to_quotes(extra+2);

		if (txn_query)
			xstrfmtcat(txn_query,
				   ", (%ld, %u, '%s', '%s', '%s')",
				   (long)now, DBD_ADD_USERS, object->name,
				   user_name, tmp_extra);
		else
			xstrfmtcat(txn_query,
				   "insert into %s "
				   "(timestamp, action, name, actor, info) "
				   "values (%ld, %u, '%s', '%s', '%s')",
				   txn_table,
				   (long)now, DBD_ADD_USERS, object->name,
				   user_name, tmp_extra);
		xfree(tmp_extra);
		xfree(extra);

		/* For < 2.2 systems we need to set the is_def flag in
		   the default association/wckey so as to make sure we get
		   it set correctly.
		*/
		if (object->assoc_list) {
			slurmdb_assoc_rec_t *assoc = NULL;
			ListIterator assoc_itr =
				list_iterator_create(object->assoc_list);
			while ((assoc = list_next(assoc_itr))) {
				/* We need to mark all of the
				   associations with this account
				   since there could be multiple
				   clusters here.
				*/
				if (!xstrcmp(assoc->acct, object->default_acct))
					assoc->is_def = 1;
			}
			list_iterator_destroy(assoc_itr);
			list_transfer(assoc_list, object->assoc_list);
		}

		if (object->wckey_list) {
			if (object->default_wckey) {
				slurmdb_wckey_rec_t *wckey = NULL;
				ListIterator wckey_itr = list_iterator_create(
					object->wckey_list);
				while ((wckey = list_next(wckey_itr))) {
					/* We need to mark all of the
					   wckeys with this account
					   since there could be multiple
					   clusters here.
					*/
					if (!xstrcmp(wckey->name,
						     object->default_wckey))
						wckey->is_def = 1;
				}
				list_iterator_destroy(wckey_itr);
			}
			list_transfer(wckey_list, object->wckey_list);
		}
	}
	list_iterator_destroy(itr);
	xfree(user_name);

	if (rc != SLURM_ERROR) {
		if (txn_query) {
			xstrcat(txn_query, ";");
			rc = mysql_db_query(mysql_conn,
					    txn_query);
			xfree(txn_query);
			if (rc != SLURM_SUCCESS) {
				error("Couldn't add txn");
				rc = SLURM_SUCCESS;
			}
		}
	} else
		xfree(txn_query);

	if (list_count(assoc_list)) {
		if ((rc = as_mysql_add_assocs(mysql_conn, uid, assoc_list))
		     != SLURM_SUCCESS)
			error("Problem adding user associations");
	}
	FREE_NULL_LIST(assoc_list);

	if (rc == SLURM_SUCCESS && list_count(wckey_list)) {
		if ((rc = as_mysql_add_wckeys(mysql_conn, uid, wckey_list))
		    != SLURM_SUCCESS)
			error("Problem adding user wckeys");
	}
	FREE_NULL_LIST(wckey_list);
	return rc;
}
예제 #10
0
/*   The assoc_mgr locks should be unlocked before coming here. */
extern int as_mysql_get_usage(mysql_conn_t *mysql_conn, uid_t uid,
			      void *in, slurmdbd_msg_type_t type,
			      time_t start, time_t end)
{
	int rc = SLURM_SUCCESS;
	int is_admin=1;
	char *my_usage_table = NULL;
	slurmdb_assoc_rec_t *slurmdb_assoc = in;
	slurmdb_wckey_rec_t *slurmdb_wckey = in;
	char *username = NULL;
	uint16_t private_data = 0;
	List *my_list = NULL;
	char *cluster_name = NULL;
	char *id_str = NULL;

	if (check_connection(mysql_conn) != SLURM_SUCCESS)
		return ESLURM_DB_CONNECTION;

	switch (type) {
	case DBD_GET_ASSOC_USAGE:
		if (!slurmdb_assoc->id) {
			error("We need an id to set data for getting usage");
			return SLURM_ERROR;
		}
		id_str = xstrdup_printf("t3.id_assoc=%u", slurmdb_assoc->id);
		cluster_name = slurmdb_assoc->cluster;
		username = slurmdb_assoc->user;
		my_list = &slurmdb_assoc->accounting_list;
		my_usage_table = assoc_day_table;
		break;
	case DBD_GET_WCKEY_USAGE:
		if (!slurmdb_wckey->id) {
			error("We need an id to set data for getting usage");
			return SLURM_ERROR;
		}
		id_str = xstrdup_printf("id=%d", slurmdb_wckey->id);
		cluster_name = slurmdb_wckey->cluster;
		username = slurmdb_wckey->user;
		my_list = &slurmdb_wckey->accounting_list;
		my_usage_table = wckey_day_table;
		break;
	case DBD_GET_CLUSTER_USAGE:
		rc = _get_cluster_usage(mysql_conn, uid, in,
					type, start, end);
		return rc;
		break;
	default:
		error("Unknown usage type %d", type);
		return SLURM_ERROR;
		break;
	}

	if (!cluster_name) {
		error("We need a cluster_name to set data for getting usage");
		xfree(id_str);
		return SLURM_ERROR;
	}

	private_data = slurm_get_private_data();
	if (private_data & PRIVATE_DATA_USAGE) {
		if (!(is_admin = is_user_min_admin_level(
			      mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) {
			ListIterator itr = NULL;
			slurmdb_coord_rec_t *coord = NULL;
			slurmdb_user_rec_t user;
			bool is_coord;

			memset(&user, 0, sizeof(slurmdb_user_rec_t));
			user.uid = uid;
			is_coord = is_user_any_coord(mysql_conn, &user);

			if (username && !strcmp(username, user.name))
				goto is_user;

			if (type != DBD_GET_ASSOC_USAGE)
				goto bad_user;

			if (!slurmdb_assoc->acct) {
				debug("No account name given "
				      "in association.");
				goto bad_user;
			}

			if (!is_coord) {
				debug4("This user is not a coordinator.");
				goto bad_user;
			}

			/* Existance of user.coord_accts is checked in
			   is_user_any_coord.
			*/
			itr = list_iterator_create(user.coord_accts);
			while ((coord = list_next(itr)))
				if (!strcasecmp(coord->name,
						slurmdb_assoc->acct))
					break;
			list_iterator_destroy(itr);

			if (coord)
				goto is_user;

		bad_user:
			errno = ESLURM_ACCESS_DENIED;
			xfree(id_str);
			return SLURM_ERROR;
		}
	}
is_user:

	if (set_usage_information(&my_usage_table, type, &start, &end)
	    != SLURM_SUCCESS) {
		xfree(id_str);
		return SLURM_ERROR;
	}

	_get_object_usage(mysql_conn, type, my_usage_table, cluster_name,
			  id_str, start, end, my_list);
	xfree(id_str);

	return rc;
}