1 /****************************************************************************\
2 * resource_functions.c - functions dealing with resources in the
3 * accounting system.
4 *****************************************************************************
5 * Copyright (C) 2013 Bull S. A. S.
6 * Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois.
7 *
8 * Written by Bill Brophy <bill.brophy@bull.com>
9 *
10 * This file is part of Slurm, a resource management program.
11 * For details, see <https://slurm.schedmd.com>.
12 * Please also read the included file: DISCLAIMER.
13 *
14 * Slurm is free software; you can redistribute it and/or modify it under
15 * the terms of the GNU General Public License as published by the Free
16 * Software Foundation; either version 2 of the License, or (at your option)
17 * any later version.
18 *
19 * In addition, as a special exception, the copyright holders give permission
20 * to link the code of portions of this program with the OpenSSL library under
21 * certain conditions as described in each individual source file, and
22 * distribute linked combinations including the two. You must obey the GNU
23 * General Public License in all respects for all of the code used other than
24 * OpenSSL. If you modify file(s) with this exception, you may extend this
25 * exception to your version of the file(s), but you are not obligated to do
26 * so. If you do not wish to do so, delete this exception statement from your
27 * version. If you delete this exception statement from all source files in
28 * the program, then also delete it here.
29 *
30 * Slurm is distributed in the hope that it will be useful, but WITHOUT ANY
31 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
32 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
33 * details.
34 *
35 * You should have received a copy of the GNU General Public License along
36 * with Slurm; if not, write to the Free Software Foundation, Inc.,
37 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
38 \****************************************************************************/
39
40 #include "src/sacctmgr/sacctmgr.h"
41
_print_overcommit(slurmdb_res_rec_t * res,slurmdb_res_cond_t * res_cond)42 static void _print_overcommit(slurmdb_res_rec_t *res,
43 slurmdb_res_cond_t *res_cond)
44 {
45 List res_list = NULL, cluster_list = NULL;
46 ListIterator itr, clus_itr = NULL, found_clus_itr = NULL;
47 slurmdb_res_rec_t *found_res;
48 slurmdb_clus_res_rec_t *clus_res = NULL;
49 char *cluster;
50
51 if (res->percent_used == NO_VAL16)
52 return;
53
54 /* Don't use the global g_res_list since we are going to
55 * change the contents of this one.
56 */
57 res_cond->with_clusters = 1;
58
59 if (res_cond->cluster_list) {
60 cluster_list = res_cond->cluster_list;
61 res_cond->cluster_list = NULL;
62 }
63
64 res_list = slurmdb_res_get(db_conn, res_cond);
65 if (!res_list) {
66 exit_code=1;
67 fprintf(stderr, " Problem getting system resources "
68 "from database. Contact your admin.\n");
69 return;
70 }
71
72 itr = list_iterator_create(res_list);
73 while ((found_res = list_next(itr))) {
74 int total = 0, percent_allowed;
75 fprintf(stderr, " %s@%s\n",
76 found_res->name, found_res->server);
77 if (cluster_list)
78 clus_itr = list_iterator_create(cluster_list);
79 if (found_res->clus_res_list) {
80 found_clus_itr = list_iterator_create(
81 found_res->clus_res_list);
82 while ((clus_res = list_next(found_clus_itr))) {
83 cluster = NULL;
84 if (clus_itr) {
85 while ((cluster = list_next(clus_itr)))
86 if (!xstrcmp(cluster,
87 clus_res->cluster))
88 break;
89 list_iterator_reset(clus_itr);
90 } else {
91 /*
92 * This means we didn't specify any
93 * clusters (All clusters are
94 * overwritten with the requested
95 * percentage) so just put something
96 * there to get the correct
97 * percent_allowed.
98 */
99 cluster = "nothing";
100 }
101 percent_allowed = cluster ? res->percent_used :
102 clus_res->percent_allowed;
103 total += percent_allowed;
104
105 fprintf(stderr,
106 " Cluster - %s\t %u%%\n",
107 clus_res->cluster,
108 percent_allowed);
109 }
110 } else if (clus_itr) {
111 while ((cluster = list_next(clus_itr))) {
112 total += res->percent_used;
113 fprintf(stderr,
114 " Cluster - %s\t %u%%\n",
115 cluster,
116 res->percent_used);
117 }
118 }
119 if (clus_itr)
120 list_iterator_destroy(clus_itr);
121 if (found_clus_itr)
122 list_iterator_destroy(found_clus_itr);
123 fprintf(stderr, " total\t\t%u%%\n", total);
124 }
125 list_iterator_destroy(itr);
126
127 if (cluster_list) {
128 res_cond->cluster_list = cluster_list;
129 cluster_list = NULL;
130 }
131 }
132
_set_res_cond(int * start,int argc,char ** argv,slurmdb_res_cond_t * res_cond,List format_list)133 static int _set_res_cond(int *start, int argc, char **argv,
134 slurmdb_res_cond_t *res_cond,
135 List format_list)
136 {
137 int i;
138 int set = 0;
139 int end = 0;
140 int command_len = 0;
141
142 if (!res_cond) {
143 error("No res_cond given");
144 return -1;
145 }
146
147 for (i=(*start); i<argc; i++) {
148 end = parse_option_end(argv[i]);
149 if (!end)
150 command_len=strlen(argv[i]);
151 else {
152 command_len=end-1;
153 if (argv[i][end] == '=') {
154 end++;
155 }
156 }
157
158 if (!xstrncasecmp(argv[i], "Set", MAX(command_len, 3))) {
159 i--;
160 break;
161 } else if (!end && !xstrncasecmp(argv[i], "WithDeleted",
162 MAX(command_len, 5))) {
163 res_cond->with_deleted = 1;
164 } else if (!end && !xstrncasecmp(argv[i], "WithClusters",
165 MAX(command_len, 5))) {
166 res_cond->with_clusters = 1;
167 } else if (!end && !xstrncasecmp(argv[i], "where",
168 MAX(command_len, 5))) {
169 continue;
170 } else if (!end
171 || !xstrncasecmp(argv[i], "Names",
172 MAX(command_len, 1))) {
173 if (!res_cond->name_list) {
174 res_cond->name_list = list_create(xfree_ptr);
175 }
176 if (slurm_addto_char_list(res_cond->name_list,
177 argv[i]+end))
178 set = 1;
179 } else if (!end
180 || !xstrncasecmp(argv[i], "Clusters",
181 MAX(command_len, 1))) {
182 if (!res_cond->cluster_list) {
183 res_cond->cluster_list = list_create(xfree_ptr);
184 }
185
186 slurm_addto_char_list(res_cond->cluster_list,
187 argv[i]+end);
188 if (sacctmgr_validate_cluster_list(
189 res_cond->cluster_list) != SLURM_SUCCESS) {
190 exit_code=1;
191 fprintf(stderr,
192 " Need a valid cluster name to "
193 "add a cluster resource.\n");
194 } else
195 set = 1;
196 } else if (!xstrncasecmp(argv[i], "Descriptions",
197 MAX(command_len, 1))) {
198 if (!res_cond->description_list) {
199 res_cond->description_list =
200 list_create(xfree_ptr);
201 }
202 if (slurm_addto_char_list(
203 res_cond->description_list,
204 argv[i]+end))
205 set = 1;
206 } else if (!xstrncasecmp(argv[i], "Format",
207 MAX(command_len, 1))) {
208 if (format_list)
209 slurm_addto_char_list(format_list, argv[i]+end);
210 } else if (!xstrncasecmp(argv[i], "Ids", MAX(command_len, 1))) {
211 ListIterator itr = NULL;
212 char *temp = NULL;
213 uint32_t id = 0;
214
215 if (!res_cond->id_list) {
216 res_cond->id_list = list_create(xfree_ptr);
217 }
218 if (slurm_addto_char_list(res_cond->id_list,
219 argv[i]+end))
220 set = 1;
221
222 /* check to make sure user gave ints here */
223 itr = list_iterator_create(res_cond->id_list);
224 while ((temp = list_next(itr))) {
225 if (get_uint(temp, &id, "RES ID")
226 != SLURM_SUCCESS) {
227 exit_code = 1;
228 list_delete_item(itr);
229 }
230 }
231 list_iterator_destroy(itr);
232 } else if (!xstrncasecmp(argv[i], "PercentAllowed",
233 MAX(command_len, 1))) {
234 if (!res_cond->percent_list) {
235 res_cond->percent_list = list_create(xfree_ptr);
236 }
237 if (slurm_addto_char_list(res_cond->percent_list,
238 argv[i]+end))
239 set = 1;
240 } else if (!xstrncasecmp(argv[i], "ServerType",
241 MAX(command_len, 7))) {
242 if (!res_cond->manager_list) {
243 res_cond->manager_list = list_create(xfree_ptr);
244 }
245 if (slurm_addto_char_list(res_cond->manager_list,
246 argv[i]+end))
247 set = 1;
248 } else if (!xstrncasecmp(argv[i], "Server",
249 MAX(command_len, 2))) {
250 if (!res_cond->server_list) {
251 res_cond->server_list = list_create(xfree_ptr);
252 }
253 if (slurm_addto_char_list(res_cond->server_list,
254 argv[i]+end))
255 set = 1;
256 } else {
257 exit_code=1;
258 fprintf(stderr, " Unknown condition: %s\n"
259 " Use keyword 'set' to modify "
260 "SLURM_PRINT_VALUE\n", argv[i]);
261 }
262 }
263
264 (*start) = i;
265 return set;
266 }
267
_set_res_rec(int * start,int argc,char ** argv,List name_list,List cluster_list,slurmdb_res_rec_t * res)268 static int _set_res_rec(int *start, int argc, char **argv,
269 List name_list, List cluster_list,
270 slurmdb_res_rec_t *res)
271 {
272 int i;
273 int set = 0;
274 int end = 0;
275 int command_len = 0;
276 int option = 0;
277
278 xassert(res);
279
280 for (i=(*start); i<argc; i++) {
281 end = parse_option_end(argv[i]);
282 if (!end)
283 command_len=strlen(argv[i]);
284 else {
285 command_len=end-1;
286 if (argv[i][end] == '=') {
287 option = (int)argv[i][end-1];
288 end++;
289 }
290 }
291
292 if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))) {
293 i--;
294 break;
295 } else if (!end && !xstrncasecmp(argv[i], "set",
296 MAX(command_len, 3))) {
297 continue;
298 } else if (!end
299 || !xstrncasecmp(argv[i], "Names",
300 MAX(command_len, 1))
301 || !xstrncasecmp(argv[i], "Resources",
302 MAX(command_len, 1))) {
303 if (name_list)
304 slurm_addto_char_list(name_list, argv[i]+end);
305 } else if (!xstrncasecmp(argv[i], "Clusters",
306 MAX(command_len, 1))) {
307 if (cluster_list) {
308 slurm_addto_char_list(cluster_list,
309 argv[i]+end);
310 if (sacctmgr_validate_cluster_list(
311 cluster_list) != SLURM_SUCCESS) {
312 exit_code=1;
313 fprintf(stderr,
314 " Need a valid cluster name to "
315 "add a cluster resource.\n");
316 }
317 } else {
318 exit_code=1;
319 fprintf(stderr,
320 " Can't modify the cluster "
321 "of an resource\n");
322 }
323 } else if (!xstrncasecmp(argv[i], "Count",
324 MAX(command_len, 3))) {
325 if (get_uint(argv[i]+end, &res->count,
326 "count") == SLURM_SUCCESS) {
327 set = 1;
328 }
329 } else if (!xstrncasecmp(argv[i], "Description",
330 MAX(command_len, 1))) {
331 if (!res->description)
332 res->description =
333 strip_quotes(argv[i]+end, NULL, 1);
334 set = 1;
335 } else if (!xstrncasecmp(argv[i], "Flags",
336 MAX(command_len, 2))) {
337 res->flags = str_2_res_flags(argv[i]+end, option);
338 if (res->flags == SLURMDB_RES_FLAG_NOTSET) {
339 char *tmp_char = slurmdb_res_flags_str(
340 SLURMDB_RES_FLAG_BASE);
341 printf(" Unknown Server Resource flag used "
342 "in:\n '%s'\n"
343 " Valid Server Resource flags are\n"
344 " '%s'\n", argv[i]+end, tmp_char);
345 xfree(tmp_char);
346 exit_code = 1;
347 } else
348 set = 1;
349
350 } else if (!xstrncasecmp(argv[i], "Server",
351 MAX(command_len, 1))) {
352 if (!res->server) {
353 res->server=
354 strip_quotes(argv[i]+end, NULL, 1);
355 }
356 set = 1;
357 } else if (!xstrncasecmp(argv[i], "ServerType",
358 MAX(command_len, 1))) {
359 if (!res->manager)
360 res->manager =
361 strip_quotes(argv[i]+end, NULL, 1);
362 set = 1;
363 } else if (!xstrncasecmp(argv[i], "PercentAllowed",
364 MAX(command_len, 1))) {
365 /* overload percent_used here */
366 if (get_uint16(argv[i]+end, &res->percent_used,
367 "PercentAllowed") == SLURM_SUCCESS) {
368 set = 1;
369 }
370 } else if (!xstrncasecmp(argv[i], "Type",
371 MAX(command_len, 1))) {
372 char *temp = strip_quotes(argv[i]+end, NULL, 1);
373
374 if (!xstrncasecmp("License", temp,
375 MAX(strlen(temp), 1))) {
376 res->type = SLURMDB_RESOURCE_LICENSE;
377 } else {
378 exit_code = 1;
379 fprintf(stderr,
380 " Unknown resource type: '%s' "
381 "Valid resources is License.\n",
382 temp);
383 }
384 xfree(temp);
385 } else {
386 exit_code = 1;
387 printf(" Unknown option: %s\n"
388 " Use keyword 'where' to modify condition\n",
389 argv[i]);
390 }
391 }
392
393 (*start) = i;
394
395 return set;
396 }
397
_print_res_format(slurmdb_res_rec_t * res,slurmdb_clus_res_rec_t * clus_res,ListIterator itr,int field_count)398 static void _print_res_format(slurmdb_res_rec_t *res,
399 slurmdb_clus_res_rec_t *clus_res,
400 ListIterator itr,
401 int field_count)
402 {
403 int curr_inx = 1;
404 char *tmp_char;
405 print_field_t *field = NULL;
406 uint32_t count;
407
408 xassert(itr);
409 xassert(res);
410
411 while ((field = list_next(itr))) {
412 switch(field->type) {
413 case PRINT_ALLOWED:
414 field->print_routine(
415 field, clus_res ? clus_res->percent_allowed : 0,
416 (curr_inx == field_count));
417 break;
418 case PRINT_CLUSTER:
419 field->print_routine(
420 field, clus_res ? clus_res->cluster : NULL,
421 (curr_inx == field_count));
422 break;
423 case PRINT_CALLOWED:
424 if (clus_res)
425 count = (res->count *
426 clus_res->percent_allowed) / 100;
427 else
428 count = 0;
429 field->print_routine(field, count,
430 (curr_inx == field_count));
431 break;
432 case PRINT_COUNT:
433 field->print_routine(field,
434 res->count,
435 (curr_inx == field_count));
436 break;
437 case PRINT_DESC:
438 field->print_routine(
439 field, res->description,
440 (curr_inx == field_count));
441 break;
442 case PRINT_ID:
443 field->print_routine(
444 field, res->id,
445 (curr_inx == field_count));
446 break;
447 case PRINT_FLAGS:
448 tmp_char = slurmdb_res_flags_str(res->flags);
449 field->print_routine(
450 field,
451 tmp_char,
452 (curr_inx == field_count));
453 xfree(tmp_char);
454 break;
455 case PRINT_SERVERTYPE:
456 field->print_routine(field,
457 res->manager,
458 (curr_inx == field_count));
459 break;
460 case PRINT_NAME:
461 field->print_routine(
462 field, res->name,
463 (curr_inx == field_count));
464 break;
465 case PRINT_SERVER:
466 field->print_routine(field,
467 res->server,
468 (curr_inx == field_count));
469 break;
470 case PRINT_TYPE:
471 field->print_routine(field,
472 slurmdb_res_type_str(
473 res->type),
474 (curr_inx == field_count));
475 break;
476 case PRINT_ALLOCATED:
477 field->print_routine(
478 field, res->percent_used,
479 (curr_inx == field_count));
480 break;
481 default:
482 field->print_routine(
483 field, NULL,
484 (curr_inx == field_count));
485 break;
486 }
487 curr_inx++;
488 }
489 list_iterator_reset(itr);
490 printf("\n");
491 }
492
sacctmgr_add_res(int argc,char ** argv)493 extern int sacctmgr_add_res(int argc, char **argv)
494
495 {
496 int rc = SLURM_SUCCESS;
497 int i = 0, limit_set = 0;
498 ListIterator itr = NULL;
499 ListIterator clus_itr = NULL;
500 slurmdb_res_rec_t *res = NULL;
501 slurmdb_res_rec_t *found_res = NULL;
502 slurmdb_res_rec_t *start_res = xmalloc(sizeof(slurmdb_res_rec_t));
503 List cluster_list = list_create(xfree_ptr);
504 List name_list = list_create(xfree_ptr);
505 char *name = NULL;
506 List res_list = NULL;
507 char *res_str = NULL;
508
509 slurmdb_init_res_rec(start_res, 0);
510
511 for (i = 0; i < argc; i++) {
512 int command_len = strlen(argv[i]);
513 if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))
514 || !xstrncasecmp(argv[i], "Set", MAX(command_len, 3)))
515 i++;
516
517 limit_set += _set_res_rec(&i, argc, argv, name_list,
518 cluster_list, start_res);
519 }
520
521 if (exit_code) {
522 FREE_NULL_LIST(name_list);
523 FREE_NULL_LIST(cluster_list);
524 slurmdb_destroy_res_rec(start_res);
525 return SLURM_ERROR;
526 } else if (!list_count(name_list)) {
527 FREE_NULL_LIST(name_list);
528 FREE_NULL_LIST(cluster_list);
529 slurmdb_destroy_res_rec(start_res);
530 exit_code = 1;
531 fprintf(stderr, " Need name of resource to add.\n");
532 return SLURM_SUCCESS;
533 }
534
535 if (!start_res->server) {
536 /* assign some server name */
537 start_res->server = xstrdup("slurmdb");
538 }
539
540 if (!g_res_list) {
541 slurmdb_res_cond_t res_cond;
542 slurmdb_init_res_cond(&res_cond, 0);
543 /* 2 means return all resources even if they don't
544 have clusters attached to them.
545 */
546 res_cond.with_clusters = 2;
547 g_res_list = slurmdb_res_get(db_conn, &res_cond);
548 if (!g_res_list) {
549 exit_code=1;
550 fprintf(stderr, " Problem getting system resources "
551 "from database. "
552 "Contact your admin.\n");
553 FREE_NULL_LIST(name_list);
554 FREE_NULL_LIST(cluster_list);
555 slurmdb_destroy_res_rec(start_res);
556 return SLURM_ERROR;
557 }
558 }
559
560 res_list = list_create(slurmdb_destroy_res_rec);
561
562 itr = list_iterator_create(name_list);
563 if (cluster_list)
564 clus_itr = list_iterator_create(cluster_list);
565 while ((name = list_next(itr))) {
566 bool added = false;
567 found_res = sacctmgr_find_res_from_list(
568 g_res_list, NO_VAL, name, start_res->server);
569 if (!found_res) {
570 if (start_res->type == SLURMDB_RESOURCE_NOTSET) {
571 exit_code=1;
572 fprintf(stderr,
573 " Need to designate a resource "
574 "type to initially add '%s'.\n", name);
575 break;
576
577 } else if (start_res->count == NO_VAL) {
578 exit_code=1;
579 fprintf(stderr,
580 " Need to designate a resource "
581 "count to initially add '%s'.\n", name);
582 break;
583 }
584 res = xmalloc(sizeof(slurmdb_res_rec_t));
585 slurmdb_init_res_rec(res, 0);
586 res->name = xstrdup(name);
587 res->description =
588 xstrdup(start_res->description ?
589 start_res->description : name);
590 res->manager = xstrdup(start_res->manager);
591 res->server = xstrdup(start_res->server);
592 res->count = start_res->count;
593 res->flags = start_res->flags;
594 res->type = start_res->type;
595 res->percent_used = 0;
596
597 xstrfmtcat(res_str, " %s@%s\n",
598 res->name, res->server);
599 list_append(res_list, res);
600 added = true;
601 }
602
603 if (cluster_list && list_count(cluster_list)) {
604 ListIterator found_itr = NULL;
605 slurmdb_clus_res_rec_t *clus_res;
606 char *cluster;
607 uint16_t start_used = 0;
608
609 if (found_res) {
610 if (found_res->clus_res_list)
611 found_itr = list_iterator_create(
612 found_res->clus_res_list);
613 res = xmalloc(sizeof(slurmdb_res_rec_t));
614 slurmdb_init_res_rec(res, 0);
615 res->id = found_res->id;
616 res->type = found_res->type;
617 res->server = xstrdup(found_res->server);
618 start_used = res->percent_used =
619 found_res->percent_used;
620 }
621
622 res->clus_res_list = list_create(
623 slurmdb_destroy_clus_res_rec);
624
625 while ((cluster = list_next(clus_itr))) {
626 clus_res = NULL;
627 if (found_itr) {
628 while ((clus_res =
629 list_next(found_itr))) {
630 if (!xstrcmp(clus_res->cluster,
631 cluster))
632 break;
633 }
634 list_iterator_reset(found_itr);
635 }
636
637 if (!clus_res) {
638 if (!added) {
639 xstrfmtcat(res_str,
640 " %s@%s\n", name,
641 res->server);
642 list_append(res_list, res);
643 added = true;
644 }
645 /* make sure we don't overcommit */
646 res->percent_used +=
647 start_res->percent_used;
648 if (res->percent_used > 100) {
649 exit_code = 1;
650 fprintf(stderr,
651 " Adding this %d "
652 "clusters to resource "
653 "%s@%s at %u%% each "
654 ", with %u%% already "
655 "used, would go over "
656 "100%%. Please redo "
657 "your math and "
658 "resubmit.\n",
659 list_count(
660 cluster_list),
661 res->name, res->server,
662 start_res->percent_used,
663 start_used);
664 break;
665 }
666 clus_res = xmalloc(
667 sizeof(slurmdb_clus_res_rec_t));
668 list_append(res->clus_res_list,
669 clus_res);
670 clus_res->cluster = xstrdup(cluster);
671 clus_res->percent_allowed =
672 start_res->percent_used;
673 xstrfmtcat(res_str,
674 " Cluster - %s\t%u%%\n",
675 cluster,
676 clus_res->percent_allowed);
677 /* FIXME: make sure we don't
678 overcommit */
679 }
680 }
681
682 if (!added)
683 slurmdb_destroy_res_rec(res);
684
685 if (found_itr)
686 list_iterator_destroy(found_itr);
687
688 if (added && (res->percent_used > 100))
689 break;
690
691 list_iterator_reset(clus_itr);
692 }
693 }
694
695 if (cluster_list)
696 list_iterator_destroy(clus_itr);
697
698 list_iterator_destroy(itr);
699
700 FREE_NULL_LIST(name_list);
701 FREE_NULL_LIST(cluster_list);
702
703 if (exit_code) {
704 rc = SLURM_ERROR;
705 goto end_it;
706 }
707
708 if (!list_count(res_list)) {
709 printf(" Nothing new added.\n");
710 rc = SLURM_ERROR;
711 goto end_it;
712 }
713
714 if (res_str) {
715 char *tmp_str;
716 switch (res->type) {
717 case SLURMDB_RESOURCE_LICENSE:
718 tmp_str = "License";
719 break;
720 default:
721 tmp_str = "Unknown";
722 }
723 printf(" Adding Resource(s)\n%s", res_str);
724 printf(" Settings\n");
725 if (res->name)
726 printf(" Name = %s\n", res->name);
727 if (res->server)
728 printf(" Server = %s\n", res->server);
729 if (res->description)
730 printf(" Description = %s\n", res->description);
731 if (res->manager)
732 printf(" ServerType = %s\n", res->manager);
733 if (res->count != NO_VAL)
734 printf(" Count = %u\n", res->count);
735 printf(" Type = %s\n", tmp_str);
736
737 xfree(res_str);
738 }
739
740 if (list_count(res_list)) {
741 notice_thread_init();
742 rc = slurmdb_res_add(db_conn, res_list);
743 notice_thread_fini();
744 } else
745 goto end_it;
746 if (rc == SLURM_SUCCESS) {
747 if (commit_check("Would you like to commit changes?")) {
748 slurmdb_connection_commit(db_conn, 1);
749 } else {
750 printf(" Changes Discarded\n");
751 slurmdb_connection_commit(db_conn, 0);
752 }
753 } else {
754 exit_code = 1;
755 fprintf(stderr, " Problem adding system resource: %s\n",
756 slurm_strerror(rc));
757 rc = SLURM_ERROR;
758 }
759
760 end_it:
761 FREE_NULL_LIST(res_list);
762 slurmdb_destroy_res_rec(start_res);
763 return rc;
764 }
765
sacctmgr_list_res(int argc,char ** argv)766 extern int sacctmgr_list_res(int argc, char **argv)
767
768 {
769 int rc = SLURM_SUCCESS;
770 slurmdb_res_cond_t *res_cond = xmalloc(sizeof(slurmdb_res_cond_t));
771 int i=0;
772 ListIterator itr = NULL;
773 ListIterator itr2 = NULL;
774 slurmdb_res_rec_t *res = NULL;
775 slurmdb_clus_res_rec_t *clus_res = NULL;
776 List res_list = NULL;
777 int field_count = 0;
778 List format_list = list_create(xfree_ptr);
779 List print_fields_list; /* types are of print_field_t */
780
781 slurmdb_init_res_cond(res_cond, 0);
782
783 for (i=0; i<argc; i++) {
784 int command_len = strlen(argv[i]);
785 if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))
786 || !xstrncasecmp(argv[i], "Set", MAX(command_len, 3)))
787 i++;
788 _set_res_cond(&i, argc, argv, res_cond, format_list);
789 }
790
791 if (exit_code) {
792 slurmdb_destroy_res_cond(res_cond);
793 FREE_NULL_LIST(format_list);
794 return SLURM_ERROR;
795 } else if (!list_count(format_list)) {
796 slurm_addto_char_list(
797 format_list,
798 "Name,Server,Type,Count,Allocated,ServerType");
799 if (res_cond->with_clusters)
800 slurm_addto_char_list(
801 format_list, "Cluster,Allowed");
802 }
803
804 print_fields_list = sacctmgr_process_format_list(format_list);
805 FREE_NULL_LIST(format_list);
806
807 if (exit_code) {
808 rc = SLURM_ERROR;
809 goto end_it;
810 }
811 res_list = slurmdb_res_get(db_conn, res_cond);
812
813 if (!res_list) {
814 exit_code=1;
815 fprintf(stderr, " Problem with query.\n");
816 rc = SLURM_ERROR;
817 goto end_it;
818 }
819 itr = list_iterator_create(res_list);
820 itr2 = list_iterator_create(print_fields_list);
821 print_fields_header(print_fields_list);
822
823 field_count = list_count(print_fields_list);
824 while ((res = list_next(itr))) {
825 if (res_cond->with_clusters && res->clus_res_list
826 && list_count(res->clus_res_list)) {
827 ListIterator clus_itr = list_iterator_create(
828 res->clus_res_list);
829 while ((clus_res = list_next(clus_itr))) {
830 _print_res_format(res, clus_res,
831 itr2, field_count);
832 }
833 list_iterator_destroy(clus_itr);
834 } else
835 _print_res_format(res, NULL, itr2, field_count);
836
837 }
838 list_iterator_destroy(itr2);
839 list_iterator_destroy(itr);
840 FREE_NULL_LIST(res_list);
841 end_it:
842 FREE_NULL_LIST(print_fields_list);
843 slurmdb_destroy_res_cond(res_cond);
844 return rc;
845 }
846
sacctmgr_modify_res(int argc,char ** argv)847 extern int sacctmgr_modify_res(int argc, char **argv)
848
849 {
850 int rc = SLURM_SUCCESS;
851 slurmdb_res_cond_t *res_cond =
852 xmalloc(sizeof(slurmdb_res_cond_t));
853 slurmdb_res_rec_t *res =
854 xmalloc(sizeof(slurmdb_res_rec_t));
855 int i=0;
856 int cond_set = 0, rec_set = 0, set = 0;
857 List ret_list = NULL;
858
859 slurmdb_init_res_cond(res_cond, 0);
860 slurmdb_init_res_rec(res, 0);
861
862 for (i=0; i<argc; i++) {
863 int command_len = strlen(argv[i]);
864 if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))) {
865 i++;
866 cond_set += _set_res_cond(&i, argc, argv,
867 res_cond, NULL);
868
869 } else if (!xstrncasecmp(argv[i], "Set", MAX(command_len, 3))) {
870 i++;
871 rec_set += _set_res_rec(&i, argc, argv,
872 NULL, NULL, res);
873 } else {
874 cond_set += _set_res_cond(&i, argc, argv,
875 res_cond, NULL);
876 }
877 }
878
879 if (exit_code) {
880 slurmdb_destroy_res_cond(res_cond);
881 slurmdb_destroy_res_rec(res);
882 return SLURM_ERROR;
883 } else if (!rec_set) {
884 exit_code=1;
885 fprintf(stderr, " You didn't give me anything to set\n");
886 slurmdb_destroy_res_cond(res_cond);
887 slurmdb_destroy_res_rec(res);
888 return SLURM_ERROR;
889 } else if (!cond_set) {
890 if (!commit_check("You didn't set any conditions with "
891 "'WHERE'.\n"
892 "Are you sure you want to continue?")) {
893 printf("Aborted\n");
894 slurmdb_destroy_res_cond(res_cond);
895 slurmdb_destroy_res_rec(res);
896 return SLURM_SUCCESS;
897 }
898 }
899
900 if (res->count != NO_VAL && res_cond->cluster_list &&
901 list_count(res_cond->cluster_list)) {
902 fprintf(stderr, "Can't change \"count\" on a cluster-based "
903 "resource. Remove cluster selection.\n");
904 return SLURM_ERROR;
905 } else if (res->percent_used != NO_VAL16 &&
906 !res_cond->cluster_list) {
907 fprintf(stderr, "Can't change \"percentallowed\" without "
908 "specifying a cluster.\n");
909 return SLURM_ERROR;
910 }
911
912 notice_thread_init();
913 ret_list = slurmdb_res_modify(db_conn, res_cond, res);
914 notice_thread_fini();
915 if (ret_list && list_count(ret_list)) {
916 char *object = NULL;
917 ListIterator itr = list_iterator_create(ret_list);
918 printf(" Modified server resource ...\n");
919 while ((object = list_next(itr))) {
920 printf(" %s\n", object);
921 }
922 list_iterator_destroy(itr);
923 set = 1;
924 } else if (ret_list) {
925 printf(" Nothing modified\n");
926 rc = SLURM_ERROR;
927 } else if (errno == ESLURM_OVER_ALLOCATE) {
928 exit_code=1;
929 rc = SLURM_ERROR;
930 fprintf(stderr,
931 " If change was accepted it would look like this...\n");
932 _print_overcommit(res, res_cond);
933
934 } else {
935 exit_code=1;
936 fprintf(stderr, " Error with request: %s\n",
937 slurm_strerror(errno));
938 rc = SLURM_ERROR;
939 }
940
941 if (set) {
942 if (commit_check("Would you like to commit changes?")){
943 slurmdb_connection_commit(db_conn, 1);
944 } else {
945 printf(" Changes Discarded\n");
946 slurmdb_connection_commit(db_conn, 0);
947 }
948 }
949
950 FREE_NULL_LIST(ret_list);
951
952 slurmdb_destroy_res_cond(res_cond);
953 slurmdb_destroy_res_rec(res);
954 return rc;
955 }
956
sacctmgr_delete_res(int argc,char ** argv)957 extern int sacctmgr_delete_res(int argc, char **argv)
958
959 {
960 int rc = SLURM_SUCCESS;
961 slurmdb_res_cond_t *res_cond = xmalloc(sizeof(slurmdb_res_cond_t));
962 int i=0;
963 List ret_list = NULL;
964 ListIterator itr = NULL;
965 int set = 0;
966 char *name = NULL;
967
968 slurmdb_init_res_cond(res_cond, 0);
969
970
971 for (i=0; i<argc; i++) {
972 int command_len = strlen(argv[i]);
973 if (!xstrncasecmp(argv[i], "Where", MAX(command_len, 5))
974 || !xstrncasecmp(argv[i], "Set", MAX(command_len, 3)))
975 i++;
976 set += _set_res_cond(&i, argc, argv, res_cond, NULL);
977 }
978
979 if (!set) {
980 exit_code=1;
981 fprintf(stderr,
982 " No conditions given to remove, not executing.\n");
983 slurmdb_destroy_res_cond(res_cond);
984 return SLURM_ERROR;
985 } else if (set == -1) {
986 slurmdb_destroy_res_cond(res_cond);
987 return SLURM_ERROR;
988 }
989
990 notice_thread_init();
991 ret_list = slurmdb_res_remove(db_conn, res_cond);
992 notice_thread_fini();
993 slurmdb_destroy_res_cond(res_cond);
994
995 if (ret_list && list_count(ret_list)) {
996 itr = list_iterator_create(ret_list);
997 printf(" Deleting resource(s)...\n");
998
999 while ((name = list_next(itr))) {
1000 printf(" %s\n", name);
1001 }
1002 list_iterator_destroy(itr);
1003 if (commit_check("Would you like to commit changes?")) {
1004 slurmdb_connection_commit(db_conn, 1);
1005 } else {
1006 printf(" Changes Discarded\n");
1007 slurmdb_connection_commit(db_conn, 0);
1008 }
1009 } else if (ret_list) {
1010 printf(" Nothing deleted\n");
1011 rc = SLURM_ERROR;
1012 } else {
1013 exit_code=1;
1014 fprintf(stderr, " Error with request: %s\n",
1015 slurm_strerror(errno));
1016 rc = SLURM_ERROR;
1017 }
1018
1019 FREE_NULL_LIST(ret_list);
1020
1021 xfree(name);
1022 return rc;
1023 }
1024