~ubuntu-branches/ubuntu/precise/slurm-llnl/precise

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Gennaro Oliva
  • Date: 2011-04-08 11:21:17 UTC
  • mfrom: (3.3.16 sid)
  • Revision ID: james.westby@ubuntu.com-20110408112117-nfnyq9dtm55hqoaw
Tags: 2.2.4-1
* New upstream releases 
* Cleaning spare file and directories, not belonging to the sources
  generated by the building process and not removed by distclean.
  Added debian/clean with spare files and rm -rf inside debian/rules
  for directories.
* Added new packages libslurm-perl, libslurmdb-perl, slurm-llnl-torque
  (Closes: #575822) thanks to Julien Blache

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************\
 
2
 *  as_mysql_job.c - functions dealing with jobs and job steps.
 
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 <https://computing.llnl.gov/linux/slurm/>.
 
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
 
 
40
#include "as_mysql_job.h"
 
41
#include "as_mysql_usage.h"
 
42
#include "as_mysql_wckey.h"
 
43
 
 
44
#include "src/common/parse_time.h"
 
45
#include "src/common/jobacct_common.h"
 
46
 
 
47
/* Used in job functions for getting the database index based off the
 
48
 * submit time, job and assoc id.  0 is returned if none is found
 
49
 */
 
50
static int _get_db_index(mysql_conn_t *mysql_conn,
 
51
                         time_t submit, uint32_t jobid, uint32_t associd)
 
52
{
 
53
        MYSQL_RES *result = NULL;
 
54
        MYSQL_ROW row;
 
55
        int db_index = 0;
 
56
        char *query = xstrdup_printf("select job_db_inx from \"%s_%s\" where "
 
57
                                     "time_submit=%d and id_job=%u "
 
58
                                     "and id_assoc=%u",
 
59
                                     mysql_conn->cluster_name, job_table,
 
60
                                     (int)submit, jobid, associd);
 
61
 
 
62
        if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
 
63
                xfree(query);
 
64
                return 0;
 
65
        }
 
66
        xfree(query);
 
67
 
 
68
        row = mysql_fetch_row(result);
 
69
        if (!row) {
 
70
                mysql_free_result(result);
 
71
                debug4("We can't get a db_index for this combo, "
 
72
                       "time_submit=%d and id_job=%u and id_assoc=%u.  "
 
73
                       "We must not have heard about the start yet, "
 
74
                       "no big deal, we will get one right after this.",
 
75
                       (int)submit, jobid, associd);
 
76
                return 0;
 
77
        }
 
78
        db_index = slurm_atoul(row[0]);
 
79
        mysql_free_result(result);
 
80
 
 
81
        return db_index;
 
82
}
 
83
 
 
84
static char *_get_user_from_associd(mysql_conn_t *mysql_conn,
 
85
                                    char *cluster, uint32_t associd)
 
86
{
 
87
        char *user = NULL;
 
88
        char *query = NULL;
 
89
        MYSQL_RES *result = NULL;
 
90
        MYSQL_ROW row;
 
91
 
 
92
        /* Just so we don't have to keep a
 
93
           cache of the associations around we
 
94
           will just query the db for the user
 
95
           name of the association id.  Since
 
96
           this should sort of be a rare case
 
97
           this isn't too bad.
 
98
        */
 
99
        query = xstrdup_printf("select user from \"%s_%s\" where id_assoc=%u",
 
100
                               cluster, assoc_table, associd);
 
101
 
 
102
        debug4("%d(%s:%d) query\n%s",
 
103
               mysql_conn->conn, THIS_FILE, __LINE__, query);
 
104
        if (!(result =
 
105
              mysql_db_query_ret(mysql_conn, query, 0))) {
 
106
                xfree(query);
 
107
                return NULL;
 
108
        }
 
109
        xfree(query);
 
110
 
 
111
        if ((row = mysql_fetch_row(result)))
 
112
                user = xstrdup(row[0]);
 
113
 
 
114
        mysql_free_result(result);
 
115
 
 
116
        return user;
 
117
}
 
118
 
 
119
static uint32_t _get_wckeyid(mysql_conn_t *mysql_conn, char **name,
 
120
                             uid_t uid, char *cluster, uint32_t associd)
 
121
{
 
122
        uint32_t wckeyid = 0;
 
123
 
 
124
        if (slurm_get_track_wckey()) {
 
125
                /* Here we are looking for the wckeyid if it doesn't
 
126
                 * exist we will create one.  We don't need to check
 
127
                 * if it is good or not.  Right now this is the only
 
128
                 * place things are created. We do this only on a job
 
129
                 * start, not on a job submit since we don't want to
 
130
                 * slow down getting the db_index back to the
 
131
                 * controller.
 
132
                 */
 
133
                slurmdb_wckey_rec_t wckey_rec;
 
134
                char *user = NULL;
 
135
 
 
136
                /* since we are unable to rely on uids here (someone could
 
137
                   not have there uid in the system yet) we must
 
138
                   first get the user name from the associd */
 
139
                if (!(user = _get_user_from_associd(
 
140
                              mysql_conn, cluster, associd))) {
 
141
                        error("No user for associd %u", associd);
 
142
                        goto no_wckeyid;
 
143
                }
 
144
                /* get the default key */
 
145
                if (!*name) {
 
146
                        slurmdb_user_rec_t user_rec;
 
147
                        memset(&user_rec, 0, sizeof(slurmdb_user_rec_t));
 
148
                        user_rec.uid = NO_VAL;
 
149
                        user_rec.name = user;
 
150
                        if (assoc_mgr_fill_in_user(mysql_conn, &user_rec,
 
151
                                                   1, NULL) != SLURM_SUCCESS) {
 
152
                                error("No user by name of %s assoc %u",
 
153
                                      user, associd);
 
154
                                xfree(user);
 
155
                                goto no_wckeyid;
 
156
                        }
 
157
 
 
158
                        if (user_rec.default_wckey)
 
159
                                *name = xstrdup_printf("*%s",
 
160
                                                       user_rec.default_wckey);
 
161
                        else
 
162
                                *name = xstrdup_printf("*");
 
163
                }
 
164
 
 
165
                memset(&wckey_rec, 0, sizeof(slurmdb_wckey_rec_t));
 
166
                wckey_rec.name = (*name);
 
167
                wckey_rec.uid = NO_VAL;
 
168
                wckey_rec.user = user;
 
169
                wckey_rec.cluster = cluster;
 
170
                if (assoc_mgr_fill_in_wckey(mysql_conn, &wckey_rec,
 
171
                                            ACCOUNTING_ENFORCE_WCKEYS,
 
172
                                            NULL) != SLURM_SUCCESS) {
 
173
                        List wckey_list = NULL;
 
174
                        slurmdb_wckey_rec_t *wckey_ptr = NULL;
 
175
 
 
176
                        wckey_list = list_create(slurmdb_destroy_wckey_rec);
 
177
 
 
178
                        wckey_ptr = xmalloc(sizeof(slurmdb_wckey_rec_t));
 
179
                        wckey_ptr->name = xstrdup((*name));
 
180
                        wckey_ptr->user = xstrdup(user);
 
181
                        wckey_ptr->cluster = xstrdup(cluster);
 
182
                        list_append(wckey_list, wckey_ptr);
 
183
                        /* info("adding wckey '%s' '%s' '%s'", */
 
184
                        /*           wckey_ptr->name, wckey_ptr->user, */
 
185
                        /*           wckey_ptr->cluster); */
 
186
                        /* we have already checked to make
 
187
                           sure this was the slurm user before
 
188
                           calling this */
 
189
                        if (as_mysql_add_wckeys(mysql_conn,
 
190
                                                slurm_get_slurm_user_id(),
 
191
                                                wckey_list)
 
192
                            == SLURM_SUCCESS)
 
193
                                acct_storage_p_commit(mysql_conn, 1);
 
194
                        /* If that worked lets get it */
 
195
                        assoc_mgr_fill_in_wckey(mysql_conn, &wckey_rec,
 
196
                                                ACCOUNTING_ENFORCE_WCKEYS,
 
197
                                                NULL);
 
198
 
 
199
                        list_destroy(wckey_list);
 
200
                }
 
201
                xfree(user);
 
202
                /* info("got wckeyid of %d", wckey_rec.id); */
 
203
                wckeyid = wckey_rec.id;
 
204
        }
 
205
no_wckeyid:
 
206
        return wckeyid;
 
207
}
 
