~ubuntu-branches/ubuntu/saucy/slurm-llnl/saucy

« back to all changes in this revision

Viewing changes to src/plugins/accounting_storage/mysql/mysql_rollup.c

  • Committer: Bazaar Package Importer
  • Author(s): Gennaro Oliva
  • Date: 2008-05-30 13:11:30 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20080530131130-l6ko6aie7xhrlmxe
Tags: 1.3.3-1
* New upstream release
* Removed patches to src/slurmctd/controller.c src/slurmdbd/slurmdbd.c
  doc/man/man1/sacctmgr.1 included to upstream
* Edited watch file to seek for 1.3 releases
* doc/man/man1/salloc.1 doc/man/man1/sbatch.1 doc/man/man5/slurm.conf.5
  patched to improve formatting and avoid manual warnings 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************\
 
2
 *  mysql_rollup.c - functions for rolling up data for associations
 
3
 *                   and machines from the mysql storage.
 
4
 *****************************************************************************
 
5
 *
 
6
 *  Copyright (C) 2004-2007 The Regents of the University of California.
 
7
 *  Copyright (C) 2008 Lawrence Livermore National Security.
 
8
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
 
9
 *  Written by Danny Auble <da@llnl.gov>
 
10
 *  LLNL-CODE-402394.
 
11
 *  
 
12
 *  This file is part of SLURM, a resource management program.
 
13
 *  For details, see <http://www.llnl.gov/linux/slurm/>.
 
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
 
 
41
#include "mysql_rollup.h"
 
42
 
 
43
#ifdef HAVE_MYSQL
 
44
 
 
45
typedef struct {
 
46
        int assoc_id;
 
47
        int a_cpu;
 
48
} local_assoc_usage_t;
 
49
 
 
50
typedef struct {
 
51
        char *name;
 
52
        int total_time;
 
53
        int a_cpu;
 
54
        int cpu_count;
 
55
        int d_cpu;
 
56
        int i_cpu;
 
57
        int o_cpu;
 
58
        int r_cpu;
 
59
        time_t start;
 
60
        time_t end;
 
61
} local_cluster_usage_t;
 
62
 
 
63
 
 
64
extern void _destroy_local_assoc_usage(void *object)
 
65
{
 
66
        local_assoc_usage_t *a_usage = (local_assoc_usage_t *)object;
 
67
        if(a_usage) {
 
68
                xfree(a_usage);
 
69
        }
 
70
}
 
71
 
 
72
extern void _destroy_local_cluster_usage(void *object)
 
73
{
 
74
        local_cluster_usage_t *c_usage = (local_cluster_usage_t *)object;
 
75
        if(c_usage) {
 
76
                xfree(c_usage->name);
 
77
                xfree(c_usage);
 
78
        }
 
79
}
 
80
 
 
81
extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 
82
                               time_t start, time_t end)
 
