PageRenderTime 51ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/src/plugins/accounting_storage/mysql/as_mysql_resv.c

https://github.com/cfenoy/slurm
C | 711 lines | 534 code | 90 blank | 87 comment | 120 complexity | 02681f6c467121d662874d1a09c2898c MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
  1. /*****************************************************************************\
  2. * as_mysql_resv.c - functions dealing with reservations.
  3. *****************************************************************************
  4. *
  5. * Copyright (C) 2004-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. *
  10. * This file is part of SLURM, a resource management program.
  11. * For details, see <http://www.schedmd.com/slurmdocs/>.
  12. * Please also read the included file: DISCLAIMER.
  13. *
  14. * SLURM is free software; you can redistribute it and/or modify it under
  15. * the terms of the GNU General Public License as published by the Free
  16. * Software Foundation; either version 2 of the License, or (at your option)
  17. * any later version.
  18. *
  19. * In addition, as a special exception, the copyright holders give permission
  20. * to link the code of portions of this program with the OpenSSL library under
  21. * certain conditions as described in each individual source file, and
  22. * distribute linked combinations including the two. You must obey the GNU
  23. * General Public License in all respects for all of the code used other than
  24. * OpenSSL. If you modify file(s) with this exception, you may extend this
  25. * exception to your version of the file(s), but you are not obligated to do
  26. * so. If you do not wish to do so, delete this exception statement from your
  27. * version. If you delete this exception statement from all source files in
  28. * the program, then also delete it here.
  29. *
  30. * SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
  31. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  32. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  33. * details.
  34. *
  35. * You should have received a copy of the GNU General Public License along
  36. * with SLURM; if not, write to the Free Software Foundation, Inc.,
  37. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  38. \*****************************************************************************/
  39. #include "as_mysql_resv.h"
  40. #include "as_mysql_jobacct_process.h"
  41. static int _setup_resv_limits(slurmdb_reservation_rec_t *resv,
  42. char **cols, char **vals,
  43. char **extra)
  44. {
  45. /* strip off the action item from the flags */
  46. if (resv->assocs) {
  47. int start = 0;
  48. int len = strlen(resv->assocs)-1;
  49. if (strchr(resv->assocs, '-')) {
  50. int i = 0, i2 = 0;
  51. char * assocs = xmalloc(sizeof(char) * len);
  52. /* We will remove the negative's here. This
  53. is here so if we only have negatives in the
  54. reservation we don't want to keep track of
  55. every other id so don't keep track of any
  56. since everyone except a few can use it.
  57. These id's are only used to divide up idle
  58. time so it isn't that important.
  59. */
  60. while (i < len) {
  61. if (resv->assocs[i] == ',' &&
  62. resv->assocs[i+1] == '-') {
  63. i+=2;
  64. while (i < len) {
  65. i++;
  66. if (resv->assocs[i] == ',')
  67. break;
  68. }
  69. continue;
  70. }
  71. assocs[i2++] = resv->assocs[i++];
  72. }
  73. xfree(resv->assocs);
  74. len = i2-1;
  75. resv->assocs = assocs;
  76. assocs = NULL;
  77. }
  78. /* strip off extra ,'s */
  79. if (resv->assocs[0] == ',')
  80. start = 1;
  81. if (resv->assocs[len] == ',')
  82. resv->assocs[len] = '\0';
  83. xstrcat(*cols, ", assoclist");
  84. xstrfmtcat(*vals, ", '%s'", resv->assocs+start);
  85. xstrfmtcat(*extra, ", assoclist='%s'", resv->assocs+start);
  86. }
  87. if (resv->cpus != (uint32_t)NO_VAL) {
  88. xstrcat(*cols, ", cpus");
  89. xstrfmtcat(*vals, ", %u", resv->cpus);
  90. xstrfmtcat(*extra, ", cpus=%u", resv->cpus);
  91. }
  92. if (resv->flags != (uint16_t)NO_VAL) {
  93. xstrcat(*cols, ", flags");
  94. xstrfmtcat(*vals, ", %u", resv->flags);
  95. xstrfmtcat(*extra, ", flags=%u", resv->flags);
  96. }
  97. if (resv->name) {
  98. xstrcat(*cols, ", resv_name");
  99. xstrfmtcat(*vals, ", '%s'", resv->name);
  100. xstrfmtcat(*extra, ", resv_name='%s'", resv->name);
  101. }
  102. if (resv->nodes) {
  103. xstrcat(*cols, ", nodelist");
  104. xstrfmtcat(*vals, ", '%s'", resv->nodes);
  105. xstrfmtcat(*extra, ", nodelist='%s'", resv->nodes);
  106. }
  107. if (resv->node_inx) {
  108. xstrcat(*cols, ", node_inx");
  109. xstrfmtcat(*vals, ", '%s'", resv->node_inx);
  110. xstrfmtcat(*extra, ", node_inx='%s'", resv->node_inx);
  111. }
  112. if (resv->time_end) {
  113. xstrcat(*cols, ", time_end");
  114. xstrfmtcat(*vals, ", %ld", resv->time_end);
  115. xstrfmtcat(*extra, ", time_end=%ld", resv->time_end);
  116. }
  117. if (resv->time_start) {
  118. xstrcat(*cols, ", time_start");
  119. xstrfmtcat(*vals, ", %ld", resv->time_start);
  120. xstrfmtcat(*extra, ", time_start=%ld", resv->time_start);
  121. }
  122. return SLURM_SUCCESS;
  123. }
  124. static int _setup_resv_cond_limits(slurmdb_reservation_cond_t *resv_cond,
  125. char **extra)
  126. {
  127. int set = 0;
  128. ListIterator itr = NULL;
  129. char *object = NULL;
  130. char *prefix = "t1";
  131. time_t now = time(NULL);
  132. if (!resv_cond)
  133. return 0;
  134. if (resv_cond->id_list && list_count(resv_cond->id_list)) {
  135. set = 0;
  136. if (*extra)
  137. xstrcat(*extra, " && (");
  138. else
  139. xstrcat(*extra, " where (");
  140. itr = list_iterator_create(resv_cond->id_list);
  141. while ((object = list_next(itr))) {
  142. if (set)
  143. xstrcat(*extra, " || ");
  144. xstrfmtcat(*extra, "%s.id_resv=%s", prefix, object);
  145. set = 1;
  146. }
  147. list_iterator_destroy(itr);
  148. xstrcat(*extra, ")");
  149. }
  150. if (resv_cond->name_list && list_count(resv_cond->name_list)) {
  151. set = 0;
  152. if (*extra)
  153. xstrcat(*extra, " && (");
  154. else
  155. xstrcat(*extra, " where (");
  156. itr = list_iterator_create(resv_cond->name_list);
  157. while ((object = list_next(itr))) {
  158. if (set)
  159. xstrcat(*extra, " || ");
  160. xstrfmtcat(*extra, "%s.resv_name='%s'",
  161. prefix, object);
  162. set = 1;
  163. }
  164. list_iterator_destroy(itr);
  165. xstrcat(*extra, ")");
  166. }
  167. if (resv_cond->time_start) {
  168. if (!resv_cond->time_end)
  169. resv_cond->time_end = now;
  170. if (*extra)
  171. xstrcat(*extra, " && (");
  172. else
  173. xstrcat(*extra, " where (");
  174. xstrfmtcat(*extra,
  175. "(t1.time_start < %ld "
  176. "&& (t1.time_end >= %ld || t1.time_end = 0)))",
  177. resv_cond->time_end, resv_cond->time_start);
  178. } else if (resv_cond->time_end) {
  179. if (*extra)
  180. xstrcat(*extra, " && (");
  181. else
  182. xstrcat(*extra, " where (");
  183. xstrfmtcat(*extra,
  184. "(t1.time_start < %ld))", resv_cond->time_end);
  185. }
  186. return set;
  187. }
  188. extern int as_mysql_add_resv(mysql_conn_t *mysql_conn,
  189. slurmdb_reservation_rec_t *resv)
  190. {
  191. int rc = SLURM_SUCCESS;
  192. char *cols = NULL, *vals = NULL, *extra = NULL,
  193. *query = NULL;//, *tmp_extra = NULL;
  194. if (!resv) {
  195. error("No reservation was given to edit");
  196. return SLURM_ERROR;
  197. }
  198. if (!resv->id) {
  199. error("We need an id to edit a reservation.");
  200. return SLURM_ERROR;
  201. }
  202. if (!resv->time_start) {
  203. error("We need a start time to edit a reservation.");
  204. return SLURM_ERROR;
  205. }
  206. if (!resv->cluster || !resv->cluster[0]) {
  207. error("We need a cluster name to edit a reservation.");
  208. return SLURM_ERROR;
  209. }
  210. _setup_resv_limits(resv, &cols, &vals, &extra);
  211. xstrfmtcat(query,
  212. "insert into \"%s_%s\" (id_resv%s) values (%u%s) "
  213. "on duplicate key update deleted=0%s;",
  214. resv->cluster, resv_table, cols, resv->id, vals, extra);
  215. debug3("%d(%s:%d) query\n%s",
  216. mysql_conn->conn, THIS_FILE, __LINE__, query);
  217. rc = mysql_db_query(mysql_conn, query);
  218. xfree(query);
  219. xfree(cols);
  220. xfree(vals);
  221. xfree(extra);
  222. return rc;
  223. }
  224. extern int as_mysql_modify_resv(mysql_conn_t *mysql_conn,
  225. slurmdb_reservation_rec_t *resv)
  226. {
  227. MYSQL_RES *result = NULL;
  228. MYSQL_ROW row;
  229. int rc = SLURM_SUCCESS;
  230. char *cols = NULL, *vals = NULL, *extra = NULL,
  231. *query = NULL;//, *tmp_extra = NULL;
  232. time_t start = 0, now = time(NULL);
  233. int i;
  234. int set = 0;
  235. char *resv_req_inx[] = {
  236. "assoclist",
  237. "time_start",
  238. "time_end",
  239. "cpus",
  240. "resv_name",
  241. "nodelist",
  242. "node_inx",
  243. "flags"
  244. };
  245. enum {
  246. RESV_ASSOCS,
  247. RESV_START,
  248. RESV_END,
  249. RESV_CPU,
  250. RESV_NAME,
  251. RESV_NODES,
  252. RESV_NODE_INX,
  253. RESV_FLAGS,
  254. RESV_COUNT
  255. };
  256. if (!resv) {
  257. error("No reservation was given to edit");
  258. return SLURM_ERROR;
  259. }
  260. if (!resv->id) {
  261. error("We need an id to edit a reservation.");
  262. return SLURM_ERROR;
  263. }
  264. if (!resv->time_start) {
  265. error("We need a start time to edit a reservation.");
  266. return SLURM_ERROR;
  267. }
  268. if (!resv->cluster || !resv->cluster[0]) {
  269. error("We need a cluster name to edit a reservation.");
  270. return SLURM_ERROR;
  271. }
  272. if (!resv->time_start_prev) {
  273. error("We need a time to check for last "
  274. "start of reservation.");
  275. return SLURM_ERROR;
  276. }
  277. xstrfmtcat(cols, "%s", resv_req_inx[0]);
  278. for(i=1; i<RESV_COUNT; i++) {
  279. xstrfmtcat(cols, ", %s", resv_req_inx[i]);
  280. }
  281. /* check for both the last start and the start because most
  282. likely the start time hasn't changed, but something else
  283. may have since the last time we did an update to the
  284. reservation. */
  285. query = xstrdup_printf("select %s from \"%s_%s\" where id_resv=%u "
  286. "and (time_start=%ld || time_start=%ld) "
  287. "and deleted=0 order by time_start desc "
  288. "limit 1 FOR UPDATE;",
  289. cols, resv->cluster, resv_table, resv->id,
  290. resv->time_start, resv->time_start_prev);
  291. try_again:
  292. debug4("%d(%s:%d) query\n%s",
  293. mysql_conn->conn, THIS_FILE, __LINE__, query);
  294. if (!(result = mysql_db_query_ret(
  295. mysql_conn, query, 0))) {
  296. rc = SLURM_ERROR;
  297. goto end_it;
  298. }
  299. if (!(row = mysql_fetch_row(result))) {
  300. rc = SLURM_ERROR;
  301. mysql_free_result(result);
  302. error("There is no reservation by id %u, "
  303. "time_start %ld, and cluster '%s'", resv->id,
  304. resv->time_start_prev, resv->cluster);
  305. if (!set && resv->time_end) {
  306. /* This should never really happen,
  307. but just incase the controller and the
  308. database get out of sync we check
  309. to see if there is a reservation
  310. not deleted that hasn't ended yet. */
  311. xfree(query);
  312. query = xstrdup_printf(
  313. "select %s from \"%s_%s\" where id_resv=%u "
  314. "and time_start <= %ld and deleted=0 "
  315. "order by time_start desc "
  316. "limit 1;",
  317. cols, resv->cluster, resv_table, resv->id,
  318. resv->time_end);
  319. set = 1;
  320. goto try_again;
  321. }
  322. goto end_it;
  323. }
  324. start = slurm_atoul(row[RESV_START]);
  325. xfree(query);
  326. xfree(cols);
  327. set = 0;
  328. /* check differences here */
  329. if (!resv->name
  330. && row[RESV_NAME] && row[RESV_NAME][0])
  331. // if this changes we just update the
  332. // record, no need to create a new one since
  333. // this doesn't really effect the
  334. // reservation accounting wise
  335. resv->name = xstrdup(row[RESV_NAME]);
  336. if (resv->assocs)
  337. set = 1;
  338. else if (row[RESV_ASSOCS] && row[RESV_ASSOCS][0])
  339. resv->assocs = xstrdup(row[RESV_ASSOCS]);
  340. if (resv->cpus != (uint32_t)NO_VAL)
  341. set = 1;
  342. else
  343. resv->cpus = slurm_atoul(row[RESV_CPU]);
  344. if (resv->flags != (uint16_t)NO_VAL)
  345. set = 1;
  346. else
  347. resv->flags = slurm_atoul(row[RESV_FLAGS]);
  348. if (resv->nodes)
  349. set = 1;
  350. else if (row[RESV_NODES] && row[RESV_NODES][0]) {
  351. resv->nodes = xstrdup(row[RESV_NODES]);
  352. resv->node_inx = xstrdup(row[RESV_NODE_INX]);
  353. }
  354. if (!resv->time_end)
  355. resv->time_end = slurm_atoul(row[RESV_END]);
  356. mysql_free_result(result);
  357. _setup_resv_limits(resv, &cols, &vals, &extra);
  358. /* use start below instead of resv->time_start_prev
  359. * just incase we have a different one from being out
  360. * of sync
  361. */
  362. if ((start > now) || !set) {
  363. /* we haven't started the reservation yet, or
  364. we are changing the associations or end
  365. time which we can just update it */
  366. query = xstrdup_printf("update \"%s_%s\" set deleted=0%s "
  367. "where deleted=0 and id_resv=%u "
  368. "and time_start=%ld;",
  369. resv->cluster, resv_table,
  370. extra, resv->id, start);
  371. } else {
  372. /* time_start is already done above and we
  373. * changed something that is in need on a new
  374. * entry. */
  375. query = xstrdup_printf("update \"%s_%s\" set time_end=%ld "
  376. "where deleted=0 && id_resv=%u "
  377. "&& time_start=%ld;",
  378. resv->cluster, resv_table,
  379. resv->time_start-1,
  380. resv->id, start);
  381. xstrfmtcat(query,
  382. "insert into \"%s_%s\" (id_resv%s) "
  383. "values (%u%s) "
  384. "on duplicate key update deleted=0%s;",
  385. resv->cluster, resv_table, cols, resv->id,
  386. vals, extra);
  387. }
  388. debug3("%d(%s:%d) query\n%s",
  389. mysql_conn->conn, THIS_FILE, __LINE__, query);
  390. rc = mysql_db_query(mysql_conn, query);
  391. end_it:
  392. xfree(query);
  393. xfree(cols);
  394. xfree(vals);
  395. xfree(extra);
  396. return rc;
  397. }
  398. extern int as_mysql_remove_resv(mysql_conn_t *mysql_conn,
  399. slurmdb_reservation_rec_t *resv)
  400. {
  401. int rc = SLURM_SUCCESS;
  402. char *query = NULL;//, *tmp_extra = NULL;
  403. if (!resv) {
  404. error("No reservation was given to edit");
  405. return SLURM_ERROR;
  406. }
  407. if (!resv->id || !resv->time_start || !resv->cluster) {
  408. error("We need an id, start time, and cluster "
  409. "name to edit a reservation.");
  410. return SLURM_ERROR;
  411. }
  412. /* first delete the resv that hasn't happened yet. */
  413. query = xstrdup_printf("delete from \"%s_%s\" where time_start > %ld "
  414. "and id_resv=%u and time_start=%ld;",
  415. resv->cluster, resv_table, resv->time_start_prev,
  416. resv->id,
  417. resv->time_start);
  418. /* then update the remaining ones with a deleted flag and end
  419. * time of the time_start_prev which is set to when the
  420. * command was issued */
  421. xstrfmtcat(query,
  422. "update \"%s_%s\" set time_end=%ld, "
  423. "deleted=1 where deleted=0 and "
  424. "id_resv=%u and time_start=%ld;",
  425. resv->cluster, resv_table, resv->time_start_prev,
  426. resv->id, resv->time_start);
  427. debug3("%d(%s:%d) query\n%s",
  428. mysql_conn->conn, THIS_FILE, __LINE__, query);
  429. rc = mysql_db_query(mysql_conn, query);
  430. xfree(query);
  431. return rc;
  432. }
  433. extern List as_mysql_get_resvs(mysql_conn_t *mysql_conn, uid_t uid,
  434. slurmdb_reservation_cond_t *resv_cond)
  435. {
  436. //DEF_TIMERS;
  437. char *query = NULL;
  438. char *extra = NULL;
  439. char *tmp = NULL;
  440. List resv_list = NULL;
  441. int i=0, is_admin=1;
  442. MYSQL_RES *result = NULL;
  443. MYSQL_ROW row;
  444. uint16_t private_data = 0;
  445. slurmdb_job_cond_t job_cond;
  446. void *curr_cluster = NULL;
  447. List local_cluster_list = NULL;
  448. List use_cluster_list = as_mysql_cluster_list;
  449. ListIterator itr = NULL;
  450. char *cluster_name = NULL;
  451. /* needed if we don't have an resv_cond */
  452. uint16_t with_usage = 0;
  453. /* if this changes you will need to edit the corresponding enum */
  454. char *resv_req_inx[] = {
  455. "id_resv",
  456. "resv_name",
  457. "cpus",
  458. "assoclist",
  459. "nodelist",
  460. "node_inx",
  461. "time_start",
  462. "time_end",
  463. "flags",
  464. };
  465. enum {
  466. RESV_REQ_ID,
  467. RESV_REQ_NAME,
  468. RESV_REQ_CPUS,
  469. RESV_REQ_ASSOCS,
  470. RESV_REQ_NODES,
  471. RESV_REQ_NODE_INX,
  472. RESV_REQ_START,
  473. RESV_REQ_END,
  474. RESV_REQ_FLAGS,
  475. RESV_REQ_COUNT
  476. };
  477. if (!resv_cond) {
  478. xstrcat(extra, " where deleted=0");
  479. goto empty;
  480. }
  481. if (check_connection(mysql_conn) != SLURM_SUCCESS)
  482. return NULL;
  483. private_data = slurm_get_private_data();
  484. if (private_data & PRIVATE_DATA_RESERVATIONS) {
  485. if (!(is_admin = is_user_min_admin_level(
  486. mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) {
  487. error("Only admins can look at reservations");
  488. errno = ESLURM_ACCESS_DENIED;
  489. return NULL;
  490. }
  491. }
  492. memset(&job_cond, 0, sizeof(slurmdb_job_cond_t));
  493. if (resv_cond->nodes) {
  494. job_cond.usage_start = resv_cond->time_start;
  495. job_cond.usage_end = resv_cond->time_end;
  496. job_cond.used_nodes = resv_cond->nodes;
  497. job_cond.cluster_list = resv_cond->cluster_list;
  498. local_cluster_list = setup_cluster_list_with_inx(
  499. mysql_conn, &job_cond, (void **)&curr_cluster);
  500. } else if (with_usage) {
  501. job_cond.usage_start = resv_cond->time_start;
  502. job_cond.usage_end = resv_cond->time_end;
  503. }
  504. (void) _setup_resv_cond_limits(resv_cond, &extra);
  505. with_usage = resv_cond->with_usage;
  506. if (resv_cond->cluster_list && list_count(resv_cond->cluster_list))
  507. use_cluster_list = resv_cond->cluster_list;
  508. empty:
  509. xfree(tmp);
  510. xstrfmtcat(tmp, "t1.%s", resv_req_inx[i]);
  511. for(i=1; i<RESV_REQ_COUNT; i++) {
  512. xstrfmtcat(tmp, ", t1.%s", resv_req_inx[i]);
  513. }
  514. if (use_cluster_list == as_mysql_cluster_list)
  515. slurm_mutex_lock(&as_mysql_cluster_list_lock);
  516. itr = list_iterator_create(use_cluster_list);
  517. while ((cluster_name = list_next(itr))) {
  518. if (query)
  519. xstrcat(query, " union ");
  520. //START_TIMER;
  521. xstrfmtcat(query, "select distinct %s,'%s' as cluster "
  522. "from \"%s_%s\" as t1%s",
  523. tmp, cluster_name, cluster_name, resv_table, extra);
  524. }
  525. list_iterator_destroy(itr);
  526. if (use_cluster_list == as_mysql_cluster_list)
  527. slurm_mutex_unlock(&as_mysql_cluster_list_lock);
  528. if (query)
  529. xstrcat(query, " order by cluster, resv_name;");
  530. xfree(tmp);
  531. xfree(extra);
  532. debug3("%d(%s:%d) query\n%s",
  533. mysql_conn->conn, THIS_FILE, __LINE__, query);
  534. if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
  535. xfree(query);
  536. if (local_cluster_list)
  537. list_destroy(local_cluster_list);
  538. return NULL;
  539. }
  540. xfree(query);
  541. resv_list = list_create(slurmdb_destroy_reservation_rec);
  542. while ((row = mysql_fetch_row(result))) {
  543. slurmdb_reservation_rec_t *resv =
  544. xmalloc(sizeof(slurmdb_reservation_rec_t));
  545. int start = slurm_atoul(row[RESV_REQ_START]);
  546. list_append(resv_list, resv);
  547. if (!good_nodes_from_inx(local_cluster_list, &curr_cluster,
  548. row[RESV_REQ_NODE_INX], start))
  549. continue;
  550. resv->id = slurm_atoul(row[RESV_REQ_ID]);
  551. if (with_usage) {
  552. if (!job_cond.resvid_list)
  553. job_cond.resvid_list = list_create(NULL);
  554. list_append(job_cond.resvid_list, row[RESV_REQ_ID]);
  555. }
  556. resv->name = xstrdup(row[RESV_REQ_NAME]);
  557. resv->cluster = xstrdup(row[RESV_REQ_COUNT]);
  558. resv->cpus = slurm_atoul(row[RESV_REQ_CPUS]);
  559. resv->assocs = xstrdup(row[RESV_REQ_ASSOCS]);
  560. resv->nodes = xstrdup(row[RESV_REQ_NODES]);
  561. resv->time_start = start;
  562. resv->time_end = slurm_atoul(row[RESV_REQ_END]);
  563. resv->flags = slurm_atoul(row[RESV_REQ_FLAGS]);
  564. }
  565. if (local_cluster_list)
  566. list_destroy(local_cluster_list);
  567. if (with_usage && resv_list && list_count(resv_list)) {
  568. List job_list = as_mysql_jobacct_process_get_jobs(
  569. mysql_conn, uid, &job_cond);
  570. ListIterator itr = NULL, itr2 = NULL;
  571. slurmdb_job_rec_t *job = NULL;
  572. slurmdb_reservation_rec_t *resv = NULL;
  573. if (!job_list || !list_count(job_list))
  574. goto no_jobs;
  575. itr = list_iterator_create(job_list);
  576. itr2 = list_iterator_create(resv_list);
  577. while ((job = list_next(itr))) {
  578. int start = job->start;
  579. int end = job->end;
  580. int set = 0;
  581. while ((resv = list_next(itr2))) {
  582. int elapsed = 0;
  583. /* since a reservation could have
  584. changed while a job was running we
  585. have to make sure we get the time
  586. in the correct record.
  587. */
  588. if (resv->id != job->resvid)
  589. continue;
  590. set = 1;
  591. if (start < resv->time_start)
  592. start = resv->time_start;
  593. if (!end || end > resv->time_end)
  594. end = resv->time_end;
  595. if ((elapsed = (end - start)) < 1)
  596. continue;
  597. if (job->alloc_cpus)
  598. resv->alloc_secs +=
  599. elapsed * job->alloc_cpus;
  600. }
  601. list_iterator_reset(itr2);
  602. if (!set) {
  603. error("we got a job %u with no reservation "
  604. "associatied with it?", job->jobid);
  605. }
  606. }
  607. list_iterator_destroy(itr2);
  608. list_iterator_destroy(itr);
  609. no_jobs:
  610. if (job_list)
  611. list_destroy(job_list);
  612. }
  613. if (job_cond.resvid_list) {
  614. list_destroy(job_cond.resvid_list);
  615. job_cond.resvid_list = NULL;
  616. }
  617. /* free result after we use the list with resv id's in it. */
  618. mysql_free_result(result);
  619. //END_TIMER2("get_resvs");
  620. return resv_list;
  621. }