208
 
 
209
/* extern functions */
 
210
 
 
211
extern int as_mysql_job_start(mysql_conn_t *mysql_conn,
 
212
                              struct job_record *job_ptr)
 
213
{
 
214
        int rc=SLURM_SUCCESS;
 
215
        char *nodes = NULL, *jname = NULL, *node_inx = NULL;
 
216
        int track_steps = 0;
 
217
        char *block_id = NULL;
 
218
        char *query = NULL;
 
219
        int reinit = 0;
 
220
        time_t begin_time, check_time, start_time, submit_time;
 
221
        uint32_t wckeyid = 0;
 
222
        int job_state, node_cnt = 0;
 
223
        uint32_t job_db_inx = job_ptr->db_index;
 
224
 
 
225
        if ((!job_ptr->details || !job_ptr->details->submit_time)
 
226
            && !job_ptr->resize_time) {
 
227
                error("as_mysql_job_start: "
 
228
                      "Not inputing this job, it has no submit time.");
 
229
                return SLURM_ERROR;
 
230
        }
 
231
 
 
232
        if (check_connection(mysql_conn) != SLURM_SUCCESS)
 
233
                return ESLURM_DB_CONNECTION;
 
234
 
 
235
        debug2("as_mysql_slurmdb_job_start() called");
 
236
 
 
237
        job_state = job_ptr->job_state;
 
238
 
 
239
        /* Since we need a new db_inx make sure the old db_inx
 
240
         * removed. This is most likely the only time we are going to
 
241
         * be notified of the change also so make the state without
 
242
         * the resize. */
 
243
        if (IS_JOB_RESIZING(job_ptr)) {
 
244
                /* If we have a db_index lets end the previous record. */
 
245
                if (job_ptr->db_index)
 
246
                        as_mysql_job_complete(mysql_conn, job_ptr);
 
247
                else
 
248
                        error("We don't have a db_index for job %u, "
 
249
                              "this should never happen.", job_ptr->job_id);
 
250
                job_state &= (~JOB_RESIZING);
 
251
                job_ptr->db_index = 0;
 
252
        }
 
253
 
 
254
        job_state &= JOB_STATE_BASE;
 
255
 
 
256
        if (job_ptr->resize_time) {
 
257
                begin_time  = job_ptr->resize_time;
 
258
                submit_time = job_ptr->resize_time;
 
259
                start_time  = job_ptr->resize_time;
 
260
        } else {
 
261
                begin_time  = job_ptr->details->begin_time;
 
262
                submit_time = job_ptr->details->submit_time;
 
263
                start_time  = job_ptr->start_time;
 
264
        }
 
265
 
 
266
        /* See what we are hearing about here if no start time. If
 
267
         * this job latest time is before the last roll up we will
 
268
         * need to reset it to look at this job. */
 
269
        if (start_time)
 
270
                check_time = start_time;
 
271
        else if (begin_time)
 
272
                check_time = begin_time;
 
273
        else
 
274
                check_time = submit_time;
 
275
 
 
276
        slurm_mutex_lock(&rollup_lock);
 
277
        if (check_time < global_last_rollup) {
 
278
                MYSQL_RES *result = NULL;
 
279
                MYSQL_ROW row;
 
280
 
 
281
                /* check to see if we are hearing about this time for the
 
282
                 * first time.
 
283
                 */
 
284
                query = xstrdup_printf("select job_db_inx "
 
285
                                       "from \"%s_%s\" where id_job=%u and "
 
286
                                       "time_submit=%ld and time_eligible=%ld "
 
287
                                       "and time_start=%ld;",
 
288
                                       mysql_conn->cluster_name,
 
289
                                       job_table, job_ptr->job_id,
 
290
                                       submit_time, begin_time, start_time);
 
291
                debug3("%d(%s:%d) query\n%s",
 
292
                       mysql_conn->conn, THIS_FILE, __LINE__, query);
 
293
                if (!(result =
 
294
                      mysql_db_query_ret(mysql_conn, query, 0))) {
 
295
                        xfree(query);
 
296
                        slurm_mutex_unlock(&rollup_lock);
 
297
                        return SLURM_ERROR;
 
298
                }
 
299
                xfree(query);
 
300
                if ((row = mysql_fetch_row(result))) {
 
301
                        mysql_free_result(result);
 
302
                        debug4("revieved an update for a "
 
303
                               "job (%u) already known about",
 
304
                               job_ptr->job_id);
 
305
                        slurm_mutex_unlock(&rollup_lock);
 
306
                        goto no_rollup_change;
 
307
                }
 
308
                mysql_free_result(result);
 
309
 
 
310
                if (job_ptr->start_time)
 
311
                        debug("Need to reroll usage from %sJob %u "
 
312
                              "from %s started then and we are just "
 
313
                              "now hearing about it.",
 
314
                              ctime(&check_time),
 
315
                              job_ptr->job_id, mysql_conn->cluster_name);
 
316
                else if (begin_time)
 
317
                        debug("Need to reroll usage from %sJob %u "
 
318
                              "from %s became eligible then and we are just "
 
319
                              "now hearing about it.",
 
320
                              ctime(&check_time),
 
321
                              job_ptr->job_id, mysql_conn->cluster_name);
 
322
                else
 
323
                        debug("Need to reroll usage from %sJob %u "
 
324
                              "from %s was submitted then and we are just "
 
325
                              "now hearing about it.",
 
326
                              ctime(&check_time),
 
327
                              job_ptr->job_id, mysql_conn->cluster_name);
 
328
 
 
329
                global_last_rollup = check_time;
 
330
                slurm_mutex_unlock(&rollup_lock);
 
331
 
 
332
                /* If the times here are later than the daily_rollup
 
333
                   or monthly rollup it isn't a big deal since they
 
334
                   are always shrunk down to the beginning of each
 
335
                   time period.
 
336
                */
 
337
                query = xstrdup_printf("update \"%s_%s\" set "
 
338
                                       "hourly_rollup=%ld, "
 
339
                                       "daily_rollup=%ld, monthly_rollup=%ld",
 
340
                                       mysql_conn->cluster_name,
 
341
                                       last_ran_table, check_time,
 
342
                                       check_time, check_time);
 
343
                debug3("%d(%s:%d) query\n%s",
 
344
                       mysql_conn->conn, THIS_FILE, __LINE__, query);
 
345
                rc = mysql_db_query(mysql_conn, query);
 
346
                xfree(query);
 
347
        } else
 
348
                slurm_mutex_unlock(&rollup_lock);
 
349
 
 
350
no_rollup_change:
 
351
 
 
352
        if (job_ptr->name && job_ptr->name[0])
 
353
                jname = slurm_add_slash_to_quotes(job_ptr->name);
 
354
        else {
 
355
                jname = xstrdup("allocation");
 
356
                track_steps = 1;
 
357
        }
 
358
 
 
359
        if (job_ptr->nodes && job_ptr->nodes[0])
 
360
                nodes = job_ptr->nodes;
 
361
        else
 
362
                nodes = "None assigned";
 
363
 
 
364
        if (job_ptr->batch_flag)
 
365
                track_steps = 1;
 
366
 
 
367
        if (slurmdbd_conf) {
 
368
                block_id = xstrdup(job_ptr->comment);
 
369
                node_cnt = job_ptr->total_nodes;
 
370
                node_inx = job_ptr->network;
 
371
        } else {
 
372
                char temp_bit[BUF_SIZE];
 
373
 
 
374
                if (job_ptr->node_bitmap) {
 
375
                        node_inx = bit_fmt(temp_bit, sizeof(temp_bit),
 
376
                                           job_ptr->node_bitmap);
 
377
                }
 
378
#ifdef HAVE_BG
 
379
                select_g_select_jobinfo_get(job_ptr->select_jobinfo,
 
380
                                            SELECT_JOBDATA_BLOCK_ID,
 
381
                                            &block_id);
 
382
                select_g_select_jobinfo_get(job_ptr->select_jobinfo,
 
383
                                            SELECT_JOBDATA_NODE_CNT,
 
384
                                            &node_cnt);
 
385
#else
 
386
                node_cnt = job_ptr->total_nodes;
 
387
#endif
 
388
        }
 
389
 
 
390
        /* If there is a start_time get the wckeyid.  If the job is
 
391
         * cancelled before the job starts we also want to grab it. */
 
392
        if (job_ptr->assoc_id
 
393
            && (job_ptr->start_time || IS_JOB_CANCELLED(job_ptr)))
 
394
                wckeyid = _get_wckeyid(mysql_conn, &job_ptr->wckey,
 
395
                                       job_ptr->user_id,
 
396
                                       mysql_conn->cluster_name,
 
397
                                       job_ptr->assoc_id);
 
398
 
 
399
        if (!job_ptr->db_index) {
 
400
                if (!begin_time)
 
401
                        begin_time = submit_time;
 
402
                query = xstrdup_printf(
 
403
                        "insert into \"%s_%s\" "
 
404
                        "(id_job, id_assoc, id_qos, id_wckey, id_user, "
 
405
                        "id_group, nodelist, id_resv, timelimit, "
 
406
                        "time_eligible, time_submit, time_start, "
 
407
                        "job_name, track_steps, state, priority, cpus_req, "
 
408
                        "cpus_alloc, nodes_alloc",
 
409
                        mysql_conn->cluster_name, job_table);
 
410
 
 
411
                if (job_ptr->account)
 
412
                        xstrcat(query, ", account");
 
413
                if (job_ptr->partition)
 
414
                        xstrcat(query, ", partition");
 
415
                if (block_id)
 
416
                        xstrcat(query, ", id_block");
 
417
                if (job_ptr->wckey)
 
418
                        xstrcat(query, ", wckey");
 
419
                if (node_inx)
 
420
                        xstrcat(query, ", node_inx");
 
421
 
 
422
                xstrfmtcat(query,
 
423
                           ") values (%u, %u, %u, %u, %u, %u, '%s', %u, %u, "
 
424
                           "%ld, %ld, %ld, '%s', %u, %u, %u, %u, %u, %u",
 
425
                           job_ptr->job_id, job_ptr->assoc_id,
 
426
                           job_ptr->qos_id, wckeyid,
 
427
                           job_ptr->user_id, job_ptr->group_id, nodes,
 
428
                           job_ptr->resv_id, job_ptr->time_limit,
 
429
                           begin_time, submit_time, start_time,
 
430
                           jname, track_steps, job_state,
 
431
                           job_ptr->priority, job_ptr->details->min_cpus,
 
432
                           job_ptr->total_cpus, node_cnt);
 
433
 
 
434
                if (job_ptr->account)
 
435
                        xstrfmtcat(query, ", '%s'", job_ptr->account);
 
436
                if (job_ptr->partition)
 
437
                        xstrfmtcat(query, ", '%s'", job_ptr->partition);
 
438
                if (block_id)
 
439
                        xstrfmtcat(query, ", '%s'", block_id);
 
440
                if (job_ptr->wckey)
 
441
                        xstrfmtcat(query, ", '%s'", job_ptr->wckey);
 
442
                if (node_inx)
 
443
                        xstrfmtcat(query, ", '%s'", node_inx);
 
444
 
 
445
                xstrfmtcat(query,
 
446
                           ") on duplicate key update "
 
447
                           "job_db_inx=LAST_INSERT_ID(job_db_inx), "
 
448
                           "id_wckey=%u, id_user=%u, id_group=%u, "
 
449
                           "nodelist='%s', id_resv=%u, timelimit=%u, "
 
450
                           "time_submit=%ld, time_start=%ld, "
 
451
                           "job_name='%s', track_steps=%u, id_qos=%u, "
 
452
                           "state=greatest(state, %u), priority=%u, "
 
453
                           "cpus_req=%u, cpus_alloc=%u, nodes_alloc=%u",
 
454
                           wckeyid, job_ptr->user_id, job_ptr->group_id, nodes,
 
455
                           job_ptr->resv_id, job_ptr->time_limit,
 
456
                           submit_time, start_time,
 
457
                           jname, track_steps, job_ptr->qos_id, job_state,
 
458
                           job_ptr->priority, job_ptr->details->min_cpus,
 
459
                           job_ptr->total_cpus, node_cnt);
 
460
 
 
461
                if (job_ptr->account)
 
462
                        xstrfmtcat(query, ", account='%s'", job_ptr->account);
 
463
                if (job_ptr->partition)
 
464
                        xstrfmtcat(query, ", partition='%s'",
 
465
                                   job_ptr->partition);
 
466
                if (block_id)
 
467
                        xstrfmtcat(query, ", id_block='%s'", block_id);
 
468
                if (job_ptr->wckey)
 
469
                        xstrfmtcat(query, ", wckey='%s'", job_ptr->wckey);
 
470
                if (node_inx)
 
471
                        xstrfmtcat(query, ", node_inx='%s'", node_inx);
 
472
 
 
473
                debug3("%d(%s:%d) query\n%s",
 
474
                       mysql_conn->conn, THIS_FILE, __LINE__, query);
 
475
        try_again:
 
476
                if (!(job_ptr->db_index = mysql_db_insert_ret_id(
 
477
                              mysql_conn, query))) {
 
478
                        if (!reinit) {
 
479
                                error("It looks like the storage has gone "
 
480
                                      "away trying to reconnect");
 
481
                                mysql_db_close_db_connection(
 
482
                                        mysql_conn);
 
483
                                /* reconnect */
 
484
                                check_connection(mysql_conn);
 
485
                                reinit = 1;
 
486
                                goto try_again;
 
487
                        } else
 
488
                                rc = SLURM_ERROR;
 
489
                }
 
490
        } else {
 
491
                query = xstrdup_printf("update \"%s_%s\" set nodelist='%s', ",
 
492
                                       mysql_conn->cluster_name,
 
493
                                       job_table, nodes);
 
494
 
 
495
                if (job_ptr->account)
 
496
                        xstrfmtcat(query, "account='%s', ", job_ptr->account);
 
497
                if (job_ptr->partition)
 
498
                        xstrfmtcat(query, "partition='%s', ",
 
499
                                   job_ptr->partition);
 
500
                if (block_id)
 
501
                        xstrfmtcat(query, "id_block='%s', ", block_id);
 
502
                if (job_ptr->wckey)
 
503
                        xstrfmtcat(query, "wckey='%s', ", job_ptr->wckey);
 
504
                if (node_inx)
 
505
                        xstrfmtcat(query, "node_inx='%s', ", node_inx);
 
506
 
 
507
                xstrfmtcat(query, "time_start=%ld, job_name='%s', state=%u, "
 
508
                           "cpus_alloc=%u, nodes_alloc=%u, id_qos=%u, "
 
509
                           "id_assoc=%u, id_wckey=%u, id_resv=%u, timelimit=%u "
 
510
                           "where job_db_inx=%d",
 
511
                           start_time, jname, job_state,
 
512
                           job_ptr->total_cpus, node_cnt, job_ptr->qos_id,
 
513
                           job_ptr->assoc_id, wckeyid,
 
514
                           job_ptr->resv_id, job_ptr->time_limit,
 
515
                           job_ptr->db_index);
 
516
                debug3("%d(%s:%d) query\n%s",
 
517
                       mysql_conn->conn, THIS_FILE, __LINE__, query);
 
518
                rc = mysql_db_query(mysql_conn, query);
 
519
        }
 
520
 
 
521
        xfree(block_id);
 
522
        xfree(jname);
 
523
        xfree(query);
 
524
 
 
525
        /* now we will reset all the steps */
 
526
        if (IS_JOB_RESIZING(job_ptr)) {
 
527
                if (IS_JOB_SUSPENDED(job_ptr))
 
528
                        as_mysql_suspend(mysql_conn, job_db_inx, job_ptr);
 
529
                /* Here we aren't sure how many cpus are being changed here in
 
530
                   the step since we don't have that information from the
 
531
                   job.  The resize of steps shouldn't happen very often in
 
532
                   the first place (srun --no-kill option), and this don't
 
533
                   effect accounting in the first place so it isn't a
 
534
                   big deal. */
 
535
 
 
536
                query = xstrdup_printf("update \"%s_%s\" set job_db_inx=%u "
 
537
                                       "where job_db_inx=%u;",
 
538
                                       mysql_conn->cluster_name, step_table,
 
539
                                       job_ptr->db_index, job_db_inx);
 
540
 
 
541
                debug3("%d(%s:%d) query\n%s",
 
542
                       mysql_conn->conn, THIS_FILE, __LINE__, query);
 
543
                rc = mysql_db_query(mysql_conn, query);
 
544
                xfree(query);
 
545
        }
 
546
 
 
547
        return rc;
 
548
}
 
