blob: 729633b40b02bb645646d4e9387367ef74582374 [file] [log] [blame]
/****************************************************************************\
* resource_functions.c - functions dealing with resources in the
* accounting system.
*****************************************************************************
* Copyright (C) 2013 Bull S. A. S.
* Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois.
*
* Written by Bill Brophy <bill.brophy@bull.com>
*
* This file is part of Slurm, a resource management program.
* For details, see <https://slurm.schedmd.com>.
* Please also read the included file: DISCLAIMER.
*
* Slurm is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* In addition, as a special exception, the copyright holders give permission
* to link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two. You must obey the GNU
* General Public License in all respects for all of the code used other than
* OpenSSL. If you modify file(s) with this exception, you may extend this
* exception to your version of the file(s), but you are not obligated to do
* so. If you do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source files in
* the program, then also delete it here.
*
* Slurm is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along
* with Slurm; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\****************************************************************************/
#include "src/sacctmgr/sacctmgr.h"
static void _print_overcommit(slurmdb_res_rec_t *res,
slurmdb_res_cond_t *res_cond)
{
list_t *res_list = NULL, *cluster_list = NULL;
list_itr_t *itr, *clus_itr = NULL, *found_clus_itr = NULL;
slurmdb_res_rec_t *found_res;
slurmdb_clus_res_rec_t *clus_res = NULL;
char *cluster;
if (res->allocated == NO_VAL)
return;
/* Don't use the global g_res_list since we are going to
* change the contents of this one.
*/
res_cond->with_clusters = 1;
if (res_cond->cluster_list) {
cluster_list = res_cond->cluster_list;
res_cond->cluster_list = NULL;
}
res_list = slurmdb_res_get(db_conn, res_cond);
if (!res_list) {
exit_code=1;
fprintf(stderr, " Problem getting system resources "
"from database. Contact your admin.\n");
return;
}
itr = list_iterator_create(res_list);
while ((found_res = list_next(itr))) {
int total = 0, allowed;
char *percent_str = "%";
if (found_res->flags & SLURMDB_RES_FLAG_ABSOLUTE)
percent_str = "";
fprintf(stderr, " %s@%s\n",
found_res->name, found_res->server);
if (cluster_list)
clus_itr = list_iterator_create(cluster_list);
if (found_res->clus_res_list) {
found_clus_itr = list_iterator_create(
found_res->clus_res_list);
while ((clus_res = list_next(found_clus_itr))) {
cluster = NULL;
if (clus_itr) {
while ((cluster = list_next(clus_itr)))
if (!xstrcmp(cluster,
clus_res->cluster))
break;
list_iterator_reset(clus_itr);
} else {
/*
* This means we didn't specify any
* clusters (All clusters are
* overwritten with the requested
* percentage/count) so just put
* something there to get the correct
* allowed.
*/
cluster = "nothing";
}
allowed = cluster ? res->allocated :
clus_res->allowed;
total += allowed;
fprintf(stderr,
" Cluster - %s\t %u%s\n",
clus_res->cluster,
allowed, percent_str);
}
} else if (clus_itr) {
while ((cluster = list_next(clus_itr))) {
total += res->allocated;
fprintf(stderr,
" Cluster - %s\t %u%s\n",
cluster, res->allocated,
percent_str);
}
}
if (clus_itr)
list_iterator_destroy(clus_itr);
if (found_clus_itr)
list_iterator_destroy(found_clus_itr);
fprintf(stderr, " total\t\t%u%s\n", total, percent_str);
}
list_iterator_destroy(itr);
if (cluster_list) {
res_cond->cluster_list = cluster_list;
cluster_list = NULL;
}
}
static int _set_res_cond(int *start, int argc, char **argv,
slurmdb_res_cond_t *res_cond,
list_t *format_list)
{
int i;
int set = 0;
int end = 0;
int command_len = 0;
if (!res_cond) {
error("No res_cond given");
return -1;
}
for (i=(*start); i<argc; i++) {
int op_type;
end = parse_option_end(argv[i], &op_type, &command_len);
if (!common_verify_option_syntax(argv[i], op_type, false))
continue;
if (!xstrncasecmp(argv[i], "Set", MAX(command_len, 3))) {
i--;
break;
} else if (!end && !xstrncasecmp(argv[i], "WithDeleted",
MAX(command_len, 5))) {
res_cond->with_deleted = 1;
} else if (!end && !xstrncasecmp(argv[i], "WithClusters",
MAX(command_len, 5))) {
res_cond->with_clusters = 1;
} else if (!end && !xstrncasecmp(argv[i], "where",
MAX(command_len, 5))) {
continue;
} else if (!end
|| !xstrncasecmp(argv[i], "Names",
MAX(command_len, 1))) {
if (!res_cond->name_list) {
res_cond->name_list = list_create(xfree_ptr);
}
if (slurm_addto_char_list(res_cond->name_list,
argv[i]+end))
set = 1;
} else if (!end
|| !xstrncasecmp(argv[i], "Clusters",
MAX(command_len, 1))) {
if (!res_cond->cluster_list) {
res_cond->cluster_list = list_create(xfree_ptr);
}
slurm_addto_char_list(res_cond->cluster_list,
argv[i]+end);
if (sacctmgr_validate_cluster_list(
res_cond->cluster_list) != SLURM_SUCCESS) {
exit_code=1;
fprintf(stderr,
" Need a valid cluster name to "
"add a cluster resource.\n");
} else
set = 1;
} else if (!xstrncasecmp(argv[i], "Descriptions",
MAX(command_len, 1))) {
if (!res_cond->description_list) {
res_cond->description_list =
list_create(xfree_ptr);
}
if (slurm_addto_char_list(
res_cond->description_list,
argv[i]+end))
set = 1;
} else if (!xstrncasecmp(argv[i], "Format",
MAX(command_len, 1))) {
if (format_list)
slurm_addto_char_list(format_list, argv[i]+end);
} else if (!xstrncasecmp(argv[i], "Ids", MAX(command_len, 1))) {
list_itr_t *itr = NULL;
char *temp = NULL;
uint32_t id = 0;
if (!res_cond->id_list) {
res_cond->id_list = list_create(xfree_ptr);
}
if (slurm_addto_char_list(res_cond->id_list,
argv[i]+end))
set = 1;
/* check to make sure user gave ints here */
itr = list_iterator_create(res_cond->id_list);
while ((temp = list_next(itr))) {
if (get_uint(temp, &id, "RES ID")
!= SLURM_SUCCESS) {
exit_code = 1;
list_delete_item(itr);
}
}
list_iterator_destroy(itr);
} else if (!xstrncasecmp(argv[i], "Allowed",
MAX(command_len, 1)) ||
!xstrncasecmp(argv[i], "PercentAllowed",
MAX(command_len, 1))) {
if (!res_cond->allowed_list)
res_cond->allowed_list = list_create(xfree_ptr);
if (slurm_addto_char_list(res_cond->allowed_list,
argv[i]+end))
set = 1;
} else if (!xstrncasecmp(argv[i], "ServerType",
MAX(command_len, 7))) {
if (!res_cond->manager_list) {
res_cond->manager_list = list_create(xfree_ptr);
}
if (slurm_addto_char_list(res_cond->manager_list,
argv[i]+end))
set = 1;
} else if (!xstrncasecmp(argv[i], "Server",
MAX(command_len, 2))) {
if (!res_cond->server_list) {
res_cond->server_list = list_create(xfree_ptr);
}
if (slurm_addto_char_list(res_cond->server_list,
argv[i]+end))
set = 1;
} else {
exit_code=1;
fprintf(stderr, " Unknown condition: %s\n"
" Use keyword 'set' to modify "
"SLURM_PRINT_VALUE\n", argv[i]);
}
}
(*start) = i;
return set;
}
static int _set_res_rec(int *start, int argc, char **argv,
list_t *name_list, list_t *cluster_list,
slurmdb_res_rec_t *res)
{
int i;
int set = 0;
int end = 0;
int command_len = 0;
int option = 0;
bool allow_option = false;
xassert(res);
for (i=(*start); i<argc; i++) {
end = parse_option_end(argv[i], &option, &command_len);
if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))) {
i--;
break;
} else if (!end && !xstrncasecmp(argv[i], "set",
MAX(command_len, 3))) {
continue;
} else if (!end
|| !xstrncasecmp(argv[i], "Names",
MAX(command_len, 1))
|| !xstrncasecmp(argv[i], "Resources",
MAX(command_len, 1))) {
if (name_list)
slurm_addto_char_list(name_list, argv[i]+end);
} else if (!xstrncasecmp(argv[i], "Clusters",
MAX(command_len, 1))) {
if (cluster_list) {
slurm_addto_char_list(cluster_list,
argv[i]+end);
if (sacctmgr_validate_cluster_list(
cluster_list) != SLURM_SUCCESS) {
exit_code=1;
fprintf(stderr,
" Need a valid cluster name to "
"add a cluster resource.\n");
}
} else {
exit_code=1;
fprintf(stderr,
" Can't modify the cluster "
"of an resource\n");
}
} else if (!xstrncasecmp(argv[i], "Count",
MAX(command_len, 3))) {
if (get_uint(argv[i]+end, &res->count,
"count") == SLURM_SUCCESS) {
set = 1;
}
} else if (!xstrncasecmp(argv[i], "Description",
MAX(command_len, 1))) {
if (!res->description)
res->description =
strip_quotes(argv[i]+end, NULL, 1);
set = 1;
} else if (!xstrncasecmp(argv[i], "Flags",
MAX(command_len, 2))) {
allow_option = true;
res->flags = str_2_res_flags(argv[i]+end, option);
if (res->flags == SLURMDB_RES_FLAG_NOTSET) {
char *tmp_char = slurmdb_res_flags_str(
SLURMDB_RES_FLAG_BASE);
printf(" Unknown Server Resource flag used "
"in:\n '%s'\n"
" Valid Server Resource flags are\n"
" '%s'\n", argv[i]+end, tmp_char);
xfree(tmp_char);
exit_code = 1;
} else
set = 1;
} else if (!xstrncasecmp(argv[i], "Server",
MAX(command_len, 1))) {
if (!res->server) {
res->server=
strip_quotes(argv[i]+end, NULL, 1);
}
set = 1;
} else if (!xstrncasecmp(argv[i], "ServerType",
MAX(command_len, 1))) {
if (!res->manager)
res->manager =
strip_quotes(argv[i]+end, NULL, 1);
set = 1;
} else if (!xstrncasecmp(argv[i], "Allowed",
MAX(command_len, 1)) ||
!xstrncasecmp(argv[i], "PercentAllowed",
MAX(command_len, 1))) {
/* overload allocated here */
if (get_uint(argv[i]+end, &res->allocated,
"Allowed") == SLURM_SUCCESS) {
set = 1;
}
} else if (!xstrncasecmp(argv[i], "LastConsumed",
MAX(command_len, 8))) {
if (get_uint(argv[i]+end, &res->last_consumed,
"LastConsumed") == SLURM_SUCCESS) {
set = 1;
}
} else if (!xstrncasecmp(argv[i], "Type",
MAX(command_len, 1))) {
char *temp = strip_quotes(argv[i]+end, NULL, 1);
if (!xstrncasecmp("License", temp,
MAX(strlen(temp), 1))) {
res->type = SLURMDB_RESOURCE_LICENSE;
} else {
exit_code = 1;
fprintf(stderr,
" Unknown resource type: '%s' "
"Valid resources is License.\n",
temp);
}
xfree(temp);
} else {
allow_option = true;
exit_code = 1;
printf(" Unknown option: %s\n"
" Use keyword 'where' to modify condition\n",
argv[i]);
}
common_verify_option_syntax(argv[i], option, allow_option);
}
(*start) = i;
return set;
}
static void _print_res_format(slurmdb_res_rec_t *res,
slurmdb_clus_res_rec_t *clus_res,
list_itr_t *itr,
int field_count)
{
int curr_inx = 1;
char *tmp_char;
print_field_t *field = NULL;
uint32_t tmp_uint32;
xassert(itr);
xassert(res);
while ((field = list_next(itr))) {
switch(field->type) {
case PRINT_LAST_CONSUMED:
field->print_routine(field, &res->last_consumed,
(curr_inx == field_count));
break;
case PRINT_ALLOWED:
tmp_uint32 = clus_res ? clus_res->allowed : 0;
field->print_routine(
field, &tmp_uint32,
(curr_inx == field_count));
break;
case PRINT_CLUSTER:
tmp_char = clus_res ? clus_res->cluster : NULL;
field->print_routine(
field, tmp_char,
(curr_inx == field_count));
break;
case PRINT_CALLOWED:
if (clus_res) {
if (res->flags & SLURMDB_RES_FLAG_ABSOLUTE)
tmp_uint32 = res->count;
else
tmp_uint32 = (res->count *
clus_res->allowed) / 100;
} else
tmp_uint32 = 0;
field->print_routine(field, &tmp_uint32,
(curr_inx == field_count));
break;
case PRINT_COUNT:
field->print_routine(field,
&res->count,
(curr_inx == field_count));
break;
case PRINT_DESC:
field->print_routine(
field, res->description,
(curr_inx == field_count));
break;
case PRINT_ID:
field->print_routine(
field, &res->id,
(curr_inx == field_count));
break;
case PRINT_FLAGS:
tmp_char = slurmdb_res_flags_str(res->flags);
field->print_routine(
field,
tmp_char,
(curr_inx == field_count));
xfree(tmp_char);
break;
case PRINT_SERVERTYPE:
field->print_routine(field,
res->manager,
(curr_inx == field_count));
break;
case PRINT_NAME:
field->print_routine(
field, res->name,
(curr_inx == field_count));
break;
case PRINT_SERVER:
field->print_routine(field,
res->server,
(curr_inx == field_count));
break;
case PRINT_TYPE:
tmp_char = slurmdb_res_type_str(res->type);
field->print_routine(field,
tmp_char,
(curr_inx == field_count));
tmp_char = NULL;
break;
case PRINT_ALLOCATED:
field->print_routine(
field, &res->allocated,
(curr_inx == field_count));
break;
default:
field->print_routine(
field, NULL,
(curr_inx == field_count));
break;
}
curr_inx++;
}
list_iterator_reset(itr);
printf("\n");
}
extern int sacctmgr_add_res(int argc, char **argv)
{
int rc = SLURM_SUCCESS;
int i = 0;
list_itr_t *itr = NULL;
list_itr_t *clus_itr = NULL;
slurmdb_res_rec_t *res = NULL;
slurmdb_res_rec_t *found_res = NULL;
slurmdb_res_rec_t *start_res = xmalloc(sizeof(slurmdb_res_rec_t));
list_t *cluster_list = list_create(xfree_ptr);
list_t *name_list = list_create(xfree_ptr);
char *name = NULL;
list_t *res_list = NULL;
char *res_str = NULL;
slurmdb_init_res_rec(start_res, 0);
for (i = 0; i < argc; i++) {
int command_len = strlen(argv[i]);
if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))
|| !xstrncasecmp(argv[i], "Set", MAX(command_len, 3)))
i++;
_set_res_rec(&i, argc, argv, name_list, cluster_list,
start_res);
}
if (exit_code) {
FREE_NULL_LIST(name_list);
FREE_NULL_LIST(cluster_list);
slurmdb_destroy_res_rec(start_res);
return SLURM_ERROR;
} else if (!list_count(name_list)) {
FREE_NULL_LIST(name_list);
FREE_NULL_LIST(cluster_list);
slurmdb_destroy_res_rec(start_res);
exit_code = 1;
fprintf(stderr, " Need name of resource to add.\n");
return SLURM_SUCCESS;
}
if (!start_res->server) {
/* assign some server name */
start_res->server = xstrdup("slurmdb");
}
if (!g_res_list) {
slurmdb_res_cond_t res_cond;
slurmdb_init_res_cond(&res_cond, 0);
/* 2 means return all resources even if they don't
have clusters attached to them.
*/
res_cond.with_clusters = 2;
g_res_list = slurmdb_res_get(db_conn, &res_cond);
if (!g_res_list) {
exit_code=1;
fprintf(stderr, " Problem getting system resources "
"from database. "
"Contact your admin.\n");
FREE_NULL_LIST(name_list);
FREE_NULL_LIST(cluster_list);
slurmdb_destroy_res_rec(start_res);
return SLURM_ERROR;
}
}
res_list = list_create(slurmdb_destroy_res_rec);
itr = list_iterator_create(name_list);
if (cluster_list)
clus_itr = list_iterator_create(cluster_list);
while ((name = list_next(itr))) {
bool added = false;
found_res = sacctmgr_find_res_from_list(
g_res_list, NO_VAL, name, start_res->server);
if (!found_res) {
if (start_res->count == NO_VAL) {
exit_code=1;
fprintf(stderr,
" Need to designate a resource "
"count to initially add '%s'.\n", name);
break;
}
res = xmalloc(sizeof(slurmdb_res_rec_t));
slurmdb_init_res_rec(res, 0);
res->name = xstrdup(name);
res->description =
xstrdup(start_res->description ?
start_res->description : name);
res->manager = xstrdup(start_res->manager);
res->server = xstrdup(start_res->server);
res->count = start_res->count;
res->last_consumed = start_res->last_consumed;
res->flags = start_res->flags;
res->type = start_res->type;
res->allocated = 0;
xstrfmtcat(res_str, " %s@%s\n",
res->name, res->server);
list_append(res_list, res);
added = true;
}
if (cluster_list && list_count(cluster_list)) {
list_itr_t *found_itr = NULL;
slurmdb_clus_res_rec_t *clus_res;
char *cluster;
if (found_res) {
if (found_res->clus_res_list)
found_itr = list_iterator_create(
found_res->clus_res_list);
res = xmalloc(sizeof(slurmdb_res_rec_t));
slurmdb_init_res_rec(res, 0);
res->count = found_res->count;
res->last_consumed = found_res->last_consumed;
res->id = found_res->id;
xfree(res->name);
res->name = xstrdup(found_res->name);
res->type = found_res->type;
xfree(res->server);
res->server = xstrdup(found_res->server);
res->flags = found_res->flags;
res->allocated = found_res->allocated;
}
res->clus_res_list = list_create(
slurmdb_destroy_clus_res_rec);
while ((cluster = list_next(clus_itr))) {
clus_res = NULL;
if (found_itr) {
while ((clus_res =
list_next(found_itr))) {
if (!xstrcmp(clus_res->cluster,
cluster))
break;
}
list_iterator_reset(found_itr);
}
if (!clus_res) {
if (!added) {
xstrfmtcat(res_str,
" %s@%s\n", name,
res->server);
list_append(res_list, res);
added = true;
}
clus_res = xmalloc(
sizeof(slurmdb_clus_res_rec_t));
list_append(res->clus_res_list,
clus_res);
clus_res->cluster = xstrdup(cluster);
clus_res->allowed =
start_res->allocated;
xstrfmtcat(res_str,
" Cluster - %s\t%u\n",
cluster,
clus_res->allowed);
}
}
if (!added)
slurmdb_destroy_res_rec(res);
if (found_itr)
list_iterator_destroy(found_itr);
list_iterator_reset(clus_itr);
}
}
if (cluster_list)
list_iterator_destroy(clus_itr);
list_iterator_destroy(itr);
FREE_NULL_LIST(name_list);
FREE_NULL_LIST(cluster_list);
if (exit_code) {
rc = SLURM_ERROR;
goto end_it;
}
if (!list_count(res_list)) {
printf(" Nothing new added.\n");
rc = SLURM_ERROR;
goto end_it;
}
if (res_str) {
char *tmp_str;
switch (res->type) {
case SLURMDB_RESOURCE_LICENSE:
tmp_str = "License";
break;
default:
tmp_str = "Unknown";
}
printf(" Adding Resource(s)\n%s", res_str);
printf(" Settings\n");
if (res->name)
printf(" Name = %s\n", res->name);
if (res->server)
printf(" Server = %s\n", res->server);
if (res->description)
printf(" Description = %s\n", res->description);
if (res->manager)
printf(" ServerType = %s\n", res->manager);
if (res->count != NO_VAL)
printf(" Count = %u\n", res->count);
if (res->last_consumed != NO_VAL)
printf(" LastConsumed = %u\n", res->last_consumed);
if (!(res->flags & SLURMDB_RES_FLAG_NOTSET)) {
char *res_tmp_str = slurmdb_res_flags_str(res->flags);
printf(" Flags = %s\n", res_tmp_str);
xfree(res_tmp_str);
}
printf(" Type = %s\n", tmp_str);
xfree(res_str);
}
if (list_count(res_list)) {
notice_thread_init();
rc = slurmdb_res_add(db_conn, res_list);
notice_thread_fini();
} else
goto end_it;
if (rc == SLURM_SUCCESS) {
if (commit_check("Would you like to commit changes?")) {
rc = slurmdb_connection_commit(db_conn, 1);
if (rc != SLURM_SUCCESS)
fprintf(stderr, " Error committing changes: %s\n",
slurm_strerror(rc));
} else {
printf(" Changes Discarded\n");
rc = slurmdb_connection_commit(db_conn, 0);
if (rc != SLURM_SUCCESS)
fprintf(stderr, " Error rolling back changes: %s\n",
slurm_strerror(rc));
}
} else {
exit_code = 1;
fprintf(stderr, " Problem adding system resource: %s\n",
slurm_strerror(rc));
rc = SLURM_ERROR;
}
end_it:
FREE_NULL_LIST(res_list);
slurmdb_destroy_res_rec(start_res);
return rc;
}
extern int sacctmgr_list_res(int argc, char **argv)
{
int rc = SLURM_SUCCESS;
slurmdb_res_cond_t *res_cond = xmalloc(sizeof(slurmdb_res_cond_t));
int i=0;
list_itr_t *itr = NULL;
list_itr_t *itr2 = NULL;
slurmdb_res_rec_t *res = NULL;
slurmdb_clus_res_rec_t *clus_res = NULL;
list_t *res_list = NULL;
int field_count = 0;
list_t *format_list = list_create(xfree_ptr);
list_t *print_fields_list; /* types are of print_field_t */
slurmdb_init_res_cond(res_cond, 0);
for (i=0; i<argc; i++) {
int command_len = strlen(argv[i]);
if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))
|| !xstrncasecmp(argv[i], "Set", MAX(command_len, 3)))
i++;
_set_res_cond(&i, argc, argv, res_cond, format_list);
}
if (exit_code) {
slurmdb_destroy_res_cond(res_cond);
FREE_NULL_LIST(format_list);
return SLURM_ERROR;
} else if (!list_count(format_list)) {
slurm_addto_char_list(
format_list,
"Name,Server,Type,Count,LastConsumed,Allocated,ServerType");
if (res_cond->with_clusters)
slurm_addto_char_list(
format_list, "Cluster,Allowed");
slurm_addto_char_list(format_list, "Flags");
}
print_fields_list = sacctmgr_process_format_list(format_list);
FREE_NULL_LIST(format_list);
if (exit_code) {
rc = SLURM_ERROR;
goto end_it;
}
res_list = slurmdb_res_get(db_conn, res_cond);
if (!res_list) {
exit_code=1;
fprintf(stderr, " Problem with query.\n");
rc = SLURM_ERROR;
goto end_it;
}
itr = list_iterator_create(res_list);
itr2 = list_iterator_create(print_fields_list);
print_fields_header(print_fields_list);
field_count = list_count(print_fields_list);
while ((res = list_next(itr))) {
if (res_cond->with_clusters && res->clus_res_list
&& list_count(res->clus_res_list)) {
list_itr_t *clus_itr = list_iterator_create(
res->clus_res_list);
while ((clus_res = list_next(clus_itr))) {
_print_res_format(res, clus_res,
itr2, field_count);
}
list_iterator_destroy(clus_itr);
} else
_print_res_format(res, NULL, itr2, field_count);
}
list_iterator_destroy(itr2);
list_iterator_destroy(itr);
FREE_NULL_LIST(res_list);
end_it:
FREE_NULL_LIST(print_fields_list);
slurmdb_destroy_res_cond(res_cond);
return rc;
}
extern int sacctmgr_modify_res(int argc, char **argv)
{
int rc = SLURM_SUCCESS;
slurmdb_res_cond_t *res_cond =
xmalloc(sizeof(slurmdb_res_cond_t));
slurmdb_res_rec_t *res =
xmalloc(sizeof(slurmdb_res_rec_t));
int i=0;
int cond_set = 0, rec_set = 0, set = 0;
list_t *ret_list = NULL;
slurmdb_init_res_cond(res_cond, 0);
slurmdb_init_res_rec(res, 0);
for (i=0; i<argc; i++) {
int command_len = strlen(argv[i]);
if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))) {
i++;
cond_set += _set_res_cond(&i, argc, argv,
res_cond, NULL);
} else if (!xstrncasecmp(argv[i], "Set", MAX(command_len, 3))) {
i++;
rec_set += _set_res_rec(&i, argc, argv,
NULL, NULL, res);
} else {
cond_set += _set_res_cond(&i, argc, argv,
res_cond, NULL);
}
}
if (exit_code) {
slurmdb_destroy_res_cond(res_cond);
slurmdb_destroy_res_rec(res);
return SLURM_ERROR;
} else if (!rec_set) {
exit_code=1;
fprintf(stderr, " You didn't give me anything to set\n");
slurmdb_destroy_res_cond(res_cond);
slurmdb_destroy_res_rec(res);
return SLURM_ERROR;
} else if (!cond_set) {
if (!commit_check("You didn't set any conditions with "
"'WHERE'.\n"
"Are you sure you want to continue?")) {
printf("Aborted\n");
slurmdb_destroy_res_cond(res_cond);
slurmdb_destroy_res_rec(res);
return SLURM_SUCCESS;
}
}
if (res->count != NO_VAL && res_cond->cluster_list &&
list_count(res_cond->cluster_list)) {
fprintf(stderr, "Can't change \"count\" on a cluster-based "
"resource. Remove cluster selection.\n");
return SLURM_ERROR;
} else if (res->last_consumed != NO_VAL && res_cond->cluster_list &&
list_count(res_cond->cluster_list)) {
fprintf(stderr, "Can't change \"lastconsumed\" on a cluster-based resource. Remove cluster selection.\n");
return SLURM_ERROR;
} else if ((res->allocated != NO_VAL) && !res_cond->cluster_list) {
fprintf(stderr, "Can't change \"allowed\" without "
"specifying a cluster.\n");
return SLURM_ERROR;
}
notice_thread_init();
ret_list = slurmdb_res_modify(db_conn, res_cond, res);
notice_thread_fini();
if (ret_list && list_count(ret_list)) {
char *object = NULL;
list_itr_t *itr = list_iterator_create(ret_list);
printf(" Modified server resource ...\n");
while ((object = list_next(itr))) {
printf(" %s\n", object);
}
list_iterator_destroy(itr);
set = 1;
} else if (ret_list) {
printf(" Nothing modified\n");
rc = SLURM_ERROR;
} else if (errno == ESLURM_OVER_ALLOCATE) {
exit_code=1;
rc = SLURM_ERROR;
fprintf(stderr,
" If change was accepted it would look like this...\n");
_print_overcommit(res, res_cond);
} else {
exit_code=1;
fprintf(stderr, " Error with request: %s\n",
slurm_strerror(errno));
rc = SLURM_ERROR;
}
if (set) {
if (commit_check("Would you like to commit changes?")) {
rc = slurmdb_connection_commit(db_conn, 1);
if (rc != SLURM_SUCCESS)
fprintf(stderr, " Error committing changes: %s\n",
slurm_strerror(rc));
} else {
printf(" Changes Discarded\n");
rc = slurmdb_connection_commit(db_conn, 0);
if (rc != SLURM_SUCCESS)
fprintf(stderr, " Error rolling back changes: %s\n",
slurm_strerror(rc));
}
}
FREE_NULL_LIST(ret_list);
slurmdb_destroy_res_cond(res_cond);
slurmdb_destroy_res_rec(res);
return rc;
}
extern int sacctmgr_delete_res(int argc, char **argv)
{
int rc = SLURM_SUCCESS;
slurmdb_res_cond_t *res_cond = xmalloc(sizeof(slurmdb_res_cond_t));
int i=0;
list_t *ret_list = NULL;
list_itr_t *itr = NULL;
int set = 0;
char *name = NULL;
slurmdb_init_res_cond(res_cond, 0);
for (i=0; i<argc; i++) {
int command_len = strlen(argv[i]);
if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))
|| !xstrncasecmp(argv[i], "Set", MAX(command_len, 3)))
i++;
set += _set_res_cond(&i, argc, argv, res_cond, NULL);
}
if (!set) {
exit_code=1;
fprintf(stderr,
" No conditions given to remove, not executing.\n");
slurmdb_destroy_res_cond(res_cond);
return SLURM_ERROR;
} else if (set == -1) {
slurmdb_destroy_res_cond(res_cond);
return SLURM_ERROR;
}
notice_thread_init();
ret_list = slurmdb_res_remove(db_conn, res_cond);
notice_thread_fini();
slurmdb_destroy_res_cond(res_cond);
if (ret_list && list_count(ret_list)) {
itr = list_iterator_create(ret_list);
printf(" Deleting resource(s)...\n");
while ((name = list_next(itr))) {
printf(" %s\n", name);
}
list_iterator_destroy(itr);
if (commit_check("Would you like to commit changes?")) {
rc = slurmdb_connection_commit(db_conn, 1);
if (rc != SLURM_SUCCESS)
fprintf(stderr, " Error committing changes: %s\n",
slurm_strerror(rc));
} else {
printf(" Changes Discarded\n");
rc = slurmdb_connection_commit(db_conn, 0);
if (rc != SLURM_SUCCESS)
fprintf(stderr, " Error rolling back changes: %s\n",
slurm_strerror(rc));
}
} 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;
}
FREE_NULL_LIST(ret_list);
xfree(name);
return rc;
}