PageRenderTime 54ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/src/sacctmgr/cluster_functions.c

https://github.com/cfenoy/slurm
C | 1179 lines | 1011 code | 105 blank | 63 comment | 214 complexity | 8cc7ee14e887c58e3110c617a78878d8 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
  1. /*****************************************************************************\
  2. * cluster_functions.c - functions dealing with clusters in the
  3. * accounting system.
  4. *****************************************************************************
  5. * Copyright (C) 2002-2007 The Regents of the University of California.
  6. * Copyright (C) 2008-2011 Lawrence Livermore National Security.
  7. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  8. * Written by Danny Auble <da@llnl.gov>
  9. * CODE-OCEC-09-009. All rights reserved.
  10. *
  11. * This file is part of SLURM, a resource management program.
  12. * For details, see <http://www.schedmd.com/slurmdocs/>.
  13. * Please also read the included file: DISCLAIMER.
  14. *
  15. * SLURM is free software; you can redistribute it and/or modify it under
  16. * the terms of the GNU General Public License as published by the Free
  17. * Software Foundation; either version 2 of the License, or (at your option)
  18. * any later version.
  19. *
  20. * In addition, as a special exception, the copyright holders give permission
  21. * to link the code of portions of this program with the OpenSSL library under
  22. * certain conditions as described in each individual source file, and
  23. * distribute linked combinations including the two. You must obey the GNU
  24. * General Public License in all respects for all of the code used other than
  25. * OpenSSL. If you modify file(s) with this exception, you may extend this
  26. * exception to your version of the file(s), but you are not obligated to do
  27. * so. If you do not wish to do so, delete this exception statement from your
  28. * version. If you delete this exception statement from all source files in
  29. * the program, then also delete it here.
  30. *
  31. * SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
  32. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  33. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  34. * details.
  35. *
  36. * You should have received a copy of the GNU General Public License along
  37. * with SLURM; if not, write to the Free Software Foundation, Inc.,
  38. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  39. \*****************************************************************************/
  40. #include "src/sacctmgr/sacctmgr.h"
  41. #include "src/common/uid.h"
  42. static bool with_deleted = 0;
  43. static bool without_limits = 0;
  44. static int _set_cond(int *start, int argc, char *argv[],
  45. slurmdb_cluster_cond_t *cluster_cond,
  46. List format_list)
  47. {
  48. int i;
  49. int c_set = 0;
  50. int a_set = 0;
  51. int end = 0;
  52. int command_len = 0;
  53. with_deleted = 0;
  54. without_limits = 0;
  55. for (i=(*start); i<argc; i++) {
  56. end = parse_option_end(argv[i]);
  57. if(!end)
  58. command_len=strlen(argv[i]);
  59. else {
  60. command_len=end-1;
  61. if (argv[i][end] == '=') {
  62. end++;
  63. }
  64. }
  65. if (!strncasecmp(argv[i], "Set", MAX(command_len, 3))) {
  66. i--;
  67. break;
  68. } else if(!end && !strncasecmp(argv[i], "where",
  69. MAX(command_len, 5))) {
  70. continue;
  71. } else if (!end &&
  72. !strncasecmp(argv[i], "WithDeleted",
  73. MAX(command_len, 5))) {
  74. with_deleted = 1;
  75. } else if (!end && !strncasecmp(argv[i], "WOLimits",
  76. MAX(command_len, 3))) {
  77. without_limits = 1;
  78. } else if(!end || !strncasecmp(argv[i], "Names",
  79. MAX(command_len, 1))
  80. || !strncasecmp(argv[i], "Clusters",
  81. MAX(command_len, 3))) {
  82. if(!cluster_cond->cluster_list)
  83. cluster_cond->cluster_list =
  84. list_create(slurm_destroy_char);
  85. if(slurm_addto_char_list(cluster_cond->cluster_list,
  86. argv[i]+end))
  87. a_set = 1;
  88. } else if (!strncasecmp(argv[i], "Classification",
  89. MAX(command_len, 3))) {
  90. cluster_cond->classification =
  91. str_2_classification(argv[i]+end);
  92. if(cluster_cond->classification)
  93. c_set = 1;
  94. } else if (!strncasecmp(argv[i], "flags",
  95. MAX(command_len, 2))) {
  96. cluster_cond->flags = slurmdb_str_2_cluster_flags(
  97. argv[i]+end);
  98. c_set = 1;
  99. } else if (!strncasecmp(argv[i], "Format",
  100. MAX(command_len, 2))) {
  101. if(format_list)
  102. slurm_addto_char_list(format_list, argv[i]+end);
  103. } else if(!end || !strncasecmp(argv[i], "PluginIDSelect",
  104. MAX(command_len, 1))) {
  105. if(!cluster_cond->plugin_id_select_list)
  106. cluster_cond->plugin_id_select_list =
  107. list_create(slurm_destroy_char);
  108. if(slurm_addto_char_list(
  109. cluster_cond->plugin_id_select_list,
  110. argv[i]+end))
  111. c_set = 1;
  112. } else if(!end || !strncasecmp(argv[i], "RPCVersions",
  113. MAX(command_len, 1))) {
  114. if(!cluster_cond->rpc_version_list)
  115. cluster_cond->rpc_version_list =
  116. list_create(slurm_destroy_char);
  117. if(slurm_addto_char_list(cluster_cond->rpc_version_list,
  118. argv[i]+end))
  119. c_set = 1;
  120. } else {
  121. exit_code=1;
  122. fprintf(stderr, " Unknown condition: %s\n"
  123. " Use keyword 'set' to modify value\n",
  124. argv[i]);
  125. break;
  126. }
  127. }
  128. (*start) = i;
  129. if(c_set && a_set)
  130. return 3;
  131. else if(a_set) {
  132. return 2;
  133. } else if(c_set)
  134. return 1;
  135. return 0;
  136. }
  137. static int _set_rec(int *start, int argc, char *argv[],
  138. List name_list,
  139. slurmdb_association_rec_t *assoc,
  140. uint16_t *classification)
  141. {
  142. int i;
  143. int set = 0;
  144. int end = 0;
  145. int command_len = 0;
  146. int option = 0;
  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. option = (int)argv[i][end-1];
  155. end++;
  156. }
  157. }
  158. if (!strncasecmp(argv[i], "Where", MAX(command_len, 5))) {
  159. i--;
  160. break;
  161. } else if(!end && !strncasecmp(argv[i], "set",
  162. MAX(command_len, 3))) {
  163. continue;
  164. } else if(!end
  165. || !strncasecmp(argv[i], "Names",
  166. MAX(command_len, 1))
  167. || !strncasecmp(argv[i], "Clusters",
  168. MAX(command_len, 3))) {
  169. if(name_list)
  170. slurm_addto_char_list(name_list,
  171. argv[i]+end);
  172. } else if (!strncasecmp(argv[i], "Classification",
  173. MAX(command_len, 3))) {
  174. if(classification) {
  175. *classification =
  176. str_2_classification(argv[i]+end);
  177. if(*classification)
  178. set = 1;
  179. }
  180. } else if (!strncasecmp(argv[i], "GrpCPUMins",
  181. MAX(command_len, 7))) {
  182. exit_code=1;
  183. fprintf(stderr, "GrpCPUMins is not a valid option "
  184. "for the root association of a cluster.\n");
  185. break;
  186. } else if (!strncasecmp(argv[i], "GrpWall",
  187. MAX(command_len, 4))) {
  188. exit_code=1;
  189. fprintf(stderr, "GrpWall is not a valid option "
  190. "for the root association of a cluster.\n");
  191. } else if(!assoc ||
  192. (assoc && !(set = sacctmgr_set_association_rec(
  193. assoc, argv[i], argv[i]+end,
  194. command_len, option)))) {
  195. exit_code=1;
  196. fprintf(stderr, " Unknown option: %s\n"
  197. " Use keyword 'where' to modify condition\n",
  198. argv[i]);
  199. }
  200. }
  201. (*start) = i;
  202. return set;
  203. }
  204. extern int sacctmgr_add_cluster(int argc, char *argv[])
  205. {
  206. int rc = SLURM_SUCCESS;
  207. int i = 0;
  208. slurmdb_cluster_rec_t *cluster = NULL;
  209. List name_list = list_create(slurm_destroy_char);
  210. List cluster_list = NULL;
  211. slurmdb_association_rec_t start_assoc;
  212. int limit_set = 0;
  213. ListIterator itr = NULL, itr_c = NULL;
  214. char *name = NULL;
  215. uint16_t class = 0;
  216. slurmdb_init_association_rec(&start_assoc, 0);
  217. for (i=0; i<argc; i++) {
  218. int command_len = strlen(argv[i]);
  219. if (!strncasecmp(argv[i], "Where", MAX(command_len, 5))
  220. || !strncasecmp(argv[i], "Set", MAX(command_len, 3)))
  221. i++;
  222. limit_set += _set_rec(&i, argc, argv,
  223. name_list, &start_assoc, &class);
  224. }
  225. if(exit_code) {
  226. list_destroy(name_list);
  227. return SLURM_ERROR;
  228. } else if(!list_count(name_list)) {
  229. list_destroy(name_list);
  230. exit_code=1;
  231. fprintf(stderr, " Need name of cluster to add.\n");
  232. return SLURM_ERROR;
  233. } else {
  234. List temp_list = NULL;
  235. slurmdb_cluster_cond_t cluster_cond;
  236. slurmdb_init_cluster_cond(&cluster_cond, 0);
  237. cluster_cond.cluster_list = name_list;
  238. cluster_cond.classification = class;
  239. temp_list = acct_storage_g_get_clusters(db_conn, my_uid,
  240. &cluster_cond);
  241. if(!temp_list) {
  242. exit_code=1;
  243. fprintf(stderr,
  244. " Problem getting clusters from database. "
  245. "Contact your admin.\n");
  246. return SLURM_ERROR;
  247. }
  248. itr_c = list_iterator_create(name_list);
  249. itr = list_iterator_create(temp_list);
  250. while((name = list_next(itr_c))) {
  251. slurmdb_cluster_rec_t *cluster_rec = NULL;
  252. list_iterator_reset(itr);
  253. while((cluster_rec = list_next(itr))) {
  254. if(!strcasecmp(cluster_rec->name, name))
  255. break;
  256. }
  257. if(cluster_rec) {
  258. printf(" This cluster %s already exists. "
  259. "Not adding.\n", name);
  260. list_delete_item(itr_c);
  261. }
  262. }
  263. list_iterator_destroy(itr);
  264. list_iterator_destroy(itr_c);
  265. list_destroy(temp_list);
  266. if(!list_count(name_list)) {
  267. list_destroy(name_list);
  268. return SLURM_ERROR;
  269. }
  270. }
  271. printf(" Adding Cluster(s)\n");
  272. cluster_list = list_create(slurmdb_destroy_cluster_rec);
  273. itr = list_iterator_create(name_list);
  274. while((name = list_next(itr))) {
  275. if(!name[0]) {
  276. exit_code=1;
  277. fprintf(stderr, " No blank names are "
  278. "allowed when adding.\n");
  279. rc = SLURM_ERROR;
  280. continue;
  281. }
  282. cluster = xmalloc(sizeof(slurmdb_cluster_rec_t));
  283. slurmdb_init_cluster_rec(cluster, 0);
  284. list_append(cluster_list, cluster);
  285. cluster->flags = NO_VAL;
  286. cluster->name = xstrdup(name);
  287. cluster->classification = class;
  288. cluster->root_assoc =
  289. xmalloc(sizeof(slurmdb_association_rec_t));
  290. slurmdb_init_association_rec(cluster->root_assoc, 0);
  291. printf(" Name = %s\n", cluster->name);
  292. if(cluster->classification)
  293. printf(" Classification= %s\n",
  294. get_classification_str(cluster->classification));
  295. cluster->root_assoc->def_qos_id = start_assoc.def_qos_id;
  296. cluster->root_assoc->shares_raw = start_assoc.shares_raw;
  297. cluster->root_assoc->grp_cpus = start_assoc.grp_cpus;
  298. cluster->root_assoc->grp_jobs = start_assoc.grp_jobs;
  299. cluster->root_assoc->grp_mem = start_assoc.grp_mem;
  300. cluster->root_assoc->grp_nodes = start_assoc.grp_nodes;
  301. cluster->root_assoc->grp_submit_jobs =
  302. start_assoc.grp_submit_jobs;
  303. cluster->root_assoc->max_cpu_mins_pj =
  304. start_assoc.max_cpu_mins_pj;
  305. cluster->root_assoc->max_cpus_pj = start_assoc.max_cpus_pj;
  306. cluster->root_assoc->max_jobs = start_assoc.max_jobs;
  307. cluster->root_assoc->max_nodes_pj = start_assoc.max_nodes_pj;
  308. cluster->root_assoc->max_submit_jobs =
  309. start_assoc.max_submit_jobs;
  310. cluster->root_assoc->max_wall_pj = start_assoc.max_wall_pj;
  311. cluster->root_assoc->qos_list =
  312. copy_char_list(start_assoc.qos_list);
  313. }
  314. list_iterator_destroy(itr);
  315. list_destroy(name_list);
  316. if(limit_set) {
  317. printf(" Default Limits\n");
  318. sacctmgr_print_assoc_limits(&start_assoc);
  319. if(start_assoc.qos_list)
  320. list_destroy(start_assoc.qos_list);
  321. }
  322. if(!list_count(cluster_list)) {
  323. printf(" Nothing new added.\n");
  324. goto end_it;
  325. }
  326. /* Since we are creating tables with add cluster that can't be
  327. rolled back. So we ask before hand if they are serious
  328. about it so we can rollback if needed.
  329. */
  330. if(commit_check("Would you like to commit changes?")) {
  331. notice_thread_init();
  332. rc = acct_storage_g_add_clusters(db_conn, my_uid, cluster_list);
  333. notice_thread_fini();
  334. if(rc == SLURM_SUCCESS) {
  335. acct_storage_g_commit(db_conn, 1);
  336. } else {
  337. exit_code=1;
  338. fprintf(stderr, " Problem adding clusters: %s\n",
  339. slurm_strerror(rc));
  340. /* this isn't really needed, but just to be safe */
  341. acct_storage_g_commit(db_conn, 0);
  342. }
  343. } else {
  344. printf(" Changes Discarded\n");
  345. /* this isn't really needed, but just to be safe */
  346. acct_storage_g_commit(db_conn, 0);
  347. }
  348. end_it:
  349. list_destroy(cluster_list);
  350. return rc;
  351. }
  352. extern int sacctmgr_list_cluster(int argc, char *argv[])
  353. {
  354. int rc = SLURM_SUCCESS;
  355. slurmdb_cluster_cond_t *cluster_cond =
  356. xmalloc(sizeof(slurmdb_cluster_cond_t));
  357. List cluster_list;
  358. int i=0;
  359. ListIterator itr = NULL;
  360. ListIterator itr2 = NULL;
  361. slurmdb_cluster_rec_t *cluster = NULL;
  362. char *tmp_char = NULL;
  363. int field_count = 0;
  364. print_field_t *field = NULL;
  365. List format_list = list_create(slurm_destroy_char);
  366. List print_fields_list; /* types are of print_field_t */
  367. slurmdb_init_cluster_cond(cluster_cond, 0);
  368. cluster_cond->cluster_list = list_create(slurm_destroy_char);
  369. for (i=0; i<argc; i++) {
  370. int command_len = strlen(argv[i]);
  371. if (!strncasecmp(argv[i], "Where", MAX(command_len, 5))
  372. || !strncasecmp(argv[i], "Set", MAX(command_len, 3)))
  373. i++;
  374. _set_cond(&i, argc, argv, cluster_cond, format_list);
  375. }
  376. if(exit_code) {
  377. slurmdb_destroy_cluster_cond(cluster_cond);
  378. list_destroy(format_list);
  379. return SLURM_ERROR;
  380. }
  381. if(!list_count(format_list)) {
  382. slurm_addto_char_list(format_list,
  383. "Cl,Controlh,Controlp,RPC");
  384. if(!without_limits)
  385. slurm_addto_char_list(format_list,
  386. "Fa,GrpJ,GrpN,GrpS,MaxJ,MaxN,"
  387. "MaxS,MaxW,QOS,DefaultQOS");
  388. }
  389. cluster_cond->with_deleted = with_deleted;
  390. print_fields_list = sacctmgr_process_format_list(format_list);
  391. list_destroy(format_list);
  392. if(exit_code) {
  393. slurmdb_destroy_cluster_cond(cluster_cond);
  394. list_destroy(print_fields_list);
  395. return SLURM_ERROR;
  396. }
  397. cluster_list = acct_storage_g_get_clusters(db_conn, my_uid,
  398. cluster_cond);
  399. slurmdb_destroy_cluster_cond(cluster_cond);
  400. if(!cluster_list) {
  401. exit_code=1;
  402. fprintf(stderr, " Problem with query.\n");
  403. list_destroy(print_fields_list);
  404. return SLURM_ERROR;
  405. }
  406. itr = list_iterator_create(cluster_list);
  407. itr2 = list_iterator_create(print_fields_list);
  408. print_fields_header(print_fields_list);
  409. field_count = list_count(print_fields_list);
  410. while((cluster = list_next(itr))) {
  411. int curr_inx = 1;
  412. slurmdb_association_rec_t *assoc = cluster->root_assoc;
  413. /* set up the working cluster rec so nodecnt's and node names
  414. * are handled correctly */
  415. working_cluster_rec = cluster;
  416. while((field = list_next(itr2))) {
  417. switch(field->type) {
  418. case PRINT_CLUSTER:
  419. field->print_routine(field,
  420. cluster->name,
  421. (curr_inx == field_count));
  422. break;
  423. case PRINT_CHOST:
  424. field->print_routine(field,
  425. cluster->control_host,
  426. (curr_inx == field_count));
  427. break;
  428. case PRINT_CPORT:
  429. field->print_routine(field,
  430. cluster->control_port,
  431. (curr_inx == field_count));
  432. break;
  433. case PRINT_CLASS:
  434. field->print_routine(field,
  435. get_classification_str(
  436. cluster->
  437. classification),
  438. (curr_inx == field_count));
  439. break;
  440. case PRINT_CPUS:
  441. {
  442. char tmp_char[9];
  443. convert_num_unit((float)cluster->cpu_count,
  444. tmp_char, sizeof(tmp_char),
  445. UNIT_NONE);
  446. field->print_routine(field,
  447. tmp_char,
  448. (curr_inx == field_count));
  449. break;
  450. }
  451. case PRINT_DQOS:
  452. if(!g_qos_list) {
  453. g_qos_list = acct_storage_g_get_qos(
  454. db_conn,
  455. my_uid,
  456. NULL);
  457. }
  458. tmp_char = slurmdb_qos_str(g_qos_list,
  459. assoc->def_qos_id);
  460. field->print_routine(
  461. field,
  462. tmp_char,
  463. (curr_inx == field_count));
  464. break;
  465. case PRINT_FAIRSHARE:
  466. field->print_routine(
  467. field,
  468. assoc->shares_raw,
  469. (curr_inx == field_count));
  470. break;
  471. case PRINT_FLAGS:
  472. {
  473. char *tmp_char = slurmdb_cluster_flags_2_str(
  474. cluster->flags);
  475. field->print_routine(
  476. field,
  477. tmp_char,
  478. (curr_inx == field_count));
  479. xfree(tmp_char);
  480. break;
  481. }
  482. case PRINT_GRPC:
  483. field->print_routine(field,
  484. assoc->grp_cpus,
  485. (curr_inx == field_count));
  486. break;
  487. case PRINT_GRPJ:
  488. field->print_routine(field,
  489. assoc->grp_jobs,
  490. (curr_inx == field_count));
  491. break;
  492. case PRINT_GRPMEM:
  493. field->print_routine(field,
  494. assoc->grp_mem,
  495. (curr_inx == field_count));
  496. break;
  497. case PRINT_GRPN:
  498. field->print_routine(field,
  499. assoc->grp_nodes,
  500. (curr_inx == field_count));
  501. break;
  502. case PRINT_GRPS:
  503. field->print_routine(field,
  504. assoc->grp_submit_jobs,
  505. (curr_inx == field_count));
  506. break;
  507. case PRINT_MAXCM:
  508. field->print_routine(
  509. field,
  510. assoc->max_cpu_mins_pj,
  511. (curr_inx == field_count));
  512. break;
  513. case PRINT_MAXC:
  514. field->print_routine(field,
  515. assoc->max_cpus_pj,
  516. (curr_inx == field_count));
  517. break;
  518. case PRINT_MAXJ:
  519. field->print_routine(field,
  520. assoc->max_jobs,
  521. (curr_inx == field_count));
  522. break;
  523. case PRINT_MAXN:
  524. field->print_routine(field,
  525. assoc->max_nodes_pj,
  526. (curr_inx == field_count));
  527. break;
  528. case PRINT_MAXS:
  529. field->print_routine(field,
  530. assoc->max_submit_jobs,
  531. (curr_inx == field_count));
  532. break;
  533. case PRINT_MAXW:
  534. field->print_routine(
  535. field,
  536. assoc->max_wall_pj,
  537. (curr_inx == field_count));
  538. break;
  539. case PRINT_NODECNT:
  540. {
  541. hostlist_t hl = hostlist_create(cluster->nodes);
  542. int cnt = 0;
  543. if(hl) {
  544. cnt = hostlist_count(hl);
  545. hostlist_destroy(hl);
  546. }
  547. field->print_routine(
  548. field,
  549. cnt,
  550. (curr_inx == field_count));
  551. break;
  552. }
  553. case PRINT_CLUSTER_NODES:
  554. field->print_routine(
  555. field,
  556. cluster->nodes,
  557. (curr_inx == field_count));
  558. break;
  559. case PRINT_QOS:
  560. if(!g_qos_list)
  561. g_qos_list = acct_storage_g_get_qos(
  562. db_conn, my_uid, NULL);
  563. field->print_routine(field,
  564. g_qos_list,
  565. assoc->qos_list,
  566. (curr_inx == field_count));
  567. break;
  568. case PRINT_QOS_RAW:
  569. field->print_routine(field,
  570. assoc->qos_list,
  571. (curr_inx == field_count));
  572. break;
  573. case PRINT_RPC_VERSION:
  574. field->print_routine(
  575. field,
  576. cluster->rpc_version,
  577. (curr_inx == field_count));
  578. break;
  579. case PRINT_SELECT:
  580. field->print_routine(
  581. field,
  582. cluster->plugin_id_select,
  583. (curr_inx == field_count));
  584. break;
  585. default:
  586. field->print_routine(
  587. field, NULL,
  588. (curr_inx == field_count));
  589. break;
  590. }
  591. curr_inx++;
  592. }
  593. list_iterator_reset(itr2);
  594. printf("\n");
  595. }
  596. /* clear the working cluster rec */
  597. working_cluster_rec = NULL;
  598. list_iterator_destroy(itr2);
  599. list_iterator_destroy(itr);
  600. list_destroy(cluster_list);
  601. list_destroy(print_fields_list);
  602. return rc;
  603. }
  604. extern int sacctmgr_modify_cluster(int argc, char *argv[])
  605. {
  606. int rc = SLURM_SUCCESS;
  607. int i=0;
  608. slurmdb_association_rec_t *assoc =
  609. xmalloc(sizeof(slurmdb_association_rec_t));
  610. slurmdb_association_cond_t *assoc_cond =
  611. xmalloc(sizeof(slurmdb_association_cond_t));
  612. int cond_set = 0, prev_set = 0, rec_set = 0, set = 0;
  613. List ret_list = NULL;
  614. uint16_t class_rec = 0;
  615. slurmdb_cluster_cond_t cluster_cond;
  616. slurmdb_init_association_rec(assoc, 0);
  617. assoc_cond->cluster_list = list_create(slurm_destroy_char);
  618. assoc_cond->acct_list = list_create(NULL);
  619. slurmdb_init_cluster_cond(&cluster_cond, 0);
  620. cluster_cond.cluster_list = assoc_cond->cluster_list;
  621. for (i=0; i<argc; i++) {
  622. int command_len = strlen(argv[i]);
  623. if (!strncasecmp(argv[i], "Where", MAX(command_len, 5))) {
  624. i++;
  625. prev_set = _set_cond(&i, argc, argv,
  626. &cluster_cond, NULL);
  627. cond_set |= prev_set;
  628. } else if (!strncasecmp(argv[i], "Set", MAX(command_len, 3))) {
  629. i++;
  630. prev_set = _set_rec(&i, argc, argv,
  631. NULL, assoc, &class_rec);
  632. rec_set |= prev_set;
  633. } else {
  634. prev_set = _set_cond(&i, argc, argv,
  635. &cluster_cond, NULL);
  636. cond_set |= prev_set;
  637. }
  638. }
  639. if(!rec_set) {
  640. exit_code=1;
  641. fprintf(stderr, " You didn't give me anything to set\n");
  642. rc = SLURM_ERROR;
  643. goto end_it;
  644. } else if(!cond_set) {
  645. if(!commit_check("You didn't set any conditions with 'WHERE'.\n"
  646. "Are you sure you want to continue?")) {
  647. printf("Aborted\n");
  648. rc = SLURM_SUCCESS;
  649. goto end_it;
  650. }
  651. } else if(exit_code) {
  652. rc = SLURM_ERROR;
  653. goto end_it;
  654. }
  655. if(cond_set & 1) {
  656. List temp_list = NULL;
  657. temp_list = acct_storage_g_get_clusters(db_conn, my_uid,
  658. &cluster_cond);
  659. if(!temp_list) {
  660. exit_code=1;
  661. fprintf(stderr,
  662. " Problem getting clusters from database. "
  663. "Contact your admin.\n");
  664. rc = SLURM_ERROR;
  665. goto end_it;
  666. } else if(!list_count(temp_list)) {
  667. fprintf(stderr,
  668. " Query didn't return any clusters.\n");
  669. rc = SLURM_ERROR;
  670. goto end_it;
  671. }
  672. /* we are only looking for the clusters returned from
  673. this query, so we free the cluster_list and replace
  674. it */
  675. if(assoc_cond->cluster_list)
  676. list_destroy(assoc_cond->cluster_list);
  677. assoc_cond->cluster_list = temp_list;
  678. }
  679. printf(" Setting\n");
  680. if(rec_set) {
  681. printf(" Default Limits =\n");
  682. sacctmgr_print_assoc_limits(assoc);
  683. if(class_rec)
  684. printf(" Cluster Classification = %s\n",
  685. get_classification_str(class_rec));
  686. }
  687. list_append(assoc_cond->acct_list, "root");
  688. notice_thread_init();
  689. ret_list = acct_storage_g_modify_associations(
  690. db_conn, my_uid, assoc_cond, assoc);
  691. if(ret_list && list_count(ret_list)) {
  692. char *object = NULL;
  693. ListIterator itr = list_iterator_create(ret_list);
  694. printf(" Modified cluster defaults for associations...\n");
  695. while((object = list_next(itr))) {
  696. printf(" %s\n", object);
  697. }
  698. list_iterator_destroy(itr);
  699. set = 1;
  700. } else if(ret_list) {
  701. printf(" Nothing modified\n");
  702. } else {
  703. exit_code=1;
  704. fprintf(stderr, " Error with request: %s\n",
  705. slurm_strerror(errno));
  706. rc = SLURM_ERROR;
  707. }
  708. if(ret_list)
  709. list_destroy(ret_list);
  710. if(class_rec) {
  711. slurmdb_cluster_rec_t cluster_rec;
  712. slurmdb_init_cluster_rec(&cluster_rec, 0);
  713. /* the class has already returned these clusters so
  714. just go with it */
  715. cluster_rec.classification = class_rec;
  716. ret_list = acct_storage_g_modify_clusters(
  717. db_conn, my_uid, &cluster_cond, &cluster_rec);
  718. if(ret_list && list_count(ret_list)) {
  719. char *object = NULL;
  720. ListIterator itr = list_iterator_create(ret_list);
  721. printf(" Modified cluster classifications...\n");
  722. while((object = list_next(itr))) {
  723. printf(" %s\n", object);
  724. }
  725. list_iterator_destroy(itr);
  726. set = 1;
  727. } else if(ret_list) {
  728. printf(" Nothing modified\n");
  729. } else {
  730. exit_code=1;
  731. fprintf(stderr, " Error with request: %s\n",
  732. slurm_strerror(errno));
  733. rc = SLURM_ERROR;
  734. }
  735. if(ret_list)
  736. list_destroy(ret_list);
  737. }
  738. notice_thread_fini();
  739. if(set) {
  740. if(commit_check("Would you like to commit changes?"))
  741. acct_storage_g_commit(db_conn, 1);
  742. else {
  743. printf(" Changes Discarded\n");
  744. acct_storage_g_commit(db_conn, 0);
  745. }
  746. }
  747. end_it:
  748. slurmdb_destroy_association_cond(assoc_cond);
  749. slurmdb_destroy_association_rec(assoc);
  750. return rc;
  751. }
  752. extern int sacctmgr_delete_cluster(int argc, char *argv[])
  753. {
  754. int rc = SLURM_SUCCESS;
  755. slurmdb_cluster_cond_t *cluster_cond =
  756. xmalloc(sizeof(slurmdb_cluster_cond_t));
  757. int i=0;
  758. List ret_list = NULL;
  759. int cond_set = 0, prev_set;
  760. slurmdb_init_cluster_cond(cluster_cond, 0);
  761. cluster_cond->cluster_list = list_create(slurm_destroy_char);
  762. for (i=0; i<argc; i++) {
  763. int command_len = strlen(argv[i]);
  764. if (!strncasecmp(argv[i], "Where", MAX(command_len, 5))
  765. || !strncasecmp(argv[i], "Set", MAX(command_len, 3)))
  766. i++;
  767. prev_set = _set_cond(&i, argc, argv, cluster_cond, NULL);
  768. cond_set |= prev_set;
  769. }
  770. if(exit_code) {
  771. slurmdb_destroy_cluster_cond(cluster_cond);
  772. return SLURM_ERROR;
  773. } else if(!cond_set) {
  774. exit_code=1;
  775. fprintf(stderr,
  776. " No conditions given to remove, not executing.\n");
  777. slurmdb_destroy_cluster_cond(cluster_cond);
  778. return SLURM_ERROR;
  779. }
  780. if(!list_count(cluster_cond->cluster_list)
  781. && !cluster_cond->classification) {
  782. exit_code=1;
  783. fprintf(stderr,
  784. "problem with delete request. "
  785. "Nothing given to delete.\n");
  786. slurmdb_destroy_cluster_cond(cluster_cond);
  787. return SLURM_SUCCESS;
  788. }
  789. notice_thread_init();
  790. ret_list = acct_storage_g_remove_clusters(
  791. db_conn, my_uid, cluster_cond);
  792. rc = errno;
  793. notice_thread_fini();
  794. slurmdb_destroy_cluster_cond(cluster_cond);
  795. if(ret_list && list_count(ret_list)) {
  796. char *object = NULL;
  797. ListIterator itr = list_iterator_create(ret_list);
  798. /* If there were jobs running with an association to
  799. be deleted, don't.
  800. */
  801. if(rc == ESLURM_JOBS_RUNNING_ON_ASSOC) {
  802. fprintf(stderr, " Error with request: %s\n",
  803. slurm_strerror(rc));
  804. while((object = list_next(itr))) {
  805. fprintf(stderr," %s\n", object);
  806. }
  807. list_destroy(ret_list);
  808. acct_storage_g_commit(db_conn, 0);
  809. return rc;
  810. }
  811. printf(" Deleting clusters...\n");
  812. while((object = list_next(itr))) {
  813. printf(" %s\n", object);
  814. }
  815. list_iterator_destroy(itr);
  816. if(commit_check("Would you like to commit changes?")) {
  817. acct_storage_g_commit(db_conn, 1);
  818. } else {
  819. printf(" Changes Discarded\n");
  820. acct_storage_g_commit(db_conn, 0);
  821. }
  822. } else if(ret_list) {
  823. printf(" Nothing deleted\n");
  824. } else {
  825. exit_code=1;
  826. fprintf(stderr, " Error with request: %s\n",
  827. slurm_strerror(errno));
  828. rc = SLURM_ERROR;
  829. }
  830. if(ret_list)
  831. list_destroy(ret_list);
  832. return rc;
  833. }
  834. extern int sacctmgr_dump_cluster (int argc, char *argv[])
  835. {
  836. slurmdb_user_cond_t user_cond;
  837. slurmdb_user_rec_t *user = NULL;
  838. slurmdb_hierarchical_rec_t *slurmdb_hierarchical_rec = NULL;
  839. slurmdb_association_rec_t *assoc = NULL;
  840. slurmdb_association_cond_t assoc_cond;
  841. List assoc_list = NULL;
  842. List acct_list = NULL;
  843. List user_list = NULL;
  844. List slurmdb_hierarchical_rec_list = NULL;
  845. char *cluster_name = NULL;
  846. char *file_name = NULL;
  847. char *user_name = NULL;
  848. char *line = NULL;
  849. int i, command_len = 0;
  850. FILE *fd = NULL;
  851. char *class_str = NULL;
  852. for (i = 0; i < argc; i++) {
  853. int end = parse_option_end(argv[i]);
  854. if (!end)
  855. command_len = strlen(argv[i]);
  856. else {
  857. command_len = end - 1;
  858. if (argv[i][end] == '=') {
  859. end++;
  860. }
  861. }
  862. if (!end || !strncasecmp(argv[i], "Cluster",
  863. MAX(command_len, 1))) {
  864. if (cluster_name) {
  865. exit_code = 1;
  866. fprintf(stderr,
  867. " Can only do one cluster at a time. "
  868. "Already doing %s\n", cluster_name);
  869. continue;
  870. }
  871. cluster_name = xstrdup(argv[i]+end);
  872. } else if (!strncasecmp(argv[i], "File",
  873. MAX(command_len, 1))) {
  874. if (file_name) {
  875. exit_code = 1;
  876. fprintf(stderr,
  877. " File name already set to %s\n",
  878. file_name);
  879. continue;
  880. }
  881. file_name = xstrdup(argv[i]+end);
  882. } else {
  883. exit_code = 1;
  884. fprintf(stderr, " Unknown option: %s\n", argv[i]);
  885. }
  886. }
  887. if (!cluster_name) {
  888. exit_code = 1;
  889. fprintf(stderr, " We need a cluster to dump.\n");
  890. xfree(file_name);
  891. return SLURM_ERROR;
  892. } else {
  893. List temp_list = NULL;
  894. slurmdb_cluster_cond_t cluster_cond;
  895. slurmdb_cluster_rec_t *cluster_rec = NULL;
  896. slurmdb_init_cluster_cond(&cluster_cond, 0);
  897. cluster_cond.cluster_list = list_create(NULL);
  898. list_push(cluster_cond.cluster_list, cluster_name);
  899. temp_list = acct_storage_g_get_clusters(db_conn, my_uid,
  900. &cluster_cond);
  901. FREE_NULL_LIST(cluster_cond.cluster_list);
  902. if (!temp_list) {
  903. exit_code = 1;
  904. fprintf(stderr,
  905. " Problem getting clusters from database. "
  906. "Contact your admin.\n");
  907. xfree(cluster_name);
  908. xfree(file_name);
  909. return SLURM_ERROR;
  910. }
  911. cluster_rec = list_peek(temp_list);
  912. if (!cluster_rec) {
  913. exit_code = 1;
  914. fprintf(stderr, " Cluster %s doesn't exist.\n",
  915. cluster_name);
  916. xfree(cluster_name);
  917. xfree(file_name);
  918. FREE_NULL_LIST(temp_list);
  919. return SLURM_ERROR;
  920. }
  921. class_str = get_classification_str(cluster_rec->classification);
  922. FREE_NULL_LIST(temp_list);
  923. }
  924. if (!file_name) {
  925. file_name = xstrdup_printf("./%s.cfg", cluster_name);
  926. printf(" No filename given, using %s.\n", file_name);
  927. }
  928. memset(&user_cond, 0, sizeof(slurmdb_user_cond_t));
  929. user_cond.with_coords = 1;
  930. user_cond.with_wckeys = 1;
  931. user_cond.with_assocs = 1;
  932. memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t));
  933. assoc_cond.without_parent_limits = 1;
  934. assoc_cond.with_raw_qos = 1;
  935. assoc_cond.cluster_list = list_create(NULL);
  936. list_append(assoc_cond.cluster_list, cluster_name);
  937. /* this is needed for getting the correct wckeys */
  938. user_cond.assoc_cond = &assoc_cond;
  939. user_list = acct_storage_g_get_users(db_conn, my_uid, &user_cond);
  940. /* If not running with the DBD assoc_cond.user_list can be set,
  941. * which will mess other things up.
  942. */
  943. if (assoc_cond.user_list) {
  944. FREE_NULL_LIST(assoc_cond.user_list);
  945. assoc_cond.user_list = NULL;
  946. }
  947. /* make sure this person running is an admin */
  948. user_name = uid_to_string(my_uid);
  949. if (!(user = sacctmgr_find_user_from_list(user_list, user_name))) {
  950. exit_code = 1;
  951. fprintf(stderr, " Your uid (%u) is not in the "
  952. "accounting system, can't dump cluster.\n", my_uid);
  953. FREE_NULL_LIST(assoc_cond.cluster_list);
  954. xfree(cluster_name);
  955. xfree(file_name);
  956. FREE_NULL_LIST(user_list);
  957. xfree(user_name);
  958. return SLURM_ERROR;
  959. } else {
  960. if (my_uid != slurm_get_slurm_user_id() && my_uid != 0
  961. && user->admin_level < SLURMDB_ADMIN_SUPER_USER) {
  962. exit_code = 1;
  963. fprintf(stderr, " Your user does not have sufficient "
  964. "privileges to dump clusters.\n");
  965. FREE_NULL_LIST(assoc_cond.cluster_list);
  966. xfree(cluster_name);
  967. xfree(file_name);
  968. FREE_NULL_LIST(user_list);
  969. xfree(user_name);
  970. return SLURM_ERROR;
  971. }
  972. }
  973. xfree(user_name);
  974. /* assoc_cond is set up above */
  975. assoc_list = acct_storage_g_get_associations(db_conn, my_uid,
  976. &assoc_cond);
  977. FREE_NULL_LIST(assoc_cond.cluster_list);
  978. if (!assoc_list) {
  979. exit_code = 1;
  980. fprintf(stderr, " Problem with query.\n");
  981. xfree(cluster_name);
  982. xfree(file_name);
  983. return SLURM_ERROR;
  984. } else if (!list_count(assoc_list)) {
  985. exit_code = 1;
  986. fprintf(stderr, " Cluster %s returned nothing.\n",
  987. cluster_name);
  988. FREE_NULL_LIST(assoc_list);
  989. xfree(cluster_name);
  990. xfree(file_name);
  991. return SLURM_ERROR;
  992. }
  993. slurmdb_hierarchical_rec_list = slurmdb_get_acct_hierarchical_rec_list(
  994. assoc_list);
  995. acct_list = acct_storage_g_get_accounts(db_conn, my_uid, NULL);
  996. if ((fd = fopen(file_name,"w")) == NULL) {
  997. fprintf(stderr, "Can't open file %s, %m\n", file_name);
  998. FREE_NULL_LIST(acct_list);
  999. FREE_NULL_LIST(assoc_list);
  1000. xfree(cluster_name);
  1001. xfree(file_name);
  1002. FREE_NULL_LIST(slurmdb_hierarchical_rec_list);
  1003. return SLURM_ERROR;
  1004. }
  1005. /* Add header */
  1006. if (fprintf(fd,
  1007. "# To edit this file start with a cluster line "
  1008. "for the new cluster\n"
  1009. "# Cluster - cluster_name:MaxNodesPerJob=50\n"
  1010. "# Followed by Accounts you want in this fashion "
  1011. "(root is created by default)...\n"
  1012. "# Parent - root\n"
  1013. "# Account - cs:MaxNodesPerJob=5:MaxJobs=4:"
  1014. "MaxProcSecondsPerJob=20:FairShare=399:"
  1015. "MaxWallDurationPerJob=40:Description='Computer Science':"
  1016. "Organization='LC'\n"
  1017. "# Any of the options after a ':' can be left out and "
  1018. "they can be in any order.\n"
  1019. "# If you want to add any sub accounts just list the "
  1020. "Parent THAT HAS ALREADY \n"
  1021. "# BEEN CREATED before the account line in this "
  1022. "fashion...\n"
  1023. "# Parent - cs\n"
  1024. "# Account - test:MaxNodesPerJob=1:MaxJobs=1:"
  1025. "MaxProcSecondsPerJob=1:FairShare=1:"
  1026. "MaxWallDurationPerJob=1:"
  1027. "Description='Test Account':Organization='Test'\n"
  1028. "# To add users to a account add a line like this after a "
  1029. "Parent - line\n"
  1030. "# User - lipari:MaxNodesPerJob=2:MaxJobs=3:"
  1031. "MaxProcSecondsPerJob=4:FairShare=1:"
  1032. "MaxWallDurationPerJob=1\n") < 0) {
  1033. exit_code = 1;
  1034. fprintf(stderr, "Can't write to file");
  1035. FREE_NULL_LIST(acct_list);
  1036. FREE_NULL_LIST(assoc_list);
  1037. xfree(cluster_name);
  1038. xfree(file_name);
  1039. FREE_NULL_LIST(slurmdb_hierarchical_rec_list);
  1040. return SLURM_ERROR;
  1041. }
  1042. line = xstrdup_printf("Cluster - %s", cluster_name);
  1043. if (class_str)
  1044. xstrfmtcat(line, ":Classification=%s", class_str);
  1045. slurmdb_hierarchical_rec = list_peek(slurmdb_hierarchical_rec_list);
  1046. assoc = slurmdb_hierarchical_rec->assoc;
  1047. if (strcmp(assoc->acct, "root")) {
  1048. fprintf(stderr, "Root association not on the top it was %s\n",
  1049. assoc->acct);
  1050. } else
  1051. print_file_add_limits_to_line(&line, assoc);
  1052. if (fprintf(fd, "%s\n", line) < 0) {
  1053. exit_code = 1;
  1054. fprintf(stderr, " Can't write to file");
  1055. FREE_NULL_LIST(acct_list);
  1056. FREE_NULL_LIST(assoc_list);
  1057. xfree(cluster_name);
  1058. xfree(file_name);
  1059. xfree(line);
  1060. FREE_NULL_LIST(slurmdb_hierarchical_rec_list);
  1061. return SLURM_ERROR;
  1062. }
  1063. info("%s", line);
  1064. xfree(line);
  1065. print_file_slurmdb_hierarchical_rec_list(
  1066. fd, slurmdb_hierarchical_rec_list, user_list, acct_list);
  1067. FREE_NULL_LIST(acct_list);
  1068. FREE_NULL_LIST(assoc_list);
  1069. xfree(cluster_name);
  1070. xfree(file_name);
  1071. FREE_NULL_LIST(slurmdb_hierarchical_rec_list);
  1072. fclose(fd);
  1073. return SLURM_SUCCESS;
  1074. }