549
 
 
550
extern List as_mysql_modify_job(mysql_conn_t *mysql_conn, uint32_t uid,
 
551
                                slurmdb_job_modify_cond_t *job_cond,
 
552
                                slurmdb_job_rec_t *job)
 
553
{
 
554
        List ret_list = NULL;
 
555
        int rc = SLURM_SUCCESS;
 
556
        char *object = NULL;
 
557
        char *vals = NULL, *query = NULL, *cond_char = NULL;
 
558
        time_t now = time(NULL);
 
559
        char *user_name = NULL;
 
560
        MYSQL_RES *result = NULL;
 
561
        MYSQL_ROW row;
 
562
 
 
563
        if (!job_cond || !job) {
 
564
                error("we need something to change");
 
565
                return NULL;
 
566
        } else if (job_cond->job_id == NO_VAL) {
 
567
                errno = SLURM_NO_CHANGE_IN_DATA;
 
568
                error("Job ID was not specified for job modification\n");
 
569
                return NULL;
 
570
        } else if (!job_cond->cluster) {
 
571
                errno = SLURM_NO_CHANGE_IN_DATA;
 
572
                error("Cluster was not specified for job modification\n");
 
573
                return NULL;
 
574
        } else if (check_connection(mysql_conn) != SLURM_SUCCESS)
 
575
                return NULL;
 
576
 
 
577
        if (job->derived_ec != NO_VAL)
 
578
                xstrfmtcat(vals, ", derived_ec=%u", job->derived_ec);
 
579
 
 
580
        if (job->derived_es)
 
581
                xstrfmtcat(vals, ", derived_es='%s'", job->derived_es);
 
582
 
 
583
        if (!vals) {
 
584
                errno = SLURM_NO_CHANGE_IN_DATA;
 
585
                error("No change specified for job modification");
 
586
                return NULL;
 
587
        }
 
588
 
 
589
        /* Here we want to get the last job submitted here */
 
590
        query = xstrdup_printf("select job_db_inx, id_job, time_submit "
 
591
                               "from \"%s_%s\" where deleted=0 "
 
592
                               "&& id_job=%u && id_user=%u "
 
593
                               "order by time_submit desc limit 1;",
 
594
                               job_cond->cluster, job_table,
 
595
                               job_cond->job_id, uid);
 
596
 
 
597
        debug3("%d(%s:%d) query\n%s",
 
598
               mysql_conn->conn, THIS_FILE, __LINE__, query);
 
599
        if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
 
600
                xfree(vals);
 
601
                xfree(query);
 
602
                return NULL;
 
603
        }
 