83
{
 
84
        int rc = SLURM_SUCCESS;
 
85
        int add_sec = 3600;
 
86
        int i=0;
 
87
        time_t now = time(NULL);
 
88
        time_t curr_start = start;
 
89
        time_t curr_end = curr_start + add_sec;
 
90
        char *query = NULL;
 
91
        MYSQL_RES *result = NULL;
 
92
        MYSQL_ROW row;
 
93
        ListIterator a_itr = NULL;
 
94
        ListIterator c_itr = NULL;
 
95
        List assoc_usage_list = list_create(_destroy_local_assoc_usage);
 
96
        List cluster_usage_list = list_create(_destroy_local_cluster_usage);
 
97
        char *event_req_inx[] = {
 
98
                "node_name",
 
99
                "cluster",
 
100
                "cpu_count",
 
101
                "period_start",
 
102
                "period_end"
 
103
        };
 
104
        char *event_str = NULL;
 
105
        enum {
 
106
                EVENT_REQ_NAME,
 
107
                EVENT_REQ_CLUSTER,
 
108
                EVENT_REQ_CPU,
 
109
                EVENT_REQ_START,
 
110
                EVENT_REQ_END,
 
111
                EVENT_REQ_COUNT
 
112
        };
 
113
        char *job_req_inx[] = {
 
114
                "t1.id",
 
115
                "jobid",
 
116
                "associd",
 
117
                "cluster",
 
118
                "eligible",
 
119
                "start",
 
120
                "end",
 
121
                "suspended",
 
122
                "alloc_cpus",
 
123
                "req_cpus"
 
124
        };
 
125
        char *job_str = NULL;
 
126
        enum {
 
127
                JOB_REQ_DB_INX,
 
128
                JOB_REQ_JOBID,
 
129
                JOB_REQ_ASSOCID,
 
130
                JOB_REQ_CLUSTER,
 
131
                JOB_REQ_ELG,
 
132
                JOB_REQ_START,
 
133
                JOB_REQ_END,
 
134
                JOB_REQ_SUSPENDED,
 
135
                JOB_REQ_ACPU,
 
136
                JOB_REQ_RCPU,
 
137
                JOB_REQ_COUNT
 
138
        };
 
139
        char *suspend_req_inx[] = {
 
140
                "start",
 
141
                "end"
 
142
        };
 
143
        char *suspend_str = NULL;
 
144
        enum {
 
145
                SUSPEND_REQ_START,
 
146
                SUSPEND_REQ_END,
 
147
                SUSPEND_REQ_COUNT
 
148
        };
 
149
 
 
150
        i=0;
 
151
        xstrfmtcat(event_str, "%s", event_req_inx[i]);
 
152
        for(i=1; i<EVENT_REQ_COUNT; i++) {
 
153
                xstrfmtcat(event_str, ", %s", event_req_inx[i]);
 
154
        }
 
155
 
 
156
        i=0;
 
157
        xstrfmtcat(job_str, "%s", job_req_inx[i]);
 
158
        for(i=1; i<JOB_REQ_COUNT; i++) {
 
159
                xstrfmtcat(job_str, ", %s", job_req_inx[i]);
 
160
        }
 
161
 
 
162
        i=0;
 
163
        xstrfmtcat(suspend_str, "%s", suspend_req_inx[i]);
 
164
        for(i=1; i<SUSPEND_REQ_COUNT; i++) {
 
165
                xstrfmtcat(suspend_str, ", %s", suspend_req_inx[i]);
 
166
        }
 
167
 
 
168
/*      info("begin start %s", ctime(&curr_start)); */
 
169
/*      info("begin end %s", ctime(&curr_end)); */
 
170
        a_itr = list_iterator_create(assoc_usage_list);
 
171
        c_itr = list_iterator_create(cluster_usage_list);
 
172
        while(curr_start < end) {
 
173
                int last_id = 0;
 
174
                int seconds = 0;
 
175
                local_cluster_usage_t *c_usage = NULL;
 
176
                local_assoc_usage_t *a_usage = NULL;
 
177
                debug3("curr hour is now %d-%d", curr_start, curr_end);
 
178
/*              info("start %s", ctime(&curr_start)); */
 
179
/*              info("end %s", ctime(&curr_end)); */
 
180
                
 
181
                // first get the events during this time
 
182
                query = xstrdup_printf("select %s from %s where "
 
183
                                       "(period_start < %d "
 
184
                                       "&& (period_end >= %d "
 
185
                                       "|| period_end = 0)) "
 
186
                                       "order by node_name, period_start",
 
187
                                       event_str, event_table,
 
188
                                       curr_end, curr_start);
 
189
 
 
190
                debug3("%d query\n%s", mysql_conn->conn, query);
 
191
                if(!(result = mysql_db_query_ret(
 
192
                             mysql_conn->acct_mysql_db, query, 0))) {
 
193
                        xfree(query);
 
194
                        return SLURM_ERROR;
 
195
                }
 
196
                xfree(query);
 
197
                
 
198
                while((row = mysql_fetch_row(result))) {
 
199
                        int row_start = atoi(row[EVENT_REQ_START]);
 
200
                        int row_end = atoi(row[EVENT_REQ_END]);
 
201
                        int row_cpu = atoi(row[EVENT_REQ_CPU]);
 
202
                                        
 
203
                        if(row_start < curr_start)
 
204
                                row_start = curr_start;
 
205
                
 
206
                        if(!row_end || row_end > curr_end) 
 
207
                                row_end = curr_end;
 
208
 
 
209
                        /* Don't worry about it if the time is less
 
210
                         * than 1 second.
 
211
                         */
 
212
                        if((row_end - row_start) < 1)
 
213
                                continue;
 
214
 
 
215
                        if(!row[EVENT_REQ_NAME][0]) {
 
216
                                list_iterator_reset(c_itr);
 
217
                                while((c_usage = list_next(c_itr))) {
 
218
                                        if(!strcmp(c_usage->name,
 
219
                                           row[EVENT_REQ_CLUSTER])) {
 
220
                                                break;
 
221
                                        }
 
222
                                }
 
223
                                /* if the cpu count changes we will
 
224
                                 * only care about the last cpu count but
 
225
                                 * we will keep a total of the time for
 
226
                                 * all cpus to get the correct cpu time
 
227
                                 * for the entire period.
 
228
                                 */
 
229
                                if(!c_usage) {
 
230
                                        c_usage = xmalloc(
 
231
                                                sizeof(local_cluster_usage_t));
 
232
                                        c_usage->name = 
 
233
                                                xstrdup(row[EVENT_REQ_CLUSTER]);
 
234
                                        c_usage->cpu_count = row_cpu;
 
235
                                        c_usage->total_time =
 
236
                                                (row_end - row_start) * row_cpu;
 
237
                                        c_usage->start = row_start;
 
238
                                        c_usage->end = row_end;
 
239
                                        list_append(cluster_usage_list, 
 
240
                                                    c_usage);
 
241
                                } else {
 
242
                                        c_usage->cpu_count = row_cpu;
 
243
                                        c_usage->total_time +=
 
244
                                                (row_end - row_start) * row_cpu;
 
245
                                        c_usage->end = row_end;
 
246
                                }
 
247
                                continue;
 
248
                        }
 
249
 
 
250
                        list_iterator_reset(c_itr);
 
251
                        while((c_usage = list_next(c_itr))) {
 
252
                                if(!strcmp(c_usage->name,
 
253
                                           row[EVENT_REQ_CLUSTER])) {
 
254
                                        int local_start = row_start;
 
255
                                        int local_end = row_end;
 
256
                                        if(c_usage->start > local_start)
 
257
                                                local_start = c_usage->start;
 
258
                                        if(c_usage->end < local_end)
 
259
                                                local_end = c_usage->end;
 
260
 
 
261
                                        if((local_end - local_start) < 1)
 
262
                                                continue;
 
263
 
 
264
                                        seconds = (local_end - local_start);
 
265
 
 
266
/*                                      info("node %s adds " */
 
267
/*                                           "(%d)(%d-%d) * %d = %d " */
 
268
/*                                           "to %d", */
 
269
/*                                           row[EVENT_REQ_NAME], */
 
270
/*                                           seconds, */
 
271
/*                                           local_end, local_start, */
 
272
/*                                           row_cpu,  */
 
273
/*                                           seconds * row_cpu,  */
 
274
/*                                           row_cpu); */
 
275
                                        c_usage->d_cpu += seconds * row_cpu;
 
276
                                        
 
277
                                        break;
 
278
                                }                                  
 
279
                        }
 
280
                }
 
281
                mysql_free_result(result);
 
282
 
 
283
                query = xstrdup_printf("select %s from %s as t1, "
 
284
                                       "%s as t2 where "
 
285
                                       "(eligible < %d && (end >= %d "
 
286
                                       "|| end = 0)) && associd=t2.id "
 
287
                                       "order by associd, eligible",
 
288
                                       job_str, job_table, assoc_table,
 
289
                                       curr_end, curr_start, curr_start);
 
290
 
 
291
                debug3("%d query\n%s", mysql_conn->conn, query);
 
292
                if(!(result = mysql_db_query_ret(
 
293
                             mysql_conn->acct_mysql_db, query, 0))) {
 
294
                        xfree(query);
 
295
                        return SLURM_ERROR;
 
296
                }
 
297
                xfree(query);
 
298
                
 
299
                while((row = mysql_fetch_row(result))) {
 
300
                        int job_id = atoi(row[JOB_REQ_JOBID]);
 
301
                        int assoc_id = atoi(row[JOB_REQ_ASSOCID]);
 
302
                        int row_eligible = atoi(row[JOB_REQ_ELG]);
 
303
                        int row_start = atoi(row[JOB_REQ_START]);
 
304
                        int row_end = atoi(row[JOB_REQ_END]);
 
305
                        int row_acpu = atoi(row[JOB_REQ_ACPU]);
 
306
                        int row_rcpu = atoi(row[JOB_REQ_RCPU]);
 
307
                        seconds = 0;
 
308
                       
 
309
                        if(row_start && (row_start < curr_start))
 
310
                                row_start = curr_start;
 
311
 
 
312
                        if(!row_start && row_end)
 
313
                                row_start = row_end;
 
314
 
 
315
                        if(!row_end || row_end > curr_end) 
 
316
                                row_end = curr_end;
 
317
                        
 
318
                        if(last_id != assoc_id) {
 
319
                                a_usage =
 
320
                                        xmalloc(sizeof(local_cluster_usage_t));
 
321
                                a_usage->assoc_id = assoc_id;
 
322
                                list_append(assoc_usage_list, a_usage);
 
323
                                last_id = assoc_id;
 
324
                        }
 
325
 
 
326
 
 
327
                        if(!row_start || ((row_end - row_start) < 1)) 
 
328
                                goto calc_cluster;
 
329
 
 
330
                        seconds = (row_end - row_start);
 
331
 
 
332
                        if(row[JOB_REQ_SUSPENDED]) {
 
333
                                MYSQL_RES *result2 = NULL;
 
334
                                MYSQL_ROW row2;
 
335
                                /* get the suspended time for this job */
 
336
                                query = xstrdup_printf(
 
337
                                        "select %s from %s where "
 
338
                                        "(start < %d && (end >= %d "
 
339
                                        "|| end = 0)) && id=%s "
 
340
                                        "order by start",
 
341
                                        suspend_str, suspend_table,
 
342
                                        curr_end, curr_start,
 
343
                                        row[JOB_REQ_DB_INX]);
 
344
                                
 
345
                                debug4("%d query\n%s", mysql_conn->conn, query);
 
346
                                if(!(result2 = mysql_db_query_ret(
 
347
                                             mysql_conn->acct_mysql_db,
 
348
                                             query, 0))) {
 
349
                                        xfree(query);
 
350
                                        return SLURM_ERROR;
 
351
                                }
 
352
                                xfree(query);
 
353
                                while((row2 = mysql_fetch_row(result2))) {
 
354
                                        int local_start =
 
355
                                                atoi(row2[SUSPEND_REQ_START]);
 
356
                                        int local_end = 
 
357
                                                atoi(row2[SUSPEND_REQ_END]);
 
358
 
 
359
                                        if(!local_start)
 
360
                                                continue;
 
361
 
 
362
                                        if(row_start > local_start)
 
363
                                                local_start = row_start;
 
364
                                        if(row_end < local_end)
 
365
                                                local_end = row_end;
 
366
 
 
367
                                        if((local_end - local_start) < 1)
 
368
                                                continue;
 
369
                                        
 
370
                                        seconds -= (local_end - local_start);
 
371
                                }
 
372
                                mysql_free_result(result2);                     
 
373
 
 
374
                        }
 
375
                        if(seconds < 1) {
 
376
                                debug4("This job (%u) was suspended "
 
377
                                       "the entire hour", job_id);
 
378
                                continue;
 
379
                        }
 
380
 
 
381
 
 
382
                        a_usage->a_cpu += seconds * row_acpu;
 
383
 
 
384
                calc_cluster:
 
385
                        if(!row[JOB_REQ_CLUSTER]) 
 
386
                                continue;
 
387
                        
 
388
                        list_iterator_reset(c_itr);
 
389
                        while((c_usage = list_next(c_itr))) {
 
390
                                if(!strcmp(c_usage->name,
 
391
                                           row[JOB_REQ_CLUSTER])) {
 
392
                                        if(!row_start || seconds < 1)
 
393
                                                goto calc_resv;
 
394
 
 
395
/*                                      info("%d assoc %d adds " */
 
396
/*                                           "(%d)(%d-%d) * %d = %d " */
 
397
/*                                           "to %d", */
 
398
/*                                           job_id, */
 
399
/*                                           a_usage->assoc_id, */
 
400
/*                                           seconds, */
 
401
/*                                           row_end, row_start, */
 
402
/*                                           row_acpu, */
 
403
/*                                           seconds * row_acpu, */
 
404
/*                                           row_acpu); */
 
405
 
 
406
                                        c_usage->a_cpu += seconds * row_acpu;
 
407
 
 
408
                                calc_resv:
 
409
                                        /* now reserved time */
 
410
                                        if(row_start && 
 
411
                                           row_start < c_usage->start)
 
412
                                                continue;
 
413
                                        
 
414
                                        row_end = row_start;
 
415
                                        row_start = row_eligible;
 
416
                                        if(c_usage->start > row_start)
 
417
                                                row_start = c_usage->start;
 
418
                                        if(c_usage->end < row_end)
 
419
                                                row_end = c_usage->end;
 
420
                                        
 
421
                                        if((row_end - row_start) < 1)
 
422
                                                continue;
 
423
                                        
 
424
                                        seconds = (row_end - row_start);
 
425
 
 
426
/*                                      info("%d assoc %d reserved " */
 
427
/*                                           "(%d)(%d-%d) * %d = %d " */
 
428
/*                                           "to %d", */
 
429
/*                                           job_id, */
 
430
/*                                           assoc_id, */
 
431
/*                                           seconds, */
 
432
/*                                           row_end, row_start, */
 
433
/*                                           row_rcpu, */
 
434
/*                                           seconds * row_rcpu, */
 
435
/*                                           row_rcpu); */
 
436
                                        c_usage->r_cpu += seconds * row_rcpu;
 
437
 
 
438
                                        break;
 
439
                                }
 
440
                        }
 
441
                }
 
442
                mysql_free_result(result);
 
443
 
 
444
                list_iterator_reset(c_itr);
 
445
                while((c_usage = list_next(c_itr))) {
 
446
                        c_usage->i_cpu = c_usage->total_time - c_usage->a_cpu -
 
447
                                c_usage->d_cpu - c_usage->r_cpu;
 
448
                        /* sanity check just to make sure we have a
 
449
                         * legitimate time after we calulated
 
450
                         * idle/reserved time put extra in the over
 
451
                         * commit field
 
452
                         */
 
453
                        
 
454
                        if(c_usage->i_cpu < 0) {
 
455
                                c_usage->r_cpu += c_usage->i_cpu;
 
456
                                c_usage->o_cpu -= c_usage->i_cpu;
 
457
                                c_usage->i_cpu = 0;
 
458
                        }
 
459
                        
 
460
/*                      info("cluster %s(%d) down %d alloc %d " */
 
461
/*                           "resv %d idle %d over %d " */
 
462
/*                           "total= %d = %d from %s", */
 
463
/*                           c_usage->name, */
 
464
/*                           c_usage->cpu_count, c_usage->d_cpu, */
 
465
/*                           c_usage->a_cpu, */
 
466
/*                           c_usage->r_cpu, c_usage->i_cpu, c_usage->o_cpu, */
 
467
/*                           c_usage->d_cpu + c_usage->a_cpu + */
 
468
/*                           c_usage->r_cpu + c_usage->i_cpu, */
 
469
/*                           c_usage->total_time, */
 
470
/*                           ctime(&c_usage->start)); */
 
471
/*                      info("to %s", ctime(&c_usage->end)); */
 
472
                        if(query) {
 
473
                                xstrfmtcat(query, 
 
474
                                           ", (%d, %d, '%s', %d, %d, "
 
475
                                           "%d, %d, %d, %d, %d) "
 
476
                                           "on duplicate key update "
 
477
                                           "mod_time=%d, cpu_count=%d, "
 
478
                                           "alloc_cpu_secs=%d, "
 
479
                                           "down_cpu_secs=%d, "
 
480
                                           "idle_cpu_secs=%d, "
 
481
                                           "over_cpu_secs=%d, resv_cpu_secs=%d",
 
482
                                           now, now, 
 
483
                                           c_usage->name, c_usage->start, 
 
484
                                           c_usage->cpu_count, c_usage->a_cpu,
 
485
                                           c_usage->d_cpu, c_usage->i_cpu,
 
486
                                           c_usage->o_cpu, c_usage->r_cpu,
 
487
                                           now, 
 
488
                                           c_usage->cpu_count, c_usage->a_cpu,
 
489
                                           c_usage->d_cpu, c_usage->i_cpu,
 
490
                                           c_usage->o_cpu, c_usage->r_cpu); 
 
491
                        } else {
 
492
                                xstrfmtcat(query, 
 
493
                                           "insert into %s (creation_time, "
 
494
                                           "mod_time, cluster, period_start, "
 
495
                                           "cpu_count, alloc_cpu_secs, "
 
496
                                           "down_cpu_secs, idle_cpu_secs, "
 
497
                                           "over_cpu_secs, resv_cpu_secs) "
 
498
                                           "values (%d, %d, '%s', %d, %d, "
 
499
                                           "%d, %d, %d, %d, %d) "
 
500
                                           "on duplicate key update "
 
501
                                           "mod_time=%d, cpu_count=%d, "
 
502
                                           "alloc_cpu_secs=%d, "
 
503
                                           "down_cpu_secs=%d, "
 
504
                                           "idle_cpu_secs=%d, "
 
505
                                           "over_cpu_secs=%d, resv_cpu_secs=%d",
 
506
                                           cluster_hour_table, now, now, 
 
507
                                           c_usage->name, c_usage->start, 
 
508
                                           c_usage->cpu_count, c_usage->a_cpu,
 
509
                                           c_usage->d_cpu, c_usage->i_cpu,
 
510
                                           c_usage->o_cpu, c_usage->r_cpu,
 
511
                                           now,
 
512
                                           c_usage->cpu_count, c_usage->a_cpu,
 
513
                                           c_usage->d_cpu, c_usage->i_cpu,
 
514
                                           c_usage->o_cpu, c_usage->r_cpu); 
 
515
                        }
 
516
                }
 
517
                if(query) {
 
518
                        rc = mysql_db_query(mysql_conn->acct_mysql_db, query);
 
519
                        xfree(query);
 
520
                        if(rc != SLURM_SUCCESS) {
 
521
                                error("Couldn't add cluster hour rollup");
 
522
                                goto end_it;
 
523
                        }
 
524
                }
 
525
 
 
526
                list_iterator_reset(a_itr);
 
527
                while((a_usage = list_next(a_itr))) {
 
528
/*                      info("association (%d) %d alloc %d", */
 
529
/*                           a_usage->assoc_id, last_id, */
 
530
/*                           a_usage->a_cpu); */
 
531
                        if(query) {
 
532
                                xstrfmtcat(query, 
 
533
                                           ", (%d, %d, %d, %d, %d, "
 
534
                                           "%d, %d, %d, %d) "
 
535
                                           "on duplicate key update "
 
536
                                           "mod_time=%d, alloc_cpu_secs=%d",
 
537
                                           now, now, 
 
538
                                           a_usage->assoc_id, curr_start,
 
539
                                           a_usage->a_cpu,
 
540
                                           now, a_usage->a_cpu); 
 
541
                        } else {
 
542
                                xstrfmtcat(query, 
 
543
                                           "insert into %s (creation_time, "
 
544
                                           "mod_time, id, period_start, "
 
545
                                           "alloc_cpu_secs) values "
 
546
                                           "(%d, %d, %d, %d, %d) "
 
547
                                           "on duplicate key update "
 
548
                                           "mod_time=%d, alloc_cpu_secs=%d",
 
549
                                           assoc_hour_table, now, now, 
 
550
                                           a_usage->assoc_id, curr_start,
 
551
                                           a_usage->a_cpu,
 
552
                                           now, a_usage->a_cpu); 
 
553
                        }
 
554
                }
 
555
                
 
556
                if(query) {
 
557
                        debug3("%d query\n%s", mysql_conn->conn, query);
 
558
                        rc = mysql_db_query(mysql_conn->acct_mysql_db, query);
 
559
                        xfree(query);
 
560
                        if(rc != SLURM_SUCCESS) {
 
561
                                error("Couldn't add assoc hour rollup");
 
562
                                goto end_it;
 
563
                        }
 
564
                }
 
565
                list_flush(assoc_usage_list);
 
566
                list_flush(cluster_usage_list);
 
567
                curr_start = curr_end;
 
568
                curr_end = curr_start + add_sec;
 
569
        }
 
570
end_it:
 
571
        xfree(suspend_str);     
 
572
        xfree(event_str);       
 
573
        xfree(job_str);
 
574
        list_iterator_destroy(a_itr);
 
575
        list_iterator_destroy(c_itr);
 
576
                
 
577
        list_destroy(assoc_usage_list);
 
578
        list_destroy(cluster_usage_list);
 
579
/*      info("stop start %s", ctime(&curr_start)); */
 
580
/*      info("stop end %s", ctime(&curr_end)); */
 
581
        return rc;
 
582
}
 
