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

« back to all changes in this revision

Viewing changes to src/plugins/sched/builtin/builtin.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
 *  builtin.h - header for simple builtin scheduler plugin.
 
3
 *              Periodically when pending jobs can start.
 
4
 *              This is a minimal implementation of the logic found in
 
5
 *              src/plugins/sched/backfill/backfill.c and disregards
 
6
 *              how jobs are scheduled sequencially.
 
7
 *****************************************************************************
 
8
 *  Copyright (C) 2003-2007 The Regents of the University of California.
 
9
 *  Copyright (C) 2008-2010 Lawrence Livermore National Security.
 
10
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
 
11
 *  Written by Morris Jette <jette1@llnl.gov>
 
12
 *  CODE-OCEC-09-009. All rights reserved.
 
13
 *
 
14
 *  This file is part of SLURM, a resource management program.
 
15
 *  For details, see <https://computing.llnl.gov/linux/slurm/>.
 
16
 *  Please also read the included file: DISCLAIMER.
 
17
 *
 
18
 *  SLURM is free software; you can redistribute it and/or modify it under
 
19
 *  the terms of the GNU General Public License as published by the Free
 
20
 *  Software Foundation; either version 2 of the License, or (at your option)
 
21
 *  any later version.
 
22
 *
 
23
 *  In addition, as a special exception, the copyright holders give permission
 
24
 *  to link the code of portions of this program with the OpenSSL library under
 
25
 *  certain conditions as described in each individual source file, and
 
26
 *  distribute linked combinations including the two. You must obey the GNU
 
27
 *  General Public License in all respects for all of the code used other than
 
28
 *  OpenSSL. If you modify file(s) with this exception, you may extend this
 
29
 *  exception to your version of the file(s), but you are not obligated to do
 
30
 *  so. If you do not wish to do so, delete this exception statement from your
 
31
 *  version.  If you delete this exception statement from all source files in
 
32
 *  the program, then also delete it here.
 
33
 *
 
34
 *  SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
 
35
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
36
 *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 
37
 *  details.
 
38
 *
 
39
 *  You should have received a copy of the GNU General Public License along
 
40
 *  with SLURM; if not, write to the Free Software Foundation, Inc.,
 
41
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
 
42
\*****************************************************************************/
 
43
 
 
44
#include <pthread.h>
 
45
#include <stdio.h>
 
46
#include <stdlib.h>
 
47
#include <string.h>
 
48
#include <time.h>
 
49
#include <unistd.h>
 
50
 
 
51
#include "slurm/slurm.h"
 
52
#include "slurm/slurm_errno.h"
 
53
 
 
54
#include "src/common/list.h"
 
55
#include "src/common/macros.h"
 
56
#include "src/common/node_select.h"
 
57
#include "src/common/parse_time.h"
 
58
#include "src/common/slurm_protocol_api.h"
 
59
#include "src/common/xmalloc.h"
 
60
#include "src/common/xstring.h"
 
61
 
 
62
#include "src/slurmctld/locks.h"
 
63
#include "src/slurmctld/preempt.h"
 
64
#include "src/slurmctld/reservation.h"
 
65
#include "src/slurmctld/slurmctld.h"
 
66
#include "src/plugins/sched/builtin/builtin.h"
 
67
 
 
68
#ifndef BACKFILL_INTERVAL
 
69
#  define BACKFILL_INTERVAL     30
 
70
#endif
 
71
 
 
72
/*********************** local variables *********************/
 
73
static bool stop_builtin = false;
 
74
static pthread_mutex_t term_lock = PTHREAD_MUTEX_INITIALIZER;
 
75
static pthread_cond_t  term_cond = PTHREAD_COND_INITIALIZER;
 
76
static bool config_flag = false;
 
77
static int backfill_interval = BACKFILL_INTERVAL;
 
78
static int max_backfill_job_cnt = 50;
 
79
static int sched_timeout = 0;
 
80
 
 
81
/*********************** local functions *********************/
 
82
static void _compute_start_times(void);
 