604
 
 
605
        if ((row = mysql_fetch_row(result))) {
 
606
                char tmp_char[25];
 
607
                time_t time_submit = atol(row[2]);
 
608
                slurm_make_time_str(&time_submit, tmp_char, sizeof(tmp_char));
 
609
 
 
610
                xstrfmtcat(cond_char, "job_db_inx=%s", row[0]);
 
611
                object = xstrdup_printf("%s submitted at %s", row[1], tmp_char);
 
612
 
 
613
                ret_list = list_create(slurm_destroy_char);
 
614
                list_append(ret_list, object);
 
615
                mysql_free_result(result);
 
616
        } else {
 
617
                errno = SLURM_NO_CHANGE_IN_DATA;
 
618
                debug3("didn't effect anything\n%s", query);
 
619
                xfree(vals);
 
620
                xfree(query);
 
621
                mysql_free_result(result);
 
622
                return NULL;
 
623
        }
 
624
        xfree(query);
 
625
 
 
626
        user_name = uid_to_string((uid_t) uid);
 
627
        rc = modify_common(mysql_conn, DBD_MODIFY_JOB, now, user_name,
 
628
                           job_table, cond_char, vals, job_cond->cluster);
 
629
        xfree(user_name);
 
630
        xfree(cond_char);
 
631
        xfree(vals);
 
632
        if (rc == SLURM_ERROR) {
 
633
                error("Couldn't modify job");
 
634
                list_destroy(ret_list);
 
635
                ret_list = NULL;
 
636
        }
 
637
 
 
638
        return ret_list;
 
639
}
 
