89
static int _write_archive_file(MYSQL_RES *result, int start_col, int col_count,
90
time_t curr_end, char *arch_dir,
91
char *arch_type, char *insert,
94
time_t period_start = 0;
96
int rc = SLURM_SUCCESS;
99
char *old_file = NULL, *new_file = NULL, *reg_file = NULL;
108
slurm_mutex_lock(&local_file_lock);
109
while((row = mysql_fetch_row(result))) {
111
xstrcat(values, ",\n(");
113
period_start = atoi(row[start_col]);
114
localtime_r((time_t *)&period_start, &time_tm);
119
snprintf(start_char, sizeof(start_char),
121
"T%2.2u:%2.2u:%2.2u",
122
(time_tm.tm_year + 1900),
129
localtime_r((time_t *)&curr_end, &time_tm);
130
snprintf(end_char, sizeof(end_char),
132
"T%2.2u:%2.2u:%2.2u",
133
(time_tm.tm_year + 1900),
140
/* write the buffer to file */
141
reg_file = xstrdup_printf(
142
"%s/%s_archive_%s_%s.sql",
144
start_char, end_char);
145
debug("Storing event archive at %s", reg_file);
146
old_file = xstrdup_printf("%s.old", reg_file);
147
new_file = xstrdup_printf("%s.new", reg_file);
149
fd = creat(new_file, 0600);
151
error("Can't save archive, "
152
"create file %s error %m",
158
values = xstrdup_printf("%s\nvalues\n(", insert);
161
xstrfmtcat(values, "'%s'", row[0]);
162
for(i=1; i<col_count; i++) {
163
xstrfmtcat(values, ", '%s'", row[i]);
167
xstrcat(values, ", '1')");
169
xstrcat(values, ")");
172
|| ((rc = _write_to_file(fd, values)) != SLURM_SUCCESS)) {
180
rc = _write_to_file(fd,
181
" on duplicate key update "
184
rc = _write_to_file(fd,
185
" on duplicate key update "
186
"period_end=VALUES(period_end);");
187
// END_TIMER2("write file");
188
// info("write file took %s", TIME_STR);
194
(void) unlink(new_file);
195
else { /* file shuffle */
196
int ign; /* avoid warning */
197
(void) unlink(old_file);
198
ign = link(reg_file, old_file);
199
(void) unlink(reg_file);
200
ign = link(new_file, reg_file);
201
(void) unlink(new_file);
206
slurm_mutex_unlock(&local_file_lock);
70
211
static int _archive_script(acct_archive_cond_t *arch_cond, time_t last_submit)
72
213
char * args[] = {arch_cond->archive_script, NULL};
106
247
env = env_array_create();
108
if(arch_cond->step_purge) {
249
if(arch_cond->purge_event) {
109
250
/* use localtime to avoid any daylight savings issues */
110
251
if(!localtime_r(&last_submit, &time_tm)) {
111
error("Couldn't get localtime from first step start %d",
252
error("Couldn't get localtime from "
253
"first event start %d",
113
255
return SLURM_ERROR;
115
time_tm.tm_mon -= arch_cond->step_purge;
257
time_tm.tm_mon -= arch_cond->purge_step;
116
258
time_tm.tm_isdst = -1;
117
259
curr_end = mktime(&time_tm);
118
env_array_append_fmt(&env, "SLURM_ARCHIVE_STEPS", "%u",
119
arch_cond->archive_steps);
120
env_array_append_fmt(&env, "SLURM_ARCHIVE_LAST_STEP", "%d",
260
env_array_append_fmt(&env, "SLURM_ARCHIVE_EVENTS", "%u",
261
arch_cond->archive_events);
262
env_array_append_fmt(&env, "SLURM_ARCHIVE_LAST_EVENT", "%d",
124
if(arch_cond->job_purge) {
266
if(arch_cond->purge_job) {
125
267
/* use localtime to avoid any daylight savings issues */
126
268
if(!localtime_r(&last_submit, &time_tm)) {
127
269
error("Couldn't get localtime from first start %d",
129
271
return SLURM_ERROR;
131
time_tm.tm_mon -= arch_cond->job_purge;
273
time_tm.tm_mon -= arch_cond->purge_job;
132
274
time_tm.tm_isdst = -1;
133
275
curr_end = mktime(&time_tm);
283
if(arch_cond->purge_step) {
284
/* use localtime to avoid any daylight savings issues */
285
if(!localtime_r(&last_submit, &time_tm)) {
286
error("Couldn't get localtime from first step start %d",
290
time_tm.tm_mon -= arch_cond->purge_step;
291
time_tm.tm_isdst = -1;
292
curr_end = mktime(&time_tm);
293
env_array_append_fmt(&env, "SLURM_ARCHIVE_STEPS", "%u",
294
arch_cond->archive_steps);
295
env_array_append_fmt(&env, "SLURM_ARCHIVE_LAST_STEP", "%d",
299
if(arch_cond->purge_suspend) {
300
/* use localtime to avoid any daylight savings issues */
301
if(!localtime_r(&last_submit, &time_tm)) {
302
error("Couldn't get localtime from first "
307
time_tm.tm_mon -= arch_cond->purge_step;
308
time_tm.tm_isdst = -1;
309
curr_end = mktime(&time_tm);
310
env_array_append_fmt(&env, "SLURM_ARCHIVE_SUSPEND", "%u",
311
arch_cond->archive_steps);
312
env_array_append_fmt(&env, "SLURM_ARCHIVE_LAST_SUSPEND", "%d",
141
316
#ifdef _PATH_STDPATH
142
317
env_array_append (&env, "PATH", _PATH_STDPATH);
150
325
return SLURM_SUCCESS;
154
extern int setup_job_cond_limits(acct_job_cond_t *job_cond, char **extra)
328
extern List setup_cluster_list_with_inx(mysql_conn_t *mysql_conn,
329
acct_job_cond_t *job_cond,
332
List local_cluster_list = NULL;
333
time_t now = time(NULL);
334
MYSQL_RES *result = NULL;
336
hostlist_t temp_hl = NULL;
337
hostlist_iterator_t h_itr = NULL;
341
if(!job_cond || !job_cond->used_nodes)
344
if(!job_cond->cluster_list || list_count(job_cond->cluster_list) != 1) {
345
error("If you are doing a query against nodes "
346
"you must only have 1 cluster "
347
"you are asking for.");
351
temp_hl = hostlist_create(job_cond->used_nodes);
352
if(!hostlist_count(temp_hl)) {
353
error("we didn't get any real hosts to look for.");
356
h_itr = hostlist_iterator_create(temp_hl);
358
query = xstrdup_printf("select cluster_nodes, period_start, "
359
"period_end from %s where node_name='' "
360
"&& cluster_nodes !=''",
363
if((object = list_peek(job_cond->cluster_list)))
364
xstrfmtcat(query, " && cluster='%s'", object);
366
if(job_cond->usage_start) {
367
if(!job_cond->usage_end)
368
job_cond->usage_end = now;
371
" && ((period_start < %d) "
372
"&& (period_end >= %d || period_end = 0))",
373
job_cond->usage_end, job_cond->usage_start);
376
debug3("%d(%d) query\n%s", mysql_conn->conn, __LINE__, query);
377
if(!(result = mysql_db_query_ret(mysql_conn->db_conn, query, 0))) {
379
hostlist_destroy(temp_hl);
384
local_cluster_list = list_create(_destroy_local_cluster);
385
while((row = mysql_fetch_row(result))) {
388
local_cluster_t *local_cluster =
389
xmalloc(sizeof(local_cluster_t));
390
local_cluster->hl = hostlist_create(row[0]);
391
local_cluster->start = atoi(row[1]);
392
local_cluster->end = atoi(row[2]);
393
local_cluster->asked_bitmap =
394
bit_alloc(hostlist_count(local_cluster->hl));
395
while((host = hostlist_next(h_itr))) {
396
if((loc = hostlist_find(
397
local_cluster->hl, host)) != -1)
398
bit_set(local_cluster->asked_bitmap, loc);
401
hostlist_iterator_reset(h_itr);
402
if(bit_ffs(local_cluster->asked_bitmap) != -1) {
403
list_append(local_cluster_list, local_cluster);
404
if(local_cluster->end == 0) {
405
local_cluster->end = now;
406
(*curr_cluster) = local_cluster;
409
_destroy_local_cluster(local_cluster);
411
mysql_free_result(result);
412
hostlist_iterator_destroy(h_itr);
413
if(!list_count(local_cluster_list)) {
414
hostlist_destroy(temp_hl);
415
list_destroy(local_cluster_list);
420
hostlist_destroy(temp_hl);
422
return local_cluster_list;
425
extern int good_nodes_from_inx(List local_cluster_list,
426
void **object, char *node_inx,
429
local_cluster_t **curr_cluster = (local_cluster_t **)object;
431
/* check the bitmap to see if this is one of the jobs
432
we are looking for */
434
bitstr_t *job_bitmap = NULL;
435
if(!node_inx || !node_inx[0])
437
if((submit < (*curr_cluster)->start)
438
|| (submit > (*curr_cluster)->end)) {
439
local_cluster_t *local_cluster = NULL;
442
list_iterator_create(local_cluster_list);
443
while((local_cluster = list_next(itr))) {
444
if((submit >= local_cluster->start)
445
&& (submit <= local_cluster->end)) {
446
*curr_cluster = local_cluster;
450
list_iterator_destroy(itr);
454
job_bitmap = bit_alloc(hostlist_count((*curr_cluster)->hl));
455
bit_unfmt(job_bitmap, node_inx);
456
if(!bit_overlap((*curr_cluster)->asked_bitmap, job_bitmap)) {
457
FREE_NULL_BITMAP(job_bitmap);
460
FREE_NULL_BITMAP(job_bitmap);
465
extern int setup_job_cond_limits(mysql_conn_t *mysql_conn,
466
acct_job_cond_t *job_cond, char **extra)
157
469
ListIterator itr = NULL;
158
470
char *object = NULL;
159
471
char *table_level = "t2";
160
472
jobacct_selected_step_t *selected_step = NULL;
161
time_t now = time(NULL);
254
565
xstrcat(*extra, ")");
568
/* this must be done before resvid_list since we set
569
resvid_list up here */
570
if(job_cond->resv_list && list_count(job_cond->resv_list)) {
571
char *query = xstrdup_printf(
572
"select distinct id from %s where (");
574
MYSQL_RES *result = NULL;
577
if(job_cond->cluster_list
578
&& list_count(job_cond->cluster_list)) {
580
itr = list_iterator_create(job_cond->cluster_list);
581
while((object = list_next(itr))) {
583
xstrcat(query, " || ");
584
xstrfmtcat(query, "cluster='%s'", object);
587
list_iterator_destroy(itr);
591
xstrcat(query, ") && (");
593
itr = list_iterator_create(job_cond->resv_list);
594
while((object = list_next(itr))) {
596
xstrcat(query, " || ");
597
xstrfmtcat(query, "name='%s'", object);
600
list_iterator_destroy(itr);
602
if(!(result = mysql_db_query_ret(
603
mysql_conn->db_conn, query, 0))) {
605
error("couldn't query the database");
609
if(!job_cond->resvid_list)
610
job_cond->resvid_list = list_create(slurm_destroy_char);
611
while((row = mysql_fetch_row(result))) {
612
list_append(job_cond->resvid_list, xstrdup(row[0]));
614
mysql_free_result(result);
618
if(job_cond->resvid_list && list_count(job_cond->resvid_list)) {
621
xstrcat(*extra, " && (");
623
xstrcat(*extra, " where (");
624
itr = list_iterator_create(job_cond->resvid_list);
625
while((object = list_next(itr))) {
627
xstrcat(*extra, " || ");
628
xstrfmtcat(*extra, "t1.resvid='%s'", object);
631
list_iterator_destroy(itr);
632
xstrcat(*extra, ")");
257
635
if(job_cond->step_list && list_count(job_cond->step_list)) {
531
929
>= ACCT_ADMIN_OPERATOR)
534
assoc_mgr_fill_in_user(mysql_conn, &user, 1);
932
assoc_mgr_fill_in_user(mysql_conn, &user, 1,
539
setup_job_cond_limits(job_cond, &extra);
939
/* Here we set up environment to check used nodes of jobs.
940
Since we store the bitmap of the entire cluster we can use
941
that to set up a hostlist and set up the bitmap to make
942
things work. This should go before the setup of conds
943
since we could update the start/end time.
945
if(job_cond && job_cond->used_nodes) {
946
local_cluster_list = setup_cluster_list_with_inx(
947
mysql_conn, job_cond, (void **)&curr_cluster);
948
if(!local_cluster_list) {
949
list_destroy(job_list);
954
setup_job_cond_limits(mysql_conn, job_cond, &extra);
542
957
xstrfmtcat(tmp, "%s", job_req_inx[0]);
1112
1630
return SLURM_ERROR;
1115
if(arch_cond->step_purge) {
1116
/* remove all data from step table that was older than
1117
* start * arch_cond->step_purge.
1633
if(arch_cond->purge_event) {
1634
/* remove all data from step table that was older than
1635
* period_start * arch_cond->purge_event.
1637
/* use localtime to avoid any daylight savings issues */
1638
if(!localtime_r(&last_submit, &time_tm)) {
1639
error("Couldn't get localtime from first submit %d",
1643
time_tm.tm_mday = 1;
1644
time_tm.tm_mon -= arch_cond->purge_event;
1645
time_tm.tm_isdst = -1;
1646
curr_end = mktime(&time_tm);
1648
debug4("from %d - %d months purging events from before %d",
1649
last_submit, arch_cond->purge_event, curr_end);
1651
if(arch_cond->archive_events) {
1652
char *insert = NULL;
1653
MYSQL_RES *result = NULL;
1656
xstrfmtcat(tmp, "%s", event_req_inx[0]);
1657
for(i=1; i<EVENT_REQ_COUNT; i++) {
1658
xstrfmtcat(tmp, ", %s", event_req_inx[i]);
1661
/* get all the events started before this time
1663
query = xstrdup_printf("select %s from %s where "
1664
"period_start <= %d "
1665
"&& period_end != 0 "
1666
"order by period_start asc",
1667
tmp, event_table, curr_end);
1669
insert = xstrdup_printf("insert into %s (%s) ",
1674
debug3("%d(%d) query\n%s", mysql_conn->conn,
1676
if(!(result = mysql_db_query_ret(
1677
mysql_conn->db_conn, query, 0))) {
1683
// END_TIMER2("step query");
1684
// info("event query took %s", TIME_STR);
1686
if(!mysql_num_rows(result)) {
1688
mysql_free_result(result);
1692
rc = _write_archive_file(
1693
result, EVENT_REQ_START, EVENT_REQ_COUNT,
1694
curr_end, arch_cond->archive_dir,
1695
"event", insert, false);
1698
mysql_free_result(result);
1700
if(rc != SLURM_SUCCESS)
1703
query = xstrdup_printf("delete from %s where "
1704
"period_start <= %d && period_end != 0",
1705
event_table, curr_end);
1706
debug3("%d(%d) query\n%s", mysql_conn->conn, __LINE__, query);
1707
rc = mysql_db_query(mysql_conn->db_conn, query);
1709
if(rc != SLURM_SUCCESS) {
1710
error("Couldn't remove old event data");
1717
if(arch_cond->purge_suspend) {
1718
/* remove all data from step table that was older than
1719
* period_start * arch_cond->purge_suspend.
1721
/* use localtime to avoid any daylight savings issues */
1722
if(!localtime_r(&last_submit, &time_tm)) {
1723
error("Couldn't get localtime from first submit %d",
1727
time_tm.tm_mday = 1;
1728
time_tm.tm_mon -= arch_cond->purge_suspend;
1729
time_tm.tm_isdst = -1;
1730
curr_end = mktime(&time_tm);
1732
debug4("from %d - %d months purging suspend from before %d",
1733
last_submit, arch_cond->purge_suspend, curr_end);
1735
if(arch_cond->archive_suspend) {
1736
char *insert = NULL;
1737
MYSQL_RES *result = NULL;
1740
xstrfmtcat(tmp, "%s", suspend_req_inx[0]);
1741
for(i=1; i<SUSPEND_REQ_COUNT; i++) {
1742
xstrfmtcat(tmp, ", %s", suspend_req_inx[i]);
1745
/* get all the suspend started before this time
1747
query = xstrdup_printf("select %s from %s where "
1748
"start <= %d && end != 0 "
1749
"order by start asc",
1750
tmp, suspend_table, curr_end);
1752
insert = xstrdup_printf("insert into %s (%s) ",
1753
suspend_table, tmp);
1757
debug3("%d(%d) query\n%s", mysql_conn->conn,
1759
if(!(result = mysql_db_query_ret(
1760
mysql_conn->db_conn, query, 0))) {
1766
// END_TIMER2("step query");
1767
// info("suspend query took %s", TIME_STR);
1769
if(!mysql_num_rows(result)) {
1771
mysql_free_result(result);
1775
rc = _write_archive_file(
1776
result, SUSPEND_REQ_START, SUSPEND_REQ_COUNT,
1777
curr_end, arch_cond->archive_dir,
1778
"suspend", insert, false);
1781
mysql_free_result(result);
1783
if(rc != SLURM_SUCCESS)
1786
query = xstrdup_printf("delete from %s where start <= %d "
1788
suspend_table, curr_end);
1789
debug3("%d(%d) query\n%s", mysql_conn->conn, __LINE__, query);
1790
rc = mysql_db_query(mysql_conn->db_conn, query);
1792
if(rc != SLURM_SUCCESS) {
1793
error("Couldn't remove old suspend data");
1800
if(arch_cond->purge_step) {
1801
/* remove all data from step table that was older than
1802
* start * arch_cond->purge_step.
1119
1804
/* use localtime to avoid any daylight savings issues */
1120
1805
if(!localtime_r(&last_submit, &time_tm)) {
1173
1855
mysql_free_result(result);
1174
1856
goto exit_steps;
1178
slurm_mutex_lock(&local_file_lock);
1179
while((row = mysql_fetch_row(result))) {
1181
xstrcat(values, ",\n(");
1184
atoi(row[STEP_REQ_START]);
1185
localtime_r((time_t *)&period_start,
1189
time_tm.tm_hour = 0;
1190
time_tm.tm_mday = 1;
1191
time_tm.tm_isdst = -1;
1192
period_start = mktime(&time_tm);
1193
localtime_r((time_t *)&period_start,
1195
snprintf(start_char, sizeof(start_char),
1197
"T%2.2u:%2.2u:%2.2u",
1198
(time_tm.tm_year + 1900),
1205
localtime_r((time_t *)&curr_end,
1207
snprintf(end_char, sizeof(end_char),
1209
"T%2.2u:%2.2u:%2.2u",
1210
(time_tm.tm_year + 1900),
1217
/* write the buffer to file */
1218
reg_file = xstrdup_printf(
1219
"%s/step_archive_%s_%s.sql",
1220
arch_cond->archive_dir,
1221
start_char, end_char);
1222
debug("Storing step archive at %s",
1224
old_file = xstrdup_printf(
1225
"%s.old", reg_file);
1226
new_file = xstrdup_printf(
1227
"%s.new", reg_file);
1229
fd = creat(new_file, 0600);
1231
error("Can't save archive, "
1232
"create file %s error %m",
1238
values = xstrdup_printf("%s\nvalues\n(",
1243
xstrfmtcat(values, "'%s'", row[0]);
1244
for(i=1; i<STEP_REQ_COUNT; i++) {
1245
xstrfmtcat(values, ", '%s'", row[i]);
1247
xstrcat(values, ", '1')");
1249
if(!fd || ((rc = _write_to_file(fd, values))
1250
!= SLURM_SUCCESS)) {
1859
rc = _write_archive_file(
1860
result, STEP_REQ_START, STEP_REQ_COUNT,
1861
curr_end, arch_cond->archive_dir,
1862
"step", insert, true);
1256
1865
mysql_free_result(result);
1257
rc = _write_to_file(
1258
fd, " on duplicate key update deleted=1;");
1259
// END_TIMER2("write file");
1260
// info("write file took %s", TIME_STR);
1266
(void) unlink(new_file);
1267
else { /* file shuffle */
1268
int ign; /* avoid warning */
1269
(void) unlink(old_file);
1270
ign = link(reg_file, old_file);
1271
(void) unlink(reg_file);
1272
ign = link(new_file, reg_file);
1273
(void) unlink(new_file);
1278
slurm_mutex_unlock(&local_file_lock);
1867
if(rc != SLURM_SUCCESS)
1283
if(rc != SLURM_SUCCESS)
1286
1871
query = xstrdup_printf("delete from %s where start <= %d "
1288
1873
step_table, curr_end);
1358
1940
goto exit_jobs;
1362
slurm_mutex_lock(&local_file_lock);
1363
while((row = mysql_fetch_row(result))) {
1365
xstrcat(values, ",\n(");
1368
atoi(row[JOB_REQ_SUBMIT]);
1369
localtime_r((time_t *)&period_start,
1373
time_tm.tm_hour = 0;
1374
time_tm.tm_mday = 1;
1375
time_tm.tm_isdst = -1;
1376
period_start = mktime(&time_tm);
1377
localtime_r((time_t *)&period_start,
1379
snprintf(start_char, sizeof(start_char),
1381
"T%2.2u:%2.2u:%2.2u",
1382
(time_tm.tm_year + 1900),
1389
localtime_r((time_t *)&curr_end,
1392
snprintf(end_char, sizeof(end_char),
1394
"T%2.2u:%2.2u:%2.2u",
1395
(time_tm.tm_year + 1900),
1402
/* write the buffer to file */
1403
reg_file = xstrdup_printf(
1404
"%s/job_archive_%s_%s.sql",
1405
arch_cond->archive_dir,
1406
start_char, end_char);
1407
debug("Storing job archive at %s",
1409
old_file = xstrdup_printf(
1410
"%s.old", reg_file);
1411
new_file = xstrdup_printf(
1412
"%s.new", reg_file);
1414
fd = creat(new_file, 0600);
1416
error("Can't save archive, "
1417
"create file %s error %m",
1423
values = xstrdup_printf("%s\nvalues\n(",
1428
xstrfmtcat(values, "'%s'", row[0]);
1429
for(i=1; i<JOB_REQ_COUNT; i++) {
1430
xstrfmtcat(values, ", '%s'", row[i]);
1432
xstrcat(values, ", '1')");
1434
if(!fd || ((rc = _write_to_file(fd, values))
1435
!= SLURM_SUCCESS)) {
1943
rc = _write_archive_file(
1944
result, JOB_REQ_SUBMIT, JOB_REQ_COUNT,
1945
curr_end, arch_cond->archive_dir,
1946
"job", insert, true);
1441
1949
mysql_free_result(result);
1443
rc = _write_to_file(
1444
fd, " on duplicate key update deleted=1;");
1445
// END_TIMER2("write file");
1446
// info("write file took %s", TIME_STR);
1453
(void) unlink(new_file);
1454
else { /* file shuffle */
1455
int ign; /* avoid warning */
1456
(void) unlink(old_file);
1457
ign = link(reg_file, old_file);
1458
(void) unlink(reg_file);
1459
ign = link(new_file, reg_file);
1460
(void) unlink(new_file);
1465
slurm_mutex_unlock(&local_file_lock);
1951
if(rc != SLURM_SUCCESS)
1469
1955
query = xstrdup_printf("delete from %s where submit <= %d "
1471
1957
job_table, curr_end);