83
static void _load_config(void);
 
84
static void _my_sleep(int secs);
 
85
 
 
86
/* Terminate builtin_agent */
 
87
extern void stop_builtin_agent(void)
 
88
{
 
89
        pthread_mutex_lock(&term_lock);
 
90
        stop_builtin = true;
 
91
        pthread_cond_signal(&term_cond);
 
92
        pthread_mutex_unlock(&term_lock);
 
93
}
 
94
 
 
95
static void _my_sleep(int secs)
 
96
{
 
97
        struct timespec ts = {0, 0};
 
98
 
 
99
        ts.tv_sec = time(NULL) + secs;
 
100
        pthread_mutex_lock(&term_lock);
 
101
        if (!stop_builtin)
 
102
                pthread_cond_timedwait(&term_cond, &term_lock, &ts);
 
103
        pthread_mutex_unlock(&term_lock);
 
104
}
 
105
 
 
106
static void _load_config(void)
 
107
{
 
108
        char *sched_params, *tmp_ptr;
 
109
 
 
110
        sched_timeout = slurm_get_msg_timeout() / 2;
 
111
        sched_timeout = MAX(sched_timeout, 1);
 
112
        sched_timeout = MIN(sched_timeout, 10);
 
113
 
 
114
        sched_params = slurm_get_sched_params();
 
115
 
 
116
        if (sched_params && (tmp_ptr=strstr(sched_params, "interval=")))
 
117
                backfill_interval = atoi(tmp_ptr + 9);
 
118
        if (backfill_interval < 1) {
 
119
                fatal("Invalid backfill scheduler interval: %d",
 
120
                      backfill_interval);
 
121
        }
 
122
 
 
123
        if (sched_params && (tmp_ptr=strstr(sched_params, "max_job_bf=")))
 
124
                max_backfill_job_cnt = atoi(tmp_ptr + 11);
 
125
        if (max_backfill_job_cnt < 1) {
 
126
                fatal("Invalid backfill scheduler max_job_bf: %d",
 
127
                      max_backfill_job_cnt);
 
128
        }
 
129
        xfree(sched_params);
 
130
}
 
131
 
 
132
static void _compute_start_times(void)
 