640
 
 
641
extern int as_mysql_job_complete(mysql_conn_t *mysql_conn,
 
642
                                 struct job_record *job_ptr)
 
643
{
 
644
        char *query = NULL, *nodes = NULL;
 
645
        int rc = SLURM_SUCCESS, job_state;
 
646
        time_t submit_time, end_time;
 
647
 
 
648
        if (!job_ptr->db_index
 
649
            && ((!job_ptr->details || !job_ptr->details->submit_time)
 
650
                && !job_ptr->resize_time)) {
 
651
                error("as_mysql_job_complete: "
 
652
                      "Not inputing this job, it has no submit time.");
 
653
                return SLURM_ERROR;
 
654
        }
 
655
 
 
656
        if (check_connection(mysql_conn) != SLURM_SUCCESS)
 
657
                return ESLURM_DB_CONNECTION;
 
658
        debug2("as_mysql_slurmdb_job_complete() called");
 
659
 
 
660
        if (job_ptr->resize_time)
 
661
                submit_time = job_ptr->resize_time;
 
662
        else
 
663
                submit_time = job_ptr->details->submit_time;
 
664
 
 
665
        if (IS_JOB_RESIZING(job_ptr)) {
 
666
                end_time = job_ptr->resize_time;
 
667
                job_state = JOB_RESIZING;
 
668
        } else {
 
669
                /* If we get an error with this just fall through to avoid an
 
670
                 * infinite loop */
 
671
                if (job_ptr->end_time == 0) {
 
672
                        debug("as_mysql_jobacct: job %u never started",
 
673
                              job_ptr->job_id);
 
674
                        return SLURM_SUCCESS;
 
675
                }
 
676
                end_time = job_ptr->end_time;
 
677
                job_state = job_ptr->job_state & JOB_STATE_BASE;
 
678
        }
 
679
 
 
680
        slurm_mutex_lock(&rollup_lock);
 
681
        if (end_time < global_last_rollup) {
 
682
                global_last_rollup = job_ptr->end_time;
 
683
                slurm_mutex_unlock(&rollup_lock);
 
684
 
 
685
                query = xstrdup_printf("update \"%s_%s\" set "
 
686
                                       "hourly_rollup=%ld, "
 
687
                                       "daily_rollup=%ld, monthly_rollup=%ld",
 
688
                                       mysql_conn->cluster_name,
 
689
                                       last_ran_table, end_time,
 
690
                                       end_time, end_time);
 
691
                debug3("%d(%s:%d) query\n%s",
 
692
                       mysql_conn->conn, THIS_FILE, __LINE__, query);
 
693
                rc = mysql_db_query(mysql_conn, query);
 
694
                xfree(query);
 
695
        } else
 
696
                slurm_mutex_unlock(&rollup_lock);
 
697
 
 
698
        if (job_ptr->nodes && job_ptr->nodes[0])
 
699
                nodes = job_ptr->nodes;
 
700
        else
 
701
                nodes = "None assigned";
 
702
 
 
703
        if (!job_ptr->db_index) {
 
704
                if (!(job_ptr->db_index =
 
705
                      _get_db_index(mysql_conn,
 
706
                                    submit_time,
 
707
                                    job_ptr->job_id,
 
708
                                    job_ptr->assoc_id))) {
 
709
                        /* If we get an error with this just fall
 
710
                         * through to avoid an infinite loop
 
711
                         */
 
712
                        if (as_mysql_job_start(
 
713
                                    mysql_conn, job_ptr) == SLURM_ERROR) {
 
714
                                error("couldn't add job %u at job completion",
 
715
                                      job_ptr->job_id);
 
716
                                return SLURM_SUCCESS;
 
717
                        }
 
718
                }
 
719
        }
 
720
 
 
721
        query = xstrdup_printf("update \"%s_%s\" set "
 
722
                               "time_end=%ld, state=%d, nodelist='%s', "
 
723
                               "derived_ec=%d, exit_code=%d, "
 
724
                               "kill_requid=%d where job_db_inx=%d;",
 
725
                               mysql_conn->cluster_name, job_table,
 
726
                               end_time, job_state, nodes,
 
727
                               job_ptr->derived_ec, job_ptr->exit_code,
 
728
                               job_ptr->requid, job_ptr->db_index);
 
729
 
 
730
        debug3("%d(%s:%d) query\n%s",
 
731
               mysql_conn->conn, THIS_FILE, __LINE__, query);
 
732
        rc = mysql_db_query(mysql_conn, query);
 
733
        xfree(query);
 
734
 
 
735
        return rc;
 
736
}
 
737
 
 
738
extern int as_mysql_step_start(mysql_conn_t *mysql_conn,
 
739
                               struct step_record *step_ptr)
 