583
extern int mysql_daily_rollup(mysql_conn_t *mysql_conn, 
 
584
                              time_t start, time_t end)
 
585
{
 
586
        /* can't just add 86400 since daylight savings starts and ends every
 
587
         * once in a while
 
588
         */
 
589
        int rc = SLURM_SUCCESS;
 
590
        struct tm start_tm;
 
591
        time_t curr_start = start;
 
592
        time_t curr_end;
 
593
        time_t now = time(NULL);
 
594
        char *query = NULL;
 
595
 
 
596
        if(!localtime_r(&curr_start, &start_tm)) {
 
597
                error("Couldn't get localtime from day start %d", curr_start);
 
598
                return SLURM_ERROR;
 
599
        }
 
600
        start_tm.tm_sec = 0;
 
601
        start_tm.tm_min = 0;
 
602
        start_tm.tm_hour = 0;
 
603
        start_tm.tm_mday++;
 
604
        start_tm.tm_isdst = -1;
 
605
        curr_end = mktime(&start_tm);
 
606
 
 
607
        while(curr_start < end) {
 
608
                debug3("curr day is now %d-%d", curr_start, curr_end);
 
609
/*      info("start %s", ctime(&curr_start)); */
 
610
/*      info("end %s", ctime(&curr_end)); */
 
611
                query = xstrdup_printf(
 
612
                        "insert into %s (creation_time, mod_time, id, "
 
613
                        "period_start, alloc_cpu_secs) select %d, %d, id, "
 
614
                        "%d, @ASUM:=SUM(alloc_cpu_secs) from %s where "
 
615
                        "(period_start < %d && period_start >= %d) "
 
616
                        "group by id on duplicate key update mod_time=%d, "
 
617
                        "alloc_cpu_secs=@ASUM;",
 
618
                        assoc_day_table, now, now, curr_start,
 
619
                        assoc_hour_table,
 
620
                        curr_end, curr_start, now);
 
621
                xstrfmtcat(query,
 
622
                           "insert into %s (creation_time, "
 
623
                           "mod_time, cluster, period_start, cpu_count, "
 
624
                           "alloc_cpu_secs, down_cpu_secs, idle_cpu_secs, "
 
625
                           "over_cpu_secs, resv_cpu_secs) "
 
626
                           "select %d, %d, cluster, "
 
627
                           "%d, @CPU:=MAX(cpu_count), "
 
628
                           "@ASUM:=SUM(alloc_cpu_secs), "
 
629
                           "@DSUM:=SUM(down_cpu_secs), "
 
630
                           "@ISUM:=SUM(idle_cpu_secs), "
 
631
                           "@OSUM:=SUM(over_cpu_secs), "
 
632
                           "@RSUM:=SUM(resv_cpu_secs) from %s where "
 
633
                           "(period_start < %d && period_start >= %d) "
 
634
                           "group by cluster on duplicate key update "
 
635
                           "mod_time=%d, cpu_count=@CPU, "
 
636
                           "alloc_cpu_secs=@ASUM, down_cpu_secs=@DSUM, "
 
637
                           "idle_cpu_secs=@ISUM, over_cpu_secs=@OSUM, "
 
638
                           "resv_cpu_secs=@RSUM;",
 
639
                           cluster_day_table, now, now, curr_start,
 
640
                           cluster_hour_table,
 
641
                           curr_end, curr_start, now);
 
642
                debug3("%d query\n%s", mysql_conn->conn, query);
 
643
                rc = mysql_db_query(mysql_conn->acct_mysql_db, query);
 
644
                xfree(query);
 
645
                if(rc != SLURM_SUCCESS) {
 
646
                        error("Couldn't add day rollup");
 
647
                        return SLURM_ERROR;
 
648
                }
 
649
 
 
650
                curr_start = curr_end;
 
651
                if(!localtime_r(&curr_start, &start_tm)) {
 
652
                        error("Couldn't get localtime from day start %d",
 
653
                              curr_start);
 
654
                        return SLURM_ERROR;
 
655
                }
 
656
                start_tm.tm_sec = 0;
 
657
                start_tm.tm_min = 0;
 
658
                start_tm.tm_hour = 0;
 
659
                start_tm.tm_mday++;
 
660
                start_tm.tm_isdst = -1;
 
661
                curr_end = mktime(&start_tm);
 
662
        }
 
663
        /* remove all data from suspend table that was older than
 
664
         * start. 
 
665
         */
 
666
        query = xstrdup_printf("delete from %s where end < %d && end != 0",
 
667
                               suspend_table, start);
 
668
        rc = mysql_db_query(mysql_conn->acct_mysql_db, query);
 
669
        xfree(query);
 
670
        if(rc != SLURM_SUCCESS) {
 
671
                error("Couldn't remove old suspend data");
 
672
                return SLURM_ERROR;
 
673
        }
 
674
                               
 
675
 
 
676
/*      info("stop start %s", ctime(&curr_start)); */
 
677
/*      info("stop end %s", ctime(&curr_end)); */
 
678
 
 
679
        return SLURM_SUCCESS;
 
680
}
 
