PageRenderTime 83ms CodeModel.GetById 1ms RepoModel.GetById 1ms app.codeStats 0ms

/src/sacctmgr/file_functions.c

https://github.com/cfenoy/slurm
C | 2609 lines | 2521 code | 29 blank | 59 comment | 71 complexity | 5d8843e81f0cb400fb41c29723883d7d MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
  1. /*****************************************************************************\
  2. * file_functions.c - functions dealing with files that are generated in the
  3. * accounting system.
  4. *****************************************************************************
  5. * Copyright (C) 2008 Lawrence Livermore National Security.
  6. * Copyright (C) 2002-2007 The Regents of the University of California.
  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. typedef struct {
  43. slurmdb_admin_level_t admin;
  44. uint16_t classification;
  45. List coord_list; /* char *list */
  46. char *def_acct;
  47. uint32_t def_qos_id;
  48. char *def_wckey;
  49. char *desc;
  50. uint32_t fairshare;
  51. uint64_t grp_cpu_mins;
  52. uint32_t grp_cpus;
  53. uint32_t grp_jobs;
  54. uint32_t grp_mem;
  55. uint32_t grp_nodes;
  56. uint32_t grp_submit_jobs;
  57. uint32_t grp_wall;
  58. uint64_t max_cpu_mins_pj;
  59. uint32_t max_cpus_pj;
  60. uint32_t max_jobs;
  61. uint32_t max_nodes_pj;
  62. uint32_t max_submit_jobs;
  63. uint32_t max_wall_pj;
  64. char *name;
  65. char *org;
  66. char *part;
  67. List qos_list;
  68. List wckey_list;
  69. } sacctmgr_file_opts_t;
  70. typedef enum {
  71. MOD_CLUSTER,
  72. MOD_ACCT,
  73. MOD_USER
  74. } sacctmgr_mod_type_t;
  75. static int _init_sacctmgr_file_opts(sacctmgr_file_opts_t *file_opts)
  76. {
  77. if (!file_opts)
  78. return SLURM_ERROR;
  79. memset(file_opts, 0, sizeof(sacctmgr_file_opts_t));
  80. file_opts->admin = SLURMDB_ADMIN_NOTSET;
  81. file_opts->fairshare = NO_VAL;
  82. file_opts->def_qos_id = NO_VAL;
  83. file_opts->grp_cpu_mins = (uint64_t)NO_VAL;
  84. file_opts->grp_cpus = NO_VAL;
  85. file_opts->grp_jobs = NO_VAL;
  86. file_opts->grp_mem = NO_VAL;
  87. file_opts->grp_nodes = NO_VAL;
  88. file_opts->grp_submit_jobs = NO_VAL;
  89. file_opts->grp_wall = NO_VAL;
  90. file_opts->max_cpu_mins_pj = (uint64_t)NO_VAL;
  91. file_opts->max_cpus_pj = NO_VAL;
  92. file_opts->max_jobs = NO_VAL;
  93. file_opts->max_nodes_pj = NO_VAL;
  94. file_opts->max_submit_jobs = NO_VAL;
  95. file_opts->max_wall_pj = NO_VAL;
  96. return SLURM_SUCCESS;
  97. }
  98. static int _strip_continuation(char *buf, int len)
  99. {
  100. char *ptr;
  101. int bs = 0;
  102. for (ptr = buf+len-1; ptr >= buf; ptr--) {
  103. if (*ptr == '\\')
  104. bs++;
  105. else if (isspace(*ptr) && bs == 0)
  106. continue;
  107. else
  108. break;
  109. }
  110. /* Check for an odd number of contiguous backslashes at
  111. the end of the line */
  112. if (bs % 2 == 1) {
  113. ptr = ptr + bs;
  114. *ptr = '\0';
  115. return (ptr - buf);
  116. } else {
  117. return len; /* no continuation */
  118. }
  119. }
  120. /* Strip comments from a line by terminating the string
  121. * where the comment begins.
  122. * Everything after a non-escaped "#" is a comment.
  123. */
  124. static void _strip_comments(char *line)
  125. {
  126. int i;
  127. int len = strlen(line);
  128. int bs_count = 0;
  129. for (i = 0; i < len; i++) {
  130. /* if # character is preceded by an even number of
  131. * escape characters '\' */
  132. if (line[i] == '#' && (bs_count%2) == 0) {
  133. line[i] = '\0';
  134. break;
  135. } else if (line[i] == '\\') {
  136. bs_count++;
  137. } else {
  138. bs_count = 0;
  139. }
  140. }
  141. }
  142. /*
  143. * Strips any escape characters, "\". If you WANT a back-slash,
  144. * it must be escaped, "\\".
  145. */
  146. static void _strip_escapes(char *line)
  147. {
  148. int i, j;
  149. int len = strlen(line);
  150. for (i = 0, j = 0; i < len+1; i++, j++) {
  151. if (line[i] == '\\')
  152. i++;
  153. line[j] = line[i];
  154. }
  155. }
  156. /*
  157. * Reads the next line from the "file" into buffer "buf".
  158. *
  159. * Concatonates together lines that are continued on
  160. * the next line by a trailing "\". Strips out comments,
  161. * replaces escaped "\#" with "#", and replaces "\\" with "\".
  162. */
  163. static int _get_next_line(char *buf, int buf_size, FILE *file)
  164. {
  165. char *ptr = buf;
  166. int leftover = buf_size;
  167. int read_size, new_size;
  168. int lines = 0;
  169. while (fgets(ptr, leftover, file)) {
  170. lines++;
  171. _strip_comments(ptr);
  172. read_size = strlen(ptr);
  173. new_size = _strip_continuation(ptr, read_size);
  174. if (new_size < read_size) {
  175. ptr += new_size;
  176. leftover -= new_size;
  177. } else { /* no continuation */
  178. break;
  179. }
  180. }
  181. /* _strip_cr_nl(buf); */ /* not necessary */
  182. _strip_escapes(buf);
  183. return lines;
  184. }
  185. static void _destroy_sacctmgr_file_opts(void *object)
  186. {
  187. sacctmgr_file_opts_t *file_opts = (sacctmgr_file_opts_t *)object;
  188. if (file_opts) {
  189. if (file_opts->coord_list)
  190. list_destroy(file_opts->coord_list);
  191. xfree(file_opts->def_acct);
  192. xfree(file_opts->def_wckey);
  193. xfree(file_opts->desc);
  194. xfree(file_opts->name);
  195. xfree(file_opts->org);
  196. xfree(file_opts->part);
  197. if (file_opts->qos_list) {
  198. list_destroy(file_opts->qos_list);
  199. file_opts->qos_list = NULL;
  200. }
  201. if (file_opts->wckey_list) {
  202. list_destroy(file_opts->wckey_list);
  203. file_opts->wckey_list = NULL;
  204. }
  205. xfree(file_opts);
  206. }
  207. }
  208. static sacctmgr_file_opts_t *_parse_options(char *options)
  209. {
  210. int start=0, i=0, end=0, mins, quote = 0;
  211. char *sub = NULL;
  212. sacctmgr_file_opts_t *file_opts = xmalloc(sizeof(sacctmgr_file_opts_t));
  213. char *option = NULL;
  214. char quote_c = '\0';
  215. int command_len = 0;
  216. int option2 = 0;
  217. _init_sacctmgr_file_opts(file_opts);
  218. while (options[i]) {
  219. quote = 0;
  220. start=i;
  221. while (options[i] && options[i] != ':' && options[i] != '\n') {
  222. if (options[i] == '"' || options[i] == '\'') {
  223. if (quote) {
  224. if (options[i] == quote_c)
  225. quote = 0;
  226. } else {
  227. quote = 1;
  228. quote_c = options[i];
  229. }
  230. }
  231. i++;
  232. }
  233. if (quote) {
  234. while (options[i] && options[i] != quote_c)
  235. i++;
  236. if (!options[i])
  237. fatal("There is a problem with option "
  238. "%s with quotes.", option);
  239. i++;
  240. }
  241. if (i-start <= 0)
  242. goto next_col;
  243. sub = xstrndup(options+start, i-start);
  244. end = parse_option_end(sub);
  245. command_len = end - 1;
  246. if (sub[end] == '=') {
  247. option2 = (int)sub[end-1];
  248. end++;
  249. }
  250. option = strip_quotes(sub+end, NULL, 1);
  251. if (!end) {
  252. if (file_opts->name) {
  253. exit_code=1;
  254. fprintf(stderr, " Bad format on %s: "
  255. "End your option with "
  256. "an '=' sign\n", sub);
  257. _destroy_sacctmgr_file_opts(file_opts);
  258. break;
  259. }
  260. file_opts->name = xstrdup(option);
  261. } else if (end && !strlen(option)) {
  262. debug("blank field given for %s discarding", sub);
  263. } else if (!strncasecmp (sub, "AdminLevel",
  264. MAX(command_len, 2))) {
  265. file_opts->admin = str_2_slurmdb_admin_level(option);
  266. } else if (!strncasecmp (sub, "Coordinator",
  267. MAX(command_len, 2))) {
  268. if (!file_opts->coord_list)
  269. file_opts->coord_list =
  270. list_create(slurm_destroy_char);
  271. slurm_addto_char_list(file_opts->coord_list, option);
  272. } else if (!strncasecmp (sub, "Classification",
  273. MAX(command_len, 2))) {
  274. file_opts->classification =
  275. str_2_classification(option);
  276. } else if (!strncasecmp (sub, "DefaultAccount",
  277. MAX(command_len, 8))) {
  278. file_opts->def_acct = xstrdup(option);
  279. } else if (!strncasecmp (sub, "DefaultQOS",
  280. MAX(command_len, 8))) {
  281. if (!g_qos_list) {
  282. g_qos_list = acct_storage_g_get_qos(
  283. db_conn, my_uid, NULL);
  284. }
  285. file_opts->def_qos_id = str_2_slurmdb_qos(
  286. g_qos_list, option);
  287. if (file_opts->def_qos_id == NO_VAL) {
  288. fprintf(stderr,
  289. "You gave a bad qos '%s'. "
  290. "Use 'list qos' to get "
  291. "complete list.\n",
  292. option);
  293. _destroy_sacctmgr_file_opts(file_opts);
  294. break;
  295. }
  296. } else if (!strncasecmp (sub, "DefaultWCKey",
  297. MAX(command_len, 8))) {
  298. file_opts->def_wckey = xstrdup(option);
  299. if (!file_opts->wckey_list)
  300. file_opts->wckey_list =
  301. list_create(slurm_destroy_char);
  302. slurm_addto_char_list(file_opts->wckey_list, option);
  303. } else if (!strncasecmp (sub, "Description",
  304. MAX(command_len, 3))) {
  305. file_opts->desc = xstrdup(option);
  306. } else if (!strncasecmp (sub, "FairShare",
  307. MAX(command_len, 1))
  308. || !strncasecmp (sub, "Shares",
  309. MAX(command_len, 1))) {
  310. if (get_uint(option, &file_opts->fairshare,
  311. "FairShare") != SLURM_SUCCESS) {
  312. exit_code=1;
  313. fprintf(stderr,
  314. " Bad FairShare value: %s\n", option);
  315. _destroy_sacctmgr_file_opts(file_opts);
  316. break;
  317. }
  318. } else if (!strncasecmp (sub, "GrpCPUMins",
  319. MAX(command_len, 7))) {
  320. if (get_uint64(option, &file_opts->grp_cpu_mins,
  321. "GrpCPUMins") != SLURM_SUCCESS) {
  322. exit_code=1;
  323. fprintf(stderr,
  324. " Bad GrpCPUMins value: %s\n", option);
  325. _destroy_sacctmgr_file_opts(file_opts);
  326. break;
  327. }
  328. } else if (!strncasecmp (sub, "GrpCPUs", MAX(command_len, 7))) {
  329. if (get_uint(option, &file_opts->grp_cpus,
  330. "GrpCPUs") != SLURM_SUCCESS) {
  331. exit_code=1;
  332. fprintf(stderr,
  333. " Bad GrpCPUs value: %s\n", option);
  334. _destroy_sacctmgr_file_opts(file_opts);
  335. break;
  336. }
  337. } else if (!strncasecmp (sub, "GrpJobs", MAX(command_len, 4))) {
  338. if (get_uint(option, &file_opts->grp_jobs,
  339. "GrpJobs") != SLURM_SUCCESS) {
  340. exit_code=1;
  341. fprintf(stderr,
  342. " Bad GrpJobs value: %s\n", option);
  343. _destroy_sacctmgr_file_opts(file_opts);
  344. break;
  345. }
  346. } else if (!strncasecmp (sub, "GrpMemory",
  347. MAX(command_len, 4))) {
  348. if (get_uint(option, &file_opts->grp_mem,
  349. "GrpMemory") != SLURM_SUCCESS) {
  350. exit_code=1;
  351. fprintf(stderr,
  352. " Bad GrpMemory value: %s\n", option);
  353. _destroy_sacctmgr_file_opts(file_opts);
  354. break;
  355. }
  356. } else if (!strncasecmp (sub, "GrpNodes",
  357. MAX(command_len, 4))) {
  358. if (get_uint(option, &file_opts->grp_nodes,
  359. "GrpNodes") != SLURM_SUCCESS) {
  360. exit_code=1;
  361. fprintf(stderr,
  362. " Bad GrpNodes value: %s\n", option);
  363. _destroy_sacctmgr_file_opts(file_opts);
  364. break;
  365. }
  366. } else if (!strncasecmp (sub, "GrpSubmitJobs",
  367. MAX(command_len, 4))) {
  368. if (get_uint(option, &file_opts->grp_submit_jobs,
  369. "GrpSubmitJobs") != SLURM_SUCCESS) {
  370. exit_code=1;
  371. fprintf(stderr,
  372. " Bad GrpJobs value: %s\n", option);
  373. _destroy_sacctmgr_file_opts(file_opts);
  374. break;
  375. }
  376. } else if (!strncasecmp (sub, "GrpWall", MAX(command_len, 4))) {
  377. mins = time_str2mins(option);
  378. if (mins >= 0) {
  379. file_opts->grp_wall
  380. = (uint32_t) mins;
  381. } else if (strcmp(option, "-1")) {
  382. file_opts->grp_wall = INFINITE;
  383. } else {
  384. exit_code=1;
  385. fprintf(stderr,
  386. " Bad GrpWall time format: %s\n",
  387. option);
  388. _destroy_sacctmgr_file_opts(file_opts);
  389. break;
  390. }
  391. } else if (!strncasecmp (sub, "MaxCPUMinsPerJob",
  392. MAX(command_len, 7))
  393. || !strncasecmp (sub, "MaxProcSecPerJob",
  394. MAX(command_len, 4))) {
  395. if (get_uint64(option, &file_opts->max_cpu_mins_pj,
  396. "MaxCPUMins") != SLURM_SUCCESS) {
  397. exit_code=1;
  398. fprintf(stderr,
  399. " Bad MaxCPUMins value: %s\n", option);
  400. _destroy_sacctmgr_file_opts(file_opts);
  401. break;
  402. }
  403. } else if (!strncasecmp (sub, "MaxCPUsPerJob",
  404. MAX(command_len, 7))) {
  405. if (get_uint(option, &file_opts->max_cpus_pj,
  406. "MaxCPUs") != SLURM_SUCCESS) {
  407. exit_code=1;
  408. fprintf(stderr,
  409. " Bad MaxCPUs value: %s\n", option);
  410. _destroy_sacctmgr_file_opts(file_opts);
  411. break;
  412. }
  413. } else if (!strncasecmp (sub, "MaxJobs", MAX(command_len, 4))) {
  414. if (get_uint(option, &file_opts->max_jobs,
  415. "MaxJobs") != SLURM_SUCCESS) {
  416. exit_code=1;
  417. fprintf(stderr,
  418. " Bad MaxJobs value: %s\n", option);
  419. _destroy_sacctmgr_file_opts(file_opts);
  420. break;
  421. }
  422. } else if (!strncasecmp (sub, "MaxNodesPerJob",
  423. MAX(command_len, 4))) {
  424. if (get_uint(option, &file_opts->max_nodes_pj,
  425. "MaxNodes") != SLURM_SUCCESS) {
  426. exit_code=1;
  427. fprintf(stderr,
  428. " Bad MaxNodes value: %s\n", option);
  429. _destroy_sacctmgr_file_opts(file_opts);
  430. break;
  431. }
  432. } else if (!strncasecmp (sub, "MaxSubmitJobs",
  433. MAX(command_len, 4))) {
  434. if (get_uint(option, &file_opts->max_submit_jobs,
  435. "MaxSubmitJobs") != SLURM_SUCCESS) {
  436. exit_code=1;
  437. fprintf(stderr,
  438. " Bad MaxJobs value: %s\n", option);
  439. _destroy_sacctmgr_file_opts(file_opts);
  440. break;
  441. }
  442. } else if (!strncasecmp (sub, "MaxWallDurationPerJob",
  443. MAX(command_len, 4))) {
  444. mins = time_str2mins(option);
  445. if (mins >= 0) {
  446. file_opts->max_wall_pj
  447. = (uint32_t) mins;
  448. } else if (strcmp(option, "-1")) {
  449. file_opts->max_wall_pj = INFINITE;
  450. } else {
  451. exit_code=1;
  452. fprintf(stderr,
  453. " Bad MaxWall time format: %s\n",
  454. option);
  455. _destroy_sacctmgr_file_opts(file_opts);
  456. break;
  457. }
  458. } else if (!strncasecmp (sub, "Organization",
  459. MAX(command_len, 1))) {
  460. file_opts->org = xstrdup(option);
  461. } else if (!strncasecmp (sub, "Partition",
  462. MAX(command_len, 1))) {
  463. file_opts->part = xstrdup(option);
  464. } else if (!strncasecmp (sub, "QosLevel", MAX(command_len, 1))
  465. || !strncasecmp (sub, "Expedite",
  466. MAX(command_len, 1))) {
  467. if (!file_opts->qos_list) {
  468. file_opts->qos_list =
  469. list_create(slurm_destroy_char);
  470. }
  471. if (!g_qos_list) {
  472. g_qos_list = acct_storage_g_get_qos(
  473. db_conn, my_uid, NULL);
  474. }
  475. slurmdb_addto_qos_char_list(file_opts->qos_list,
  476. g_qos_list,
  477. option, option2);
  478. } else if (!strncasecmp (sub, "WCKeys",
  479. MAX(command_len, 2))) {
  480. if (!file_opts->wckey_list)
  481. file_opts->wckey_list =
  482. list_create(slurm_destroy_char);
  483. slurm_addto_char_list(file_opts->wckey_list, option);
  484. } else {
  485. exit_code=1;
  486. fprintf(stderr, " Unknown option: %s\n", sub);
  487. }
  488. xfree(sub);
  489. xfree(option);
  490. next_col:
  491. if (options[i] == ':')
  492. i++;
  493. else
  494. break;
  495. }
  496. xfree(sub);
  497. xfree(option);
  498. if (!file_opts->name) {
  499. exit_code=1;
  500. fprintf(stderr, " No name given\n");
  501. _destroy_sacctmgr_file_opts(file_opts);
  502. file_opts = NULL;
  503. } else if (exit_code) {
  504. _destroy_sacctmgr_file_opts(file_opts);
  505. file_opts = NULL;
  506. }
  507. return file_opts;
  508. }
  509. static int _print_out_assoc(List assoc_list, bool user, bool add)
  510. {
  511. List format_list = NULL;
  512. List print_fields_list = NULL;
  513. ListIterator itr, itr2;
  514. print_field_t *field = NULL;
  515. slurmdb_association_rec_t *assoc = NULL;
  516. int rc = SLURM_SUCCESS;
  517. char *tmp_char = NULL;
  518. if (!assoc_list || !list_count(assoc_list))
  519. return rc;
  520. format_list = list_create(slurm_destroy_char);
  521. if (user)
  522. slurm_addto_char_list(format_list,
  523. "User,Account");
  524. else
  525. slurm_addto_char_list(format_list,
  526. "Account,ParentName");
  527. slurm_addto_char_list(format_list,
  528. "Share,GrpCPUM,GrpCPUs,GrpJ,"
  529. "GrpMEM,GrpN,GrpS,GrpW,MaxCPUM,MaxCPUs,"
  530. "MaxJ,MaxS,MaxN,MaxW,QOS,DefaultQOS");
  531. print_fields_list = sacctmgr_process_format_list(format_list);
  532. list_destroy(format_list);
  533. print_fields_header(print_fields_list);
  534. itr = list_iterator_create(assoc_list);
  535. itr2 = list_iterator_create(print_fields_list);
  536. while ((assoc = list_next(itr))) {
  537. while ((field = list_next(itr2))) {
  538. switch(field->type) {
  539. case PRINT_ACCT:
  540. field->print_routine(field,
  541. assoc->acct);
  542. break;
  543. case PRINT_DQOS:
  544. if (!g_qos_list)
  545. g_qos_list = acct_storage_g_get_qos(
  546. db_conn,
  547. my_uid,
  548. NULL);
  549. tmp_char = slurmdb_qos_str(
  550. g_qos_list,
  551. assoc->def_qos_id);
  552. field->print_routine(
  553. field,
  554. tmp_char);
  555. break;
  556. case PRINT_FAIRSHARE:
  557. field->print_routine(field,
  558. assoc->shares_raw);
  559. break;
  560. case PRINT_GRPCM:
  561. field->print_routine(
  562. field,
  563. assoc->grp_cpu_mins);
  564. break;
  565. case PRINT_GRPC:
  566. field->print_routine(field,
  567. assoc->grp_cpus);
  568. break;
  569. case PRINT_GRPJ:
  570. field->print_routine(field,
  571. assoc->grp_jobs);
  572. break;
  573. case PRINT_GRPMEM:
  574. field->print_routine(field,
  575. assoc->grp_mem);
  576. break;
  577. case PRINT_GRPN:
  578. field->print_routine(field,
  579. assoc->grp_nodes);
  580. break;
  581. case PRINT_GRPS:
  582. field->print_routine(field,
  583. assoc->grp_submit_jobs);
  584. break;
  585. case PRINT_GRPW:
  586. field->print_routine(
  587. field,
  588. assoc->grp_wall);
  589. break;
  590. case PRINT_MAXCM:
  591. field->print_routine(
  592. field,
  593. assoc->max_cpu_mins_pj);
  594. break;
  595. case PRINT_MAXC:
  596. field->print_routine(field,
  597. assoc->max_cpus_pj);
  598. break;
  599. case PRINT_MAXJ:
  600. field->print_routine(field,
  601. assoc->max_jobs);
  602. break;
  603. case PRINT_MAXN:
  604. field->print_routine(field,
  605. assoc->max_nodes_pj);
  606. break;
  607. case PRINT_MAXS:
  608. field->print_routine(field,
  609. assoc->max_submit_jobs);
  610. break;
  611. case PRINT_MAXW:
  612. field->print_routine(
  613. field,
  614. assoc->max_wall_pj);
  615. break;
  616. case PRINT_PNAME:
  617. field->print_routine(field,
  618. assoc->parent_acct);
  619. break;
  620. case PRINT_PART:
  621. field->print_routine(field,
  622. assoc->partition);
  623. break;
  624. case PRINT_QOS:
  625. if (!g_qos_list)
  626. g_qos_list = acct_storage_g_get_qos(
  627. db_conn, my_uid, NULL);
  628. field->print_routine(
  629. field,
  630. g_qos_list,
  631. assoc->qos_list);
  632. break;
  633. case PRINT_USER:
  634. field->print_routine(field,
  635. assoc->user);
  636. break;
  637. default:
  638. field->print_routine(
  639. field, NULL);
  640. break;
  641. }
  642. }
  643. list_iterator_reset(itr2);
  644. printf("\n");
  645. }
  646. list_iterator_destroy(itr);
  647. list_iterator_destroy(itr2);
  648. list_destroy(print_fields_list);
  649. if (add)
  650. rc = acct_storage_g_add_associations(db_conn,
  651. my_uid, assoc_list);
  652. printf("--------------------------------------------------------------\n\n");
  653. return rc;
  654. }
  655. static int _mod_assoc(sacctmgr_file_opts_t *file_opts,
  656. slurmdb_association_rec_t *assoc,
  657. sacctmgr_mod_type_t mod_type,
  658. char *parent)
  659. {
  660. int changed = 0;
  661. slurmdb_association_rec_t mod_assoc;
  662. slurmdb_association_cond_t assoc_cond;
  663. char *type = NULL;
  664. char *name = NULL;
  665. char *my_info = NULL;
  666. switch(mod_type) {
  667. case MOD_CLUSTER:
  668. type = "Cluster";
  669. name = assoc->cluster;
  670. break;
  671. case MOD_ACCT:
  672. type = "Account";
  673. name = assoc->acct;
  674. break;
  675. case MOD_USER:
  676. type = "User";
  677. name = assoc->user;
  678. break;
  679. default:
  680. return 0;
  681. break;
  682. }
  683. slurmdb_init_association_rec(&mod_assoc, 0);
  684. memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t));
  685. if ((file_opts->fairshare != NO_VAL)
  686. && (assoc->shares_raw != file_opts->fairshare)) {
  687. mod_assoc.shares_raw = file_opts->fairshare;
  688. changed = 1;
  689. xstrfmtcat(my_info,
  690. "%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
  691. " Changed fairshare",
  692. type, name,
  693. assoc->shares_raw,
  694. file_opts->fairshare);
  695. }
  696. if ((file_opts->grp_cpu_mins != NO_VAL)
  697. && (assoc->grp_cpu_mins != file_opts->grp_cpu_mins)) {
  698. mod_assoc.grp_cpu_mins = file_opts->grp_cpu_mins;
  699. changed = 1;
  700. xstrfmtcat(my_info,
  701. "%-30.30s for %-7.7s %-10.10s "
  702. "%8"PRIu64" -> %"PRIu64"\n",
  703. " Changed GrpCPUMins",
  704. type, name,
  705. assoc->grp_cpu_mins,
  706. file_opts->grp_cpu_mins);
  707. }
  708. if ((file_opts->grp_cpus != NO_VAL)
  709. && (assoc->grp_cpus != file_opts->grp_cpus)) {
  710. mod_assoc.grp_cpus = file_opts->grp_cpus;
  711. changed = 1;
  712. xstrfmtcat(my_info,
  713. "%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
  714. " Changed GrpCpus",
  715. type, name,
  716. assoc->grp_cpus,
  717. file_opts->grp_cpus);
  718. }
  719. if ((file_opts->grp_jobs != NO_VAL)
  720. && (assoc->grp_jobs != file_opts->grp_jobs)) {
  721. mod_assoc.grp_jobs = file_opts->grp_jobs;
  722. changed = 1;
  723. xstrfmtcat(my_info,
  724. "%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
  725. " Changed GrpJobs",
  726. type, name,
  727. assoc->grp_jobs,
  728. file_opts->grp_jobs);
  729. }
  730. if((file_opts->grp_mem != NO_VAL)
  731. && (assoc->grp_mem != file_opts->grp_mem)) {
  732. mod_assoc.grp_mem = file_opts->grp_mem;
  733. changed = 1;
  734. xstrfmtcat(my_info,
  735. "%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
  736. " Changed GrpMemory",
  737. type, name,
  738. assoc->grp_mem,
  739. file_opts->grp_mem);
  740. }
  741. if ((file_opts->grp_nodes != NO_VAL)
  742. && (assoc->grp_nodes != file_opts->grp_nodes)) {
  743. mod_assoc.grp_nodes = file_opts->grp_nodes;
  744. changed = 1;
  745. xstrfmtcat(my_info,
  746. "%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
  747. " Changed GrpNodes",
  748. type, name,
  749. assoc->grp_nodes,
  750. file_opts->grp_nodes);
  751. }
  752. if ((file_opts->grp_submit_jobs != NO_VAL)
  753. && (assoc->grp_submit_jobs != file_opts->grp_submit_jobs)) {
  754. mod_assoc.grp_submit_jobs = file_opts->grp_submit_jobs;
  755. changed = 1;
  756. xstrfmtcat(my_info,
  757. "%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
  758. " Changed GrpSubmitJobs",
  759. type, name,
  760. assoc->grp_submit_jobs,
  761. file_opts->grp_submit_jobs);
  762. }
  763. if ((file_opts->grp_wall != NO_VAL)
  764. && (assoc->grp_wall != file_opts->grp_wall)) {
  765. mod_assoc.grp_wall = file_opts->grp_wall;
  766. changed = 1;
  767. xstrfmtcat(my_info,
  768. "%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
  769. " Changed GrpWallDuration",
  770. type, name,
  771. assoc->grp_wall,
  772. file_opts->grp_wall);
  773. }
  774. if ((file_opts->max_cpu_mins_pj != (uint64_t)NO_VAL)
  775. && (assoc->max_cpu_mins_pj != file_opts->max_cpu_mins_pj)) {
  776. mod_assoc.max_cpu_mins_pj =
  777. file_opts->max_cpu_mins_pj;
  778. changed = 1;
  779. xstrfmtcat(my_info,
  780. "%-30.30s for %-7.7s %-10.10s "
  781. "%8"PRIu64" -> %"PRIu64"\n",
  782. " Changed MaxCPUMinsPerJob",
  783. type, name,
  784. assoc->max_cpu_mins_pj,
  785. file_opts->max_cpu_mins_pj);
  786. }
  787. if ((file_opts->max_cpus_pj != NO_VAL)
  788. && (assoc->max_cpus_pj != file_opts->max_cpus_pj)) {
  789. mod_assoc.max_cpus_pj = file_opts->max_cpus_pj;
  790. changed = 1;
  791. xstrfmtcat(my_info,
  792. "%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
  793. " Changed MaxCpusPerJob",
  794. type, name,
  795. assoc->max_cpus_pj,
  796. file_opts->max_cpus_pj);
  797. }
  798. if ((file_opts->max_jobs != NO_VAL)
  799. && (assoc->max_jobs != file_opts->max_jobs)) {
  800. mod_assoc.max_jobs = file_opts->max_jobs;
  801. changed = 1;
  802. xstrfmtcat(my_info,
  803. "%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
  804. " Changed MaxJobs",
  805. type, name,
  806. assoc->max_jobs,
  807. file_opts->max_jobs);
  808. }
  809. if ((file_opts->max_nodes_pj != NO_VAL)
  810. && (assoc->max_nodes_pj != file_opts->max_nodes_pj)) {
  811. mod_assoc.max_nodes_pj = file_opts->max_nodes_pj;
  812. changed = 1;
  813. xstrfmtcat(my_info,
  814. "%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
  815. " Changed MaxNodesPerJob",
  816. type, name,
  817. assoc->max_nodes_pj,
  818. file_opts->max_nodes_pj);
  819. }
  820. if ((file_opts->max_submit_jobs != NO_VAL)
  821. && (assoc->max_submit_jobs != file_opts->max_submit_jobs)) {
  822. mod_assoc.max_submit_jobs = file_opts->max_submit_jobs;
  823. changed = 1;
  824. xstrfmtcat(my_info,
  825. "%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
  826. " Changed MaxSubmitJobs",
  827. type, name,
  828. assoc->max_submit_jobs,
  829. file_opts->max_submit_jobs);
  830. }
  831. if ((file_opts->max_wall_pj != NO_VAL)
  832. && (assoc->max_wall_pj != file_opts->max_wall_pj)) {
  833. mod_assoc.max_wall_pj = file_opts->max_wall_pj;
  834. changed = 1;
  835. xstrfmtcat(my_info,
  836. "%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
  837. " Changed MaxWallDurationPerJob",
  838. type, name,
  839. assoc->max_wall_pj,
  840. file_opts->max_wall_pj);
  841. }
  842. if (assoc->parent_acct && parent
  843. && strcmp(assoc->parent_acct, parent)) {
  844. mod_assoc.parent_acct = parent;
  845. changed = 1;
  846. xstrfmtcat(my_info,
  847. "%-30.30s for %-7.7s %-10.10s %8s -> %s\n",
  848. " Changed Parent",
  849. type, name,
  850. assoc->parent_acct,
  851. parent);
  852. }
  853. if (assoc->qos_list && list_count(assoc->qos_list)
  854. && file_opts->qos_list && list_count(file_opts->qos_list)) {
  855. ListIterator now_qos_itr =
  856. list_iterator_create(assoc->qos_list),
  857. new_qos_itr = list_iterator_create(file_opts->qos_list);
  858. char *now_qos = NULL, *new_qos = NULL;
  859. if (!mod_assoc.qos_list)
  860. mod_assoc.qos_list = list_create(slurm_destroy_char);
  861. while ((new_qos = list_next(new_qos_itr))) {
  862. while ((now_qos = list_next(now_qos_itr))) {
  863. if (!strcmp(new_qos, now_qos))
  864. break;
  865. }
  866. list_iterator_reset(now_qos_itr);
  867. if (!now_qos)
  868. list_append(mod_assoc.qos_list,
  869. xstrdup(new_qos));
  870. }
  871. list_iterator_destroy(new_qos_itr);
  872. list_iterator_destroy(now_qos_itr);
  873. if (mod_assoc.qos_list && list_count(mod_assoc.qos_list))
  874. new_qos = get_qos_complete_str(g_qos_list,
  875. mod_assoc.qos_list);
  876. if (new_qos) {
  877. xstrfmtcat(my_info,
  878. "%-30.30s for %-7.7s %-10.10s %8s\n",
  879. " Added QOS",
  880. type, name,
  881. new_qos);
  882. xfree(new_qos);
  883. changed = 1;
  884. } else {
  885. list_destroy(mod_assoc.qos_list);
  886. mod_assoc.qos_list = NULL;
  887. }
  888. } else if (file_opts->qos_list && list_count(file_opts->qos_list)) {
  889. char *new_qos = get_qos_complete_str(g_qos_list,
  890. file_opts->qos_list);
  891. if (new_qos) {
  892. xstrfmtcat(my_info,
  893. "%-30.30s for %-7.7s %-10.10s %8s\n",
  894. " Added QOS",
  895. type, name,
  896. new_qos);
  897. xfree(new_qos);
  898. mod_assoc.qos_list = file_opts->qos_list;
  899. file_opts->qos_list = NULL;
  900. changed = 1;
  901. }
  902. }
  903. if (changed) {
  904. List ret_list = NULL;
  905. assoc_cond.cluster_list = list_create(NULL);
  906. list_push(assoc_cond.cluster_list, assoc->cluster);
  907. assoc_cond.acct_list = list_create(NULL);
  908. list_push(assoc_cond.acct_list, assoc->acct);
  909. if (mod_type == MOD_USER) {
  910. assoc_cond.user_list = list_create(NULL);
  911. list_push(assoc_cond.user_list, assoc->user);
  912. if (assoc->partition) {
  913. assoc_cond.partition_list = list_create(NULL);
  914. list_push(assoc_cond.partition_list,
  915. assoc->partition);
  916. }
  917. }
  918. notice_thread_init();
  919. ret_list = acct_storage_g_modify_associations(
  920. db_conn, my_uid,
  921. &assoc_cond,
  922. &mod_assoc);
  923. notice_thread_fini();
  924. if (mod_assoc.qos_list)
  925. list_destroy(mod_assoc.qos_list);
  926. list_destroy(assoc_cond.cluster_list);
  927. list_destroy(assoc_cond.acct_list);
  928. if (assoc_cond.user_list)
  929. list_destroy(assoc_cond.user_list);
  930. if (assoc_cond.partition_list)
  931. list_destroy(assoc_cond.partition_list);
  932. /* if (ret_list && list_count(ret_list)) { */
  933. /* char *object = NULL; */
  934. /* ListIterator itr = list_iterator_create(ret_list); */
  935. /* printf(" Modified account defaults for " */
  936. /* "associations...\n"); */
  937. /* while ((object = list_next(itr))) */
  938. /* printf(" %s\n", object); */
  939. /* list_iterator_destroy(itr); */
  940. /* } */
  941. if (ret_list) {
  942. printf("%s", my_info);
  943. list_destroy(ret_list);
  944. } else
  945. changed = 0;
  946. xfree(my_info);
  947. }
  948. return changed;
  949. }
  950. static int _mod_cluster(sacctmgr_file_opts_t *file_opts,
  951. slurmdb_cluster_rec_t *cluster, char *parent)
  952. {
  953. int changed = 0;
  954. char *my_info = NULL;
  955. slurmdb_cluster_rec_t mod_cluster;
  956. slurmdb_cluster_cond_t cluster_cond;
  957. slurmdb_init_cluster_rec(&mod_cluster, 0);
  958. slurmdb_init_cluster_cond(&cluster_cond, 0);
  959. if (file_opts->classification
  960. && (file_opts->classification != cluster->classification)) {
  961. xstrfmtcat(my_info,
  962. "%-30.30s for %-7.7s %-10.10s %8s -> %s\n",
  963. " Changed Classification", "Cluster",
  964. cluster->name,
  965. get_classification_str(cluster->classification),
  966. get_classification_str(file_opts->classification));
  967. mod_cluster.classification = file_opts->classification;
  968. changed = 1;
  969. }
  970. if (changed) {
  971. List ret_list = NULL;
  972. cluster_cond.cluster_list = list_create(NULL);
  973. list_append(cluster_cond.cluster_list, cluster->name);
  974. notice_thread_init();
  975. ret_list = acct_storage_g_modify_clusters(db_conn, my_uid,
  976. &cluster_cond,
  977. &mod_cluster);
  978. notice_thread_fini();
  979. list_destroy(cluster_cond.cluster_list);
  980. /* if (ret_list && list_count(ret_list)) { */
  981. /* char *object = NULL; */
  982. /* ListIterator itr = list_iterator_create(ret_list); */
  983. /* printf(" Modified account defaults for " */
  984. /* "associations...\n"); */
  985. /* while ((object = list_next(itr))) */
  986. /* printf(" %s\n", object); */
  987. /* list_iterator_destroy(itr); */
  988. /* } */
  989. if (ret_list) {
  990. printf("%s", my_info);
  991. list_destroy(ret_list);
  992. } else
  993. changed = 0;
  994. xfree(my_info);
  995. }
  996. if (!cluster->root_assoc || !cluster->root_assoc->cluster) {
  997. error("Cluster %s doesn't appear to have a root association. "
  998. "Try removing this cluster and then re-run load.",
  999. cluster->name);
  1000. exit(1);
  1001. }
  1002. changed += _mod_assoc(file_opts, cluster->root_assoc,
  1003. MOD_CLUSTER, parent);
  1004. return changed;
  1005. }
  1006. static int _mod_acct(sacctmgr_file_opts_t *file_opts,
  1007. slurmdb_account_rec_t *acct, char *parent)
  1008. {
  1009. int changed = 0;
  1010. char *desc = NULL, *org = NULL, *my_info = NULL;
  1011. slurmdb_account_rec_t mod_acct;
  1012. slurmdb_account_cond_t acct_cond;
  1013. slurmdb_association_cond_t assoc_cond;
  1014. memset(&mod_acct, 0, sizeof(slurmdb_account_rec_t));
  1015. memset(&acct_cond, 0, sizeof(slurmdb_account_cond_t));
  1016. memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t));
  1017. if (file_opts->desc)
  1018. desc = xstrdup(file_opts->desc);
  1019. if (desc && strcmp(desc, acct->description)) {
  1020. xstrfmtcat(my_info,
  1021. "%-30.30s for %-7.7s %-10.10s %8s -> %s\n",
  1022. " Changed description", "Account",
  1023. acct->name,
  1024. acct->description,
  1025. desc);
  1026. mod_acct.description = desc;
  1027. changed = 1;
  1028. } else
  1029. xfree(desc);
  1030. if (file_opts->org)
  1031. org = xstrdup(file_opts->org);
  1032. if (org && strcmp(org, acct->organization)) {
  1033. xstrfmtcat(my_info,
  1034. "%-30.30s for %-7.7s %-10.10s %8s -> %s\n",
  1035. " Changed organization", "Account",
  1036. acct->name,
  1037. acct->organization,
  1038. org);
  1039. mod_acct.organization = org;
  1040. changed = 1;
  1041. } else
  1042. xfree(org);
  1043. if (changed) {
  1044. List ret_list = NULL;
  1045. assoc_cond.acct_list = list_create(NULL);
  1046. list_append(assoc_cond.acct_list, acct->name);
  1047. acct_cond.assoc_cond = &assoc_cond;
  1048. notice_thread_init();
  1049. ret_list = acct_storage_g_modify_accounts(db_conn, my_uid,
  1050. &acct_cond,
  1051. &mod_acct);
  1052. notice_thread_fini();
  1053. list_destroy(assoc_cond.acct_list);
  1054. /* if (ret_list && list_count(ret_list)) { */
  1055. /* char *object = NULL; */
  1056. /* ListIterator itr = list_iterator_create(ret_list); */
  1057. /* printf(" Modified account defaults for " */
  1058. /* "associations...\n"); */
  1059. /* while ((object = list_next(itr))) */
  1060. /* printf(" %s\n", object); */
  1061. /* list_iterator_destroy(itr); */
  1062. /* } */
  1063. if (ret_list) {
  1064. printf("%s", my_info);
  1065. list_destroy(ret_list);
  1066. } else
  1067. changed = 0;
  1068. xfree(my_info);
  1069. }
  1070. xfree(desc);
  1071. xfree(org);
  1072. return changed;
  1073. }
  1074. static int _mod_user(sacctmgr_file_opts_t *file_opts,
  1075. slurmdb_user_rec_t *user, char *cluster, char *parent)
  1076. {
  1077. int set = 0;
  1078. int changed = 0;
  1079. char *def_acct = NULL, *def_wckey = NULL, *my_info = NULL;
  1080. slurmdb_user_rec_t mod_user;
  1081. slurmdb_user_cond_t user_cond;
  1082. List ret_list = NULL;
  1083. slurmdb_association_cond_t assoc_cond;
  1084. if (!user || !user->name) {
  1085. fatal(" We need a user name in _mod_user");
  1086. }
  1087. memset(&mod_user, 0, sizeof(slurmdb_user_rec_t));
  1088. memset(&user_cond, 0, sizeof(slurmdb_user_cond_t));
  1089. memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t));
  1090. assoc_cond.user_list = list_create(NULL);
  1091. list_append(assoc_cond.user_list, user->name);
  1092. user_cond.assoc_cond = &assoc_cond;
  1093. if (file_opts->def_acct)
  1094. def_acct = xstrdup(file_opts->def_acct);
  1095. if (def_acct &&
  1096. (!user->default_acct || strcmp(def_acct, user->default_acct))) {
  1097. xstrfmtcat(my_info,
  1098. "%-30.30s for %-7.7s %-10.10s %8s -> %s\n",
  1099. " Changed Default Account", "User",
  1100. user->name,
  1101. user->default_acct,
  1102. def_acct);
  1103. mod_user.default_acct = def_acct;
  1104. changed = 1;
  1105. }
  1106. if (file_opts->def_wckey)
  1107. def_wckey = xstrdup(file_opts->def_wckey);
  1108. if (def_wckey &&
  1109. (!user->default_wckey || strcmp(def_wckey, user->default_wckey))) {
  1110. xstrfmtcat(my_info,
  1111. "%-30.30s for %-7.7s %-10.10s %8s -> %s\n",
  1112. " Changed Default WCKey", "User",
  1113. user->name,
  1114. user->default_wckey,
  1115. def_wckey);
  1116. mod_user.default_wckey = def_wckey;
  1117. changed = 1;
  1118. }
  1119. if (user->admin_level != SLURMDB_ADMIN_NOTSET
  1120. && file_opts->admin != SLURMDB_ADMIN_NOTSET
  1121. && user->admin_level != file_opts->admin) {
  1122. xstrfmtcat(my_info,
  1123. "%-30.30s for %-7.7s %-10.10s %8s -> %s\n",
  1124. " Changed Admin Level", "User",
  1125. user->name,
  1126. slurmdb_admin_level_str(
  1127. user->admin_level),
  1128. slurmdb_admin_level_str(
  1129. file_opts->admin));
  1130. mod_user.admin_level = file_opts->admin;
  1131. changed = 1;
  1132. }
  1133. if (changed) {
  1134. notice_thread_init();
  1135. ret_list = acct_storage_g_modify_users(
  1136. db_conn, my_uid,
  1137. &user_cond,
  1138. &mod_user);
  1139. notice_thread_fini();
  1140. /* if (ret_list && list_count(ret_list)) { */
  1141. /* char *object = NULL; */
  1142. /* ListIterator itr = list_iterator_create(ret_list); */
  1143. /* printf(" Modified user defaults for " */
  1144. /* "associations...\n"); */
  1145. /* while ((object = list_next(itr))) */
  1146. /* printf(" %s\n", object); */
  1147. /* list_iterator_destroy(itr); */
  1148. /* } */
  1149. if (ret_list) {
  1150. printf("%s", my_info);
  1151. list_destroy(ret_list);
  1152. set = 1;
  1153. }
  1154. xfree(my_info);
  1155. }
  1156. xfree(def_acct);
  1157. xfree(def_wckey);
  1158. if ((!user->coord_accts || !list_count(user->coord_accts))
  1159. && (file_opts->coord_list
  1160. && list_count(file_opts->coord_list))) {
  1161. ListIterator coord_itr = NULL;
  1162. char *temp_char = NULL;
  1163. slurmdb_coord_rec_t *coord = NULL;
  1164. int first = 1;
  1165. notice_thread_init();
  1166. (void) acct_storage_g_add_coord(db_conn, my_uid,
  1167. file_opts->coord_list,
  1168. &user_cond);
  1169. notice_thread_fini();
  1170. user->coord_accts = list_create(slurmdb_destroy_coord_rec);
  1171. coord_itr = list_iterator_create(file_opts->coord_list);
  1172. printf(" Making User '%s' coordinator for account(s)",
  1173. user->name);
  1174. while ((temp_char = list_next(coord_itr))) {
  1175. coord = xmalloc(sizeof(slurmdb_coord_rec_t));
  1176. coord->name = xstrdup(temp_char);
  1177. coord->direct = 1;
  1178. list_push(user->coord_accts, coord);
  1179. if (first) {
  1180. printf(" %s", temp_char);
  1181. first = 0;
  1182. } else
  1183. printf(", %s", temp_char);
  1184. }
  1185. list_iterator_destroy(coord_itr);
  1186. printf("\n");
  1187. set = 1;
  1188. } else if ((user->coord_accts && list_count(user->coord_accts))
  1189. && (file_opts->coord_list
  1190. && list_count(file_opts->coord_list))) {
  1191. ListIterator coord_itr = NULL;
  1192. ListIterator char_itr = NULL;
  1193. char *temp_char = NULL;
  1194. slurmdb_coord_rec_t *coord = NULL;
  1195. List add_list = list_create(NULL);
  1196. coord_itr = list_iterator_create(user->coord_accts);
  1197. char_itr = list_iterator_create(file_opts->coord_list);
  1198. while ((temp_char = list_next(char_itr))) {
  1199. while ((coord = list_next(coord_itr))) {
  1200. if (!coord->direct)
  1201. continue;
  1202. if (!strcmp(coord->name, temp_char)) {
  1203. break;
  1204. }
  1205. }
  1206. if (!coord) {
  1207. printf(" Making User '%s' coordinator of "
  1208. "account '%s'\n",
  1209. user->name,
  1210. temp_char);
  1211. list_append(add_list, temp_char);
  1212. }
  1213. list_iterator_reset(coord_itr);
  1214. }
  1215. list_iterator_destroy(char_itr);
  1216. list_iterator_destroy(coord_itr);
  1217. if (list_count(add_list)) {
  1218. notice_thread_init();
  1219. (void) acct_storage_g_add_coord(db_conn, my_uid,
  1220. add_list, &user_cond);
  1221. notice_thread_fini();
  1222. set = 1;
  1223. }
  1224. list_destroy(add_list);
  1225. }
  1226. if ((!user->wckey_list || !list_count(user->wckey_list))
  1227. && (file_opts->wckey_list
  1228. && list_count(file_opts->wckey_list))) {
  1229. ListIterator wckey_itr = NULL;
  1230. char *temp_char = NULL;
  1231. slurmdb_wckey_rec_t *wckey = NULL;
  1232. int first = 1;
  1233. user->wckey_list = list_create(slurmdb_destroy_wckey_rec);
  1234. wckey_itr = list_iterator_create(file_opts->wckey_list);
  1235. printf(" Adding WCKey(s) ");
  1236. while ((temp_char = list_next(wckey_itr))) {
  1237. wckey = xmalloc(sizeof(slurmdb_wckey_rec_t));
  1238. wckey->name = xstrdup(temp_char);
  1239. wckey->cluster = xstrdup(cluster);
  1240. wckey->user = xstrdup(user->name);
  1241. if (!strcmp(wckey->name, user->default_wckey))
  1242. wckey->is_def = 1;
  1243. list_push(user->wckey_list, wckey);
  1244. if (first) {
  1245. printf("'%s'", temp_char);
  1246. first = 0;
  1247. } else
  1248. printf(", '%s'", temp_char);
  1249. }
  1250. list_iterator_destroy(wckey_itr);
  1251. printf(" for user '%s'\n", user->name);
  1252. set = 1;
  1253. notice_thread_init();
  1254. acct_storage_g_add_wckeys(db_conn, my_uid, user->wckey_list);
  1255. notice_thread_fini();
  1256. } else if ((user->wckey_list && list_count(user->wckey_list))
  1257. && (file_opts->wckey_list
  1258. && list_count(file_opts->wckey_list))) {
  1259. ListIterator wckey_itr = NULL;
  1260. ListIterator char_itr = NULL;
  1261. char *temp_char = NULL;
  1262. slurmdb_wckey_rec_t *wckey = NULL;
  1263. List add_list = list_create(slurmdb_destroy_wckey_rec);
  1264. wckey_itr = list_iterator_create(user->wckey_list);
  1265. char_itr = list_iterator_create(file_opts->wckey_list);
  1266. while ((temp_char = list_next(char_itr))) {
  1267. while ((wckey = list_next(wckey_itr))) {
  1268. if (!strcmp(wckey->name, temp_char))
  1269. break;
  1270. }
  1271. if (!wckey) {
  1272. printf(" Adding WCKey '%s' to User '%s'\n",
  1273. temp_char, user->name);
  1274. wckey = xmalloc(sizeof(slurmdb_wckey_rec_t));
  1275. wckey->name = xstrdup(temp_char);
  1276. wckey->cluster = xstrdup(cluster);
  1277. wckey->user = xstrdup(user->name);
  1278. if (!strcmp(wckey->name, user->default_wckey))
  1279. wckey->is_def = 1;
  1280. list_append(add_list, wckey);
  1281. }
  1282. list_iterator_reset(wckey_itr);
  1283. }
  1284. list_iterator_destroy(char_itr);
  1285. list_iterator_destroy(wckey_itr);
  1286. if (list_count(add_list)) {
  1287. notice_thread_init();
  1288. acct_storage_g_add_wckeys(db_conn, my_uid, add_list);
  1289. notice_thread_fini();
  1290. set = 1;
  1291. }
  1292. list_transfer(user->wckey_list, add_list);
  1293. list_destroy(add_list);
  1294. }
  1295. list_destroy(assoc_cond.user_list);
  1296. return set;
  1297. }
  1298. static slurmdb_user_rec_t *_set_user_up(sacctmgr_file_opts_t *file_opts,
  1299. char *cluster, char *parent)
  1300. {
  1301. slurmdb_user_rec_t *user = xmalloc(sizeof(slurmdb_user_rec_t));
  1302. user->assoc_list = NULL;
  1303. user->name = xstrdup(file_opts->name);
  1304. if (file_opts->def_acct)
  1305. user->default_acct = xstrdup(file_opts->def_acct);
  1306. else
  1307. user->default_acct = xstrdup(parent);
  1308. if (file_opts->def_wckey)
  1309. user->default_wckey = xstrdup(file_opts->def_wckey);
  1310. else
  1311. user->default_wckey = xstrdup("");
  1312. user->admin_level = file_opts->admin;
  1313. if (file_opts->coord_list) {
  1314. slurmdb_user_cond_t user_cond;
  1315. slurmdb_association_cond_t assoc_cond;
  1316. ListIterator coord_itr = NULL;
  1317. char *temp_char = NULL;
  1318. slurmdb_coord_rec_t *coord = NULL;
  1319. memset(&user_cond, 0, sizeof(slurmdb_user_cond_t));
  1320. memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t));
  1321. assoc_cond.user_list = list_create(NULL);
  1322. list_append(assoc_cond.user_list, user->name);
  1323. user_cond.assoc_cond = &assoc_cond;
  1324. notice_thread_init();
  1325. acct_storage_g_add_coord(db_conn, my_uid,
  1326. file_opts->coord_list,
  1327. &user_cond);
  1328. notice_thread_fini();
  1329. list_destroy(assoc_cond.user_list);
  1330. user->coord_accts = list_create(slurmdb_destroy_coord_rec);
  1331. coord_itr = list_iterator_create(file_opts->coord_list);
  1332. while ((temp_char = list_next(coord_itr))) {
  1333. coord = xmalloc(sizeof(slurmdb_coord_rec_t));
  1334. coord->name = xstrdup(temp_char);
  1335. coord->direct = 1;
  1336. list_push(user->coord_accts, coord);
  1337. }
  1338. list_iterator_destroy(coord_itr);
  1339. }
  1340. if (file_opts->wckey_list) {
  1341. ListIterator wckey_itr = NULL;
  1342. char *temp_char = NULL;
  1343. slurmdb_wckey_rec_t *wckey = NULL;
  1344. user->wckey_list = list_create(slurmdb_destroy_wckey_rec);
  1345. wckey_itr = list_iterator_create(file_opts->wckey_list);
  1346. while ((temp_char = list_next(wckey_itr))) {
  1347. wckey = xmalloc(sizeof(slurmdb_wckey_rec_t));
  1348. wckey->name = xstrdup(temp_char);
  1349. wckey->user = xstrdup(user->name);
  1350. wckey->cluster = xstrdup(cluster);
  1351. if (!strcmp(wckey->name, user->default_wckey))
  1352. wckey->is_def = 1;
  1353. list_push(user->wckey_list, wckey);
  1354. }
  1355. list_iterator_destroy(wckey_itr);
  1356. notice_thread_init();
  1357. acct_storage_g_add_wckeys(db_conn, my_uid, user->wckey_list);
  1358. notice_thread_fini();
  1359. }
  1360. return user;
  1361. }
  1362. static slurmdb_account_rec_t *_set_acct_up(sacctmgr_file_opts_t *file_opts,
  1363. char *parent)
  1364. {
  1365. slurmdb_account_rec_t *acct = xmalloc(sizeof(slurmdb_account_rec_t));
  1366. acct->assoc_list = NULL;
  1367. acct->name = xstrdup(file_opts->name);
  1368. if (file_opts->desc)
  1369. acct->description = xstrdup(file_opts->desc);
  1370. else
  1371. acct->description = xstrdup(file_opts->name);
  1372. if (file_opts->org)
  1373. acct->organization = xstrdup(file_opts->org);
  1374. else if (strcmp(parent, "root"))
  1375. acct->organization = xstrdup(parent);
  1376. else
  1377. acct->organization = xstrdup(file_opts->name);
  1378. /* info("adding account %s (%s) (%s)", */
  1379. /* acct->name, acct->description, */
  1380. /* acct->organization); */
  1381. return acct;
  1382. }
  1383. static slurmdb_association_rec_t *_set_assoc_up(sacctmgr_file_opts_t *file_opts,
  1384. sacctmgr_mod_type_t mod_type,
  1385. char *cluster, char *parent)
  1386. {
  1387. slurmdb_association_rec_t *assoc = NULL;
  1388. if (!cluster) {
  1389. error("No cluster name was given for _set_assoc_up");
  1390. return NULL;
  1391. }
  1392. if (!parent && (mod_type != MOD_CLUSTER)) {
  1393. error("No parent was given for _set_assoc_up");
  1394. return NULL;
  1395. }
  1396. assoc = xmalloc(sizeof(slurmdb_association_rec_t));
  1397. slurmdb_init_association_rec(assoc, 0);
  1398. switch(mod_type) {
  1399. case MOD_CLUSTER:
  1400. assoc->acct = xstrdup(parent);
  1401. assoc->cluster = xstrdup(cluster);
  1402. break;
  1403. case MOD_ACCT:
  1404. assoc->acct = xstrdup(file_opts->name);
  1405. assoc->cluster = xstrdup(cluster);
  1406. assoc->parent_acct = xstrdup(parent);
  1407. break;
  1408. case MOD_USER:
  1409. assoc->acct = xstrdup(parent);
  1410. assoc->cluster = xstrdup(cluster);
  1411. assoc->partition = xstrdup(file_opts->part);
  1412. assoc->user = xstrdup(file_opts->name);
  1413. if (!strcmp(assoc->acct, file_opts->def_acct))
  1414. assoc->is_def = 1;
  1415. break;
  1416. default:
  1417. error("Unknown mod type for _set_assoc_up %d", mod_type);
  1418. slurmdb_destroy_association_rec(assoc);
  1419. assoc = NULL;
  1420. break;
  1421. }
  1422. assoc->shares_raw = file_opts->fairshare;
  1423. assoc->def_qos_id = file_opts->def_qos_id;
  1424. assoc->grp_cpu_mins = file_opts->grp_cpu_mins;
  1425. assoc->grp_cpus = file_opts->grp_cpus;
  1426. assoc->grp_jobs = file_opts->grp_jobs;
  1427. assoc->grp_mem = file_opts->grp_mem;
  1428. assoc->grp_nodes = file_opts->grp_nodes;
  1429. assoc->grp_submit_jobs = file_opts->grp_submit_jobs;
  1430. assoc->grp_wall = file_opts->grp_wall;
  1431. assoc->max_cpu_mins_pj = file_opts->max_cpu_mins_pj;
  1432. assoc->max_cpus_pj = file_opts->max_cpus_pj;
  1433. assoc->max_jobs = file_opts->max_jobs;
  1434. assoc->max_nodes_pj = file_opts->max_nodes_pj;
  1435. assoc->max_submit_jobs = file_opts->max_submit_jobs;
  1436. assoc->max_wall_pj = file_opts->max_wall_pj;
  1437. if (file_opts->qos_list && list_count(file_opts->qos_list))
  1438. assoc->qos_list = copy_char_list(file_opts->qos_list);
  1439. return assoc;
  1440. }
  1441. static int _print_file_slurmdb_hierarchical_rec_childern(
  1442. FILE *fd, List slurmdb_hierarchical_rec_list,
  1443. List user_list, List acct_list)
  1444. {
  1445. ListIterator itr = NULL;
  1446. slurmdb_hierarchical_rec_t *slurmdb_hierarchical_rec = NULL;
  1447. char *line = NULL;
  1448. slurmdb_user_rec_t *user_rec = NULL;
  1449. slurmdb_account_rec_t *acct_rec = NULL;
  1450. itr = list_iterator_create(slurmdb_hierarchical_rec_list);
  1451. while ((slurmdb_hierarchical_rec = list_next(itr))) {
  1452. if (slurmdb_hierarchical_rec->assoc->user) {
  1453. user_rec = sacctmgr_find_user_from_list(
  1454. user_list,
  1455. slurmdb_hierarchical_rec->assoc->user);
  1456. line = xstrdup_printf(
  1457. "User - %s",
  1458. slurmdb_hierarchical_rec->sort_name);
  1459. if (slurmdb_hierarchical_rec->assoc->partition)
  1460. xstrfmtcat(line, ":Partition='%s'",
  1461. slurmdb_hierarchical_rec->
  1462. assoc->partition);
  1463. if (user_rec) {
  1464. xstrfmtcat(line, ":DefaultAccount='%s'",
  1465. user_rec->default_acct);
  1466. if (user_rec->default_wckey
  1467. && user_rec->default_wckey[0])
  1468. xstrfmtcat(line, ":DefaultWCKey='%s'",
  1469. user_rec->default_wckey);
  1470. if (user_rec->admin_level > SLURMDB_ADMIN_NONE)
  1471. xstrfmtcat(line, ":AdminLevel='%s'",
  1472. slurmdb_admin_level_str(
  1473. user_rec->
  1474. admin_level));
  1475. if (user_rec->coord_accts
  1476. && list_count(user_rec->coord_accts)) {
  1477. ListIterator itr2 = NULL;
  1478. slurmdb_coord_rec_t *coord = NULL;
  1479. int first_coord = 1;
  1480. list_sort(user_rec->coord_accts,
  1481. (ListCmpF)sort_coord_list);
  1482. itr2 = list_iterator_create(
  1483. user_rec->coord_accts);
  1484. while ((coord = list_next(itr2))) {
  1485. /* We only care about
  1486. * the direct accounts here
  1487. */
  1488. if (!coord->direct)
  1489. continue;
  1490. if (first_coord) {
  1491. xstrfmtcat(
  1492. line,
  1493. ":Coordinator"
  1494. "='%s",
  1495. coord->name);
  1496. first_coord = 0;
  1497. } else {
  1498. xstrfmtcat(line, ",%s",
  1499. coord->name);
  1500. }
  1501. }
  1502. if (!first_coord)
  1503. xstrcat(line, "'");
  1504. list_iterator_destroy(itr2);
  1505. }
  1506. if (user_rec->wckey_list
  1507. && list_count(user_rec->wckey_list)) {
  1508. ListIterator itr2 = NULL;
  1509. slurmdb_wckey_rec_t *wckey = NULL;
  1510. int first_wckey = 1;
  1511. itr2 = list_iterator_create(
  1512. user_rec->wckey_list);
  1513. while ((wckey = list_next(itr2))) {
  1514. /* Avoid sending
  1515. non-legitimate wckeys.
  1516. */
  1517. if (!wckey->name ||
  1518. !wckey->name[0] ||
  1519. wckey->name[0] == '*')
  1520. continue;
  1521. if (first_wckey) {
  1522. xstrfmtcat(
  1523. line,
  1524. ":WCKeys='%s",
  1525. wckey->name);
  1526. first_wckey = 0;
  1527. } else {
  1528. xstrfmtcat(line, ",%s",
  1529. wckey->name);
  1530. }
  1531. }
  1532. if (!first_wckey)
  1533. xstrcat(line, "'");
  1534. list_iterator_destroy(itr2);
  1535. }
  1536. }
  1537. } else {
  1538. acct_rec = sacctmgr_find_account_from_list(
  1539. acct_list,
  1540. slurmdb_hierarchical_rec->assoc->acct);
  1541. line = xstrdup_printf(
  1542. "Account - %s",
  1543. slurmdb_hierarchical_rec->sort_name);
  1544. if (acct_rec) {
  1545. xstrfmtcat(line, ":Description='%s'",
  1546. acct_rec->description);
  1547. xstrfmtcat(line, ":Organization='%s'",
  1548. acct_rec->organization);
  1549. }
  1550. }
  1551. print_file_add_limits_to_line(&line,
  1552. slurmdb_hierarchical_rec->assoc);
  1553. if (fprintf(fd, "%s\n", line) < 0) {
  1554. exit_code=1;
  1555. fprintf(stderr, " Can't write to file");
  1556. xfree(line);
  1557. return SLURM_ERROR;
  1558. }
  1559. info("%s", line);
  1560. xfree(line);
  1561. }
  1562. list_iterator_destroy(itr);
  1563. print_file_slurmdb_hierarchical_rec_list(fd,
  1564. slurmdb_hierarchical_rec_list,
  1565. user_list, acct_list);
  1566. return SLURM_SUCCESS;
  1567. }
  1568. extern int print_file_add_limits_to_line(char **line,
  1569. slurmdb_association_rec_t *assoc)
  1570. {
  1571. if (!assoc)
  1572. return SLURM_ERROR;
  1573. if (assoc->def_qos_id && (assoc->def_qos_id != NO_VAL)) {
  1574. char *tmp_char;
  1575. if (!g_qos_list)
  1576. g_qos_list = acct_storage_g_get_qos(
  1577. db_conn, my_uid, NULL);
  1578. if ((tmp_char = slurmdb_qos_str(g_qos_list, assoc->def_qos_id)))
  1579. xstrfmtcat(*line, ":DefaultQOS='%s'", tmp_char);
  1580. }
  1581. if (assoc->shares_raw != INFINITE)
  1582. xstrfmtcat(*line, ":Fairshare=%u", assoc->shares_raw);
  1583. if (assoc->grp_cpu_mins != (uint64_t)INFINITE)
  1584. xstrfmtcat(*line, ":GrpCPUMins=%"PRIu64, assoc->grp_cpu_mins);
  1585. if (assoc->grp_cpus != INFINITE)
  1586. xstrfmtcat(*line, ":GrpCPUs=%u", assoc->grp_cpus);
  1587. if (assoc->grp_jobs != INFINITE)
  1588. xstrfmtcat(*line, ":GrpJobs=%u", assoc->grp_jobs);
  1589. if(assoc->grp_mem != INFINITE)
  1590. xstrfmtcat(*line, ":GrpMemory=%u", assoc->grp_mem);
  1591. if (assoc->grp_nodes != INFINITE)
  1592. xstrfmtcat(*line, ":GrpNodes=%u", assoc->grp_nodes);
  1593. if (assoc->grp_submit_jobs != INFINITE)
  1594. xstrfmtcat(*line, ":GrpSubmitJobs=%u", assoc->grp_submit_jobs);
  1595. if (assoc->grp_wall != INFINITE)
  1596. xstrfmtcat(*line, ":GrpWall=%u", assoc->grp_wall);
  1597. if (assoc->max_cpu_mins_pj != (uint64_t)INFINITE)
  1598. xstrfmtcat(*line, ":MaxCPUMinsPerJob=%"PRIu64,
  1599. assoc->max_cpu_mins_pj);
  1600. if (assoc->max_cpus_pj != INFINITE)
  1601. xstrfmtcat(*line, ":MaxCPUsPerJob=%u", assoc->max_cpus_pj);
  1602. if (assoc->max_jobs != INFINITE)
  1603. xstrfmtcat(*line, ":MaxJobs=%u", assoc->max_jobs);
  1604. if (assoc->max_nodes_pj != INFINITE)
  1605. xstrfmtcat(*line, ":MaxNodesPerJob=%u", assoc->max_nodes_pj);
  1606. if (assoc->max_submit_jobs != INFINITE)
  1607. xstrfmtcat(*line, ":MaxSubmitJobs=%u", assoc->max_submit_jobs);
  1608. if (assoc->max_wall_pj != INFINITE)
  1609. xstrfmtcat(*line, ":MaxWallDurationPerJob=%u",
  1610. assoc->max_wall_pj);
  1611. if (assoc->qos_list && list_count(assoc->qos_list)) {
  1612. char *temp_char = NULL;
  1613. if (!g_qos_list)
  1614. g_qos_list = acct_storage_g_get_qos(
  1615. db_conn, my_uid, NULL);
  1616. temp_char = get_qos_complete_str(g_qos_list, assoc->qos_list);
  1617. xstrfmtcat(*line, ":QOS='%s'", temp_char);
  1618. xfree(temp_char);
  1619. }
  1620. return SLURM_SUCCESS;
  1621. }
  1622. extern int print_file_slurmdb_hierarchical_rec_list(
  1623. FILE *fd,
  1624. List slurmdb_hierarchical_rec_list,
  1625. List user_list,
  1626. List acct_list)
  1627. {
  1628. ListIterator itr = NULL;
  1629. slurmdb_hierarchical_rec_t *slurmdb_hierarchical_rec = NULL;
  1630. itr = list_iterator_create(slurmdb_hierarchical_rec_list);
  1631. while ((slurmdb_hierarchical_rec = list_next(itr))) {
  1632. /* info("got here %d with %d from %s %s", */
  1633. /* depth, list_count(slurmdb_hierarchical_rec->childern), */
  1634. /* slurmdb_hierarchical_rec->assoc->acct,
  1635. slurmdb_hierarchical_rec->assoc->user); */
  1636. if (!list_count(slurmdb_hierarchical_rec->childern))
  1637. continue;
  1638. if (fprintf(fd, "Parent - %s\n",
  1639. slurmdb_hierarchical_rec->assoc->acct) < 0) {
  1640. error("Can't write to file");
  1641. return SLURM_ERROR;
  1642. }
  1643. info("%s - %s", "Parent",
  1644. slurmdb_hierarchical_rec->assoc->acct);
  1645. /* info("sending %d from %s", */
  1646. /* list_count(slurmdb_hierarchical_rec->childern), */
  1647. /* slurmdb_hierarchical_rec->assoc->acct); */
  1648. _print_file_slurmdb_hierarchical_rec_childern(
  1649. fd, slurmdb_hierarchical_rec->childern,
  1650. user_list, acct_list);
  1651. }
  1652. list_iterator_destroy(itr);
  1653. return SLURM_SUCCESS;
  1654. }
  1655. extern void load_sacctmgr_cfg_file (int argc, char *argv[])
  1656. {
  1657. DEF_TIMERS;
  1658. char line[BUFFER_SIZE];
  1659. FILE *fd = NULL;
  1660. char *parent = NULL;
  1661. char *file_name = NULL;
  1662. char *cluster_name = NULL;
  1663. char *user_name = NULL;
  1664. char object[25];
  1665. int start = 0, len = 0, i = 0;
  1666. int lc=0, num_lines=0;
  1667. int start_clean=0;
  1668. int cluster_name_set=0;
  1669. int rc = SLURM_SUCCESS;
  1670. sacctmgr_file_opts_t *file_opts = NULL;
  1671. slurmdb_association_rec_t *assoc = NULL, *assoc2 = NULL;
  1672. slurmdb_account_rec_t *acct = NULL, *acct2 = NULL;
  1673. slurmdb_cluster_rec_t *cluster = NULL;
  1674. slurmdb_user_rec_t *user = NULL, *user2 = NULL;
  1675. slurmdb_user_cond_t user_cond;
  1676. List curr_assoc_list = NULL;
  1677. List curr_acct_list = NULL;
  1678. List curr_cluster_list = NULL;
  1679. List curr_user_list = NULL;
  1680. /* This will be freed in their local counter parts */
  1681. List mod_acct_list = NULL;
  1682. List acct_list = NULL;
  1683. List slurmdb_assoc_list = NULL;
  1684. List mod_user_list = NULL;
  1685. List user_list = NULL;
  1686. List user_assoc_list = NULL;
  1687. List mod_assoc_list = NULL;
  1688. ListIterator itr;
  1689. ListIterator itr2;
  1690. List print_fields_list;
  1691. List format_list = NULL;
  1692. print_field_t *field = NULL;
  1693. int set = 0, command_len = 0;
  1694. if (readonly_flag) {
  1695. exit_code = 1;
  1696. fprintf(stderr, "Can't run this command in readonly mode.\n");
  1697. return;
  1698. }
  1699. /* reset the connection to get the most recent stuff */
  1700. acct_storage_g_commit(db_conn, 0);
  1701. for (i=0; i<argc; i++) {
  1702. int end = parse_option_end(argv[i]);
  1703. if (!end)
  1704. command_len=strlen(argv[i]);
  1705. else {
  1706. command_len=end-1;
  1707. if (argv[i][end] == '=') {
  1708. end++;
  1709. }
  1710. }
  1711. if (!end && !strncasecmp(argv[i], "clean",
  1712. MAX(command_len, 3))) {
  1713. start_clean = 1;
  1714. } else if (!end || !strncasecmp (argv[i], "File",
  1715. MAX(command_len, 1))) {
  1716. if (file_name) {
  1717. exit_code=1;
  1718. fprintf(stderr,
  1719. " File name already set to %s\n",
  1720. file_name);
  1721. continue;
  1722. }
  1723. file_name = xstrdup(argv[i]+end);
  1724. } else if (!strncasecmp (argv[i], "Cluster",
  1725. MAX(command_len, 3))) {
  1726. if (cluster_name) {
  1727. exit_code=1;
  1728. fprintf(stderr,
  1729. " Can only do one cluster at a time. "
  1730. "Already doing %s\n", cluster_name);
  1731. continue;
  1732. }
  1733. cluster_name = xstrdup(argv[i]+end);
  1734. cluster_name_set = 1;
  1735. } else {
  1736. exit_code=1;
  1737. fprintf(stderr, " Unknown option: %s\n", argv[i]);
  1738. }
  1739. }
  1740. if (!file_name) {
  1741. exit_code=1;
  1742. xfree(cluster_name);
  1743. fprintf(stderr,
  1744. " No filename given, specify one with file=''\n");
  1745. return;
  1746. }
  1747. fd = fopen(file_name, "r");
  1748. xfree(file_name);
  1749. if (fd == NULL) {
  1750. exit_code=1;
  1751. fprintf(stderr, " Unable to read \"%s\": %m\n", argv[0]);
  1752. xfree(cluster_name);
  1753. return;
  1754. }
  1755. curr_acct_list = acct_storage_g_get_accounts(db_conn, my_uid, NULL);
  1756. /* These are new info so they need to be freed here */
  1757. acct_list = list_create(slurmdb_destroy_account_rec);
  1758. slurmdb_assoc_list = list_create(slurmdb_destroy_association_rec);
  1759. user_list = list_create(slurmdb_destroy_user_rec);
  1760. user_assoc_list = list_create(slurmdb_destroy_association_rec);
  1761. mod_acct_list = list_create(slurmdb_destroy_account_rec);
  1762. mod_user_list = list_create(slurmdb_destroy_user_rec);
  1763. mod_assoc_list = list_create(slurmdb_destroy_association_rec);
  1764. format_list = list_create(slurm_destroy_char);
  1765. while ((num_lines = _get_next_line(line, BUFFER_SIZE, fd)) > 0) {
  1766. lc += num_lines;
  1767. /* skip empty lines */
  1768. if (line[0] == '\0') {
  1769. continue;
  1770. }
  1771. len = strlen(line);
  1772. memset(object, 0, sizeof(object));
  1773. /* first find the object */
  1774. start=0;
  1775. for(i=0; i<len; i++) {
  1776. if (line[i] == '-') {
  1777. start = i;
  1778. if (line[i-1] == ' ')
  1779. i--;
  1780. if (i<sizeof(object))
  1781. strncpy(object, line, i);
  1782. break;
  1783. }
  1784. }
  1785. if (!object[0])
  1786. continue;
  1787. while (line[start] != ' ' && start<len)
  1788. start++;
  1789. if (start>=len) {
  1790. exit_code=1;
  1791. fprintf(stderr, " Nothing after object "
  1792. "name '%s'. line(%d)\n",
  1793. object, lc);
  1794. rc = SLURM_ERROR;
  1795. break;
  1796. }
  1797. start++;
  1798. if (!strcasecmp("Machine", object)
  1799. || !strcasecmp("Cluster", object)) {
  1800. slurmdb_association_cond_t assoc_cond;
  1801. if (cluster_name && !cluster_name_set) {
  1802. exit_code=1;
  1803. fprintf(stderr, " You can only add one cluster "
  1804. "at a time.\n");
  1805. rc = SLURM_ERROR;
  1806. break;
  1807. }
  1808. file_opts = _parse_options(line+start);
  1809. if (!file_opts) {
  1810. exit_code=1;
  1811. fprintf(stderr,
  1812. " error: Problem with line(%d)\n", lc);
  1813. rc = SLURM_ERROR;
  1814. break;
  1815. }
  1816. if (!cluster_name_set)
  1817. cluster_name = xstrdup(file_opts->name);
  1818. /* we have to do this here since this is the
  1819. first place we have the cluster_name
  1820. */
  1821. memset(&user_cond, 0, sizeof(slurmdb_user_cond_t));
  1822. user_cond.with_coords = 1;
  1823. user_cond.with_assocs = 1;
  1824. user_cond.with_wckeys = 1;
  1825. memset(&assoc_cond, 0,
  1826. sizeof(slurmdb_association_cond_t));
  1827. assoc_cond.cluster_list = list_create(NULL);
  1828. assoc_cond.with_raw_qos = 1;
  1829. assoc_cond.without_parent_limits = 1;
  1830. list_append(assoc_cond.cluster_list, cluster_name);
  1831. user_cond.assoc_cond = &assoc_cond;
  1832. curr_user_list = acct_storage_g_get_users(
  1833. db_conn, my_uid, &user_cond);
  1834. user_cond.assoc_cond = NULL;
  1835. assoc_cond.only_defs = 0;
  1836. /* make sure this person running is an admin */
  1837. user_name = uid_to_string(my_uid);
  1838. if (!(user = sacctmgr_find_user_from_list(
  1839. curr_user_list, user_name))) {
  1840. exit_code=1;
  1841. fprintf(stderr, " Your uid (%u) is not in the "
  1842. "accounting system, can't load file.\n",
  1843. my_uid);
  1844. if (curr_user_list)
  1845. list_destroy(curr_user_list);
  1846. xfree(user_name);
  1847. return;
  1848. } else {
  1849. if (my_uid != slurm_get_slurm_user_id()
  1850. && my_uid != 0
  1851. && (user->admin_level
  1852. < SLURMDB_ADMIN_SUPER_USER)) {
  1853. exit_code=1;
  1854. fprintf(stderr,
  1855. " Your user does not have "
  1856. "sufficient "
  1857. "privileges to load files.\n");
  1858. if (curr_user_list)
  1859. list_destroy(curr_user_list);
  1860. xfree(user_name);
  1861. return;
  1862. }
  1863. }
  1864. xfree(user_name);
  1865. if (start_clean) {
  1866. slurmdb_cluster_cond_t cluster_cond;
  1867. List ret_list = NULL;
  1868. if (!commit_check("You requested to flush "
  1869. "the cluster before "
  1870. "adding it again.\n"
  1871. "Are you sure you want "
  1872. "to continue?")) {
  1873. printf("Aborted\n");
  1874. break;
  1875. }
  1876. slurmdb_init_cluster_cond(&cluster_cond, 0);
  1877. cluster_cond.cluster_list = list_create(NULL);
  1878. list_append(cluster_cond.cluster_list,
  1879. cluster_name);
  1880. notice_thread_init();
  1881. ret_list = acct_storage_g_remove_clusters(
  1882. db_conn, my_uid, &cluster_cond);
  1883. notice_thread_fini();
  1884. list_destroy(cluster_cond.cluster_list);
  1885. if (!ret_list) {
  1886. exit_code=1;
  1887. fprintf(stderr, " There was a problem "
  1888. "removing the cluster.\n");
  1889. rc = SLURM_ERROR;
  1890. break;
  1891. }
  1892. /* This needs to be commited or
  1893. problems may arise */
  1894. acct_storage_g_commit(db_conn, 1);
  1895. }
  1896. curr_cluster_list = acct_storage_g_get_clusters(
  1897. db_conn, my_uid, NULL);
  1898. if (cluster_name)
  1899. printf("For cluster %s\n", cluster_name);
  1900. if (!(cluster = sacctmgr_find_cluster_from_list(
  1901. curr_cluster_list, cluster_name))) {
  1902. List temp_assoc_list = list_create(NULL);
  1903. List cluster_list = list_create(
  1904. slurmdb_destroy_cluster_rec);
  1905. cluster = xmalloc(
  1906. sizeof(slurmdb_cluster_rec_t));
  1907. slurmdb_init_cluster_rec(cluster, 0);
  1908. list_append(cluster_list, cluster);
  1909. cluster->name = xstrdup(cluster_name);
  1910. if (file_opts->classification) {
  1911. cluster->classification =
  1912. file_opts->classification;
  1913. printf("Classification: %s\n",
  1914. get_classification_str(
  1915. cluster->
  1916. classification));
  1917. }
  1918. cluster->root_assoc = _set_assoc_up(
  1919. file_opts, MOD_CLUSTER,
  1920. cluster_name, "root");
  1921. list_append(temp_assoc_list,
  1922. cluster->root_assoc);
  1923. rc = _print_out_assoc(temp_assoc_list, 0, 0);
  1924. list_destroy(temp_assoc_list);
  1925. notice_thread_init();
  1926. rc = acct_storage_g_add_clusters(
  1927. db_conn, my_uid, cluster_list);
  1928. notice_thread_fini();
  1929. list_destroy(cluster_list);
  1930. if (rc != SLURM_SUCCESS) {
  1931. exit_code=1;
  1932. fprintf(stderr,
  1933. " Problem adding cluster: %s\n",
  1934. slurm_strerror(rc));
  1935. rc = SLURM_ERROR;
  1936. _destroy_sacctmgr_file_opts(file_opts);
  1937. break;
  1938. }
  1939. /* This needs to be commited or
  1940. problems may arise */
  1941. acct_storage_g_commit(db_conn, 1);
  1942. set = 1;
  1943. } else {
  1944. set = _mod_cluster(file_opts,
  1945. cluster, parent);
  1946. }
  1947. _destroy_sacctmgr_file_opts(file_opts);
  1948. /* assoc_cond if set up above */
  1949. curr_assoc_list = acct_storage_g_get_associations(
  1950. db_conn, my_uid, &assoc_cond);
  1951. list_destroy(assoc_cond.cluster_list);
  1952. if (!curr_assoc_list) {
  1953. exit_code=1;
  1954. fprintf(stderr, " Problem getting associations "
  1955. "for this cluster\n");
  1956. rc = SLURM_ERROR;
  1957. break;
  1958. }
  1959. //info("got %d assocs", list_count(curr_assoc_list));
  1960. continue;
  1961. } else if (!cluster_name) {
  1962. exit_code=1;
  1963. fprintf(stderr, " You need to specify a cluster name "
  1964. "first with 'Cluster - $NAME' in your file\n");
  1965. break;
  1966. }
  1967. if (!strcasecmp("Parent", object)) {
  1968. xfree(parent);
  1969. i = start;
  1970. while (line[i] != '\n' && i<len)
  1971. i++;
  1972. if (i >= len) {
  1973. exit_code=1;
  1974. fprintf(stderr, " No parent name "
  1975. "given line(%d)\n",
  1976. lc);
  1977. rc = SLURM_ERROR;
  1978. break;
  1979. }
  1980. parent = xstrndup(line+start, i-start);
  1981. //info("got parent %s", parent);
  1982. if (!sacctmgr_find_account_base_assoc_from_list(
  1983. curr_assoc_list, parent, cluster_name)
  1984. && !sacctmgr_find_account_base_assoc_from_list(
  1985. slurmdb_assoc_list, parent, cluster_name)) {
  1986. exit_code=1;
  1987. fprintf(stderr, " line(%d) You need to add "
  1988. "this parent (%s) as a child before "
  1989. "you can add childern to it.\n",
  1990. lc, parent);
  1991. break;
  1992. }
  1993. continue;
  1994. } else if (!parent) {
  1995. parent = xstrdup("root");
  1996. printf(" No parent given creating off root, "
  1997. "If incorrect specify 'Parent - name' "
  1998. "before any childern in your file\n");
  1999. }
  2000. if (!strcasecmp("Project", object)
  2001. || !strcasecmp("Account", object)) {
  2002. file_opts = _parse_options(line+start);
  2003. if (!file_opts) {
  2004. exit_code=1;
  2005. fprintf(stderr, " Problem with line(%d)\n", lc);
  2006. rc = SLURM_ERROR;
  2007. break;
  2008. }
  2009. //info("got a project %s of %s", file_opts->name, parent);
  2010. if (!(acct = sacctmgr_find_account_from_list(
  2011. curr_acct_list, file_opts->name))
  2012. && !sacctmgr_find_account_from_list(
  2013. acct_list, file_opts->name)) {
  2014. acct = _set_acct_up(file_opts, parent);
  2015. list_append(acct_list, acct);
  2016. /* don't add anything to the
  2017. curr_acct_list */
  2018. assoc = _set_assoc_up(file_opts, MOD_ACCT,
  2019. cluster_name, parent);
  2020. list_append(slurmdb_assoc_list, assoc);
  2021. /* don't add anything to the
  2022. curr_assoc_list */
  2023. } else if (!(assoc =
  2024. sacctmgr_find_account_base_assoc_from_list(
  2025. curr_assoc_list, file_opts->name,
  2026. cluster_name)) &&
  2027. !sacctmgr_find_account_base_assoc_from_list(
  2028. slurmdb_assoc_list, file_opts->name,
  2029. cluster_name)) {
  2030. acct2 = sacctmgr_find_account_from_list(
  2031. mod_acct_list, file_opts->name);
  2032. if (!acct2) {
  2033. acct2 = xmalloc(
  2034. sizeof(slurmdb_account_rec_t));
  2035. list_append(mod_acct_list, acct2);
  2036. acct2->name = xstrdup(file_opts->name);
  2037. if (_mod_acct(file_opts, acct, parent))
  2038. set = 1;
  2039. } else {
  2040. debug2("already modified this account");
  2041. }
  2042. assoc = _set_assoc_up(file_opts, MOD_ACCT,
  2043. cluster_name, parent);
  2044. list_append(slurmdb_assoc_list, assoc);
  2045. /* don't add anything to the
  2046. curr_assoc_list */
  2047. } else if (assoc) {
  2048. acct2 = sacctmgr_find_account_from_list(
  2049. mod_acct_list, file_opts->name);
  2050. if (!acct2) {
  2051. acct2 = xmalloc(
  2052. sizeof(slurmdb_account_rec_t));
  2053. list_append(mod_acct_list, acct2);
  2054. acct2->name = xstrdup(file_opts->name);
  2055. if (_mod_acct(file_opts, acct, parent))
  2056. set = 1;
  2057. } else {
  2058. debug2("already modified this account");
  2059. }
  2060. assoc2 = sacctmgr_find_association_from_list(
  2061. mod_assoc_list,
  2062. NULL, file_opts->name,
  2063. cluster_name,
  2064. NULL);
  2065. if (!assoc2) {
  2066. assoc2 = xmalloc(
  2067. sizeof(slurmdb_association_rec_t));
  2068. slurmdb_init_association_rec(assoc2, 0);
  2069. list_append(mod_assoc_list, assoc2);
  2070. assoc2->cluster = xstrdup(cluster_name);
  2071. assoc2->acct = xstrdup(file_opts->name);
  2072. assoc2->parent_acct =
  2073. xstrdup(assoc->parent_acct);
  2074. if (_mod_assoc(file_opts,
  2075. assoc, MOD_ACCT, parent))
  2076. set = 1;
  2077. } else {
  2078. debug2("already modified this assoc");
  2079. }
  2080. }
  2081. _destroy_sacctmgr_file_opts(file_opts);
  2082. continue;
  2083. } else if (!strcasecmp("User", object)) {
  2084. file_opts = _parse_options(line+start);
  2085. if (!file_opts) {
  2086. exit_code=1;
  2087. fprintf(stderr, " Problem with line(%d)\n", lc);
  2088. rc = SLURM_ERROR;
  2089. break;
  2090. }
  2091. if (!(user = sacctmgr_find_user_from_list(
  2092. curr_user_list, file_opts->name))
  2093. && !sacctmgr_find_user_from_list(
  2094. user_list, file_opts->name)) {
  2095. user = _set_user_up(file_opts, cluster_name,
  2096. parent);
  2097. list_append(user_list, user);
  2098. /* don't add anything to the
  2099. curr_user_list */
  2100. assoc = _set_assoc_up(file_opts, MOD_USER,
  2101. cluster_name, parent);
  2102. list_append(user_assoc_list, assoc);
  2103. /* don't add anything to the
  2104. curr_assoc_list */
  2105. } else if (!(assoc =
  2106. sacctmgr_find_association_from_list(
  2107. curr_assoc_list,
  2108. file_opts->name, parent,
  2109. cluster_name, file_opts->part))
  2110. && !sacctmgr_find_association_from_list(
  2111. user_assoc_list,
  2112. file_opts->name, parent,
  2113. cluster_name,
  2114. file_opts->part)) {
  2115. /* This means the user was added
  2116. * during this round but this is a new
  2117. * association we are adding
  2118. */
  2119. if (!user)
  2120. goto new_association;
  2121. /* This means there could be a change
  2122. * on the user.
  2123. */
  2124. user2 = sacctmgr_find_user_from_list(
  2125. mod_user_list, file_opts->name);
  2126. if (!user2) {
  2127. user2 = xmalloc(
  2128. sizeof(slurmdb_user_rec_t));
  2129. list_append(mod_user_list, user2);
  2130. user2->name = xstrdup(file_opts->name);
  2131. if (_mod_user(file_opts, user,
  2132. cluster_name, parent))
  2133. set = 1;
  2134. } else {
  2135. debug2("already modified this user");
  2136. }
  2137. new_association:
  2138. assoc = _set_assoc_up(file_opts, MOD_USER,
  2139. cluster_name, parent);
  2140. list_append(user_assoc_list, assoc);
  2141. /* don't add anything to the
  2142. curr_assoc_list */
  2143. } else if (assoc) {
  2144. user2 = sacctmgr_find_user_from_list(
  2145. mod_user_list, file_opts->name);
  2146. if (!user2) {
  2147. user2 = xmalloc(
  2148. sizeof(slurmdb_user_rec_t));
  2149. list_append(mod_user_list, user2);
  2150. user2->name = xstrdup(file_opts->name);
  2151. if (_mod_user(file_opts, user,
  2152. cluster_name, parent))
  2153. set = 1;
  2154. } else {
  2155. debug2("already modified this user");
  2156. }
  2157. assoc2 = sacctmgr_find_association_from_list(
  2158. mod_assoc_list,
  2159. file_opts->name, parent,
  2160. cluster_name,
  2161. file_opts->part);
  2162. if (!assoc2) {
  2163. assoc2 = xmalloc(
  2164. sizeof(slurmdb_association_rec_t));
  2165. slurmdb_init_association_rec(assoc2, 0);
  2166. list_append(mod_assoc_list, assoc2);
  2167. assoc2->cluster = xstrdup(cluster_name);
  2168. assoc2->acct = xstrdup(parent);
  2169. assoc2->user = xstrdup(file_opts->name);
  2170. assoc2->partition =
  2171. xstrdup(file_opts->part);
  2172. if (_mod_assoc(file_opts,
  2173. assoc, MOD_USER, parent))
  2174. set = 1;
  2175. } else {
  2176. debug2("already modified this assoc");
  2177. }
  2178. }
  2179. //info("got a user %s", file_opts->name);
  2180. _destroy_sacctmgr_file_opts(file_opts);
  2181. continue;
  2182. } else {
  2183. exit_code=1;
  2184. fprintf(stderr,
  2185. " Misformatted line(%d): %s\n", lc, line);
  2186. rc = SLURM_ERROR;
  2187. break;
  2188. }
  2189. }
  2190. fclose(fd);
  2191. xfree(cluster_name);
  2192. xfree(parent);
  2193. START_TIMER;
  2194. if (rc == SLURM_SUCCESS && list_count(acct_list)) {
  2195. printf("Accounts\n");
  2196. slurm_addto_char_list(format_list,
  2197. "Name,Description,Organization,QOS");
  2198. print_fields_list = sacctmgr_process_format_list(format_list);
  2199. list_flush(format_list);
  2200. print_fields_header(print_fields_list);
  2201. itr = list_iterator_create(acct_list);
  2202. itr2 = list_iterator_create(print_fields_list);
  2203. while ((acct = list_next(itr))) {
  2204. while ((field = list_next(itr2))) {
  2205. switch(field->type) {
  2206. case PRINT_DESC:
  2207. field->print_routine(
  2208. field, acct->description);
  2209. break;
  2210. case PRINT_NAME:
  2211. field->print_routine(
  2212. field, acct->name);
  2213. break;
  2214. case PRINT_ORG:
  2215. field->print_routine(
  2216. field, acct->organization);
  2217. break;
  2218. default:
  2219. field->print_routine(
  2220. field, NULL);
  2221. break;
  2222. }
  2223. }
  2224. list_iterator_reset(itr2);
  2225. printf("\n");
  2226. }
  2227. list_iterator_destroy(itr);
  2228. list_iterator_destroy(itr2);
  2229. list_destroy(print_fields_list);
  2230. rc = acct_storage_g_add_accounts(db_conn, my_uid, acct_list);
  2231. printf("-----------------------------"
  2232. "----------------------\n\n");
  2233. set = 1;
  2234. }
  2235. if (rc == SLURM_SUCCESS && list_count(slurmdb_assoc_list)) {
  2236. printf("Account Associations\n");
  2237. rc = _print_out_assoc(slurmdb_assoc_list, 0, 1);
  2238. set = 1;
  2239. }
  2240. if (rc == SLURM_SUCCESS && list_count(user_list)) {
  2241. printf("Users\n");
  2242. slurm_addto_char_list(format_list,
  2243. "Name,DefaultA,DefaultW,QOS,Admin,Coord");
  2244. print_fields_list = sacctmgr_process_format_list(format_list);
  2245. list_flush(format_list);
  2246. print_fields_header(print_fields_list);
  2247. itr = list_iterator_create(user_list);
  2248. itr2 = list_iterator_create(print_fields_list);
  2249. while ((user = list_next(itr))) {
  2250. while ((field = list_next(itr2))) {
  2251. switch(field->type) {
  2252. case PRINT_ADMIN:
  2253. field->print_routine(
  2254. field,
  2255. slurmdb_admin_level_str(
  2256. user->admin_level));
  2257. break;
  2258. case PRINT_COORDS:
  2259. field->print_routine(
  2260. field,
  2261. user->coord_accts);
  2262. break;
  2263. case PRINT_DACCT:
  2264. field->print_routine(
  2265. field,
  2266. user->default_acct);
  2267. break;
  2268. case PRINT_DWCKEY:
  2269. field->print_routine(
  2270. field,
  2271. user->default_wckey);
  2272. break;
  2273. case PRINT_NAME:
  2274. field->print_routine(
  2275. field, user->name);
  2276. break;
  2277. case PRINT_WCKEYS:
  2278. field->print_routine(
  2279. field, user->wckey_list);
  2280. break;
  2281. default:
  2282. field->print_routine(
  2283. field, NULL);
  2284. break;
  2285. }
  2286. }
  2287. list_iterator_reset(itr2);
  2288. printf("\n");
  2289. }
  2290. list_iterator_destroy(itr);
  2291. list_iterator_destroy(itr2);
  2292. list_destroy(print_fields_list);
  2293. rc = acct_storage_g_add_users(db_conn, my_uid, user_list);
  2294. printf("---------------------------"
  2295. "------------------------\n\n");
  2296. set = 1;
  2297. }
  2298. if (rc == SLURM_SUCCESS && list_count(user_assoc_list)) {
  2299. printf("User Associations\n");
  2300. rc = _print_out_assoc(user_assoc_list, 1, 1);
  2301. set = 1;
  2302. }
  2303. END_TIMER2("add cluster");
  2304. if (set)
  2305. info("Done adding cluster in %s", TIME_STR);
  2306. if (rc == SLURM_SUCCESS) {
  2307. if (set) {
  2308. if (commit_check("Would you like to commit changes?")) {
  2309. acct_storage_g_commit(db_conn, 1);
  2310. } else {
  2311. printf(" Changes Discarded\n");
  2312. acct_storage_g_commit(db_conn, 0);
  2313. }
  2314. } else {
  2315. printf(" Nothing new added.\n");
  2316. }
  2317. } else {
  2318. exit_code=1;
  2319. fprintf(stderr, " Problem with requests: %s\n",
  2320. slurm_strerror(rc));
  2321. }
  2322. list_destroy(format_list);
  2323. list_destroy(mod_acct_list);
  2324. list_destroy(acct_list);
  2325. list_destroy(slurmdb_assoc_list);
  2326. list_destroy(mod_user_list);
  2327. list_destroy(user_list);
  2328. list_destroy(user_assoc_list);
  2329. list_destroy(mod_assoc_list);
  2330. if (curr_acct_list)
  2331. list_destroy(curr_acct_list);
  2332. if (curr_assoc_list)
  2333. list_destroy(curr_assoc_list);
  2334. if (curr_cluster_list)
  2335. list_destroy(curr_cluster_list);
  2336. if (curr_user_list)
  2337. list_destroy(curr_user_list);
  2338. }