740
{
 
741
        int cpus = 0, tasks = 0, nodes = 0, task_dist = 0;
 
742
        int rc=SLURM_SUCCESS;
 
743
        char node_list[BUFFER_SIZE];
 
744
        char *node_inx = NULL, *step_name = NULL;
 
745
        time_t start_time, submit_time;
 
746
 
 
747
#ifdef HAVE_BG
 
748
        char *ionodes = NULL;
 
749
#endif
 
750
        char *query = NULL;
 
751
 
 
752
        if (!step_ptr->job_ptr->db_index
 
753
            && ((!step_ptr->job_ptr->details
 
754
                 || !step_ptr->job_ptr->details->submit_time)
 
755
                && !step_ptr->job_ptr->resize_time)) {
 
756
                error("as_mysql_step_start: "
 
757
                      "Not inputing this job, it has no submit time.");
 
758
                return SLURM_ERROR;
 
759
        }
 
760
 
 
761
        if (step_ptr->job_ptr->resize_time) {
 
762
                submit_time = start_time = step_ptr->job_ptr->resize_time;
 
763
                if (step_ptr->start_time > submit_time)
 
764
                        start_time = step_ptr->start_time;
 
765
        } else {
 
766
                start_time = step_ptr->start_time;
 
767
                submit_time = step_ptr->job_ptr->details->submit_time;
 
768
        }
 
769
 
 
770
        if (check_connection(mysql_conn) != SLURM_SUCCESS)
 
771
                return ESLURM_DB_CONNECTION;
 
772
        if (slurmdbd_conf) {
 
773
                tasks = step_ptr->job_ptr->details->num_tasks;
 
774
                cpus = step_ptr->cpu_count;
 
775
                snprintf(node_list, BUFFER_SIZE, "%s",
 
776
                         step_ptr->job_ptr->nodes);
 
777
                nodes = step_ptr->step_layout->node_cnt;
 
778
                task_dist = step_ptr->step_layout->task_dist;
 
779
                node_inx = step_ptr->network;
 
780
        } else if (step_ptr->step_id == SLURM_BATCH_SCRIPT) {
 
781
                char temp_bit[BUF_SIZE];
 
782
 
 
783
                if (step_ptr->step_node_bitmap) {
 
784
                        node_inx = bit_fmt(temp_bit, sizeof(temp_bit),
 
785
                                           step_ptr->step_node_bitmap);
 
786
                }
 
787
                /* We overload gres with the node name of where the
 
788
                   script was running.
 
789
                */
 
790
                snprintf(node_list, BUFFER_SIZE, "%s", step_ptr->gres);
 
791
                nodes = cpus = tasks = 1;
 
792
        } else {
 
793
                char temp_bit[BUF_SIZE];
 
794
 
 
795
                if (step_ptr->step_node_bitmap) {
 
796
                        node_inx = bit_fmt(temp_bit, sizeof(temp_bit),
 
797
                                           step_ptr->step_node_bitmap);
 
798
                }
 
799
#ifdef HAVE_BG
 
800
                tasks = cpus = step_ptr->job_ptr->details->min_cpus;
 
801
                select_g_select_jobinfo_get(step_ptr->job_ptr->select_jobinfo,
 
802
                                            SELECT_JOBDATA_IONODES,
 
803
                                            &ionodes);
 
804
                if (ionodes) {
 
805
                        snprintf(node_list, BUFFER_SIZE,
 
806
                                 "%s[%s]", step_ptr->job_ptr->nodes, ionodes);
 
807
                        xfree(ionodes);
 
808
                } else
 
809
                        snprintf(node_list, BUFFER_SIZE, "%s",
 
810
                                 step_ptr->job_ptr->nodes);
 
811
                select_g_select_jobinfo_get(step_ptr->job_ptr->select_jobinfo,
 
812
                                            SELECT_JOBDATA_NODE_CNT,
 
813
                                            &nodes);
 
814
#else
 
815
                if (!step_ptr->step_layout
 
816
                    || !step_ptr->step_layout->task_cnt) {
 
817
                        tasks = cpus = step_ptr->job_ptr->total_cpus;
 
818
                        snprintf(node_list, BUFFER_SIZE, "%s",
 
819
                                 step_ptr->job_ptr->nodes);
 
820
                        nodes = step_ptr->job_ptr->total_nodes;
 
821
                } else {
 
822
                        cpus = step_ptr->cpu_count;
 
823
                        tasks = step_ptr->step_layout->task_cnt;
 
824
                        nodes = step_ptr->step_layout->node_cnt;
 
825
                        task_dist = step_ptr->step_layout->task_dist;
 
826
                        snprintf(node_list, BUFFER_SIZE, "%s",
 
827
                                 step_ptr->step_layout->node_list);
 
828
                }
 
829
#endif
 
830
        }
 
831
 
 
832
        if (!step_ptr->job_ptr->db_index) {
 
833
                if (!(step_ptr->job_ptr->db_index =
 
834
                      _get_db_index(mysql_conn,
 
835
                                    submit_time,
 
836
                                    step_ptr->job_ptr->job_id,
 
837
                                    step_ptr->job_ptr->assoc_id))) {
 
838
                        /* If we get an error with this just fall
 
839
                         * through to avoid an infinite loop
 
840
                         */
 
841
                        if (as_mysql_job_start(mysql_conn, step_ptr->job_ptr)
 
842
                            == SLURM_ERROR) {
 
843
                                error("couldn't add job %u at step start",
 
844
                                      step_ptr->job_ptr->job_id);
 
845
                                return SLURM_SUCCESS;
 
846
                        }
 
847
                }
 
848
        }
 
849
 
 
850
        step_name = slurm_add_slash_to_quotes(step_ptr->name);
 
851
 
 
852
        /* we want to print a -1 for the requid so leave it a
 
853
           %d */
 
854
        /* The stepid could be -2 so use %d not %u */
 
855
        query = xstrdup_printf(
 
856
                "insert into \"%s_%s\" (job_db_inx, id_step, time_start, "
 
857
                "step_name, state, "
 
858
                "cpus_alloc, nodes_alloc, task_cnt, nodelist, "
 
859
                "node_inx, task_dist) "
 
860
                "values (%d, %d, %d, '%s', %d, %d, %d, %d, "
 
861
                "'%s', '%s', %d) "
 
862
                "on duplicate key update cpus_alloc=%d, nodes_alloc=%d, "
 
863
                "task_cnt=%d, time_end=0, state=%d, "
 
864
                "nodelist='%s', node_inx='%s', task_dist=%d",
 
865
                mysql_conn->cluster_name, step_table,
 
866
                step_ptr->job_ptr->db_index,
 
867
                step_ptr->step_id,
 
868
                (int)start_time, step_name,
 
869
                JOB_RUNNING, cpus, nodes, tasks, node_list, node_inx, task_dist,
 
870
                cpus, nodes, tasks, JOB_RUNNING,
 
871
                node_list, node_inx, task_dist);
 
872
        debug3("%d(%s:%d) query\n%s",
 
873
               mysql_conn->conn, THIS_FILE, __LINE__, query);
 
874
        rc = mysql_db_query(mysql_conn, query);
 
875
        xfree(query);
 
876
        xfree(step_name);
 
877
 
 
878
        return rc;
 
879
}
 
880
 
 
881
extern int as_mysql_step_complete(mysql_conn_t *mysql_conn,
 
882
                                  struct step_record *step_ptr)
 
