PageRenderTime 54ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/src/sacctmgr/account_functions.c

https://github.com/cfenoy/slurm
C | 1231 lines | 1047 code | 124 blank | 60 comment | 246 complexity | 661c81878109bd626001d9f67239fb03 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
  1. /*****************************************************************************\
  2. * account_functions.c - functions dealing with accounts in the
  3. * accounting system.
  4. *****************************************************************************
  5. * Copyright (C) 2002-2007 The Regents of the University of California.
  6. * Copyright (C) 2008-2010 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/assoc_mgr.h"
  42. static int _set_cond(int *start, int argc, char *argv[],
  43. slurmdb_account_cond_t *acct_cond,
  44. List format_list)
  45. {
  46. int i;
  47. int a_set = 0;
  48. int u_set = 0;
  49. int end = 0;
  50. slurmdb_association_cond_t *assoc_cond = NULL;
  51. int command_len = 0;
  52. int option = 0;
  53. if(!acct_cond) {
  54. exit_code=1;
  55. fprintf(stderr, "No acct_cond given");
  56. return -1;
  57. }
  58. if(!acct_cond->assoc_cond) {
  59. acct_cond->assoc_cond =
  60. xmalloc(sizeof(slurmdb_association_cond_t));
  61. }
  62. assoc_cond = acct_cond->assoc_cond;
  63. for (i=(*start); i<argc; i++) {
  64. end = parse_option_end(argv[i]);
  65. if(!end)
  66. command_len=strlen(argv[i]);
  67. else {
  68. command_len=end-1;
  69. if(argv[i][end] == '=') {
  70. option = (int)argv[i][end-1];
  71. end++;
  72. }
  73. }
  74. if (!strncasecmp(argv[i], "Set", MAX(command_len, 3))) {
  75. i--;
  76. break;
  77. } else if (!end &&
  78. !strncasecmp(argv[i], "WithAssoc",
  79. MAX(command_len, 5))) {
  80. acct_cond->with_assocs = 1;
  81. } else if (!end &&
  82. !strncasecmp(argv[i], "WithCoordinators",
  83. MAX(command_len, 5))) {
  84. acct_cond->with_coords = 1;
  85. } else if (!end &&
  86. !strncasecmp(argv[i], "WithDeleted",
  87. MAX(command_len, 5))) {
  88. acct_cond->with_deleted = 1;
  89. assoc_cond->with_deleted = 1;
  90. } else if (!end &&
  91. !strncasecmp(argv[i], "WithRawQOSLevel",
  92. MAX(command_len, 5))) {
  93. assoc_cond->with_raw_qos = 1;
  94. } else if (!end && !strncasecmp(argv[i], "WOPLimits",
  95. MAX(command_len, 4))) {
  96. assoc_cond->without_parent_limits = 1;
  97. } else if(!end && !strncasecmp(argv[i], "where",
  98. MAX(command_len, 5))) {
  99. continue;
  100. } else if(!end
  101. || !strncasecmp(argv[i], "Names",
  102. MAX(command_len, 1))
  103. || !strncasecmp(argv[i], "Accounts",
  104. MAX(command_len, 1))
  105. || !strncasecmp(argv[i], "Acct",
  106. MAX(command_len, 4))) {
  107. if(!assoc_cond->acct_list) {
  108. assoc_cond->acct_list =
  109. list_create(slurm_destroy_char);
  110. }
  111. if(slurm_addto_char_list(
  112. assoc_cond->acct_list,
  113. argv[i]+end))
  114. u_set = 1;
  115. } else if (!strncasecmp(argv[i], "Descriptions",
  116. MAX(command_len, 1))) {
  117. if(!acct_cond->description_list) {
  118. acct_cond->description_list =
  119. list_create(slurm_destroy_char);
  120. }
  121. if(slurm_addto_char_list(acct_cond->description_list,
  122. argv[i]+end))
  123. u_set = 1;
  124. } else if (!strncasecmp(argv[i], "Format",
  125. MAX(command_len, 1))) {
  126. if(format_list)
  127. slurm_addto_char_list(format_list, argv[i]+end);
  128. } else if (!strncasecmp(argv[i], "Organizations",
  129. MAX(command_len, 1))) {
  130. if(!acct_cond->organization_list) {
  131. acct_cond->organization_list =
  132. list_create(slurm_destroy_char);
  133. }
  134. if(slurm_addto_char_list(acct_cond->organization_list,
  135. argv[i]+end))
  136. u_set = 1;
  137. } else if(!(a_set = sacctmgr_set_association_cond(
  138. assoc_cond, argv[i], argv[i]+end,
  139. command_len, option))) {
  140. exit_code=1;
  141. fprintf(stderr, " Unknown condition: %s\n"
  142. " Use keyword 'set' to modify value\n",
  143. argv[i]);
  144. }
  145. }
  146. (*start) = i;
  147. if(u_set && a_set)
  148. return 3;
  149. else if(a_set)
  150. return 2;
  151. else if(u_set)
  152. return 1;
  153. return 0;
  154. }
  155. static int _set_rec(int *start, int argc, char *argv[],
  156. List acct_list,
  157. List cluster_list,
  158. slurmdb_account_rec_t *acct,
  159. slurmdb_association_rec_t *assoc)
  160. {
  161. int i;
  162. int u_set = 0;
  163. int a_set = 0;
  164. int end = 0;
  165. int command_len = 0;
  166. int option = 0;
  167. for (i=(*start); i<argc; i++) {
  168. end = parse_option_end(argv[i]);
  169. if(!end)
  170. command_len=strlen(argv[i]);
  171. else {
  172. command_len=end-1;
  173. if(argv[i][end] == '=') {
  174. option = (int)argv[i][end-1];
  175. end++;
  176. }
  177. }
  178. if (!strncasecmp(argv[i], "Where", MAX(command_len, 5))) {
  179. i--;
  180. break;
  181. } else if(!end && !strncasecmp(argv[i], "set",
  182. MAX(command_len, 3))) {
  183. continue;
  184. } else if(!end
  185. || !strncasecmp(argv[i], "Accounts",
  186. MAX(command_len, 1))
  187. || !strncasecmp(argv[i], "Names",
  188. MAX(command_len, 1))
  189. || !strncasecmp(argv[i], "Acct",
  190. MAX(command_len, 4))) {
  191. if(acct_list)
  192. slurm_addto_char_list(acct_list, argv[i]+end);
  193. else {
  194. exit_code=1;
  195. fprintf(stderr,
  196. " Can't modify the name "
  197. "of an account\n");
  198. }
  199. } else if (!strncasecmp(argv[i], "Clusters",
  200. MAX(command_len, 1))) {
  201. if(cluster_list)
  202. slurm_addto_char_list(cluster_list,
  203. argv[i]+end);
  204. else {
  205. exit_code=1;
  206. fprintf(stderr,
  207. " Can't modify the cluster "
  208. "of an account\n");
  209. }
  210. } else if (!strncasecmp(argv[i], "Description",
  211. MAX(command_len, 1))) {
  212. acct->description = strip_quotes(argv[i]+end, NULL, 1);
  213. u_set = 1;
  214. } else if (!strncasecmp(argv[i], "Organization",
  215. MAX(command_len, 1))) {
  216. acct->organization = strip_quotes(argv[i]+end, NULL, 1);
  217. u_set = 1;
  218. } else if (!strncasecmp (argv[i], "RawUsage",
  219. MAX(command_len, 7))) {
  220. uint32_t usage;
  221. if(!assoc)
  222. continue;
  223. assoc->usage = xmalloc(sizeof(
  224. assoc_mgr_association_usage_t));
  225. if (get_uint(argv[i]+end, &usage,
  226. "RawUsage") == SLURM_SUCCESS) {
  227. assoc->usage->usage_raw = usage;
  228. a_set = 1;
  229. }
  230. } else if(!assoc ||
  231. (assoc && !(a_set = sacctmgr_set_association_rec(
  232. assoc, argv[i], argv[i]+end,
  233. command_len, option)))) {
  234. exit_code=1;
  235. fprintf(stderr, " Unknown option: %s\n"
  236. " Use keyword 'where' to modify condition\n",
  237. argv[i]);
  238. }
  239. }
  240. (*start) = i;
  241. if(u_set && a_set)
  242. return 3;
  243. else if(a_set)
  244. return 2;
  245. else if(u_set)
  246. return 1;
  247. return 0;
  248. }
  249. static int _isdefault_old(List acct_list)
  250. {
  251. int rc = 0;
  252. slurmdb_user_cond_t user_cond;
  253. List ret_list = NULL;
  254. if(!acct_list || !list_count(acct_list))
  255. return rc;
  256. memset(&user_cond, 0, sizeof(slurmdb_user_cond_t));
  257. user_cond.def_acct_list = acct_list;
  258. ret_list = acct_storage_g_get_users(db_conn, my_uid, &user_cond);
  259. if(ret_list && list_count(ret_list)) {
  260. ListIterator itr = list_iterator_create(ret_list);
  261. slurmdb_user_rec_t *user = NULL;
  262. fprintf(stderr," Users listed below have these "
  263. "as their Default Accounts.\n");
  264. while((user = list_next(itr))) {
  265. fprintf(stderr, " User - %-10.10s Account - %s\n",
  266. user->name, user->default_acct);
  267. }
  268. list_iterator_destroy(itr);
  269. rc = 1;
  270. }
  271. if(ret_list)
  272. list_destroy(ret_list);
  273. return rc;
  274. }
  275. static int _isdefault(int cond_set, List acct_list, List assoc_list)
  276. {
  277. int rc = 0;
  278. ListIterator itr = NULL;
  279. ListIterator itr2 = NULL;
  280. char *acct;
  281. char *output = NULL;
  282. slurmdb_association_rec_t *assoc = NULL;
  283. if (!acct_list || !list_count(acct_list)
  284. || !assoc_list || !list_count(assoc_list))
  285. return rc;
  286. /* Since not all plugins have been converted to the new style
  287. of default accounts we have to handle those that aren't.
  288. If the plugin have been converted all the associations here
  289. will have is_def set.
  290. */
  291. assoc = list_peek(assoc_list);
  292. if (!assoc->is_def)
  293. return _isdefault_old(acct_list);
  294. itr = list_iterator_create(acct_list);
  295. itr2 = list_iterator_create(assoc_list);
  296. while ((acct = list_next(itr))) {
  297. while ((assoc = list_next(itr2))) {
  298. char tmp[1000];
  299. /* The pgsql plugin doesn't have the idea of
  300. only_defs, so thre query could return all
  301. the associations, even without defaults. */
  302. if (cond_set == 1) {
  303. if (strcasecmp(acct, assoc->acct))
  304. continue;
  305. } else {
  306. snprintf(tmp, 1000, " A = %s ", assoc->acct);
  307. if (!strstr(acct, tmp))
  308. continue;
  309. }
  310. snprintf(tmp, 1000, "C = %-10s A = %-20s U = %-9s\n",
  311. assoc->cluster, assoc->acct, assoc->user);
  312. if (output && strstr(output, tmp))
  313. continue;
  314. xstrcat(output, tmp);
  315. rc = 1;
  316. }
  317. list_iterator_reset(itr2);
  318. }
  319. list_iterator_destroy(itr);
  320. list_iterator_destroy(itr2);
  321. if (output) {
  322. fprintf(stderr," Users listed below have these "
  323. "as their Default Accounts.\n%s", output);
  324. xfree(output);
  325. }
  326. return rc;
  327. }
  328. extern int sacctmgr_add_account(int argc, char *argv[])
  329. {
  330. int rc = SLURM_SUCCESS;
  331. int i=0;
  332. ListIterator itr = NULL, itr_c = NULL;
  333. slurmdb_account_rec_t *acct = NULL;
  334. slurmdb_association_rec_t *assoc = NULL;
  335. slurmdb_association_cond_t assoc_cond;
  336. List name_list = list_create(slurm_destroy_char);
  337. List cluster_list = list_create(slurm_destroy_char);
  338. char *cluster = NULL;
  339. char *name = NULL;
  340. List acct_list = NULL;
  341. List assoc_list = NULL;
  342. List local_assoc_list = NULL;
  343. List local_account_list = NULL;
  344. char *acct_str = NULL;
  345. char *assoc_str = NULL;
  346. int limit_set = 0;
  347. slurmdb_account_rec_t *start_acct =
  348. xmalloc(sizeof(slurmdb_account_rec_t));
  349. slurmdb_association_rec_t *start_assoc =
  350. xmalloc(sizeof(slurmdb_association_rec_t));
  351. slurmdb_init_association_rec(start_assoc, 0);
  352. for (i=0; i<argc; i++) {
  353. int command_len = strlen(argv[i]);
  354. if (!strncasecmp(argv[i], "Where", MAX(command_len, 5))
  355. || !strncasecmp(argv[i], "Set", MAX(command_len, 3)))
  356. i++;
  357. limit_set += _set_rec(&i, argc, argv, name_list, cluster_list,
  358. start_acct, start_assoc);
  359. }
  360. if(exit_code)
  361. return SLURM_ERROR;
  362. if(!name_list || !list_count(name_list)) {
  363. list_destroy(name_list);
  364. list_destroy(cluster_list);
  365. slurmdb_destroy_association_rec(start_assoc);
  366. slurmdb_destroy_account_rec(start_acct);
  367. exit_code=1;
  368. fprintf(stderr, " Need name of account to add.\n");
  369. return SLURM_SUCCESS;
  370. } else {
  371. slurmdb_account_cond_t account_cond;
  372. memset(&account_cond, 0, sizeof(slurmdb_account_cond_t));
  373. memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t));
  374. assoc_cond.acct_list = name_list;
  375. account_cond.assoc_cond = &assoc_cond;
  376. local_account_list = acct_storage_g_get_accounts(
  377. db_conn, my_uid, &account_cond);
  378. }
  379. if(!local_account_list) {
  380. exit_code=1;
  381. fprintf(stderr, " Problem getting accounts from database. "
  382. "Contact your admin.\n");
  383. list_destroy(name_list);
  384. list_destroy(cluster_list);
  385. slurmdb_destroy_association_rec(start_assoc);
  386. slurmdb_destroy_account_rec(start_acct);
  387. return SLURM_ERROR;
  388. }
  389. if(!start_assoc->parent_acct)
  390. start_assoc->parent_acct = xstrdup("root");
  391. if(!cluster_list || !list_count(cluster_list)) {
  392. slurmdb_cluster_rec_t *cluster_rec = NULL;
  393. List tmp_list =
  394. acct_storage_g_get_clusters(db_conn, my_uid, NULL);
  395. if(!tmp_list) {
  396. exit_code=1;
  397. fprintf(stderr,
  398. " Problem getting clusters from database. "
  399. "Contact your admin.\n");
  400. list_destroy(name_list);
  401. list_destroy(cluster_list);
  402. slurmdb_destroy_association_rec(start_assoc);
  403. slurmdb_destroy_account_rec(start_acct);
  404. list_destroy(local_account_list);
  405. return SLURM_ERROR;
  406. }
  407. if(!list_count(tmp_list)) {
  408. exit_code=1;
  409. fprintf(stderr,
  410. " Can't add accounts, no cluster "
  411. "defined yet.\n"
  412. " Please contact your administrator.\n");
  413. list_destroy(name_list);
  414. list_destroy(cluster_list);
  415. slurmdb_destroy_association_rec(start_assoc);
  416. slurmdb_destroy_account_rec(start_acct);
  417. list_destroy(local_account_list);
  418. return SLURM_ERROR;
  419. }
  420. if(!cluster_list)
  421. list_create(slurm_destroy_char);
  422. else
  423. list_flush(cluster_list);
  424. itr_c = list_iterator_create(tmp_list);
  425. while((cluster_rec = list_next(itr_c))) {
  426. list_append(cluster_list, xstrdup(cluster_rec->name));
  427. }
  428. list_iterator_destroy(itr_c);
  429. list_destroy(tmp_list);
  430. } else {
  431. List temp_list = NULL;
  432. slurmdb_cluster_cond_t cluster_cond;
  433. slurmdb_init_cluster_cond(&cluster_cond, 0);
  434. cluster_cond.cluster_list = cluster_list;
  435. temp_list = acct_storage_g_get_clusters(db_conn, my_uid,
  436. &cluster_cond);
  437. itr_c = list_iterator_create(cluster_list);
  438. itr = list_iterator_create(temp_list);
  439. while((cluster = list_next(itr_c))) {
  440. slurmdb_cluster_rec_t *cluster_rec = NULL;
  441. list_iterator_reset(itr);
  442. while((cluster_rec = list_next(itr))) {
  443. if(!strcasecmp(cluster_rec->name, cluster))
  444. break;
  445. }
  446. if(!cluster_rec) {
  447. exit_code=1;
  448. fprintf(stderr, " This cluster '%s' "
  449. "doesn't exist.\n"
  450. " Contact your admin "
  451. "to add it to accounting.\n",
  452. cluster);
  453. list_delete_item(itr_c);
  454. }
  455. }
  456. list_iterator_destroy(itr);
  457. list_iterator_destroy(itr_c);
  458. list_destroy(temp_list);
  459. if(!list_count(cluster_list)) {
  460. slurmdb_destroy_association_rec(start_assoc);
  461. slurmdb_destroy_account_rec(start_acct);
  462. list_destroy(local_account_list);
  463. return SLURM_ERROR;
  464. }
  465. }
  466. acct_list = list_create(slurmdb_destroy_account_rec);
  467. assoc_list = list_create(slurmdb_destroy_association_rec);
  468. memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t));
  469. assoc_cond.acct_list = list_create(NULL);
  470. itr = list_iterator_create(name_list);
  471. while((name = list_next(itr)))
  472. list_append(assoc_cond.acct_list, name);
  473. list_iterator_destroy(itr);
  474. list_append(assoc_cond.acct_list, start_assoc->parent_acct);
  475. assoc_cond.cluster_list = cluster_list;
  476. local_assoc_list = acct_storage_g_get_associations(
  477. db_conn, my_uid, &assoc_cond);
  478. list_destroy(assoc_cond.acct_list);
  479. if(!local_assoc_list) {
  480. exit_code=1;
  481. fprintf(stderr, " Problem getting associations from database. "
  482. "Contact your admin.\n");
  483. list_destroy(name_list);
  484. list_destroy(cluster_list);
  485. slurmdb_destroy_association_rec(start_assoc);
  486. slurmdb_destroy_account_rec(start_acct);
  487. list_destroy(local_account_list);
  488. return SLURM_ERROR;
  489. }
  490. itr = list_iterator_create(name_list);
  491. while((name = list_next(itr))) {
  492. if(!name[0]) {
  493. exit_code=1;
  494. fprintf(stderr, " No blank names are "
  495. "allowed when adding.\n");
  496. rc = SLURM_ERROR;
  497. continue;
  498. }
  499. acct = NULL;
  500. if(!sacctmgr_find_account_from_list(local_account_list, name)) {
  501. acct = xmalloc(sizeof(slurmdb_account_rec_t));
  502. acct->assoc_list =
  503. list_create(slurmdb_destroy_association_rec);
  504. acct->name = xstrdup(name);
  505. if(start_acct->description)
  506. acct->description =
  507. xstrdup(start_acct->description);
  508. else
  509. acct->description = xstrdup(name);
  510. if(start_acct->organization)
  511. acct->organization =
  512. xstrdup(start_acct->organization);
  513. else if(strcmp(start_assoc->parent_acct, "root"))
  514. acct->organization =
  515. xstrdup(start_assoc->parent_acct);
  516. else
  517. acct->organization = xstrdup(name);
  518. xstrfmtcat(acct_str, " %s\n", name);
  519. list_append(acct_list, acct);
  520. }
  521. itr_c = list_iterator_create(cluster_list);
  522. while((cluster = list_next(itr_c))) {
  523. if(sacctmgr_find_account_base_assoc_from_list(
  524. local_assoc_list, name, cluster)) {
  525. //printf(" already have this assoc\n");
  526. continue;
  527. }
  528. if(!sacctmgr_find_account_base_assoc_from_list(
  529. local_assoc_list, start_assoc->parent_acct,
  530. cluster)) {
  531. exit_code=1;
  532. fprintf(stderr, " Parent account '%s' "
  533. "doesn't exist on "
  534. "cluster %s\n"
  535. " Contact your admin "
  536. "to add this account.\n",
  537. start_assoc->parent_acct, cluster);
  538. continue;
  539. }
  540. assoc = xmalloc(sizeof(slurmdb_association_rec_t));
  541. slurmdb_init_association_rec(assoc, 0);
  542. assoc->acct = xstrdup(name);
  543. assoc->cluster = xstrdup(cluster);
  544. assoc->def_qos_id = start_assoc->def_qos_id;
  545. assoc->parent_acct = xstrdup(start_assoc->parent_acct);
  546. assoc->shares_raw = start_assoc->shares_raw;
  547. assoc->grp_cpu_mins = start_assoc->grp_cpu_mins;
  548. assoc->grp_cpus = start_assoc->grp_cpus;
  549. assoc->grp_jobs = start_assoc->grp_jobs;
  550. assoc->grp_mem = start_assoc->grp_mem;
  551. assoc->grp_nodes = start_assoc->grp_nodes;
  552. assoc->grp_submit_jobs = start_assoc->grp_submit_jobs;
  553. assoc->grp_wall = start_assoc->grp_wall;
  554. assoc->max_cpu_mins_pj = start_assoc->max_cpu_mins_pj;
  555. assoc->max_cpus_pj = start_assoc->max_cpus_pj;
  556. assoc->max_jobs = start_assoc->max_jobs;
  557. assoc->max_nodes_pj = start_assoc->max_nodes_pj;
  558. assoc->max_submit_jobs = start_assoc->max_submit_jobs;
  559. assoc->max_wall_pj = start_assoc->max_wall_pj;
  560. assoc->qos_list = copy_char_list(start_assoc->qos_list);
  561. if(acct)
  562. list_append(acct->assoc_list, assoc);
  563. else
  564. list_append(assoc_list, assoc);
  565. xstrfmtcat(assoc_str,
  566. " A = %-10.10s"
  567. " C = %-10.10s\n",
  568. assoc->acct,
  569. assoc->cluster);
  570. }
  571. list_iterator_destroy(itr_c);
  572. }
  573. list_iterator_destroy(itr);
  574. list_destroy(local_account_list);
  575. list_destroy(local_assoc_list);
  576. if(!list_count(acct_list) && !list_count(assoc_list)) {
  577. printf(" Nothing new added.\n");
  578. goto end_it;
  579. } else if(!assoc_str) {
  580. exit_code=1;
  581. fprintf(stderr, " No associations created.\n");
  582. goto end_it;
  583. }
  584. if(acct_str) {
  585. printf(" Adding Account(s)\n%s", acct_str);
  586. printf(" Settings\n");
  587. if(start_acct->description)
  588. printf(" Description = %s\n",
  589. start_acct->description);
  590. else
  591. printf(" Description = %s\n", "Account Name");
  592. if(start_acct->organization)
  593. printf(" Organization = %s\n",
  594. start_acct->organization);
  595. else
  596. printf(" Organization = %s\n",
  597. "Parent/Account Name");
  598. xfree(acct_str);
  599. }
  600. if(assoc_str) {
  601. printf(" Associations\n%s", assoc_str);
  602. xfree(assoc_str);
  603. }
  604. if(limit_set) {
  605. printf(" Settings\n");
  606. sacctmgr_print_assoc_limits(start_assoc);
  607. }
  608. notice_thread_init();
  609. if(list_count(acct_list))
  610. rc = acct_storage_g_add_accounts(db_conn, my_uid, acct_list);
  611. if(rc == SLURM_SUCCESS) {
  612. if(list_count(assoc_list))
  613. rc = acct_storage_g_add_associations(db_conn, my_uid,
  614. assoc_list);
  615. } else {
  616. exit_code=1;
  617. fprintf(stderr, " Problem adding accounts: %s\n",
  618. slurm_strerror(rc));
  619. rc = SLURM_ERROR;
  620. notice_thread_fini();
  621. goto end_it;
  622. }
  623. notice_thread_fini();
  624. if(rc == SLURM_SUCCESS) {
  625. if(commit_check("Would you like to commit changes?")) {
  626. acct_storage_g_commit(db_conn, 1);
  627. } else {
  628. printf(" Changes Discarded\n");
  629. acct_storage_g_commit(db_conn, 0);
  630. }
  631. } else {
  632. exit_code=1;
  633. fprintf(stderr,
  634. " error: Problem adding account associations: %s\n",
  635. slurm_strerror(rc));
  636. rc = SLURM_ERROR;
  637. }
  638. end_it:
  639. list_destroy(name_list);
  640. list_destroy(cluster_list);
  641. list_destroy(acct_list);
  642. list_destroy(assoc_list);
  643. slurmdb_destroy_association_rec(start_assoc);
  644. slurmdb_destroy_account_rec(start_acct);
  645. return rc;
  646. }
  647. extern int sacctmgr_list_account(int argc, char *argv[])
  648. {
  649. int rc = SLURM_SUCCESS;
  650. slurmdb_account_cond_t *acct_cond =
  651. xmalloc(sizeof(slurmdb_account_cond_t));
  652. List acct_list;
  653. int i=0, cond_set=0, prev_set=0;
  654. ListIterator itr = NULL;
  655. ListIterator itr2 = NULL;
  656. slurmdb_account_rec_t *acct = NULL;
  657. slurmdb_association_rec_t *assoc = NULL;
  658. int field_count = 0;
  659. print_field_t *field = NULL;
  660. List format_list = list_create(slurm_destroy_char);
  661. List print_fields_list; /* types are of print_field_t */
  662. acct_cond->with_assocs = with_assoc_flag;
  663. for (i=0; i<argc; i++) {
  664. int command_len = strlen(argv[i]);
  665. if (!strncasecmp(argv[i], "Where", MAX(command_len, 5))
  666. || !strncasecmp(argv[i], "Set", MAX(command_len, 3)))
  667. i++;
  668. prev_set = _set_cond(&i, argc, argv, acct_cond, format_list);
  669. cond_set |= prev_set;
  670. }
  671. if(exit_code) {
  672. slurmdb_destroy_account_cond(acct_cond);
  673. list_destroy(format_list);
  674. return SLURM_ERROR;
  675. } else if(!list_count(format_list)) {
  676. slurm_addto_char_list(format_list, "Acc,Des,O");
  677. if(acct_cond->with_assocs)
  678. slurm_addto_char_list(format_list,
  679. "Cl,ParentN,U,Share,GrpJ,GrpN,"
  680. "GrpCPUs,GrpMEM,GrpS,GrpWall,GrpCPUMins,"
  681. "MaxJ,MaxN,MaxCPUs,MaxS,MaxW,"
  682. "MaxCPUMins,QOS,DefaultQOS");
  683. if(acct_cond->with_coords)
  684. slurm_addto_char_list(format_list, "Coord");
  685. }
  686. if(!acct_cond->with_assocs && cond_set > 1) {
  687. if(!commit_check("You requested options that are only vaild "
  688. "when querying with the withassoc option.\n"
  689. "Are you sure you want to continue?")) {
  690. printf("Aborted\n");
  691. list_destroy(format_list);
  692. slurmdb_destroy_account_cond(acct_cond);
  693. return SLURM_SUCCESS;
  694. }
  695. }
  696. print_fields_list = sacctmgr_process_format_list(format_list);
  697. list_destroy(format_list);
  698. if(exit_code) {
  699. slurmdb_destroy_account_cond(acct_cond);
  700. list_destroy(print_fields_list);
  701. return SLURM_ERROR;
  702. }
  703. acct_list = acct_storage_g_get_accounts(db_conn, my_uid, acct_cond);
  704. slurmdb_destroy_account_cond(acct_cond);
  705. if(!acct_list) {
  706. exit_code=1;
  707. fprintf(stderr, " Problem with query.\n");
  708. list_destroy(print_fields_list);
  709. return SLURM_ERROR;
  710. }
  711. itr = list_iterator_create(acct_list);
  712. itr2 = list_iterator_create(print_fields_list);
  713. print_fields_header(print_fields_list);
  714. field_count = list_count(print_fields_list);
  715. while((acct = list_next(itr))) {
  716. if(acct->assoc_list) {
  717. ListIterator itr3 =
  718. list_iterator_create(acct->assoc_list);
  719. while((assoc = list_next(itr3))) {
  720. int curr_inx = 1;
  721. while((field = list_next(itr2))) {
  722. switch(field->type) {
  723. case PRINT_ACCT:
  724. field->print_routine(
  725. field, acct->name,
  726. (curr_inx ==
  727. field_count));
  728. break;
  729. case PRINT_COORDS:
  730. field->print_routine(
  731. field,
  732. acct->coordinators,
  733. (curr_inx ==
  734. field_count));
  735. break;
  736. case PRINT_DESC:
  737. field->print_routine(
  738. field,
  739. acct->description,
  740. (curr_inx ==
  741. field_count));
  742. break;
  743. case PRINT_ORG:
  744. field->print_routine(
  745. field,
  746. acct->organization,
  747. (curr_inx ==
  748. field_count));
  749. break;
  750. default:
  751. sacctmgr_print_association_rec(
  752. assoc, field, NULL,
  753. (curr_inx ==
  754. field_count));
  755. break;
  756. }
  757. curr_inx++;
  758. }
  759. list_iterator_reset(itr2);
  760. printf("\n");
  761. }
  762. list_iterator_destroy(itr3);
  763. } else {
  764. int curr_inx = 1;
  765. while((field = list_next(itr2))) {
  766. switch(field->type) {
  767. case PRINT_QOS:
  768. field->print_routine(
  769. field, NULL,
  770. NULL,
  771. (curr_inx == field_count));
  772. break;
  773. case PRINT_ACCT:
  774. field->print_routine(
  775. field, acct->name,
  776. (curr_inx ==
  777. field_count));
  778. break;
  779. case PRINT_COORDS:
  780. field->print_routine(
  781. field,
  782. acct->coordinators,
  783. (curr_inx ==
  784. field_count));
  785. break;
  786. case PRINT_DESC:
  787. field->print_routine(
  788. field, acct->description,
  789. (curr_inx ==
  790. field_count));
  791. break;
  792. case PRINT_ORG:
  793. field->print_routine(
  794. field, acct->organization,
  795. (curr_inx ==
  796. field_count));
  797. break;
  798. default:
  799. field->print_routine(
  800. field, NULL,
  801. (curr_inx == field_count));
  802. break;
  803. }
  804. curr_inx++;
  805. }
  806. list_iterator_reset(itr2);
  807. printf("\n");
  808. }
  809. }
  810. list_iterator_destroy(itr2);
  811. list_iterator_destroy(itr);
  812. list_destroy(acct_list);
  813. list_destroy(print_fields_list);
  814. return rc;
  815. }
  816. extern int sacctmgr_modify_account(int argc, char *argv[])
  817. {
  818. int rc = SLURM_SUCCESS;
  819. slurmdb_account_cond_t *acct_cond =
  820. xmalloc(sizeof(slurmdb_account_cond_t));
  821. slurmdb_account_rec_t *acct = xmalloc(sizeof(slurmdb_account_rec_t));
  822. slurmdb_association_rec_t *assoc =
  823. xmalloc(sizeof(slurmdb_association_rec_t));
  824. int i=0;
  825. int cond_set = 0, prev_set = 0, rec_set = 0, set = 0;
  826. List ret_list = NULL;
  827. slurmdb_init_association_rec(assoc, 0);
  828. for (i=0; i<argc; i++) {
  829. int command_len = strlen(argv[i]);
  830. if (!strncasecmp(argv[i], "Where", MAX(command_len, 5))) {
  831. i++;
  832. prev_set = _set_cond(&i, argc, argv, acct_cond, NULL);
  833. cond_set |= prev_set;
  834. } else if (!strncasecmp(argv[i], "Set", MAX(command_len, 3))) {
  835. i++;
  836. prev_set = _set_rec(&i, argc, argv, NULL, NULL,
  837. acct, assoc);
  838. rec_set |= prev_set;
  839. } else {
  840. prev_set = _set_cond(&i, argc, argv, acct_cond, NULL);
  841. cond_set |= prev_set;
  842. }
  843. }
  844. if(exit_code) {
  845. slurmdb_destroy_account_cond(acct_cond);
  846. slurmdb_destroy_account_rec(acct);
  847. slurmdb_destroy_association_rec(assoc);
  848. return SLURM_ERROR;
  849. } else if(!rec_set) {
  850. exit_code=1;
  851. fprintf(stderr, " You didn't give me anything to set\n");
  852. slurmdb_destroy_account_cond(acct_cond);
  853. slurmdb_destroy_account_rec(acct);
  854. slurmdb_destroy_association_rec(assoc);
  855. return SLURM_ERROR;
  856. } else if(!cond_set) {
  857. if(!commit_check("You didn't set any conditions with 'WHERE'.\n"
  858. "Are you sure you want to continue?")) {
  859. printf("Aborted\n");
  860. slurmdb_destroy_account_cond(acct_cond);
  861. slurmdb_destroy_account_rec(acct);
  862. slurmdb_destroy_association_rec(assoc);
  863. return SLURM_SUCCESS;
  864. }
  865. }
  866. // Special case: reset raw usage only
  867. if (assoc->usage) {
  868. rc = SLURM_ERROR;
  869. if (assoc->usage->usage_raw == 0.0)
  870. rc = sacctmgr_remove_assoc_usage(acct_cond->assoc_cond);
  871. else
  872. error("Raw usage can only be set to 0 (zero)");
  873. slurmdb_destroy_account_cond(acct_cond);
  874. slurmdb_destroy_account_rec(acct);
  875. slurmdb_destroy_association_rec(assoc);
  876. return rc;
  877. }
  878. notice_thread_init();
  879. if(rec_set & 1) { // process the account changes
  880. if(cond_set == 2) {
  881. exit_code=1;
  882. fprintf(stderr,
  883. " There was a problem with your "
  884. "'where' options.\n");
  885. rc = SLURM_ERROR;
  886. goto assoc_start;
  887. }
  888. ret_list = acct_storage_g_modify_accounts(
  889. db_conn, my_uid, acct_cond, acct);
  890. if(ret_list && list_count(ret_list)) {
  891. char *object = NULL;
  892. ListIterator itr = list_iterator_create(ret_list);
  893. printf(" Modified accounts...\n");
  894. while((object = list_next(itr))) {
  895. printf(" %s\n", object);
  896. }
  897. list_iterator_destroy(itr);
  898. set = 1;
  899. } else if(ret_list) {
  900. printf(" Nothing modified\n");
  901. rc = SLURM_ERROR;
  902. } else {
  903. exit_code=1;
  904. fprintf(stderr, " Error with request: %s\n",
  905. slurm_strerror(errno));
  906. rc = SLURM_ERROR;
  907. }
  908. if(ret_list)
  909. list_destroy(ret_list);
  910. }
  911. assoc_start:
  912. if(rec_set == 3 || rec_set == 2) { // process the association changes
  913. if(cond_set == 1 && !acct_cond->assoc_cond->acct_list) {
  914. rc = SLURM_ERROR;
  915. exit_code=1;
  916. fprintf(stderr,
  917. " There was a problem with your "
  918. "'where' options.\n");
  919. goto assoc_end;
  920. }
  921. if(assoc->parent_acct) {
  922. slurmdb_account_rec_t *acct_rec =
  923. sacctmgr_find_account(assoc->parent_acct);
  924. if(!acct_rec) {
  925. exit_code=1;
  926. fprintf(stderr,
  927. " Parent Account %s doesn't exist.\n",
  928. assoc->parent_acct);
  929. rc = SLURM_ERROR;
  930. goto assoc_end;
  931. }
  932. }
  933. ret_list = acct_storage_g_modify_associations(
  934. db_conn, my_uid, acct_cond->assoc_cond, assoc);
  935. if(ret_list && list_count(ret_list)) {
  936. set = 1;
  937. if (assoc->def_qos_id != NO_VAL)
  938. set = sacctmgr_check_default_qos(
  939. assoc->def_qos_id,
  940. acct_cond->assoc_cond);
  941. else if (assoc->qos_list)
  942. set = sacctmgr_check_default_qos(
  943. -1, acct_cond->assoc_cond);
  944. if (set) {
  945. char *object = NULL;
  946. ListIterator itr = list_iterator_create(
  947. ret_list);
  948. printf(" Modified account associations...\n");
  949. while((object = list_next(itr))) {
  950. printf(" %s\n", object);
  951. }
  952. list_iterator_destroy(itr);
  953. set = 1;
  954. }
  955. } else if(ret_list) {
  956. printf(" Nothing modified\n");
  957. } else {
  958. exit_code=1;
  959. fprintf(stderr, " Error with request: %s\n",
  960. slurm_strerror(errno));
  961. rc = SLURM_ERROR;
  962. }
  963. if(ret_list)
  964. list_destroy(ret_list);
  965. }
  966. assoc_end:
  967. notice_thread_fini();
  968. if(set) {
  969. if(commit_check("Would you like to commit changes?"))
  970. acct_storage_g_commit(db_conn, 1);
  971. else {
  972. printf(" Changes Discarded\n");
  973. acct_storage_g_commit(db_conn, 0);
  974. }
  975. }
  976. slurmdb_destroy_account_cond(acct_cond);
  977. slurmdb_destroy_account_rec(acct);
  978. slurmdb_destroy_association_rec(assoc);
  979. return rc;
  980. }
  981. extern int sacctmgr_delete_account(int argc, char *argv[])
  982. {
  983. int rc = SLURM_SUCCESS;
  984. slurmdb_account_cond_t *acct_cond =
  985. xmalloc(sizeof(slurmdb_account_cond_t));
  986. int i=0;
  987. List ret_list = NULL, local_assoc_list = NULL;
  988. ListIterator itr = NULL;
  989. int cond_set = 0, prev_set = 0;
  990. for (i=0; i<argc; i++) {
  991. int command_len = strlen(argv[i]);
  992. if (!strncasecmp(argv[i], "Where", MAX(command_len, 5))
  993. || !strncasecmp(argv[i], "Set", MAX(command_len, 3)))
  994. i++;
  995. prev_set = _set_cond(&i, argc, argv, acct_cond, NULL);
  996. cond_set |= prev_set;
  997. }
  998. if(!cond_set) {
  999. exit_code=1;
  1000. fprintf(stderr,
  1001. " No conditions given to remove, not executing.\n");
  1002. slurmdb_destroy_account_cond(acct_cond);
  1003. return SLURM_ERROR;
  1004. }
  1005. if(exit_code) {
  1006. slurmdb_destroy_account_cond(acct_cond);
  1007. return SLURM_ERROR;
  1008. }
  1009. /* check to see if person is trying to remove root account. This is
  1010. * bad, and should not be allowed outside of deleting a cluster.
  1011. */
  1012. if(acct_cond->assoc_cond
  1013. && acct_cond->assoc_cond->acct_list
  1014. && list_count(acct_cond->assoc_cond->acct_list)) {
  1015. char *tmp_char = NULL;
  1016. itr = list_iterator_create(acct_cond->assoc_cond->acct_list);
  1017. while((tmp_char = list_next(itr))) {
  1018. if(!strcasecmp(tmp_char, "root"))
  1019. break;
  1020. }
  1021. list_iterator_destroy(itr);
  1022. if(tmp_char) {
  1023. exit_code=1;
  1024. fprintf(stderr, " You are not allowed to remove "
  1025. "the root account.\n"
  1026. " Use remove cluster instead.\n");
  1027. slurmdb_destroy_account_cond(acct_cond);
  1028. return SLURM_ERROR;
  1029. }
  1030. }
  1031. acct_cond->assoc_cond->only_defs = 1;
  1032. local_assoc_list = acct_storage_g_get_associations(
  1033. db_conn, my_uid, acct_cond->assoc_cond);
  1034. acct_cond->assoc_cond->only_defs = 0;
  1035. notice_thread_init();
  1036. if(cond_set == 1) {
  1037. ret_list = acct_storage_g_remove_accounts(
  1038. db_conn, my_uid, acct_cond);
  1039. } else if(cond_set & 2) {
  1040. ret_list = acct_storage_g_remove_associations(
  1041. db_conn, my_uid, acct_cond->assoc_cond);
  1042. }
  1043. rc = errno;
  1044. notice_thread_fini();
  1045. slurmdb_destroy_account_cond(acct_cond);
  1046. if(ret_list && list_count(ret_list)) {
  1047. char *object = NULL;
  1048. ListIterator itr = NULL;
  1049. /* Check to see if person is trying to remove a default
  1050. * account of a user. _isdefault only works with the
  1051. * output from acct_storage_g_remove_accounts, and
  1052. * with a previously got assoc_list.
  1053. */
  1054. if(_isdefault(cond_set, ret_list, local_assoc_list)) {
  1055. exit_code=1;
  1056. fprintf(stderr, " Please either remove the "
  1057. "accounts listed "
  1058. "above from list and resubmit,\n"
  1059. " or change these users default account to "
  1060. "remove the account(s).\n"
  1061. " Changes Discarded\n");
  1062. acct_storage_g_commit(db_conn, 0);
  1063. goto end_it;
  1064. }
  1065. itr = list_iterator_create(ret_list);
  1066. /* If there were jobs running with an association to
  1067. be deleted, don't.
  1068. */
  1069. if(rc == ESLURM_JOBS_RUNNING_ON_ASSOC) {
  1070. fprintf(stderr, " Error with request: %s\n",
  1071. slurm_strerror(rc));
  1072. while((object = list_next(itr))) {
  1073. fprintf(stderr," %s\n", object);
  1074. }
  1075. acct_storage_g_commit(db_conn, 0);
  1076. goto end_it;
  1077. }
  1078. if(cond_set == 1) {
  1079. printf(" Deleting accounts...\n");
  1080. } else if(cond_set & 2) {
  1081. printf(" Deleting account associations...\n");
  1082. }
  1083. while((object = list_next(itr))) {
  1084. printf(" %s\n", object);
  1085. }
  1086. list_iterator_destroy(itr);
  1087. if(commit_check("Would you like to commit changes?")) {
  1088. acct_storage_g_commit(db_conn, 1);
  1089. } else {
  1090. printf(" Changes Discarded\n");
  1091. acct_storage_g_commit(db_conn, 0);
  1092. }
  1093. } else if(ret_list) {
  1094. printf(" Nothing deleted\n");
  1095. } else {
  1096. exit_code=1;
  1097. fprintf(stderr, " Error with request: %s\n",
  1098. slurm_strerror(errno));
  1099. rc = SLURM_ERROR;
  1100. }
  1101. end_it:
  1102. if(ret_list)
  1103. list_destroy(ret_list);
  1104. if (local_assoc_list)
  1105. list_destroy(local_assoc_list);
  1106. return rc;
  1107. }