Пример #1
0
extern int sacctmgr_dump_cluster (int argc, char **argv)
{
	slurmdb_user_cond_t user_cond;
	slurmdb_user_rec_t *user = NULL;
	slurmdb_hierarchical_rec_t *slurmdb_hierarchical_rec = NULL;
	slurmdb_assoc_rec_t *assoc = NULL;
	slurmdb_assoc_cond_t assoc_cond;
	List assoc_list = NULL;
	List acct_list = NULL;
	List user_list = NULL;
	List slurmdb_hierarchical_rec_list = NULL;
	char *cluster_name = NULL;
	char *file_name = NULL;
	char *user_name = NULL;
	char *line = NULL;
	int i, command_len = 0;
	FILE *fd = NULL;
	char *class_str = NULL;

	for (i = 0; i < argc; i++) {
		int end = parse_option_end(argv[i]);

		if (!end)
			command_len = strlen(argv[i]);
		else {
			command_len = end - 1;
			if (argv[i][end] == '=') {
				end++;
			}
		}
		if (!end || !strncasecmp(argv[i], "Cluster",
					 MAX(command_len, 1))) {
			if (cluster_name) {
				exit_code = 1;
				fprintf(stderr,
					" Can only do one cluster at a time.  "
					"Already doing %s\n", cluster_name);
				continue;
			}
			cluster_name = xstrdup(argv[i]+end);
		} else if (!strncasecmp(argv[i], "File",
					MAX(command_len, 1))) {
			if (file_name) {
				exit_code = 1;
				fprintf(stderr,
					" File name already set to %s\n",
					file_name);
				continue;
			}
			file_name = xstrdup(argv[i]+end);
		} else {
			exit_code = 1;
			fprintf(stderr, " Unknown option: %s\n", argv[i]);
		}
	}

	if (!cluster_name) {
		exit_code = 1;
		fprintf(stderr, " We need a cluster to dump.\n");
		xfree(file_name);
		return SLURM_ERROR;
	} else {
		List temp_list = NULL;
		slurmdb_cluster_cond_t cluster_cond;
		slurmdb_cluster_rec_t *cluster_rec = NULL;

		slurmdb_init_cluster_cond(&cluster_cond, 0);
		cluster_cond.cluster_list = list_create(NULL);
		list_push(cluster_cond.cluster_list, cluster_name);

		temp_list = acct_storage_g_get_clusters(db_conn, my_uid,
							&cluster_cond);
		FREE_NULL_LIST(cluster_cond.cluster_list);
		if (!temp_list) {
			exit_code = 1;
			fprintf(stderr,
				" Problem getting clusters from database.  "
				"Contact your admin.\n");
			xfree(cluster_name);
			xfree(file_name);
			return SLURM_ERROR;
		}

		cluster_rec = list_peek(temp_list);
		if (!cluster_rec) {
			exit_code = 1;
			fprintf(stderr, " Cluster %s doesn't exist.\n",
				cluster_name);
			xfree(cluster_name);
			xfree(file_name);
			FREE_NULL_LIST(temp_list);
			return SLURM_ERROR;
		}
		class_str = get_classification_str(cluster_rec->classification);
		FREE_NULL_LIST(temp_list);
	}

	if (!file_name) {
		file_name = xstrdup_printf("./%s.cfg", cluster_name);
		printf(" No filename given, using %s.\n", file_name);
	}

	memset(&user_cond, 0, sizeof(slurmdb_user_cond_t));
	user_cond.with_coords = 1;
	user_cond.with_wckeys = 1;
	user_cond.with_assocs = 1;

	memset(&assoc_cond, 0, sizeof(slurmdb_assoc_cond_t));
	assoc_cond.without_parent_limits = 1;
	assoc_cond.with_raw_qos = 1;
	assoc_cond.cluster_list = list_create(NULL);
	list_append(assoc_cond.cluster_list, cluster_name);
	/* this is needed for getting the correct wckeys */
	user_cond.assoc_cond = &assoc_cond;

	user_list = acct_storage_g_get_users(db_conn, my_uid, &user_cond);
	/* If not running with the DBD assoc_cond.user_list can be set,
	 * which will mess other things up.
	 */
	if (assoc_cond.user_list) {
		FREE_NULL_LIST(assoc_cond.user_list);
		assoc_cond.user_list = NULL;
	}

	/* make sure this person running is an admin */
	user_name = uid_to_string_cached(my_uid);
	if (!(user = sacctmgr_find_user_from_list(user_list, user_name))) {
		exit_code = 1;
		fprintf(stderr, " Your uid (%u) is not in the "
			"accounting system, can't dump cluster.\n", my_uid);
		FREE_NULL_LIST(assoc_cond.cluster_list);
		xfree(cluster_name);
		xfree(file_name);
		FREE_NULL_LIST(user_list);
		return SLURM_ERROR;

	} else {
		if (my_uid != slurm_get_slurm_user_id() && my_uid != 0
		    && user->admin_level < SLURMDB_ADMIN_SUPER_USER) {
			exit_code = 1;
			fprintf(stderr, " Your user does not have sufficient "
				"privileges to dump clusters.\n");
			FREE_NULL_LIST(assoc_cond.cluster_list);
			xfree(cluster_name);
			xfree(file_name);
			FREE_NULL_LIST(user_list);
			return SLURM_ERROR;
		}
	}
	xfree(user_name);

	/* assoc_cond is set up above */
	assoc_list = acct_storage_g_get_assocs(db_conn, my_uid,
						     &assoc_cond);
	FREE_NULL_LIST(assoc_cond.cluster_list);
	if (!assoc_list) {
		exit_code = 1;
		fprintf(stderr, " Problem with query.\n");
		xfree(cluster_name);
		xfree(file_name);
		return SLURM_ERROR;
	} else if (!list_count(assoc_list)) {
		exit_code = 1;
		fprintf(stderr, " Cluster %s returned nothing.\n",
			cluster_name);
		FREE_NULL_LIST(assoc_list);
		xfree(cluster_name);
		xfree(file_name);
		return SLURM_ERROR;
	}

	slurmdb_hierarchical_rec_list = slurmdb_get_acct_hierarchical_rec_list(
		assoc_list);

	acct_list = acct_storage_g_get_accounts(db_conn, my_uid, NULL);

	if ((fd = fopen(file_name,"w")) == NULL) {
		fprintf(stderr, "Can't open file %s, %s\n", file_name,
			slurm_strerror(errno));
		FREE_NULL_LIST(acct_list);
		FREE_NULL_LIST(assoc_list);
		xfree(cluster_name);
		xfree(file_name);
		FREE_NULL_LIST(slurmdb_hierarchical_rec_list);
		return SLURM_ERROR;
	}

	/* Add header */
	if (fprintf(fd,
		    "# To edit this file start with a cluster line "
		    "for the new cluster\n"
		    "# Cluster - 'cluster_name':MaxNodesPerJob=50\n"
		    "# Followed by Accounts you want in this fashion "
		    "(root is created by default)...\n"
		    "# Parent - 'root'\n"
		    "# Account - 'cs':MaxNodesPerJob=5:MaxJobs=4:"
		    "MaxTRESMins=cpu=20:FairShare=399:"
		    "MaxWallDuration=40:Description='Computer Science':"
		    "Organization='LC'\n"
		    "# Any of the options after a ':' can be left out and "
		    "they can be in any order.\n"
		    "# If you want to add any sub accounts just list the "
		    "Parent THAT HAS ALREADY \n"
		    "# BEEN CREATED before the account line in this "
		    "fashion...\n"
		    "# Parent - 'cs'\n"
		    "# Account - 'test':MaxNodesPerJob=1:MaxJobs=1:"
		    "MaxTRESMins=cpu=1:FairShare=1:"
		    "MaxWallDuration=1:"
		    "Description='Test Account':Organization='Test'\n"
		    "# To add users to a account add a line like this after a "
		    "Parent - 'line'\n"
		    "# User - 'lipari':MaxNodesPerJob=2:MaxJobs=3:"
		    "MaxTRESMins=cpu=4:FairShare=1:"
		    "MaxWallDurationPerJob=1\n") < 0) {
		exit_code = 1;
		fprintf(stderr, "Can't write to file");
		FREE_NULL_LIST(acct_list);
		FREE_NULL_LIST(assoc_list);
		xfree(cluster_name);
		xfree(file_name);
		FREE_NULL_LIST(slurmdb_hierarchical_rec_list);
		return SLURM_ERROR;
	}

	line = xstrdup_printf("Cluster - '%s'", cluster_name);

	if (class_str)
		xstrfmtcat(line, ":Classification='%s'", class_str);

	slurmdb_hierarchical_rec = list_peek(slurmdb_hierarchical_rec_list);
	assoc = slurmdb_hierarchical_rec->assoc;
	if (xstrcmp(assoc->acct, "root")) {
		fprintf(stderr, "Root association not on the top it was %s\n",
			assoc->acct);
	} else
		print_file_add_limits_to_line(&line, assoc);

	if (fprintf(fd, "%s\n", line) < 0) {
		exit_code = 1;
		fprintf(stderr, " Can't write to file");
		FREE_NULL_LIST(acct_list);
		FREE_NULL_LIST(assoc_list);
		xfree(cluster_name);
		xfree(file_name);
		xfree(line);
		FREE_NULL_LIST(slurmdb_hierarchical_rec_list);
		return SLURM_ERROR;
	}
	info("%s", line);
	xfree(line);

	print_file_slurmdb_hierarchical_rec_list(
		fd, slurmdb_hierarchical_rec_list, user_list, acct_list);

	FREE_NULL_LIST(acct_list);
	FREE_NULL_LIST(assoc_list);
	xfree(cluster_name);
	xfree(file_name);
	FREE_NULL_LIST(slurmdb_hierarchical_rec_list);
	fclose(fd);

	return SLURM_SUCCESS;
}
Пример #2
0
/* FIXME: This only works for CPUS now */
static List _process_grouped_report(
	void *db_conn, slurmdb_job_cond_t *job_cond, List grouping_list,
	bool flat_view, bool wckey_type, bool both)
{
	int exit_code = 0;
	void *object = NULL, *object2 = NULL;

	ListIterator itr = NULL, itr2 = NULL;
	ListIterator cluster_itr = NULL;
	ListIterator local_itr = NULL;
	ListIterator acct_itr = NULL;
	ListIterator group_itr = NULL;

	slurmdb_job_rec_t *job = NULL;
	slurmdb_report_cluster_grouping_t *cluster_group = NULL;
	slurmdb_report_acct_grouping_t *acct_group = NULL;
	slurmdb_report_job_grouping_t *job_group = NULL;

	List job_list = NULL;
	List cluster_list = NULL;
	List object_list = NULL, object2_list = NULL;

	List tmp_acct_list = NULL;
	bool destroy_job_cond = 0;
	bool destroy_grouping_list = 0;
	bool individual = 0;
	uint32_t tres_id = TRES_CPU;

	uid_t my_uid = getuid();

	/* we don't want to actually query by accounts in the jobs
	   here since we may be looking for sub accounts of a specific
	   account.
	*/
	if (!job_cond) {
		destroy_job_cond = 1;
		job_cond = xmalloc(sizeof(slurmdb_job_cond_t));
	}
	if (!grouping_list) {
		destroy_grouping_list = 1;
		grouping_list = list_create(slurm_destroy_char);
		slurm_addto_char_list(grouping_list, "50,250,500,1000");
	}

	tmp_acct_list = job_cond->acct_list;
	job_cond->acct_list = NULL;

	job_list = jobacct_storage_g_get_jobs_cond(db_conn, my_uid, job_cond);
	job_cond->acct_list = tmp_acct_list;
	tmp_acct_list = NULL;

	if (!job_list) {
		exit_code=1;
		fprintf(stderr, " Problem with job query.\n");
		goto end_it;
	}

	group_itr = list_iterator_create(grouping_list);
	/* make a group for each job size we find. */
	if (!list_count(grouping_list)) {
		char *group = NULL;

		individual = 1;
		itr = list_iterator_create(job_list);
		while ((job = list_next(itr))) {
			char *tmp = NULL;
			uint64_t count;

			if (!job->elapsed)
				continue;

			if ((count = slurmdb_find_tres_count_in_string(
				     job->tres_alloc_str, tres_id))
			    == INFINITE64)
				continue;

			tmp = xstrdup_printf("%"PRIu64, count);

			while ((group = list_next(group_itr))) {
				if (!xstrcmp(group, tmp)) {
					break;
				}
			}
			if (!group)
				list_append(grouping_list, tmp);
			else
				xfree(tmp);
			list_iterator_reset(group_itr);
		}
		list_iterator_destroy(itr);
		list_sort(grouping_list, (ListCmpF)_sort_group_asc);
	}

	cluster_list = list_create(slurmdb_destroy_report_cluster_grouping);

	cluster_itr = list_iterator_create(cluster_list);

	if (flat_view)
		goto no_objects;

	if (!wckey_type || both) {
		slurmdb_assoc_cond_t assoc_cond;
		memset(&assoc_cond, 0, sizeof(slurmdb_assoc_cond_t));
		assoc_cond.id_list = job_cond->associd_list;
		assoc_cond.cluster_list = job_cond->cluster_list;
		/* don't limit associations to having the partition_list */
		//assoc_cond.partition_list = job_cond->partition_list;
		if (!job_cond->acct_list || !list_count(job_cond->acct_list)) {
			FREE_NULL_LIST(job_cond->acct_list);
			job_cond->acct_list = list_create(NULL);
			list_append(job_cond->acct_list, "root");
		}
		assoc_cond.parent_acct_list = job_cond->acct_list;
		object_list = acct_storage_g_get_assocs(db_conn, my_uid,
							      &assoc_cond);
	}

	if (wckey_type || both) {
		slurmdb_wckey_cond_t wckey_cond;
		memset(&wckey_cond, 0, sizeof(slurmdb_wckey_cond_t));
		wckey_cond.name_list = job_cond->wckey_list;
		wckey_cond.cluster_list = job_cond->cluster_list;

		object2_list = acct_storage_g_get_wckeys(db_conn, my_uid,
							 &wckey_cond);
		if (!object_list) {
			object_list = object2_list;
			object2_list = NULL;
		}
	}

	if (!object_list) {
		debug2(" No join list given.\n");
		goto no_objects;
	}

	itr = list_iterator_create(object_list);
	if (object2_list)
		itr2 = list_iterator_create(object2_list);
	while ((object = list_next(itr))) {
		char *cluster = NULL;
		slurmdb_wckey_rec_t *wckey = (slurmdb_wckey_rec_t *)object;
		slurmdb_assoc_rec_t *assoc =
			(slurmdb_assoc_rec_t *)object;
		if (!itr2) {
			char *name = NULL;
			if (wckey_type) {
				cluster = wckey->cluster;
				name = wckey->name;
			} else {
				cluster = assoc->cluster;
				name = assoc->acct;
			}
			_check_create_grouping(cluster_list, group_itr,
					       cluster, name, object,
					       individual, wckey_type);
			continue;
		}

		while ((object2 = list_next(itr2))) {
			slurmdb_wckey_rec_t *wckey2 =
				(slurmdb_wckey_rec_t *)object2;
			slurmdb_assoc_rec_t *assoc2 =
				(slurmdb_assoc_rec_t *)object2;
			char name[200];
			if (!wckey_type) {
				if (xstrcmp(assoc->cluster, wckey2->cluster))
					continue;
				cluster = assoc->cluster;
				snprintf(name, sizeof(name), "%s:%s",
					 assoc->acct, wckey2->name);
			} else {
				if (xstrcmp(wckey->cluster, assoc2->cluster))
					continue;
				cluster = wckey->cluster;
				snprintf(name, sizeof(name), "%s:%s",
					 wckey2->name, assoc->acct);
			}
			_check_create_grouping(cluster_list, group_itr,
					       cluster, name, object,
					       individual, wckey_type);
		}
		list_iterator_reset(itr2);
	}
	list_iterator_destroy(itr);
	if (itr2)
		list_iterator_destroy(itr2);

no_objects:
	itr = list_iterator_create(job_list);

	while((job = list_next(itr))) {
		char *local_cluster = "UNKNOWN";
		char tmp_acct[200];

		if (!job->elapsed) {
			/* here we don't care about jobs that didn't
			 * really run here */
			continue;
		}
		if (job->cluster)
			local_cluster = job->cluster;

		if (!wckey_type) {
			if (both && job->wckey) {
				snprintf(tmp_acct, sizeof(tmp_acct),
					 "%s:%s",
					 job->account,
					 job->wckey);
			} else {
				snprintf(tmp_acct, sizeof(tmp_acct),
					 "%s", job->account);
			}
		} else {
			if (both && job->account) {
				snprintf(tmp_acct, sizeof(tmp_acct),
					 "%s:%s",
					 job->wckey,
					 job->account);
			} else {
				snprintf(tmp_acct, sizeof(tmp_acct),
					 "%s", job->wckey);
			}
		}

		list_iterator_reset(cluster_itr);
		while((cluster_group = list_next(cluster_itr))) {
			if (!xstrcmp(local_cluster, cluster_group->cluster))
				break;
		}
		if (!cluster_group) {
			/* here we are only looking for groups that
			 * were added with the associations above
			 */
			if (!flat_view)
				continue;
			cluster_group = xmalloc(
				sizeof(slurmdb_report_cluster_grouping_t));
			cluster_group->cluster = xstrdup(local_cluster);
			cluster_group->acct_list = list_create(
				slurmdb_destroy_report_acct_grouping);
			list_append(cluster_list, cluster_group);
		}

		acct_itr = list_iterator_create(cluster_group->acct_list);
		while((acct_group = list_next(acct_itr))) {
			if (wckey_type) {
				if (!xstrcmp(tmp_acct, acct_group->acct))
					break;
				continue;
			}

			if (!flat_view
			   && (acct_group->lft != (uint32_t)NO_VAL)
			   && (job->lft != (uint32_t)NO_VAL)) {
				/* keep separate since we don't want
				 * to so a xstrcmp if we don't have to
				 */
				if (job->lft > acct_group->lft
				    && job->lft < acct_group->rgt) {
					char *mywckey;
					if (!both)
						break;
					mywckey = strstr(acct_group->acct, ":");
					mywckey++;
					if (!job->wckey && !mywckey)
						break;
					else if (!mywckey || !job->wckey)
						continue;
					else if (!xstrcmp(mywckey, job->wckey))
						break;
				}
			} else if (!xstrcmp(acct_group->acct, tmp_acct))
				break;
		}
		list_iterator_destroy(acct_itr);

		if (!acct_group) {
			char *group = NULL;
			uint32_t last_size = 0;
			/* here we are only looking for groups that
			 * were added with the associations above
			 */
			if (!flat_view)
				continue;

			acct_group = xmalloc(
				sizeof(slurmdb_report_acct_grouping_t));
			acct_group->acct = xstrdup(tmp_acct);
			acct_group->groups = list_create(
				slurmdb_destroy_report_job_grouping);
			list_append(cluster_group->acct_list, acct_group);

			while((group = list_next(group_itr))) {
				job_group = xmalloc(
					sizeof(slurmdb_report_job_grouping_t));
				job_group->jobs = list_create(NULL);
				if (!individual)
					job_group->min_size = last_size;
				last_size = atoi(group);
				if (!individual)
					job_group->max_size = last_size-1;
				else
					job_group->min_size =
						job_group->max_size = last_size;
				list_append(acct_group->groups, job_group);
			}
			if (last_size && !individual) {
				job_group = xmalloc(
					sizeof(slurmdb_report_job_grouping_t));
				job_group->jobs = list_create(NULL);
				job_group->min_size = last_size;
				if (individual)
					job_group->max_size =
						job_group->min_size;
				else
					job_group->max_size = INFINITE;
				list_append(acct_group->groups, job_group);
			}
			list_iterator_reset(group_itr);
		}

		local_itr = list_iterator_create(acct_group->groups);
		while ((job_group = list_next(local_itr))) {
			uint64_t count;

			if (((count = slurmdb_find_tres_count_in_string(
				      job->tres_alloc_str, tres_id))
			     == INFINITE64) ||
			    (count < job_group->min_size) ||
			    (count > job_group->max_size))
				continue;

			list_append(job_group->jobs, job);
			job_group->count++;
			acct_group->count++;
			cluster_group->count++;

			slurmdb_transfer_tres_time(
				&job_group->tres_list, job->tres_alloc_str,
				job->elapsed);
			slurmdb_transfer_tres_time(
				&acct_group->tres_list, job->tres_alloc_str,
				job->elapsed);
			slurmdb_transfer_tres_time(
				&cluster_group->tres_list, job->tres_alloc_str,
				job->elapsed);
		}
		list_iterator_destroy(local_itr);
	}
	list_iterator_destroy(itr);
	list_iterator_destroy(group_itr);
	list_iterator_reset(cluster_itr);
	while ((cluster_group = list_next(cluster_itr))) {
		ListIterator acct_itr;
		if (!cluster_group->count) {
			list_delete_item(cluster_itr);
			continue;
		}
		acct_itr = list_iterator_create(cluster_group->acct_list);
		while ((acct_group = list_next(acct_itr))) {
			if (!acct_group->count) {
				list_delete_item(acct_itr);
				continue;
			}
		}
		list_iterator_destroy(acct_itr);
	}
	list_iterator_destroy(cluster_itr);

end_it:
	FREE_NULL_LIST(object_list);

	FREE_NULL_LIST(object2_list);

	if (destroy_job_cond)
		slurmdb_destroy_job_cond(job_cond);

	if (destroy_grouping_list)
		FREE_NULL_LIST(grouping_list);

	if (exit_code) {
		FREE_NULL_LIST(cluster_list);
	}

	return cluster_list;
}
Пример #3
0
static bool _isdefault(List qos_list)
{
	int rc = 0;
	slurmdb_assoc_cond_t assoc_cond;
	slurmdb_assoc_rec_t *assoc = NULL;
	ListIterator itr;
	List ret_list = NULL;
	char *name = NULL;

	if (!qos_list || !list_count(qos_list))
		return rc;

	/* this needs to happen before any removing takes place so we
	   can figure out things correctly */
	xassert(g_qos_list);

	memset(&assoc_cond, 0, sizeof(slurmdb_assoc_cond_t));
	assoc_cond.without_parent_info = 1;
	assoc_cond.def_qos_id_list = list_create(slurm_destroy_char);

	itr = list_iterator_create(qos_list);
	while ((name = list_next(itr))) {
		uint32_t id = str_2_slurmdb_qos(g_qos_list, name);
		if (id == NO_VAL)
			continue;
		list_append(assoc_cond.def_qos_id_list,
			    xstrdup_printf("%u", id));
	}
	list_iterator_destroy(itr);

	ret_list = acct_storage_g_get_assocs(
		db_conn, my_uid, &assoc_cond);
	list_destroy(assoc_cond.def_qos_id_list);

	if (!ret_list || !list_count(ret_list))
		goto end_it;

	fprintf(stderr," Associations listed below have these "
		"as their Default QOS.\n");
	itr = list_iterator_create(ret_list);
	while((assoc = list_next(itr))) {
		name = slurmdb_qos_str(g_qos_list, assoc->def_qos_id);
		if (!assoc->user) {
			// see if this isn't a user
			fprintf(stderr,
				"  DefQOS = %-10s C = %-10s A = %-20s\n",
				name, assoc->cluster, assoc->acct);
		} else if (assoc->partition) {
			// see if there is a partition name
			fprintf(stderr,
				"  DefQOS = %-10s C = %-10s A = %-20s "
				"U = %-9s P = %s\n",
				name, assoc->cluster, assoc->acct,
				assoc->user, assoc->partition);
		} else {
			fprintf(stderr,
				"  DefQOS = %-10s C = %-10s A = %-20s "
				"U = %-9s\n",
				name, assoc->cluster, assoc->acct, assoc->user);
		}
	}
	list_iterator_destroy(itr);
	rc = 1;
end_it:
	if (ret_list)
		list_destroy(ret_list);

	return rc;
}
Пример #4
0
static List _process_util_by_report(void *db_conn, char *calling_name,
				    void *cond, cluster_report_t type)
{	ListIterator itr = NULL;
	ListIterator type_itr = NULL;
	slurmdb_cluster_cond_t cluster_cond;
	List type_list = NULL;
	List cluster_list = NULL;
	List first_list = NULL;
	slurmdb_cluster_rec_t *cluster = NULL;
	slurmdb_report_cluster_rec_t *slurmdb_report_cluster = NULL;
	time_t start_time, end_time;

	int exit_code = 0;

	uid_t my_uid = getuid();
	List ret_list = list_create(slurmdb_destroy_report_cluster_rec);

	slurmdb_init_cluster_cond(&cluster_cond, 0);

	cluster_cond.with_deleted = 1;
	cluster_cond.with_usage = 1;
	if ((type == CLUSTER_REPORT_UA) || (type == CLUSTER_REPORT_AU)) {
		start_time = ((slurmdb_assoc_cond_t *)cond)->usage_start;
		end_time = ((slurmdb_assoc_cond_t *)cond)->usage_end;

		cluster_cond.cluster_list =
			((slurmdb_assoc_cond_t *)cond)->cluster_list;
	} else if ((type == CLUSTER_REPORT_UW) || (type == CLUSTER_REPORT_WU)) {
		start_time = ((slurmdb_wckey_cond_t *)cond)->usage_start;
		end_time = ((slurmdb_wckey_cond_t *)cond)->usage_end;

		cluster_cond.cluster_list =
			((slurmdb_wckey_cond_t *)cond)->cluster_list;
	} else {
		error("unknown report type %d", type);
		return NULL;
	}

	/* This needs to be done on some systems to make sure
	   cluster_cond isn't messed.  This has happened on some 64
	   bit machines and this is here to be on the safe side.
	*/
	slurmdb_report_set_start_end_time(&start_time, &end_time);
	cluster_cond.usage_end = end_time;
	cluster_cond.usage_start = start_time;


	cluster_list = acct_storage_g_get_clusters(
		db_conn, my_uid, &cluster_cond);

	if (!cluster_list) {
		exit_code=1;
		fprintf(stderr, "%s: Problem with cluster query.\n",
			calling_name);
		goto end_it;
	}

	if ((type == CLUSTER_REPORT_UA) || (type == CLUSTER_REPORT_AU)) {
		((slurmdb_assoc_cond_t *)cond)->usage_start = start_time;
		((slurmdb_assoc_cond_t *)cond)->usage_end = end_time;
		type_list = acct_storage_g_get_assocs(
			db_conn, my_uid, cond);
	} else if ((type == CLUSTER_REPORT_UW) || (type == CLUSTER_REPORT_WU)) {
		((slurmdb_wckey_cond_t *)cond)->usage_start = start_time;
		((slurmdb_wckey_cond_t *)cond)->usage_end = end_time;
		type_list = acct_storage_g_get_wckeys(
			db_conn, my_uid, cond);
	}

	if (!type_list) {
		exit_code=1;
		fprintf(stderr, "%s: Problem with get query.\n", calling_name);
		goto end_it;
	}

	if ((type == CLUSTER_REPORT_UA) || (type == CLUSTER_REPORT_AU)) {
		first_list = type_list;
		type_list = slurmdb_get_hierarchical_sorted_assoc_list(
			first_list, true);
	}

	/* set up the structures for easy retrieval later */
	itr = list_iterator_create(cluster_list);
	type_itr = list_iterator_create(type_list);
	while((cluster = list_next(itr))) {
		/* check to see if this cluster is around during the
		   time we are looking at */
		if (!cluster->accounting_list
		   || !list_count(cluster->accounting_list))
			continue;

		slurmdb_report_cluster = slurmdb_cluster_rec_2_report(cluster);

		list_append(ret_list, slurmdb_report_cluster);

		if ((type == CLUSTER_REPORT_UA) || (type == CLUSTER_REPORT_UW))
			slurmdb_report_cluster->user_list =
				list_create(slurmdb_destroy_report_user_rec);
		else if ((type == CLUSTER_REPORT_AU)
			|| (type == CLUSTER_REPORT_WU))
			slurmdb_report_cluster->assoc_list =
				list_create(slurmdb_destroy_report_assoc_rec);

		if ((type == CLUSTER_REPORT_UA) || (type == CLUSTER_REPORT_AU))
			_process_assoc_type(type_itr, slurmdb_report_cluster,
					    cluster->name, type);
		else if ((type == CLUSTER_REPORT_UW)
			|| (type == CLUSTER_REPORT_WU))
			_process_wckey_type(type_itr, slurmdb_report_cluster,
					    cluster->name, type);
		list_iterator_reset(type_itr);
	}
	list_iterator_destroy(type_itr);
	list_iterator_destroy(itr);

end_it:
	FREE_NULL_LIST(type_list);
	FREE_NULL_LIST(first_list);
	FREE_NULL_LIST(cluster_list);
	if (exit_code)
		FREE_NULL_LIST(ret_list);
	return ret_list;
}
Пример #5
0
extern int sacctmgr_add_account(int argc, char *argv[])
{
	int rc = SLURM_SUCCESS;
	int i=0;
	ListIterator itr = NULL, itr_c = NULL;
	slurmdb_account_rec_t *acct = NULL;
	slurmdb_assoc_rec_t *assoc = NULL;
	slurmdb_assoc_cond_t assoc_cond;
	List name_list = list_create(slurm_destroy_char);
	List cluster_list = list_create(slurm_destroy_char);
	char *cluster = NULL;
	char *name = NULL;
	List acct_list = NULL;
	List assoc_list = NULL;
	List local_assoc_list = NULL;
	List local_account_list = NULL;
	char *acct_str = NULL;
	char *assoc_str = NULL;
	int limit_set = 0;
	slurmdb_account_rec_t *start_acct =
		xmalloc(sizeof(slurmdb_account_rec_t));
	slurmdb_assoc_rec_t *start_assoc =
		xmalloc(sizeof(slurmdb_assoc_rec_t));

	slurmdb_init_assoc_rec(start_assoc, 0);

	for (i=0; i<argc; i++) {
		int command_len = strlen(argv[i]);
		if (!strncasecmp(argv[i], "Where", MAX(command_len, 5))
		    || !strncasecmp(argv[i], "Set", MAX(command_len, 3)))
			i++;
		limit_set += _set_rec(&i, argc, argv, name_list, cluster_list,
				      start_acct, start_assoc);
	}
	if (exit_code)
		return SLURM_ERROR;

	if (!name_list || !list_count(name_list)) {
		FREE_NULL_LIST(name_list);
		FREE_NULL_LIST(cluster_list);
		slurmdb_destroy_assoc_rec(start_assoc);
		slurmdb_destroy_account_rec(start_acct);
		exit_code=1;
		fprintf(stderr, " Need name of account to add.\n");
		return SLURM_SUCCESS;
	} else {
		slurmdb_account_cond_t account_cond;
		memset(&account_cond, 0, sizeof(slurmdb_account_cond_t));
		memset(&assoc_cond, 0, sizeof(slurmdb_assoc_cond_t));

		assoc_cond.acct_list = name_list;
		account_cond.assoc_cond = &assoc_cond;

		local_account_list = acct_storage_g_get_accounts(
			db_conn, my_uid, &account_cond);
	}

	if (!local_account_list) {
		exit_code=1;
		fprintf(stderr, " Problem getting accounts from database.  "
			"Contact your admin.\n");
		FREE_NULL_LIST(name_list);
		FREE_NULL_LIST(cluster_list);
		slurmdb_destroy_assoc_rec(start_assoc);
		slurmdb_destroy_account_rec(start_acct);
		return SLURM_ERROR;
	}

	if (!start_assoc->parent_acct)
		start_assoc->parent_acct = xstrdup("root");

	if (!cluster_list || !list_count(cluster_list)) {
		slurmdb_cluster_rec_t *cluster_rec = NULL;
		List tmp_list =
			acct_storage_g_get_clusters(db_conn, my_uid, NULL);
		if (!tmp_list) {
			exit_code=1;
			fprintf(stderr,
				" Problem getting clusters from database.  "
				"Contact your admin.\n");
			FREE_NULL_LIST(name_list);
			FREE_NULL_LIST(cluster_list);
			slurmdb_destroy_assoc_rec(start_assoc);
			slurmdb_destroy_account_rec(start_acct);
			FREE_NULL_LIST(local_account_list);
			return SLURM_ERROR;
		}

		if (!list_count(tmp_list)) {
			exit_code=1;
			fprintf(stderr,
				"  Can't add accounts, no cluster "
				"defined yet.\n"
				" Please contact your administrator.\n");
			FREE_NULL_LIST(name_list);
			FREE_NULL_LIST(cluster_list);
			slurmdb_destroy_assoc_rec(start_assoc);
			slurmdb_destroy_account_rec(start_acct);
			FREE_NULL_LIST(local_account_list);
			return SLURM_ERROR;
		}
		if (!cluster_list)
			list_create(slurm_destroy_char);
		else
			list_flush(cluster_list);

		itr_c = list_iterator_create(tmp_list);
		while((cluster_rec = list_next(itr_c))) {
			list_append(cluster_list, xstrdup(cluster_rec->name));
		}
		list_iterator_destroy(itr_c);
		FREE_NULL_LIST(tmp_list);
	} else if (sacctmgr_validate_cluster_list(cluster_list)
		   != SLURM_SUCCESS) {
		slurmdb_destroy_assoc_rec(start_assoc);
		slurmdb_destroy_account_rec(start_acct);
		FREE_NULL_LIST(local_account_list);

		return SLURM_ERROR;
	}


	acct_list = list_create(slurmdb_destroy_account_rec);
	assoc_list = list_create(slurmdb_destroy_assoc_rec);

	memset(&assoc_cond, 0, sizeof(slurmdb_assoc_cond_t));

	assoc_cond.acct_list = list_create(NULL);
	itr = list_iterator_create(name_list);
	while((name = list_next(itr)))
		list_append(assoc_cond.acct_list, name);
	list_iterator_destroy(itr);
	list_append(assoc_cond.acct_list, start_assoc->parent_acct);

	assoc_cond.cluster_list = cluster_list;
	local_assoc_list = acct_storage_g_get_assocs(
		db_conn, my_uid, &assoc_cond);
	FREE_NULL_LIST(assoc_cond.acct_list);
	if (!local_assoc_list) {
		exit_code=1;
		fprintf(stderr, " Problem getting associations from database.  "
			"Contact your admin.\n");
		FREE_NULL_LIST(name_list);
		FREE_NULL_LIST(cluster_list);
		slurmdb_destroy_assoc_rec(start_assoc);
		slurmdb_destroy_account_rec(start_acct);
		FREE_NULL_LIST(local_account_list);
		return SLURM_ERROR;
	}

	itr = list_iterator_create(name_list);
	while((name = list_next(itr))) {
		if (!name[0]) {
			exit_code=1;
			fprintf(stderr, " No blank names are "
				"allowed when adding.\n");
			rc = SLURM_ERROR;
			continue;
		}

		acct = NULL;
		if (!sacctmgr_find_account_from_list(local_account_list, name)) {
			acct = xmalloc(sizeof(slurmdb_account_rec_t));
			acct->assoc_list =
				list_create(slurmdb_destroy_assoc_rec);
			acct->name = xstrdup(name);
			if (start_acct->description)
				acct->description =
					xstrdup(start_acct->description);
			else
				acct->description = xstrdup(name);

			if (start_acct->organization)
				acct->organization =
					xstrdup(start_acct->organization);
			else if (strcmp(start_assoc->parent_acct, "root"))
				acct->organization =
					xstrdup(start_assoc->parent_acct);
			else
				acct->organization = xstrdup(name);

			xstrfmtcat(acct_str, "  %s\n", name);
			list_append(acct_list, acct);
		}

		itr_c = list_iterator_create(cluster_list);
		while((cluster = list_next(itr_c))) {
			if (sacctmgr_find_account_base_assoc_from_list(
				   local_assoc_list, name, cluster)) {
				//printf(" already have this assoc\n");
				continue;
			}
			if (!sacctmgr_find_account_base_assoc_from_list(
				   local_assoc_list, start_assoc->parent_acct,
				   cluster)) {
				exit_code=1;
				fprintf(stderr, " Parent account '%s' "
					"doesn't exist on "
					"cluster %s\n"
					"        Contact your admin "
					"to add this account.\n",
					start_assoc->parent_acct, cluster);
				continue;
			}

			assoc = xmalloc(sizeof(slurmdb_assoc_rec_t));
			slurmdb_init_assoc_rec(assoc, 0);
			assoc->acct = xstrdup(name);
			assoc->cluster = xstrdup(cluster);
			assoc->def_qos_id = start_assoc->def_qos_id;
			assoc->parent_acct = xstrdup(start_assoc->parent_acct);
			assoc->shares_raw = start_assoc->shares_raw;

			assoc->grp_cpu_mins = start_assoc->grp_cpu_mins;
			assoc->grp_cpu_run_mins = start_assoc->grp_cpu_run_mins;
			assoc->grp_cpus = start_assoc->grp_cpus;
			assoc->grp_jobs = start_assoc->grp_jobs;
			assoc->grp_mem = start_assoc->grp_mem;
			assoc->grp_nodes = start_assoc->grp_nodes;
			assoc->grp_submit_jobs = start_assoc->grp_submit_jobs;
			assoc->grp_wall = start_assoc->grp_wall;

			assoc->max_cpu_mins_pj = start_assoc->max_cpu_mins_pj;
			assoc->max_cpus_pj = start_assoc->max_cpus_pj;
			assoc->max_jobs = start_assoc->max_jobs;
			assoc->max_nodes_pj = start_assoc->max_nodes_pj;
			assoc->max_submit_jobs = start_assoc->max_submit_jobs;
			assoc->max_wall_pj = start_assoc->max_wall_pj;

			assoc->qos_list = copy_char_list(start_assoc->qos_list);

			if (acct)
				list_append(acct->assoc_list, assoc);
			else
				list_append(assoc_list, assoc);
			xstrfmtcat(assoc_str,
				   "  A = %-10.10s"
				   " C = %-10.10s\n",
				   assoc->acct,
				   assoc->cluster);

		}
		list_iterator_destroy(itr_c);
	}
	list_iterator_destroy(itr);
	FREE_NULL_LIST(local_account_list);
	FREE_NULL_LIST(local_assoc_list);


	if (!list_count(acct_list) && !list_count(assoc_list)) {
		printf(" Nothing new added.\n");
		rc = SLURM_ERROR;
		goto end_it;
	} else if (!assoc_str) {
		exit_code=1;
		fprintf(stderr, " No associations created.\n");
		goto end_it;
	}

	if (acct_str) {
		printf(" Adding Account(s)\n%s", acct_str);
		printf(" Settings\n");
		if (start_acct->description)
			printf("  Description     = %s\n",
			       start_acct->description);
		else
			printf("  Description     = %s\n", "Account Name");

		if (start_acct->organization)
			printf("  Organization    = %s\n",
			       start_acct->organization);
		else
			printf("  Organization    = %s\n",
			       "Parent/Account Name");

		xfree(acct_str);
	}

	if (assoc_str) {
		printf(" Associations\n%s", assoc_str);
		xfree(assoc_str);
	}

	if (limit_set) {
		printf(" Settings\n");
		sacctmgr_print_assoc_limits(start_assoc);
	}

	notice_thread_init();
	if (list_count(acct_list))
		rc = acct_storage_g_add_accounts(db_conn, my_uid, acct_list);


	if (rc == SLURM_SUCCESS) {
		if (list_count(assoc_list))
			rc = acct_storage_g_add_assocs(db_conn, my_uid,
							     assoc_list);
	} else {
		exit_code=1;
		fprintf(stderr, " Problem adding accounts: %s\n",
			slurm_strerror(rc));
		rc = SLURM_ERROR;
		notice_thread_fini();
		goto end_it;
	}
	notice_thread_fini();

	if (rc == SLURM_SUCCESS) {
		if (commit_check("Would you like to commit changes?")) {
			acct_storage_g_commit(db_conn, 1);
		} else {
			printf(" Changes Discarded\n");
			acct_storage_g_commit(db_conn, 0);
		}
	} else {
		exit_code=1;
		fprintf(stderr,
			" error: Problem adding account associations: %s\n",
			slurm_strerror(rc));
		rc = SLURM_ERROR;
	}

end_it:
	FREE_NULL_LIST(name_list);
	FREE_NULL_LIST(cluster_list);
	FREE_NULL_LIST(acct_list);
	FREE_NULL_LIST(assoc_list);

	slurmdb_destroy_assoc_rec(start_assoc);
	slurmdb_destroy_account_rec(start_acct);
	return rc;
}
Пример #6
0
extern int sacctmgr_delete_account(int argc, char *argv[])
{
	int rc = SLURM_SUCCESS;
	slurmdb_account_cond_t *acct_cond =
		xmalloc(sizeof(slurmdb_account_cond_t));
	int i = 0;
	List ret_list = NULL, local_assoc_list = NULL;
	ListIterator itr = NULL;
	int cond_set = 0, prev_set = 0;

	for (i = 0; i < argc; i++) {
		int command_len = strlen(argv[i]);
		if (!strncasecmp(argv[i], "Where", MAX(command_len, 5))
		    || !strncasecmp(argv[i], "Set", MAX(command_len, 3)))
			i++;
		prev_set = _set_cond(&i, argc, argv, acct_cond, NULL);
		cond_set |= prev_set;
	}

	if (!cond_set) {
		exit_code = 1;
		fprintf(stderr,
			" No conditions given to remove, not executing.\n");
		slurmdb_destroy_account_cond(acct_cond);
		return SLURM_ERROR;
	}

	if (exit_code) {
		slurmdb_destroy_account_cond(acct_cond);
		return SLURM_ERROR;
	}

	if (!acct_cond->assoc_cond) {
		error("%s: Association condition is NULL", __func__);
		slurmdb_destroy_account_cond(acct_cond);
		return SLURM_ERROR;
	}

	/* check to see if person is trying to remove root account.  This is
	 * bad, and should not be allowed outside of deleting a cluster.
	 */
	if (acct_cond->assoc_cond
	   && acct_cond->assoc_cond->acct_list
	   && list_count(acct_cond->assoc_cond->acct_list)) {
		char *tmp_char = NULL;
		itr = list_iterator_create(acct_cond->assoc_cond->acct_list);
		while ((tmp_char = list_next(itr))) {
			if (!strcasecmp(tmp_char, "root"))
				break;
		}
		list_iterator_destroy(itr);
		if (tmp_char) {
			exit_code=1;
			fprintf(stderr, " You are not allowed to remove "
				"the root account.\n"
				" Use remove cluster instead.\n");
			slurmdb_destroy_account_cond(acct_cond);
			return SLURM_ERROR;
		}
	}

	acct_cond->assoc_cond->only_defs = 1;
	local_assoc_list = acct_storage_g_get_assocs(
		db_conn, my_uid, acct_cond->assoc_cond);
	acct_cond->assoc_cond->only_defs = 0;

	notice_thread_init();
	if (cond_set == 1) {
		ret_list = acct_storage_g_remove_accounts(
			db_conn, my_uid, acct_cond);
	} else if (cond_set & 2) {
		ret_list = acct_storage_g_remove_assocs(
			db_conn, my_uid, acct_cond->assoc_cond);
	}
	rc = errno;
	notice_thread_fini();
	slurmdb_destroy_account_cond(acct_cond);

	if (ret_list && list_count(ret_list)) {
		char *object = NULL;
		ListIterator itr = NULL;

		/* Check to see if person is trying to remove a default
		 * account of a user.  _isdefault only works with the
		 * output from acct_storage_g_remove_accounts, and
		 * with a previously got assoc_list.
		 */
		if (_isdefault(cond_set, ret_list, local_assoc_list)) {
			exit_code=1;
			fprintf(stderr, " Please either remove the "
				"accounts listed "
				"above from list and resubmit,\n"
				" or change these users default account to "
				"remove the account(s).\n"
				" Changes Discarded\n");
			acct_storage_g_commit(db_conn, 0);
			goto end_it;
		}
		itr = list_iterator_create(ret_list);
		/* If there were jobs running with an association to
		   be deleted, don't.
		*/
		if (rc == ESLURM_JOBS_RUNNING_ON_ASSOC) {
			fprintf(stderr, " Error with request: %s\n",
				slurm_strerror(rc));
			while((object = list_next(itr))) {
				fprintf(stderr,"  %s\n", object);
			}
			acct_storage_g_commit(db_conn, 0);
			goto end_it;
		}

		if (cond_set == 1) {
			printf(" Deleting accounts...\n");
		} else if (cond_set & 2) {
			printf(" Deleting account associations...\n");
		}
		while((object = list_next(itr))) {
			printf("  %s\n", object);
		}
		list_iterator_destroy(itr);
		if (commit_check("Would you like to commit changes?")) {
			acct_storage_g_commit(db_conn, 1);
		} else {
			printf(" Changes Discarded\n");
			acct_storage_g_commit(db_conn, 0);
		}
	} else if (ret_list) {
		printf(" Nothing deleted\n");
		rc = SLURM_ERROR;
	} else {
		exit_code=1;
		fprintf(stderr, " Error with request: %s\n",
			slurm_strerror(errno));

		rc = SLURM_ERROR;
	}

end_it:

	FREE_NULL_LIST(ret_list);
	FREE_NULL_LIST(local_assoc_list);

	return rc;
}