883
{
 
884
        time_t now;
 
885
        int elapsed;
 
886
        int comp_status;
 
887
        int cpus = 0, tasks = 0;
 
888
        struct jobacctinfo *jobacct = (struct jobacctinfo *)step_ptr->jobacct;
 
889
        struct jobacctinfo dummy_jobacct;
 
890
        double ave_vsize = 0, ave_rss = 0, ave_pages = 0;
 
891
        double ave_cpu = 0, ave_cpu2 = 0;
 
892
        char *query = NULL;
 
893
        int rc =SLURM_SUCCESS;
 
894
        uint32_t exit_code = 0;
 
895
        time_t start_time, submit_time;
 
896
 
 
897
        if (!step_ptr->job_ptr->db_index
 
898
            && ((!step_ptr->job_ptr->details
 
899
                 || !step_ptr->job_ptr->details->submit_time)
 
900
                && !step_ptr->job_ptr->resize_time)) {
 
901
                error("as_mysql_step_complete: "
 
902
                      "Not inputing this job, it has no submit time.");
 
903
                return SLURM_ERROR;
 
904
        }
 
905
 
 
906
        if (step_ptr->job_ptr->resize_time) {
 
907
                submit_time = start_time = step_ptr->job_ptr->resize_time;
 
908
                if (step_ptr->start_time > submit_time)
 
909
                        start_time = step_ptr->start_time;
 
910
        } else {
 
911
                start_time = step_ptr->start_time;
 
912
                submit_time = step_ptr->job_ptr->details->submit_time;
 
913
        }
 
914
 
 
915
        if (jobacct == NULL) {
 
916
                /* JobAcctGather=slurmdb_gather/none, no data to process */
 
917
                memset(&dummy_jobacct, 0, sizeof(dummy_jobacct));
 
918
                jobacct = &dummy_jobacct;
 
919
        }
 
920
 
 
921
        if (check_connection(mysql_conn) != SLURM_SUCCESS)
 
922
                return ESLURM_DB_CONNECTION;
 
923
 
 
924
        if (slurmdbd_conf) {
 
925
                now = step_ptr->job_ptr->end_time;
 
926
                tasks = step_ptr->job_ptr->details->num_tasks;
 
927
                cpus = step_ptr->cpu_count;
 
928
        } else if (step_ptr->step_id == SLURM_BATCH_SCRIPT) {
 
929
                now = time(NULL);
 
930
                cpus = tasks = 1;
 
931
        } else {
 
932
                now = time(NULL);
 
933
#ifdef HAVE_BG
 
934
                tasks = cpus = step_ptr->job_ptr->details->min_cpus;
 
935
 
 
936
#else
 
937
                if (!step_ptr->step_layout || !step_ptr->step_layout->task_cnt)
 
938
                        tasks = cpus = step_ptr->job_ptr->total_cpus;
 
939
                else {
 
940
                        cpus = step_ptr->cpu_count;
 
941
                        tasks = step_ptr->step_layout->task_cnt;
 
942
                }
 
943
#endif
 
944
        }
 
945
 
 
946
        if ((elapsed = (now - start_time)) < 0)
 
947
                elapsed = 0;    /* For *very* short jobs, if clock is wrong */
 
948
 
 
949
        exit_code = step_ptr->exit_code;
 
950
        if (WIFSIGNALED(exit_code)) {
 
951
                comp_status = JOB_CANCELLED;
 
952
        } else if (exit_code)
 
953
                comp_status = JOB_FAILED;
 
954
        else {
 
955
                step_ptr->requid = -1;
 
956
                comp_status = JOB_COMPLETE;
 
957
        }
 
958
 
 
959
        /* figure out the ave of the totals sent */
 
960
        if (cpus > 0) {
 
961
                ave_vsize = (double)jobacct->tot_vsize;
 
962
                ave_vsize /= (double)cpus;
 
963
                ave_rss = (double)jobacct->tot_rss;
 
964
                ave_rss /= (double)cpus;
 
965
                ave_pages = (double)jobacct->tot_pages;
 
966
                ave_pages /= (double)cpus;
 
967
                ave_cpu = (double)jobacct->tot_cpu;
 
968
                ave_cpu /= (double)cpus;
 
969
        }
 
970
 
 
971
        if (jobacct->min_cpu != NO_VAL) {
 
972
                ave_cpu2 = (double)jobacct->min_cpu;
 
973
        }
 
974
 
 
975
        if (!step_ptr->job_ptr->db_index) {
 
976
                if (!(step_ptr->job_ptr->db_index =
 
977
                      _get_db_index(mysql_conn,
 
978
                                    submit_time,
 
979
                                    step_ptr->job_ptr->job_id,
 
980
                                    step_ptr->job_ptr->assoc_id))) {
 
981
                        /* If we get an error with this just fall
 
982
                         * through to avoid an infinite loop
 
983
                         */
 
984
                        if (as_mysql_job_start(mysql_conn, step_ptr->job_ptr)
 
985
                            == SLURM_ERROR) {
 
986
                                error("couldn't add job %u "
 
987
                                      "at step completion",
 
988
                                      step_ptr->job_ptr->job_id);
 
989
                                return SLURM_SUCCESS;
 
990
                        }
 
991
                }
 
992
        }
 
993
 
 
994
        /* The stepid could be -2 so use %d not %u */
 
995
        query = xstrdup_printf(
 
996
                "update \"%s_%s\" set time_end=%d, state=%d, "
 
997
                "kill_requid=%d, exit_code=%d, "
 
998
                "user_sec=%u, user_usec=%u, "
 
999
                "sys_sec=%u, sys_usec=%u, "
 
1000
                "max_vsize=%u, max_vsize_task=%u, "
 
1001
                "max_vsize_node=%u, ave_vsize=%f, "
 
1002
                "max_rss=%u, max_rss_task=%u, "
 
1003
                "max_rss_node=%u, ave_rss=%f, "
 
1004
                "max_pages=%u, max_pages_task=%u, "
 
1005
                "max_pages_node=%u, ave_pages=%f, "
 
1006
                "min_cpu=%f, min_cpu_task=%u, "
 
1007
                "min_cpu_node=%u, ave_cpu=%f "
 
1008
                "where job_db_inx=%d and id_step=%d",
 
1009
                mysql_conn->cluster_name, step_table, (int)now,
 
1010
                comp_status,
 
1011
                step_ptr->requid,
 
1012
                exit_code,
 
1013
                /* user seconds */
 
1014
                jobacct->user_cpu_sec,
 
1015
                /* user microseconds */
 
1016
                jobacct->user_cpu_usec,
 
1017
                /* system seconds */
 
1018
                jobacct->sys_cpu_sec,
 
1019
                /* system microsecs */
 
1020
                jobacct->sys_cpu_usec,
 
1021
                jobacct->max_vsize,     /* max vsize */
 
1022
                jobacct->max_vsize_id.taskid,   /* max vsize task */
 
1023
                jobacct->max_vsize_id.nodeid,   /* max vsize node */
 
1024
                ave_vsize,      /* ave vsize */
 
1025
                jobacct->max_rss,       /* max vsize */
 
1026
                jobacct->max_rss_id.taskid,     /* max rss task */
 
1027
                jobacct->max_rss_id.nodeid,     /* max rss node */
 
1028
                ave_rss,        /* ave rss */
 
1029
                jobacct->max_pages,     /* max pages */
 
1030
                jobacct->max_pages_id.taskid,   /* max pages task */
 
1031
                jobacct->max_pages_id.nodeid,   /* max pages node */
 
1032
                ave_pages,      /* ave pages */
 
1033
                ave_cpu2,       /* min cpu */
 
1034
                jobacct->min_cpu_id.taskid,     /* min cpu task */
 
1035
                jobacct->min_cpu_id.nodeid,     /* min cpu node */
 
1036
                ave_cpu,        /* ave cpu */
 
1037
                step_ptr->job_ptr->db_index, step_ptr->step_id);
 
1038
        debug3("%d(%s:%d) query\n%s",
 
1039
               mysql_conn->conn, THIS_FILE, __LINE__, query);
 
1040
        rc = mysql_db_query(mysql_conn, query);
 
1041
        xfree(query);
 
1042
 
 
1043
        return rc;
 
1044
}
 
1045
 
 
1046
extern int as_mysql_suspend(mysql_conn_t *mysql_conn,
 
1047
                            uint32_t old_db_inx,
 
1048
                            struct job_record *job_ptr)
 
