1
/*****************************************************************************\
2
* as_mysql_usage.c - functions dealing with usage.
3
*****************************************************************************
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>
10
* This file is part of SLURM, a resource management program.
11
* For details, see <https://computing.llnl.gov/linux/slurm/>.
12
* Please also read the included file: DISCLAIMER.
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)
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.
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
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
\*****************************************************************************/
40
#include "as_mysql_usage.h"
41
#include "as_mysql_rollup.h"
43
time_t global_last_rollup = 0;
44
pthread_mutex_t rollup_lock = PTHREAD_MUTEX_INITIALIZER;
46
static pthread_mutex_t usage_rollup_lock = PTHREAD_MUTEX_INITIALIZER;
49
uint16_t archive_data;
51
mysql_conn_t *mysql_conn;
54
pthread_mutex_t *rolledup_lock;
55
pthread_cond_t *rolledup_cond;
60
static void *_cluster_rollup_usage(void *arg)
62
local_rollup_t *local_rollup = (local_rollup_t *)arg;
63
int rc = SLURM_SUCCESS;
65
mysql_conn_t mysql_conn;
66
MYSQL_RES *result = NULL;
71
time_t my_time = local_rollup->sent_end;
72
time_t last_hour = local_rollup->sent_start;
73
time_t last_day = local_rollup->sent_start;
74
time_t last_month = local_rollup->sent_start;
83
char *update_req_inx[] = {
97
memset(&mysql_conn, 0, sizeof(mysql_conn_t));
98
mysql_conn.rollback = 1;
99
mysql_conn.conn = local_rollup->mysql_conn->conn;
100
slurm_mutex_init(&mysql_conn.lock);
102
/* Each thread needs it's own connection we can't use the one
103
* sent from the parent thread. */
104
rc = check_connection(&mysql_conn);
106
if (rc != SLURM_SUCCESS)
109
if (!local_rollup->sent_start) {
112
xstrfmtcat(tmp, "%s", update_req_inx[i]);
113
for(i=1; i<UPDATE_COUNT; i++) {
114
xstrfmtcat(tmp, ", %s", update_req_inx[i]);
116
query = xstrdup_printf("select %s from \"%s_%s\"",
117
tmp, local_rollup->cluster_name,
121
debug4("%d(%s:%d) query\n%s", mysql_conn.conn,
122
THIS_FILE, __LINE__, query);
123
if (!(result = mysql_db_query_ret(&mysql_conn, query, 0))) {
130
row = mysql_fetch_row(result);
132
last_hour = slurm_atoul(row[UPDATE_HOUR]);
133
last_day = slurm_atoul(row[UPDATE_DAY]);
134
last_month = slurm_atoul(row[UPDATE_MONTH]);
135
mysql_free_result(result);
137
time_t now = time(NULL);
140
mysql_free_result(result);
142
query = xstrdup_printf(
143
"select time_start from \"%s_%s\" "
144
"where node_name='' order by "
145
"time_start asc limit 1;",
146
local_rollup->cluster_name, event_table);
147
debug3("%d(%s:%d) query\n%s", mysql_conn.conn,
148
THIS_FILE, __LINE__, query);
149
if (!(result = mysql_db_query_ret(
150
&mysql_conn, query, 0))) {
156
if ((row = mysql_fetch_row(result))) {
157
time_t check = slurm_atoul(row[0]);
161
mysql_free_result(result);
163
/* If we don't have any events like adding a
164
* cluster this will not work correctly, so we
165
* will insert now as a starting point.
168
query = xstrdup_printf(
169
"insert into \"%s_%s\" "
170
"(hourly_rollup, daily_rollup, monthly_rollup) "
171
"values (%ld, %ld, %ld);",
172
local_rollup->cluster_name, last_ran_table,
173
lowest, lowest, lowest);
175
debug3("%d(%s:%d) query\n%s", mysql_conn.conn,
176
THIS_FILE, __LINE__, query);
177
rc = mysql_db_query(&mysql_conn, query);
179
if (rc != SLURM_SUCCESS) {
185
debug("Cluster %s not registered, "
187
local_rollup->cluster_name);
192
last_hour = last_day = last_month = lowest;
197
my_time = time(NULL);
200
/* last_hour = 1212299999; */
201
/* last_day = 1212217200; */
202
/* last_month = 1212217200; */
203
/* my_time = 1212307200; */
205
/* last_hour = 1211475599; */
206
/* last_day = 1211475599; */
207
/* last_month = 1211475599; */
209
// last_hour = 1211403599;
210
// last_hour = 1206946800;
211
// last_day = 1207033199;
212
// last_day = 1197033199;
213
// last_month = 1204358399;
215
if (!localtime_r(&last_hour, &start_tm)) {
216
error("Couldn't get localtime from hour start %ld", last_hour);
221
if (!localtime_r(&my_time, &end_tm)) {
222
error("Couldn't get localtime from hour end %ld", my_time);
227
/* Below and anywhere in a rollup plugin when dealing with
228
* epoch times we need to set the tm_isdst = -1 so we don't
229
* have to worry about the time changes. Not setting it to -1
230
* will cause problems in the day and month with the date change.
235
start_tm.tm_isdst = -1;
236
hour_start = mktime(&start_tm);
240
end_tm.tm_isdst = -1;
241
hour_end = mktime(&end_tm);
243
/* info("hour start %s", ctime(&hour_start)); */
244
/* info("hour end %s", ctime(&hour_end)); */
245
/* info("diff is %d", hour_end-hour_start); */
247
slurm_mutex_lock(&rollup_lock);
248
global_last_rollup = hour_end;
249
slurm_mutex_unlock(&rollup_lock);
251
/* set up the day period */
252
if (!localtime_r(&last_day, &start_tm)) {
253
error("Couldn't get localtime from day %ld", last_day);
260
start_tm.tm_hour = 0;
261
start_tm.tm_isdst = -1;
262
day_start = mktime(&start_tm);
265
end_tm.tm_isdst = -1;
266
day_end = mktime(&end_tm);
268
/* info("day start %s", ctime(&day_start)); */
269
/* info("day end %s", ctime(&day_end)); */
270
/* info("diff is %d", day_end-day_start); */
272
/* set up the month period */
273
if (!localtime_r(&last_month, &start_tm)) {
274
error("Couldn't get localtime from month %ld", last_month);
281
start_tm.tm_hour = 0;
282
start_tm.tm_mday = 1;
283
start_tm.tm_isdst = -1;
284
month_start = mktime(&start_tm);
290
end_tm.tm_isdst = -1;
291
month_end = mktime(&end_tm);
293
/* info("month start %s", ctime(&month_start)); */
294
/* info("month end %s", ctime(&month_end)); */
295
/* info("diff is %d", month_end-month_start); */
297
if ((hour_end - hour_start) > 0) {
299
rc = as_mysql_hourly_rollup(&mysql_conn,
300
local_rollup->cluster_name,
303
local_rollup->archive_data);
304
snprintf(timer_str, sizeof(timer_str),
305
"hourly_rollup for %s", local_rollup->cluster_name);
306
END_TIMER3(timer_str, 5000000);
307
if (rc != SLURM_SUCCESS)
311
if ((day_end - day_start) > 0) {
313
rc = as_mysql_daily_rollup(&mysql_conn,
314
local_rollup->cluster_name,
317
local_rollup->archive_data);
318
snprintf(timer_str, sizeof(timer_str),
319
"daily_rollup for %s", local_rollup->cluster_name);
320
END_TIMER3(timer_str, 5000000);
321
if (rc != SLURM_SUCCESS)
325
if ((month_end - month_start) > 0) {
327
rc = as_mysql_monthly_rollup(&mysql_conn,
328
local_rollup->cluster_name,
331
local_rollup->archive_data);
332
snprintf(timer_str, sizeof(timer_str),
333
"monthly_rollup for %s", local_rollup->cluster_name);
334
END_TIMER3(timer_str, 5000000);
335
if (rc != SLURM_SUCCESS)
339
if ((hour_end - hour_start) > 0) {
340
/* If we have a sent_end do not update the last_run_table */
341
if (!local_rollup->sent_end)
342
query = xstrdup_printf(
343
"update \"%s_%s\" set hourly_rollup=%ld",
344
local_rollup->cluster_name,
345
last_ran_table, hour_end);
347
debug2("No need to roll cluster %s this hour %ld <= %ld",
348
local_rollup->cluster_name, hour_end, hour_start);
350
if ((day_end - day_start) > 0) {
351
if (query && !local_rollup->sent_end)
352
xstrfmtcat(query, ", daily_rollup=%ld", day_end);
353
else if (!local_rollup->sent_end)
354
query = xstrdup_printf(
355
"update \"%s_%s\" set daily_rollup=%ld",
356
local_rollup->cluster_name,
357
last_ran_table, day_end);
359
debug2("No need to roll cluster %s this day %ld <= %ld",
360
local_rollup->cluster_name, day_end, day_start);
362
if ((month_end - month_start) > 0) {
363
if (query && !local_rollup->sent_end)
364
xstrfmtcat(query, ", monthly_rollup=%ld", month_end);
365
else if (!local_rollup->sent_end)
366
query = xstrdup_printf(
367
"update \"%s_%s\" set monthly_rollup=%ld",
368
local_rollup->cluster_name,
369
last_ran_table, month_end);
371
debug2("No need to roll cluster %s this month %ld <= %ld",
372
local_rollup->cluster_name, month_end, month_start);
375
debug3("%d(%s:%d) query\n%s",
376
mysql_conn.conn, THIS_FILE, __LINE__, query);
377
rc = mysql_db_query(&mysql_conn, query);
381
if (rc == SLURM_SUCCESS) {
382
if (mysql_db_commit(&mysql_conn)) {
383
error("Couldn't commit rollup of cluster %s",
384
local_rollup->cluster_name);
388
error("Cluster %s rollup failed", local_rollup->cluster_name);
389
if (mysql_db_rollback(&mysql_conn))
390
error("rollback failed");
393
mysql_db_close_db_connection(&mysql_conn);
394
slurm_mutex_destroy(&mysql_conn.lock);
396
slurm_mutex_lock(local_rollup->rolledup_lock);
397
(*local_rollup->rolledup)++;
398
if ((rc != SLURM_SUCCESS) && ((*local_rollup->rc) == SLURM_SUCCESS))
399
(*local_rollup->rc) = rc;
400
pthread_cond_signal(local_rollup->rolledup_cond);
401
slurm_mutex_unlock(local_rollup->rolledup_lock);
408
static int _get_cluster_usage(mysql_conn_t *mysql_conn, uid_t uid,
409
slurmdb_cluster_rec_t *cluster_rec,
410
slurmdbd_msg_type_t type,
411
time_t start, time_t end)
413
int rc = SLURM_SUCCESS;
415
MYSQL_RES *result = NULL;
418
char *my_usage_table = cluster_day_table;
420
char *cluster_req_inx[] = {
443
if (!cluster_rec->name || !cluster_rec->name[0]) {
444
error("We need a cluster name to set data for");
448
if (set_usage_information(&my_usage_table, type, &start, &end)
455
xstrfmtcat(tmp, "%s", cluster_req_inx[i]);
456
for(i=1; i<CLUSTER_COUNT; i++) {
457
xstrfmtcat(tmp, ", %s", cluster_req_inx[i]);
460
query = xstrdup_printf(
461
"select %s from \"%s_%s\" where (time_start < %ld "
462
"&& time_start >= %ld)",
463
tmp, cluster_rec->name, my_usage_table, end, start);
466
debug4("%d(%s:%d) query\n%s",
467
mysql_conn->conn, THIS_FILE, __LINE__, query);
468
if (!(result = mysql_db_query_ret(
469
mysql_conn, query, 0))) {
475
if (!cluster_rec->accounting_list)
476
cluster_rec->accounting_list =
477
list_create(slurmdb_destroy_cluster_accounting_rec);
479
while ((row = mysql_fetch_row(result))) {
480
slurmdb_cluster_accounting_rec_t *accounting_rec =
481
xmalloc(sizeof(slurmdb_cluster_accounting_rec_t));
482
accounting_rec->alloc_secs = slurm_atoull(row[CLUSTER_ACPU]);
483
accounting_rec->down_secs = slurm_atoull(row[CLUSTER_DCPU]);
484
accounting_rec->pdown_secs = slurm_atoull(row[CLUSTER_PDCPU]);
485
accounting_rec->idle_secs = slurm_atoull(row[CLUSTER_ICPU]);
486
accounting_rec->over_secs = slurm_atoull(row[CLUSTER_OCPU]);
487
accounting_rec->resv_secs = slurm_atoull(row[CLUSTER_RCPU]);
488
accounting_rec->cpu_count = slurm_atoul(row[CLUSTER_CPU_COUNT]);
489
accounting_rec->period_start = slurm_atoul(row[CLUSTER_START]);
490
list_append(cluster_rec->accounting_list, accounting_rec);
492
mysql_free_result(result);
499
/* checks should already be done before this to see if this is a valid
502
extern int get_usage_for_list(mysql_conn_t *mysql_conn,
503
slurmdbd_msg_type_t type, List object_list,
504
char *cluster_name, time_t start, time_t end)
506
int rc = SLURM_SUCCESS;
508
MYSQL_RES *result = NULL;
511
char *my_usage_table = NULL;
513
List usage_list = NULL;
515
ListIterator itr = NULL, u_itr = NULL;
517
slurmdb_association_rec_t *assoc = NULL;
518
slurmdb_wckey_rec_t *wckey = NULL;
519
slurmdb_accounting_rec_t *accounting_rec = NULL;
521
/* Since for id in association table we
522
use t3 and in wckey table we use t1 we can't define it here */
523
char **usage_req_inx = NULL;
534
error("We need an object to set data for getting usage");
538
if (check_connection(mysql_conn) != SLURM_SUCCESS)
539
return ESLURM_DB_CONNECTION;
542
case DBD_GET_ASSOC_USAGE:
544
char *temp_usage[] = {
549
usage_req_inx = temp_usage;
551
itr = list_iterator_create(object_list);
552
while ((assoc = list_next(itr))) {
554
xstrfmtcat(id_str, " || t3.id_assoc=%d",
557
xstrfmtcat(id_str, "t3.id_assoc=%d", assoc->id);
559
list_iterator_destroy(itr);
561
my_usage_table = assoc_day_table;
564
case DBD_GET_WCKEY_USAGE:
566
char *temp_usage[] = {
571
usage_req_inx = temp_usage;
573
itr = list_iterator_create(object_list);
574
while ((wckey = list_next(itr))) {
576
xstrfmtcat(id_str, " || id_wckey=%d",
579
xstrfmtcat(id_str, "id_wckey=%d", wckey->id);
581
list_iterator_destroy(itr);
583
my_usage_table = wckey_day_table;
587
error("Unknown usage type %d", type);
592
if (set_usage_information(&my_usage_table, type, &start, &end)
600
xstrfmtcat(tmp, "%s", usage_req_inx[i]);
601
for(i=1; i<USAGE_COUNT; i++) {
602
xstrfmtcat(tmp, ", %s", usage_req_inx[i]);
605
case DBD_GET_ASSOC_USAGE:
606
query = xstrdup_printf(
607
"select %s from \"%s_%s\" as t1, "
608
"\"%s_%s\" as t2, \"%s_%s\" as t3 "
609
"where (t1.time_start < %ld && t1.time_start >= %ld) "
610
"&& t1.id_assoc=t2.id_assoc && (%s) && "
611
"t2.lft between t3.lft and t3.rgt "
612
"order by t3.id_assoc, time_start;",
613
tmp, cluster_name, my_usage_table,
614
cluster_name, assoc_table, cluster_name, assoc_table,
617
case DBD_GET_WCKEY_USAGE:
618
query = xstrdup_printf(
619
"select %s from \"%s_%s\" "
620
"where (time_start < %ld && time_start >= %ld) "
621
"&& (%s) order by id_wckey, time_start;",
622
tmp, cluster_name, my_usage_table, end, start, id_str);
625
error("Unknown usage type %d", type);
634
debug4("%d(%s:%d) query\n%s",
635
mysql_conn->conn, THIS_FILE, __LINE__, query);
636
if (!(result = mysql_db_query_ret(
637
mysql_conn, query, 0))) {
643
usage_list = list_create(slurmdb_destroy_accounting_rec);
645
while ((row = mysql_fetch_row(result))) {
646
slurmdb_accounting_rec_t *accounting_rec =
647
xmalloc(sizeof(slurmdb_accounting_rec_t));
648
accounting_rec->id = slurm_atoul(row[USAGE_ID]);
649
accounting_rec->period_start = slurm_atoul(row[USAGE_START]);
650
accounting_rec->alloc_secs = slurm_atoull(row[USAGE_ACPU]);
651
list_append(usage_list, accounting_rec);
653
mysql_free_result(result);
655
u_itr = list_iterator_create(usage_list);
656
itr = list_iterator_create(object_list);
657
while ((object = list_next(itr))) {
660
List acct_list = NULL;
663
case DBD_GET_ASSOC_USAGE:
664
assoc = (slurmdb_association_rec_t *)object;
665
if (!assoc->accounting_list)
666
assoc->accounting_list = list_create(
667
slurmdb_destroy_accounting_rec);
668
acct_list = assoc->accounting_list;
671
case DBD_GET_WCKEY_USAGE:
672
wckey = (slurmdb_wckey_rec_t *)object;
673
if (!wckey->accounting_list)
674
wckey->accounting_list = list_create(
675
slurmdb_destroy_accounting_rec);
676
acct_list = wckey->accounting_list;
684
while ((accounting_rec = list_next(u_itr))) {
685
if (id == accounting_rec->id) {
686
list_append(acct_list, accounting_rec);
691
list is in id order so
695
there is no reason to
696
go through the rest of
697
the list when we know
703
list_iterator_reset(u_itr);
705
list_iterator_destroy(itr);
706
list_iterator_destroy(u_itr);
708
if (list_count(usage_list))
709
error("we have %d records not added "
710
"to the association list",
711
list_count(usage_list));
712
list_destroy(usage_list);
718
extern int as_mysql_get_usage(mysql_conn_t *mysql_conn, uid_t uid,
719
void *in, slurmdbd_msg_type_t type,
720
time_t start, time_t end)
722
int rc = SLURM_SUCCESS;
724
MYSQL_RES *result = NULL;
727
char *my_usage_table = NULL;
728
slurmdb_association_rec_t *slurmdb_assoc = in;
729
slurmdb_wckey_rec_t *slurmdb_wckey = in;
731
char *username = NULL;
732
uint16_t private_data = 0;
733
slurmdb_user_rec_t user;
735
uint32_t id = NO_VAL;
736
char *cluster_name = NULL;
737
char **usage_req_inx = NULL;
747
case DBD_GET_ASSOC_USAGE:
749
char *temp_usage[] = {
754
usage_req_inx = temp_usage;
756
id = slurmdb_assoc->id;
757
cluster_name = slurmdb_assoc->cluster;
758
username = slurmdb_assoc->user;
759
my_list = &slurmdb_assoc->accounting_list;
760
my_usage_table = assoc_day_table;
763
case DBD_GET_WCKEY_USAGE:
765
char *temp_usage[] = {
770
usage_req_inx = temp_usage;
772
id = slurmdb_wckey->id;
773
cluster_name = slurmdb_wckey->cluster;
774
username = slurmdb_wckey->user;
775
my_list = &slurmdb_wckey->accounting_list;
776
my_usage_table = wckey_day_table;
779
case DBD_GET_CLUSTER_USAGE:
781
return _get_cluster_usage(mysql_conn, uid, in,
786
error("Unknown usage type %d", type);
792
error("We need an id to set data for getting usage");
794
} else if (!cluster_name) {
795
error("We need a cluster_name to set data for getting usage");
799
if (check_connection(mysql_conn) != SLURM_SUCCESS)
800
return ESLURM_DB_CONNECTION;
802
memset(&user, 0, sizeof(slurmdb_user_rec_t));
805
private_data = slurm_get_private_data();
806
if (private_data & PRIVATE_DATA_USAGE) {
807
if (!(is_admin = is_user_min_admin_level(
808
mysql_conn, uid, SLURMDB_ADMIN_OPERATOR))) {
809
ListIterator itr = NULL;
810
slurmdb_coord_rec_t *coord = NULL;
812
if (username && !strcmp(slurmdb_assoc->user, user.name))
815
if (type != DBD_GET_ASSOC_USAGE)
818
if (!slurmdb_assoc->acct) {
819
debug("No account name given "
824
if (!is_user_any_coord(mysql_conn, &user)) {
825
debug4("This user is not a coordinator.");
829
/* Existance of user.coord_accts is checked in
832
itr = list_iterator_create(user.coord_accts);
833
while ((coord = list_next(itr)))
834
if (!strcasecmp(coord->name,
835
slurmdb_assoc->acct))
837
list_iterator_destroy(itr);
843
errno = ESLURM_ACCESS_DENIED;
849
if (set_usage_information(&my_usage_table, type, &start, &end)
856
xstrfmtcat(tmp, "%s", usage_req_inx[i]);
857
for(i=1; i<USAGE_COUNT; i++) {
858
xstrfmtcat(tmp, ", %s", usage_req_inx[i]);
861
case DBD_GET_ASSOC_USAGE:
862
query = xstrdup_printf(
863
"select %s from \"%s_%s\" as t1, "
864
"\"%s_%s\" as t2, \"%s_%s\" as t3 "
865
"where (t1.time_start < %ld && t1.time_start >= %ld) "
866
"&& t1.id_assoc=t2.id_assoc && t3.id_assoc=%d && "
867
"t2.lft between t3.lft and t3.rgt "
868
"order by t3.id_assoc, time_start;",
869
tmp, cluster_name, my_usage_table,
870
cluster_name, cluster_name, assoc_table, assoc_table,
873
case DBD_GET_WCKEY_USAGE:
874
query = xstrdup_printf(
875
"select %s from \"%s_%s\" "
876
"where (time_start < %ld && time_start >= %ld) "
877
"&& id_wckey=%d order by id_wckey, time_start;",
878
tmp, cluster_name, my_usage_table, end, start, id);
881
error("Unknown usage type %d", type);
887
debug4("%d(%s:%d) query\n%s",
888
mysql_conn->conn, THIS_FILE, __LINE__, query);
889
if (!(result = mysql_db_query_ret(
890
mysql_conn, query, 0))) {
897
(*my_list) = list_create(slurmdb_destroy_accounting_rec);
899
while ((row = mysql_fetch_row(result))) {
900
slurmdb_accounting_rec_t *accounting_rec =
901
xmalloc(sizeof(slurmdb_accounting_rec_t));
902
accounting_rec->id = slurm_atoul(row[USAGE_ID]);
903
accounting_rec->period_start = slurm_atoul(row[USAGE_START]);
904
accounting_rec->alloc_secs = slurm_atoull(row[USAGE_ACPU]);
905
list_append((*my_list), accounting_rec);
907
mysql_free_result(result);
912
extern int as_mysql_roll_usage(mysql_conn_t *mysql_conn,
913
time_t sent_start, time_t sent_end,
914
uint16_t archive_data)
916
int rc = SLURM_SUCCESS;
918
char *cluster_name = NULL;
920
pthread_mutex_t rolledup_lock = PTHREAD_MUTEX_INITIALIZER;
921
pthread_cond_t rolledup_cond;
924
if (check_connection(mysql_conn) != SLURM_SUCCESS)
925
return ESLURM_DB_CONNECTION;
927
slurm_mutex_lock(&usage_rollup_lock);
929
slurm_mutex_init(&rolledup_lock);
930
pthread_cond_init(&rolledup_cond, NULL);
933
slurm_mutex_lock(&as_mysql_cluster_list_lock);
934
itr = list_iterator_create(as_mysql_cluster_list);
935
while ((cluster_name = list_next(itr))) {
936
/* pthread_t rollup_tid; */
937
/* pthread_attr_t rollup_attr; */
938
local_rollup_t *local_rollup = xmalloc(sizeof(local_rollup_t));
940
local_rollup->archive_data = archive_data;
941
local_rollup->cluster_name = cluster_name;
943
local_rollup->mysql_conn = mysql_conn;
944
local_rollup->rc = &rc;
945
local_rollup->rolledup = &rolledup;
946
local_rollup->rolledup_lock = &rolledup_lock;
947
local_rollup->rolledup_cond = &rolledup_cond;
949
local_rollup->sent_end = sent_end;
950
local_rollup->sent_start = sent_start;
952
/* _cluster_rollup_usage is responsible for freeing
954
_cluster_rollup_usage(local_rollup);
955
/* It turns out doing this with threads only buys a
956
very small victory, and can skew the timings. So
957
just doing them one after the other isn't too bad.
958
If you really want to do this in threads you can
959
just uncomment this, and comment the call above.
961
/* slurm_attr_init(&rollup_attr); */
962
/* if (pthread_create(&rollup_tid, &rollup_attr, */
963
/* _cluster_rollup_usage, */
964
/* (void *)local_rollup)) */
965
/* fatal("pthread_create: %m"); */
966
/* slurm_attr_destroy(&rollup_attr); */
968
slurm_mutex_lock(&rolledup_lock);
969
list_iterator_destroy(itr);
970
slurm_mutex_unlock(&as_mysql_cluster_list_lock);
972
while (rolledup < list_count(as_mysql_cluster_list)) {
973
pthread_cond_wait(&rolledup_cond, &rolledup_lock);
974
debug2("Got %d rolled up", rolledup);
976
slurm_mutex_unlock(&rolledup_lock);
977
debug2("Everything rolled up");
978
slurm_mutex_destroy(&rolledup_lock);
979
pthread_cond_destroy(&rolledup_cond);
981
/* info("total time was %s", TIME_STR); */
983
slurm_mutex_unlock(&usage_rollup_lock);