171
221
xstrfmtcat(suspend_str, ", %s", suspend_req_inx[i]);
225
xstrfmtcat(resv_str, "%s", resv_req_inx[i]);
226
for(i=1; i<RESV_REQ_COUNT; i++) {
227
xstrfmtcat(resv_str, ", %s", resv_req_inx[i]);
174
230
/* info("begin start %s", ctime(&curr_start)); */
175
231
/* info("begin end %s", ctime(&curr_end)); */
176
232
a_itr = list_iterator_create(assoc_usage_list);
177
233
c_itr = list_iterator_create(cluster_usage_list);
178
234
w_itr = list_iterator_create(wckey_usage_list);
235
r_itr = list_iterator_create(resv_usage_list);
179
236
while(curr_start < end) {
237
local_cluster_usage_t *last_c_usage = NULL;
180
238
int last_id = -1;
181
239
int last_wckeyid = -1;
183
241
local_cluster_usage_t *c_usage = NULL;
242
local_resv_usage_t *r_usage = NULL;
184
243
local_id_usage_t *a_usage = NULL;
185
244
local_id_usage_t *w_usage = NULL;
189
246
debug3("curr hour is now %d-%d", curr_start, curr_end);
190
247
/* info("start %s", ctime(&curr_start)); */
191
248
/* info("end %s", ctime(&curr_end)); */
193
// first get the events during this time
250
/* first get the events during this time. All that is
251
* except things with the maintainance flag set in the
252
* state. We handle those later with the reservations.
194
254
query = xstrdup_printf("select %s from %s where "
195
"(period_start < %d "
255
"!(state & %d) && (period_start < %d "
196
256
"&& (period_end >= %d "
197
257
"|| period_end = 0)) "
198
258
"order by node_name, period_start",
199
259
event_str, event_table,
200
261
curr_end, curr_start);
202
263
debug3("%d(%d) query\n%s", mysql_conn->conn, __LINE__, query);
300
361
mysql_free_result(result);
363
// now get the reservations during this time
364
query = xstrdup_printf("select %s from %s where "
365
"(start < %d && end >= %d) "
366
"order by cluster, start",
367
resv_str, resv_table,
368
curr_end, curr_start);
370
debug3("%d(%d) query\n%s", mysql_conn->conn, __LINE__, query);
371
if(!(result = mysql_db_query_ret(
372
mysql_conn->db_conn, query, 0))) {
378
/* If a reservation overlaps another reservation we
379
total up everything here as if they didn't but when
380
calculating the total time for a cluster we will
381
remove the extra time received. This may result in
382
unexpected results with association based reports
383
since the association is given the total amount of
384
time of each reservation, thus equaling more time
385
that is available. Job/Cluster/Reservation reports
386
should be fine though since we really don't over
389
while((row = mysql_fetch_row(result))) {
390
int row_start = atoi(row[RESV_REQ_START]);
391
int row_end = atoi(row[RESV_REQ_END]);
392
int row_cpu = atoi(row[RESV_REQ_CPU]);
393
int row_flags = atoi(row[RESV_REQ_FLAGS]);
395
if(row_start < curr_start)
396
row_start = curr_start;
398
if(!row_end || row_end > curr_end)
401
/* Don't worry about it if the time is less
404
if((row_end - row_start) < 1)
407
r_usage = xmalloc(sizeof(local_resv_usage_t));
408
r_usage->id = atoi(row[RESV_REQ_ID]);
410
r_usage->local_assocs = list_create(slurm_destroy_char);
411
slurm_addto_char_list(r_usage->local_assocs,
412
row[RESV_REQ_ASSOCS]);
414
r_usage->cluster = xstrdup(row[RESV_REQ_CLUSTER]);
415
r_usage->total_time = (row_end - row_start) * row_cpu;
416
r_usage->start = row_start;
417
r_usage->end = row_end;
418
list_append(resv_usage_list, r_usage);
420
/* Since this reservation was added to the
421
cluster and only certain people could run
422
there we will use this as allocated time on
423
the system. If the reservation was a
424
maintenance then we add the time to planned
427
if(last_c_usage && !strcmp(last_c_usage->name,
429
c_usage = last_c_usage;
431
list_iterator_reset(c_itr);
432
while((c_usage = list_next(c_itr))) {
433
if(!strcmp(c_usage->name,
435
last_c_usage = c_usage;
440
if(row_flags & RESERVE_FLAG_MAINT)
441
c_usage->pd_cpu += r_usage->total_time;
443
c_usage->a_cpu += r_usage->total_time;
444
/* info("adding this much %lld to cluster %s", */
445
/* r_usage->total_time, c_usage->name); */
448
mysql_free_result(result);
450
/* now get the jobs during this time only */
302
451
query = xstrdup_printf("select %s from %s where "
303
452
"(eligible < %d && (end >= %d "
423
573
if(!row[JOB_REQ_CLUSTER] || !row[JOB_REQ_CLUSTER][0])
576
/* first figure out the reservation */
580
/* Since we have already added the
581
entire reservation as used time on
582
the cluster we only need to
583
calculate the used time for the
584
reservation and then divy up the
585
unused time over the associations
586
able to run in the reservation.
587
Since the job was to run, or ran a
588
reservation we don't care about eligible time
589
since that could totally skew the
590
clusters reserved time
591
since the job may be able to run
592
outside of the reservation. */
593
list_iterator_reset(r_itr);
594
while((r_usage = list_next(r_itr))) {
595
/* since the reservation could
596
have changed in some way,
598
reservation record in the
599
database, we have to make
600
sure all the reservations
601
are checked to see if such
602
a thing has happened */
603
if((r_usage->id == resv_id)
604
&& !strcmp(r_usage->cluster,
605
row[JOB_REQ_CLUSTER])) {
606
int temp_end = row_end;
607
int temp_start = row_start;
608
if(r_usage->start > temp_start)
611
if(r_usage->end < temp_end)
612
temp_end = r_usage->end;
614
if((temp_end - temp_start)
426
626
if(last_c_usage && !strcmp(last_c_usage->name,
427
627
row[JOB_REQ_CLUSTER])) {
428
628
c_usage = last_c_usage;
482
683
/* seconds * row_rcpu, */
484
c_usage->r_cpu += seconds * row_rcpu;
685
c_usage->r_cpu += seconds;
488
689
mysql_free_result(result);
691
/* now figure out how much more to add to the
692
associations that could had run in the reservation
694
list_iterator_reset(r_itr);
695
while((r_usage = list_next(r_itr))) {
696
int64_t idle = r_usage->total_time - r_usage->a_cpu;
698
ListIterator tmp_itr = NULL;
703
/* now divide that time by the number of
704
associations in the reservation and add
705
them to each association */
706
seconds = idle / list_count(r_usage->local_assocs);
707
/* info("resv %d got %d for seconds for %d assocs", */
708
/* r_usage->id, seconds, */
709
/* list_count(r_usage->local_assocs)); */
710
tmp_itr = list_iterator_create(r_usage->local_assocs);
711
while((assoc = list_next(tmp_itr))) {
712
int associd = atoi(assoc);
713
if(last_id != associd) {
714
list_iterator_reset(a_itr);
715
while((a_usage = list_next(a_itr))) {
716
if(!a_usage->id == associd) {
717
last_id = a_usage->id;
725
sizeof(local_id_usage_t));
726
a_usage->id = associd;
727
list_append(assoc_usage_list, a_usage);
731
a_usage->a_cpu += seconds;
733
list_iterator_destroy(tmp_itr);
490
736
/* Now put the lists into the usage tables */
491
737
list_iterator_reset(c_itr);
492
738
while((c_usage = list_next(c_itr))) {
493
c_usage->i_cpu = c_usage->total_time - c_usage->a_cpu -
494
c_usage->d_cpu - c_usage->r_cpu;
739
uint64_t total_used = 0;
741
/* sanity check to make sure we don't have more
742
allocated cpus than possible. */
743
if(c_usage->total_time < c_usage->a_cpu) {
744
char *start_char = xstrdup(ctime(&curr_start));
745
char *end_char = xstrdup(ctime(&curr_end));
746
error("We have more allocated time than is "
747
"possible (%llu > %llu) for "
748
"cluster %s(%d) from %s - %s",
749
c_usage->a_cpu, c_usage->total_time,
750
c_usage->name, c_usage->cpu_count,
751
start_char, end_char);
754
c_usage->a_cpu = c_usage->total_time;
757
total_used = c_usage->a_cpu +
758
c_usage->d_cpu + c_usage->pd_cpu;
760
/* Make sure the total time we care about
761
doesn't go over the limit */
762
if(c_usage->total_time < (total_used)) {
763
char *start_char = xstrdup(ctime(&curr_start));
764
char *end_char = xstrdup(ctime(&curr_end));
765
error("We have more time than is "
766
"possible (%llu+%llu+%llu)(%llu) "
768
"cluster %s(%d) from %s - %s",
769
c_usage->a_cpu, c_usage->d_cpu,
770
c_usage->pd_cpu, total_used,
772
c_usage->name, c_usage->cpu_count,
773
start_char, end_char);
777
/* set the planned down to 0 and the
778
down to what ever is left from the
782
c_usage->total_time - c_usage->a_cpu;
784
total_used = c_usage->a_cpu +
785
c_usage->d_cpu + c_usage->pd_cpu;
788
c_usage->i_cpu = c_usage->total_time -
789
total_used - c_usage->r_cpu;
495
790
/* sanity check just to make sure we have a
496
791
* legitimate time after we calulated
497
792
* idle/reserved time put extra in the over
795
/* info("%s got idle of %lld", c_usage->name, */
796
/* (int64_t)c_usage->i_cpu); */
501
797
if((int64_t)c_usage->i_cpu < 0) {
502
798
/* info("got %d %d %d", c_usage->r_cpu, */
503
799
/* c_usage->i_cpu, c_usage->o_cpu); */
524
820
xstrfmtcat(query,
525
821
", (%d, %d, '%s', %d, %d, "
526
"%llu, %llu, %llu, %llu, %llu)",
528
825
c_usage->name, c_usage->start,
529
826
c_usage->cpu_count, c_usage->a_cpu,
530
c_usage->d_cpu, c_usage->i_cpu,
531
c_usage->o_cpu, c_usage->r_cpu);
827
c_usage->d_cpu, c_usage->pd_cpu,
828
c_usage->i_cpu, c_usage->o_cpu,
533
831
xstrfmtcat(query,
534
832
"insert into %s (creation_time, "
535
833
"mod_time, cluster, period_start, "
536
834
"cpu_count, alloc_cpu_secs, "
537
"down_cpu_secs, idle_cpu_secs, "
538
"over_cpu_secs, resv_cpu_secs) "
835
"down_cpu_secs, pdown_cpu_secs, "
836
"idle_cpu_secs, over_cpu_secs, "
539
838
"values (%d, %d, '%s', %d, %d, "
540
"%llu, %llu, %llu, %llu, %llu)",
541
841
cluster_hour_table, now, now,
542
842
c_usage->name, c_usage->start,
543
843
c_usage->cpu_count,
545
c_usage->d_cpu, c_usage->i_cpu,
844
c_usage->a_cpu, c_usage->d_cpu,
845
c_usage->pd_cpu, c_usage->i_cpu,
546
846
c_usage->o_cpu, c_usage->r_cpu);
659
961
xfree(suspend_str);
660
962
xfree(event_str);
662
965
list_iterator_destroy(a_itr);
663
966
list_iterator_destroy(c_itr);
664
967
list_iterator_destroy(w_itr);
968
list_iterator_destroy(r_itr);
666
970
list_destroy(assoc_usage_list);
667
971
list_destroy(cluster_usage_list);
668
972
list_destroy(wckey_usage_list);
973
list_destroy(resv_usage_list);
669
975
/* info("stop start %s", ctime(&curr_start)); */
670
976
/* info("stop end %s", ctime(&curr_end)); */
673
979
extern int mysql_daily_rollup(mysql_conn_t *mysql_conn,
674
time_t start, time_t end)
980
time_t start, time_t end, uint16_t archive_data)
676
982
/* can't just add 86400 since daylight savings starts and ends every
677
983
* once in a while
712
1018
xstrfmtcat(query,
713
1019
"insert into %s (creation_time, "
714
1020
"mod_time, cluster, period_start, cpu_count, "
715
"alloc_cpu_secs, down_cpu_secs, idle_cpu_secs, "
716
"over_cpu_secs, resv_cpu_secs) "
1021
"alloc_cpu_secs, down_cpu_secs, pdown_cpu_secs, "
1022
"idle_cpu_secs, over_cpu_secs, resv_cpu_secs) "
717
1023
"select %d, %d, cluster, "
718
1024
"%d, @CPU:=MAX(cpu_count), "
719
1025
"@ASUM:=SUM(alloc_cpu_secs), "
720
1026
"@DSUM:=SUM(down_cpu_secs), "
1027
"@PDSUM:=SUM(pdown_cpu_secs), "
721
1028
"@ISUM:=SUM(idle_cpu_secs), "
722
1029
"@OSUM:=SUM(over_cpu_secs), "
723
1030
"@RSUM:=SUM(resv_cpu_secs) from %s where "
725
1032
"group by cluster on duplicate key update "
726
1033
"mod_time=%d, cpu_count=@CPU, "
727
1034
"alloc_cpu_secs=@ASUM, down_cpu_secs=@DSUM, "
728
"idle_cpu_secs=@ISUM, over_cpu_secs=@OSUM, "
729
"resv_cpu_secs=@RSUM;",
1035
"pdown_cpu_secs=@PDSUM, idle_cpu_secs=@ISUM, "
1036
"over_cpu_secs=@OSUM, resv_cpu_secs=@RSUM;",
730
1037
cluster_day_table, now, now, curr_start,
731
1038
cluster_hour_table,
732
1039
curr_end, curr_start, now);
735
1042
"insert into %s (creation_time, "
736
1043
"mod_time, id, period_start, "
737
1044
"alloc_cpu_secs) select %d, %d, "
738
"id, %d, @ASUM:=SUM(alloc_cpu_secs) from %s "
739
"where (period_start < %d && "
1045
"id, %d, @ASUM:=SUM(alloc_cpu_secs) "
1046
"from %s where (period_start < %d && "
740
1047
"period_start >= %d) "
741
1048
"group by id on duplicate key update "
742
1049
"mod_time=%d, alloc_cpu_secs=@ASUM;",
823
1119
xstrfmtcat(query,
824
1120
"insert into %s (creation_time, "
825
1121
"mod_time, cluster, period_start, cpu_count, "
826
"alloc_cpu_secs, down_cpu_secs, idle_cpu_secs, "
827
"over_cpu_secs, resv_cpu_secs) "
1122
"alloc_cpu_secs, down_cpu_secs, pdown_cpu_secs, "
1123
"idle_cpu_secs, over_cpu_secs, resv_cpu_secs) "
828
1124
"select %d, %d, cluster, "
829
1125
"%d, @CPU:=MAX(cpu_count), "
830
1126
"@ASUM:=SUM(alloc_cpu_secs), "
831
1127
"@DSUM:=SUM(down_cpu_secs), "
1128
"@PDSUM:=SUM(pdown_cpu_secs), "
832
1129
"@ISUM:=SUM(idle_cpu_secs), "
833
1130
"@OSUM:=SUM(over_cpu_secs), "
834
1131
"@RSUM:=SUM(resv_cpu_secs) from %s where "
836
1133
"group by cluster on duplicate key update "
837
1134
"mod_time=%d, cpu_count=@CPU, "
838
1135
"alloc_cpu_secs=@ASUM, down_cpu_secs=@DSUM, "
839
"idle_cpu_secs=@ISUM, over_cpu_secs=@OSUM, "
840
"resv_cpu_secs=@RSUM;",
1136
"pdown_cpu_secs=@PDSUM, idle_cpu_secs=@ISUM, "
1137
"over_cpu_secs=@OSUM, resv_cpu_secs=@RSUM;",
841
1138
cluster_month_table, now, now, curr_start,
842
1139
cluster_day_table,
843
1140
curr_end, curr_start, now);
844
1141
if(track_wckey) {
845
1142
xstrfmtcat(query,
846
1143
"insert into %s (creation_time, mod_time, "
848
"period_start, alloc_cpu_secs) select %d, "
849
"%d, id, %d, @ASUM:=SUM(alloc_cpu_secs) "
1144
"id, period_start, alloc_cpu_secs) "
1145
"select %d, %d, id, %d, "
1146
"@ASUM:=SUM(alloc_cpu_secs) "
850
1147
"from %s where (period_start < %d && "
851
1148
"period_start >= %d) "
852
1149
"group by id on duplicate key update "
877
1174
curr_end = mktime(&start_tm);
880
/* remove all data from event table that was older than
883
query = xstrdup_printf("delete from %s where period_end < %d "
884
"&& period_end != 0",
886
rc = mysql_db_query(mysql_conn->db_conn, query);
888
if(rc != SLURM_SUCCESS) {
889
error("Couldn't remove old event data");
1177
/* if we didn't ask for archive data return here and don't do
1178
anything extra just rollup */
1181
return SLURM_SUCCESS;
892
1183
if(!slurmdbd_conf)
893
1184
return SLURM_SUCCESS;
895
1186
memset(&arch_cond, 0, sizeof(arch_cond));
896
1187
arch_cond.archive_dir = slurmdbd_conf->archive_dir;
1188
arch_cond.archive_events = slurmdbd_conf->archive_events;
897
1189
arch_cond.archive_jobs = slurmdbd_conf->archive_jobs;
898
1190
arch_cond.archive_script = slurmdbd_conf->archive_script;
899
1191
arch_cond.archive_steps = slurmdbd_conf->archive_steps;
900
arch_cond.job_purge = slurmdbd_conf->job_purge;
901
arch_cond.step_purge = slurmdbd_conf->step_purge;
1192
arch_cond.archive_suspend = slurmdbd_conf->archive_suspend;
1193
arch_cond.purge_event = slurmdbd_conf->purge_event;
1194
arch_cond.purge_job = slurmdbd_conf->purge_job;
1195
arch_cond.purge_step = slurmdbd_conf->purge_step;
1196
arch_cond.purge_suspend = slurmdbd_conf->purge_suspend;
903
1198
return mysql_jobacct_process_archive(mysql_conn, &arch_cond);