133
{
 
134
        int j, rc = SLURM_SUCCESS, job_cnt = 0;
 
135
        List job_queue;
 
136
        job_queue_rec_t *job_queue_rec;
 
137
        List preemptee_candidates = NULL;
 
138
        struct job_record *job_ptr;
 
139
        struct part_record *part_ptr;
 
140
        bitstr_t *alloc_bitmap = NULL, *avail_bitmap = NULL;
 
141
        uint32_t max_nodes, min_nodes, req_nodes, time_limit;
 
142
        time_t now = time(NULL), sched_start, last_job_alloc;
 
143
 
 
144
        sched_start = now;
 
145
        last_job_alloc = now - 1;
 
146
        alloc_bitmap = bit_alloc(node_record_count);
 
147
        if (alloc_bitmap == NULL)
 
148
                fatal("bit_alloc: malloc failure");
 
149
        job_queue = build_job_queue(true);
 
150
        while ((job_queue_rec = (job_queue_rec_t *) 
 
151
                                list_pop_bottom(job_queue, sort_job_queue2))) {
 
152
                job_ptr  = job_queue_rec->job_ptr;
 
153
                part_ptr = job_queue_rec->part_ptr;
 
154
                xfree(job_queue_rec);
 
155
                if (part_ptr != job_ptr->part_ptr)
 
156
                        continue;       /* Only test one partition */
 
157
 
 
158
                if (job_cnt++ > max_backfill_job_cnt) {
 
159
                        debug("backfill: loop taking to long, breaking out");
 
160
                        break;
 
161
                }
 
162
 
 
163
                /* Determine minimum and maximum node counts */
 
164
                min_nodes = MAX(job_ptr->details->min_nodes,
 
165
                                part_ptr->min_nodes);
 
166
 
 
167
                if (job_ptr->details->max_nodes == 0)
 
168
                        max_nodes = part_ptr->max_nodes;
 
169
                else
 
170
                        max_nodes = MIN(job_ptr->details->max_nodes,
 
171
                                        part_ptr->max_nodes);
 
172
 
 
173
                max_nodes = MIN(max_nodes, 500000);     /* prevent overflows */
 
174
 
 
175
                if (job_ptr->details->max_nodes)
 
176
                        req_nodes = max_nodes;
 
177
                else
 
178
                        req_nodes = min_nodes;
 
179
 
 
180
                if (min_nodes > max_nodes) {
 
181
                        /* job's min_nodes exceeds partition's max_nodes */
 
182
                        continue;
 
183
                }
 
184
 
 
185
                j = job_test_resv(job_ptr, &now, true, &avail_bitmap);
 
186
                if (j != SLURM_SUCCESS)
 
187
                        continue;
 
188
 
 
189
                rc = select_g_job_test(job_ptr, avail_bitmap,
 
190
                                       min_nodes, max_nodes, req_nodes,
 
191
                                       SELECT_MODE_WILL_RUN,
 
192
                                       preemptee_candidates, NULL);
 
193
                last_job_update = now;
 
194
 
 
195
                if (job_ptr->time_limit == INFINITE)
 
196
                        time_limit = 365 * 24 * 60 * 60;
 
197
                else if (job_ptr->time_limit != NO_VAL)
 
198
                        time_limit = job_ptr->time_limit * 60;
 
199
                else if (job_ptr->part_ptr &&
 
200
                         (job_ptr->part_ptr->max_time != INFINITE))
 
201
                        time_limit = job_ptr->part_ptr->max_time * 60;
 
202
                else
 
203
                        time_limit = 365 * 24 * 60 * 60;
 
204
                if (bit_overlap(alloc_bitmap, avail_bitmap) &&
 
205
                    (job_ptr->start_time <= last_job_alloc)) {
 
206
                        job_ptr->start_time = last_job_alloc;
 
207
                }
 
208
                bit_or(alloc_bitmap, avail_bitmap);
 
209
                last_job_alloc = job_ptr->start_time + time_limit;
 
210
                FREE_NULL_BITMAP(avail_bitmap);
 
211
 
 
212
                if ((time(NULL) - sched_start) >= sched_timeout) {
 
213
                        debug("backfill: loop taking to long, breaking out");
 
214
                        break;
 
215
                }
 
216
        }
 
217
        list_destroy(job_queue);
 
218
        FREE_NULL_BITMAP(alloc_bitmap);
 
219
}
 
220
 
 
221
/* Note that slurm.conf has changed */
 
222
extern void builtin_reconfig(void)
 
223
{
 
224
        config_flag = true;
 
225
}
 
226
 
 
227
/* builtin_agent - detached thread periodically when pending jobs can start */
 
228
extern void *builtin_agent(void *args)
 
229
{
 
230
        time_t now;
 
231
        double wait_time;
 
232
        static time_t last_backfill_time = 0;
 
233
        /* Read config, nodes and partitions; Write jobs */
 
234
        slurmctld_lock_t all_locks = {
 
235
                READ_LOCK, WRITE_LOCK, READ_LOCK, READ_LOCK };
 
236
 
 
237
        _load_config();
 
238
        last_backfill_time = time(NULL);
 
239
        while (!stop_builtin) {
 
240
                _my_sleep(backfill_interval);
 
241
                if (stop_builtin)
 
242
                        break;
 
243
                if (config_flag) {
 
244
                        config_flag = false;
 
245
                        _load_config();
 
246
                }
 
247
                now = time(NULL);
 
248
                wait_time = difftime(now, last_backfill_time);
 
249
                if ((wait_time < backfill_interval))
 
250
                        continue;
 
251
 
 
252
                lock_slurmctld(all_locks);
 
253
                _compute_start_times();
 
254
                last_backfill_time = time(NULL);
 
255
                unlock_slurmctld(all_locks);
 
256
        }
 
257
        return NULL;
 
258
}