1049
{
 
1050
        char *query = NULL;
 
1051
        int rc = SLURM_SUCCESS;
 
1052
        time_t submit_time;
 
1053
        uint32_t job_db_inx;
 
1054
 
 
1055
        if (check_connection(mysql_conn) != SLURM_SUCCESS)
 
1056
                return ESLURM_DB_CONNECTION;
 
1057
 
 
1058
        if (job_ptr->resize_time)
 
1059
                submit_time = job_ptr->resize_time;
 
1060
        else
 
1061
                submit_time = job_ptr->details->submit_time;
 
1062
 
 
1063
        if (!job_ptr->db_index) {
 
1064
                if (!(job_ptr->db_index =
 
1065
                      _get_db_index(mysql_conn,
 
1066
                                    submit_time,
 
1067
                                    job_ptr->job_id,
 
1068
                                    job_ptr->assoc_id))) {
 
1069
                        /* If we get an error with this just fall
 
1070
                         * through to avoid an infinite loop
 
1071
                         */
 
1072
                        if (as_mysql_job_start(
 
1073
                                    mysql_conn, job_ptr) == SLURM_ERROR) {
 
1074
                                error("couldn't suspend job %u",
 
1075
                                      job_ptr->job_id);
 
1076
                                return SLURM_SUCCESS;
 
1077
                        }
 
1078
                }
 
1079
        }
 
1080
 
 
1081
        if (IS_JOB_RESIZING(job_ptr)) {
 
1082
                if (!old_db_inx) {
 
1083
                        error("No old db inx given for job %u cluster %s, "
 
1084
                              "can't update suspend table.",
 
1085
                              job_ptr->job_id, mysql_conn->cluster_name);
 
1086
                        return SLURM_ERROR;
 
1087
                }
 
1088
                job_db_inx = old_db_inx;
 
1089
                xstrfmtcat(query,
 
1090
                           "update \"%s_%s\" set time_end=%d where "
 
1091
                           "job_db_inx=%u && time_end=0;",
 
1092
                           mysql_conn->cluster_name, suspend_table,
 
1093
                           (int)job_ptr->suspend_time, job_db_inx);
 
1094
 
 
1095
        } else
 
1096
                job_db_inx = job_ptr->db_index;
 
1097
 
 
1098
        /* use job_db_inx for this one since we want to update the
 
1099
           supend time of the job before it was resized.
 
1100
        */
 
1101
        xstrfmtcat(query,
 
1102
                   "update \"%s_%s\" set time_suspended=%d-time_suspended, "
 
1103
                   "state=%d where job_db_inx=%d;",
 
1104
                   mysql_conn->cluster_name, job_table,
 
1105
                   (int)job_ptr->suspend_time,
 
1106
                   job_ptr->job_state & JOB_STATE_BASE,
 
1107
                   job_db_inx);
 
1108
        if (IS_JOB_SUSPENDED(job_ptr))
 
1109
                xstrfmtcat(query,
 
1110
                           "insert into \"%s_%s\" (job_db_inx, id_assoc, "
 
1111
                           "time_start, time_end) values (%u, %u, %d, 0);",
 
1112
                           mysql_conn->cluster_name, suspend_table,
 
1113
                           job_ptr->db_index, job_ptr->assoc_id,
 
1114
                           (int)job_ptr->suspend_time);
 
1115
        else
 
1116
                xstrfmtcat(query,
 
1117
                           "update \"%s_%s\" set time_end=%d where "
 
1118
                           "job_db_inx=%u && time_end=0;",
 
1119
                           mysql_conn->cluster_name, suspend_table,
 
1120
                           (int)job_ptr->suspend_time, job_ptr->db_index);
 
1121
        debug3("%d(%s:%d) query\n%s",
 
1122
               mysql_conn->conn, THIS_FILE, __LINE__, query);
 
1123
 
 
1124
        rc = mysql_db_query(mysql_conn, query);
 
1125
 
 
1126
        xfree(query);
 
1127
        if (rc != SLURM_ERROR) {
 
1128
                xstrfmtcat(query,
 
1129
                           "update \"%s_%s\" set "
 
1130
                           "time_suspended=%u-time_suspended, "
 
1131
                           "state=%d where job_db_inx=%u and time_end=0",
 
1132
                           mysql_conn->cluster_name, step_table,
 
1133
                           (int)job_ptr->suspend_time,
 
1134
                           job_ptr->job_state, job_ptr->db_index);
 
1135
                rc = mysql_db_query(mysql_conn, query);
 
1136
                xfree(query);
 
1137
        }
 
1138
 
 
1139
        return rc;
 
1140
}
 
1141
 
 
1142
extern int as_mysql_flush_jobs_on_cluster(
 
1143
        mysql_conn_t *mysql_conn, time_t event_time)
 
1144
{
 
1145
        int rc = SLURM_SUCCESS;
 
1146
        /* put end times for a clean start */
 
1147
        MYSQL_RES *result = NULL;
 
1148
        MYSQL_ROW row;
 
1149
        char *query = NULL;
 
1150
        char *id_char = NULL;
 
1151
        char *suspended_char = NULL;
 
1152
 
 
1153
        if (check_connection(mysql_conn) != SLURM_SUCCESS)
 
1154
                return ESLURM_DB_CONNECTION;
 
1155
 
 
1156
        /* First we need to get the job_db_inx's and states so we can clean up
 
1157
         * the suspend table and the step table
 
1158
         */
 
1159
        query = xstrdup_printf(
 
1160
                "select distinct t1.job_db_inx, t1.state from \"%s_%s\" "
 
1161
                "as t1 where t1.time_end=0;",
 
1162
                mysql_conn->cluster_name, job_table);
 
1163
        debug3("%d(%s:%d) query\n%s",
 
1164
               mysql_conn->conn, THIS_FILE, __LINE__, query);
 
1165
        if (!(result =
 
1166
              mysql_db_query_ret(mysql_conn, query, 0))) {
 
1167
                xfree(query);
 
1168
                return SLURM_ERROR;
 
1169
        }
 
1170
        xfree(query);
 
1171
 
 
1172
        while ((row = mysql_fetch_row(result))) {
 
1173
                int state = slurm_atoul(row[1]);
 
1174
                if (state == JOB_SUSPENDED) {
 
1175
                        if (suspended_char)
 
1176
                                xstrfmtcat(suspended_char,
 
1177
                                           " || job_db_inx=%s", row[0]);
 
1178
                        else
 
1179
                                xstrfmtcat(suspended_char, "job_db_inx=%s",
 
1180
                                           row[0]);
 
1181
                }
 
1182
 
 
1183
                if (id_char)
 
1184
                        xstrfmtcat(id_char, " || job_db_inx=%s", row[0]);
 
1185
                else
 
1186
                        xstrfmtcat(id_char, "job_db_inx=%s", row[0]);
 
1187
        }
 
1188
        mysql_free_result(result);
 
1189
 
 
1190
        if (suspended_char) {
 
1191
                xstrfmtcat(query,
 
1192
                           "update \"%s_%s\" set "
 
1193
                           "time_suspended=%ld-time_suspended "
 
1194
                           "where %s;",
 
1195
                           mysql_conn->cluster_name, job_table,
 
1196
                           event_time, suspended_char);
 
1197
                xstrfmtcat(query,
 
1198
                           "update \"%s_%s\" set "
 
1199
                           "time_suspended=%ld-time_suspended "
 
1200
                           "where %s;",
 
1201
                           mysql_conn->cluster_name, step_table,
 
1202
                           event_time, suspended_char);
 
1203
                xstrfmtcat(query,
 
1204
                           "update \"%s_%s\" set time_end=%ld where (%s) "
 
1205
                           "&& time_end=0;",
 
1206
                           mysql_conn->cluster_name, suspend_table,
 
1207
                           event_time, suspended_char);
 
1208
                xfree(suspended_char);
 
1209
        }
 
1210
        if (id_char) {
 
1211
                xstrfmtcat(query,
 
1212
                           "update \"%s_%s\" set state=%d, "
 
1213
                           "time_end=%ld where %s;",
 
1214
                           mysql_conn->cluster_name, job_table,
 
1215
                           JOB_CANCELLED, event_time, id_char);
 
1216
                xstrfmtcat(query,
 
1217
                           "update \"%s_%s\" set state=%d, "
 
1218
                           "time_end=%ld where %s;",
 
1219
                           mysql_conn->cluster_name, step_table,
 
1220
                           JOB_CANCELLED, event_time, id_char);
 
1221
                xfree(id_char);
 
1222
        }
 
1223
 
 
1224
        if (query) {
 
1225
                debug3("%d(%s:%d) query\n%s",
 
1226
                       mysql_conn->conn, THIS_FILE, __LINE__, query);
 
1227
 
 
1228
                rc = mysql_db_query(mysql_conn, query);
 
1229
                xfree(query);
 
1230
        }
 
1231
 
 
1232
        return rc;
 
1233
}