681
extern int mysql_monthly_rollup(mysql_conn_t *mysql_conn,
 
682
                               time_t start, time_t end)
 
683
{
 
684
        int rc = SLURM_SUCCESS;
 
685
        struct tm start_tm;
 
686
        time_t curr_start = start;
 
687
        time_t curr_end;
 
688
        time_t now = time(NULL);
 
689
        char *query = NULL;
 
690
 
 
691
        if(!localtime_r(&curr_start, &start_tm)) {
 
692
                error("Couldn't get localtime from month start %d", curr_start);
 
693
                return SLURM_ERROR;
 
694
        }
 
695
        start_tm.tm_sec = 0;
 
696
        start_tm.tm_min = 0;
 
697
        start_tm.tm_hour = 0;
 
698
        start_tm.tm_mday = 1;
 
699
        start_tm.tm_mon++;
 
700
        start_tm.tm_isdst = -1;
 
701
        curr_end = mktime(&start_tm);
 
702
 
 
703
        while(curr_start < end) {
 
704
                debug3("curr month is now %d-%d", curr_start, curr_end);
 
705
/*      info("start %s", ctime(&curr_start)); */
 
706
/*      info("end %s", ctime(&curr_end)); */
 
707
                query = xstrdup_printf(
 
708
                        "insert into %s (creation_time, mod_time, id, "
 
709
                        "period_start, alloc_cpu_secs) select %d, %d, id, "
 
710
                        "%d, @ASUM:=SUM(alloc_cpu_secs) from %s where "
 
711
                        "(period_start < %d && period_start >= %d) "
 
712
                        "group by id on duplicate key update mod_time=%d, "
 
713
                        "alloc_cpu_secs=@ASUM;",
 
714
                        assoc_month_table, now, now, curr_start,
 
715
                        assoc_day_table,
 
716
                        curr_end, curr_start, now);
 
717
                xstrfmtcat(query,
 
718
                           "insert into %s (creation_time, "
 
719
                           "mod_time, cluster, period_start, cpu_count, "
 
720
                           "alloc_cpu_secs, down_cpu_secs, idle_cpu_secs, "
 
721
                           "over_cpu_secs, resv_cpu_secs) "
 
722
                           "select %d, %d, cluster, "
 
723
                           "%d, @CPU:=MAX(cpu_count), "
 
724
                           "@ASUM:=SUM(alloc_cpu_secs), "
 
725
                           "@DSUM:=SUM(down_cpu_secs), "
 
726
                           "@ISUM:=SUM(idle_cpu_secs), "
 
727
                           "@OSUM:=SUM(over_cpu_secs), "
 
728
                           "@RSUM:=SUM(resv_cpu_secs) from %s where "
 
729
                           "(period_start < %d && period_start >= %d) "
 
730
                           "group by cluster on duplicate key update "
 
731
                           "mod_time=%d, cpu_count=@CPU, "
 
732
                           "alloc_cpu_secs=@ASUM, down_cpu_secs=@DSUM, "
 
733
                           "idle_cpu_secs=@ISUM, over_cpu_secs=@OSUM, "
 
734
                           "resv_cpu_secs=@RSUM;",
 
735
                           cluster_month_table, now, now, curr_start,
 
736
                           cluster_day_table,
 
737
                           curr_end, curr_start, now);
 
738
                debug3("%d query\n%s", mysql_conn->conn, query);
 
739
                rc = mysql_db_query(mysql_conn->acct_mysql_db, query);
 
740
                xfree(query);
 
741
                if(rc != SLURM_SUCCESS) {
 
742
                        error("Couldn't add day rollup");
 
743
                        return SLURM_ERROR;
 
744
                }
 
745
 
 
746
                curr_start = curr_end;
 
747
                if(!localtime_r(&curr_start, &start_tm)) {
 
748
                        error("Couldn't get localtime from month start %d",
 
749
                              curr_start);
 
750
                }
 
751
                start_tm.tm_sec = 0;
 
752
                start_tm.tm_min = 0;
 
753
                start_tm.tm_hour = 0;
 
754
                start_tm.tm_mday = 1;
 
755
                start_tm.tm_mon++;
 
756
                start_tm.tm_isdst = -1;
 
757
                curr_end = mktime(&start_tm);
 
758
        }
 
759
        return SLURM_SUCCESS;
 
760
}
 
761
 
 
762
#endif