1 /*****************************************************************************\
2 * as_mysql_convert.c - functions dealing with converting from tables in
3 * slurm <= 17.02.
4 *****************************************************************************
5 *
6 * Copyright (C) 2015 SchedMD LLC.
7 * Written by Danny Auble <da@schedmd.com>
8 *
9 * This file is part of Slurm, a resource management program.
10 * For details, see <https://slurm.schedmd.com/>.
11 * Please also read the included file: DISCLAIMER.
12 *
13 * Slurm is free software; you can redistribute it and/or modify it under
14 * the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
16 * any later version.
17 *
18 * In addition, as a special exception, the copyright holders give permission
19 * to link the code of portions of this program with the OpenSSL library under
20 * certain conditions as described in each individual source file, and
21 * distribute linked combinations including the two. You must obey the GNU
22 * General Public License in all respects for all of the code used other than
23 * OpenSSL. If you modify file(s) with this exception, you may extend this
24 * exception to your version of the file(s), but you are not obligated to do
25 * so. If you do not wish to do so, delete this exception statement from your
26 * version. If you delete this exception statement from all source files in
27 * the program, then also delete it here.
28 *
29 * Slurm is distributed in the hope that it will be useful, but WITHOUT ANY
30 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
31 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
32 * details.
33 *
34 * You should have received a copy of the GNU General Public License along
35 * with Slurm; if not, write to the Free Software Foundation, Inc.,
36 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
37 \*****************************************************************************/
38
39 #include "as_mysql_convert.h"
40 #include "as_mysql_tres.h"
41 #include "src/common/slurm_jobacct_gather.h"
42
43 /*
44 * Any time you have to add to an existing convert update this number.
45 * NOTE: 6 was the first version of 18.08.
46 * NOTE: 7 was the first version of 19.05.
47 * NOTE: 8 was the first version of 20.02.
48 */
49 #define CONVERT_VERSION 8
50
51 typedef struct {
52 uint64_t count;
53 uint32_t id;
54 } local_tres_t;
55
56 static uint32_t db_curr_ver = NO_VAL;
57
_set_tres_value(char * tres_str,uint64_t * tres_array)58 static void _set_tres_value(char *tres_str, uint64_t *tres_array)
59 {
60 char *tmp_str = tres_str;
61 int id;
62
63 xassert(tres_array);
64
65 if (!tres_str || !tres_str[0])
66 return;
67
68 while (tmp_str) {
69 id = atoi(tmp_str);
70 /* 0 isn't a valid tres id */
71 if (id <= 0) {
72 error("%s: no id found at %s",
73 __func__, tmp_str);
74 break;
75 }
76 if (!(tmp_str = strchr(tmp_str, '='))) {
77 error("%s: no value found %s", __func__, tres_str);
78 break;
79 }
80
81 /*
82 * The id's of static tres will be one more than the array
83 * position.
84 */
85 id--;
86
87 if (id >= g_tres_count)
88 debug2("%s: Unknown tres location %d", __func__, id);
89 else
90 tres_array[id] = slurm_atoull(++tmp_str);
91
92 if (!(tmp_str = strchr(tmp_str, ',')))
93 break;
94
95 tmp_str++;
96 }
97 }
98
_convert_job_table_pre(mysql_conn_t * mysql_conn,char * cluster_name)99 static int _convert_job_table_pre(mysql_conn_t *mysql_conn, char *cluster_name)
100 {
101 int rc = SLURM_SUCCESS;
102 char *query = NULL;
103
104 if (db_curr_ver < 8) {
105 /*
106 * Change the names pack_job_id and pack_job_offset to be het_*
107 */
108 query = xstrdup_printf(
109 "alter table \"%s_%s\" "
110 "change pack_job_id het_job_id int unsigned not null, "
111 "change pack_job_offset het_job_offset "
112 "int unsigned not null;",
113 cluster_name, job_table);
114 }
115
116 if (query) {
117 if (debug_flags & DEBUG_FLAG_DB_QUERY)
118 DB_DEBUG(mysql_conn->conn, "query\n%s", query);
119
120 rc = mysql_db_query(mysql_conn, query);
121 xfree(query);
122 if (rc != SLURM_SUCCESS)
123 error("%s: Can't convert %s_%s info: %m",
124 __func__, cluster_name, job_table);
125 }
126
127 return rc;
128 }
129
_convert_step_table_pre(mysql_conn_t * mysql_conn,char * cluster_name)130 static int _convert_step_table_pre(mysql_conn_t *mysql_conn, char *cluster_name)
131 {
132 int rc = SLURM_SUCCESS;
133 MYSQL_RES *result = NULL;
134 MYSQL_ROW row;
135 storage_field_t step_table_fields_17_11[] = {
136 { "job_db_inx", "bigint unsigned not null" },
137 { "deleted", "tinyint default 0 not null" },
138 { "exit_code", "int default 0 not null" },
139 { "id_step", "int not null" },
140 { "kill_requid", "int default -1 not null" },
141 { "nodelist", "text not null" },
142 { "nodes_alloc", "int unsigned not null" },
143 { "node_inx", "text" },
144 { "state", "smallint unsigned not null" },
145 { "step_name", "text not null" },
146 { "task_cnt", "int unsigned not null" },
147 { "task_dist", "smallint default 0 not null" },
148 { "time_start", "bigint unsigned default 0 not null" },
149 { "time_end", "bigint unsigned default 0 not null" },
150 { "time_suspended", "bigint unsigned default 0 not null" },
151 { "user_sec", "int unsigned default 0 not null" },
152 { "user_usec", "int unsigned default 0 not null" },
153 { "sys_sec", "int unsigned default 0 not null" },
154 { "sys_usec", "int unsigned default 0 not null" },
155 { "max_pages", "int unsigned default 0 not null" },
156 { "max_pages_task", "int unsigned default 0 not null" },
157 { "max_pages_node", "int unsigned default 0 not null" },
158 { "ave_pages", "double unsigned default 0.0 not null" },
159 { "max_rss", "bigint unsigned default 0 not null" },
160 { "max_rss_task", "int unsigned default 0 not null" },
161 { "max_rss_node", "int unsigned default 0 not null" },
162 { "ave_rss", "double unsigned default 0.0 not null" },
163 { "max_vsize", "bigint unsigned default 0 not null" },
164 { "max_vsize_task", "int unsigned default 0 not null" },
165 { "max_vsize_node", "int unsigned default 0 not null" },
166 { "ave_vsize", "double unsigned default 0.0 not null" },
167 { "min_cpu", "int unsigned default 0xfffffffe not null" },
168 { "min_cpu_task", "int unsigned default 0 not null" },
169 { "min_cpu_node", "int unsigned default 0 not null" },
170 { "ave_cpu", "double unsigned default 0.0 not null" },
171 { "act_cpufreq", "double unsigned default 0.0 not null" },
172 { "consumed_energy", "bigint unsigned default 0 not null" },
173 { "req_cpufreq_min", "int unsigned default 0 not null" },
174 { "req_cpufreq", "int unsigned default 0 not null" }, /* max */
175 { "req_cpufreq_gov", "int unsigned default 0 not null" },
176 { "max_disk_read", "double unsigned default 0.0 not null" },
177 { "max_disk_read_task", "int unsigned default 0 not null" },
178 { "max_disk_read_node", "int unsigned default 0 not null" },
179 { "ave_disk_read", "double unsigned default 0.0 not null" },
180 { "max_disk_write", "double unsigned default 0.0 not null" },
181 { "max_disk_write_task", "int unsigned default 0 not null" },
182 { "max_disk_write_node", "int unsigned default 0 not null" },
183 { "ave_disk_write", "double unsigned default 0.0 not null" },
184 { "tres_alloc", "text not null default ''" },
185 { "tres_usage_in_ave", "text not null default ''" },
186 { "tres_usage_in_max", "text not null default ''" },
187 { "tres_usage_in_max_taskid", "text not null default ''" },
188 { "tres_usage_in_max_nodeid", "text not null default ''" },
189 { "tres_usage_in_min", "text not null default ''" },
190 { "tres_usage_in_min_taskid", "text not null default ''" },
191 { "tres_usage_in_min_nodeid", "text not null default ''" },
192 { "tres_usage_in_tot", "text not null default ''" },
193 { "tres_usage_out_ave", "text not null default ''" },
194 { "tres_usage_out_max", "text not null default ''" },
195 { "tres_usage_out_max_taskid", "text not null default ''" },
196 { "tres_usage_out_max_nodeid", "text not null default ''" },
197 { "tres_usage_out_min", "text not null default ''" },
198 { "tres_usage_out_min_taskid", "text not null default ''" },
199 { "tres_usage_out_min_nodeid", "text not null default ''" },
200 { "tres_usage_out_tot", "text not null default ''" },
201 { NULL, NULL}
202 };
203
204 char *query = NULL, *tmp = NULL;
205 char table_name[200];
206 int i;
207
208 if (db_curr_ver < 6) {
209 char *step_req_inx[] = {
210 "job_db_inx",
211 "id_step",
212 "max_disk_read",
213 "max_disk_read_task",
214 "max_disk_read_node",
215 "ave_disk_read",
216 "max_disk_write",
217 "max_disk_write_task",
218 "max_disk_write_node",
219 "ave_disk_write",
220 "max_vsize",
221 "max_vsize_task",
222 "max_vsize_node",
223 "ave_vsize",
224 "max_rss",
225 "max_rss_task",
226 "max_rss_node",
227 "ave_rss",
228 "max_pages",
229 "max_pages_task",
230 "max_pages_node",
231 "ave_pages",
232 "min_cpu",
233 "min_cpu_task",
234 "min_cpu_node",
235 "ave_cpu",
236 "tres_usage_in_max",
237 "tres_usage_in_max_taskid",
238 "tres_usage_in_max_nodeid",
239 "tres_usage_in_ave",
240 "tres_usage_out_max",
241 "tres_usage_out_max_taskid",
242 "tres_usage_out_max_nodeid",
243 "tres_usage_out_ave"
244 };
245
246 enum {
247 STEP_REQ_INX,
248 STEP_REQ_STEPID,
249 STEP_REQ_MAX_DISK_READ,
250 STEP_REQ_MAX_DISK_READ_TASK,
251 STEP_REQ_MAX_DISK_READ_NODE,
252 STEP_REQ_AVE_DISK_READ,
253 STEP_REQ_MAX_DISK_WRITE,
254 STEP_REQ_MAX_DISK_WRITE_TASK,
255 STEP_REQ_MAX_DISK_WRITE_NODE,
256 STEP_REQ_AVE_DISK_WRITE,
257 STEP_REQ_MAX_VSIZE,
258 STEP_REQ_MAX_VSIZE_TASK,
259 STEP_REQ_MAX_VSIZE_NODE,
260 STEP_REQ_AVE_VSIZE,
261 STEP_REQ_MAX_RSS,
262 STEP_REQ_MAX_RSS_TASK,
263 STEP_REQ_MAX_RSS_NODE,
264 STEP_REQ_AVE_RSS,
265 STEP_REQ_MAX_PAGES,
266 STEP_REQ_MAX_PAGES_TASK,
267 STEP_REQ_MAX_PAGES_NODE,
268 STEP_REQ_AVE_PAGES,
269 STEP_REQ_MIN_CPU,
270 STEP_REQ_MIN_CPU_TASK,
271 STEP_REQ_MIN_CPU_NODE,
272 STEP_REQ_AVE_CPU,
273 STEP_REQ_TRES_USAGE_IN_MAX,
274 STEP_REQ_TRES_USAGE_IN_MAX_TASKID,
275 STEP_REQ_TRES_USAGE_IN_MAX_NODEID,
276 STEP_REQ_TRES_USAGE_IN_AVE,
277 STEP_REQ_TRES_USAGE_OUT_MAX,
278 STEP_REQ_TRES_USAGE_OUT_MAX_TASKID,
279 STEP_REQ_TRES_USAGE_OUT_MAX_NODEID,
280 STEP_REQ_TRES_USAGE_OUT_AVE,
281 STEP_REQ_COUNT
282 };
283
284 jobacctinfo_t *jobacct = NULL;
285 char *tres_usage_in_ave;
286 char *tres_usage_in_max;
287 char *tres_usage_in_max_nodeid;
288 char *tres_usage_in_max_taskid;
289 char *tres_usage_out_ave;
290 char *tres_usage_out_max;
291 char *tres_usage_out_max_nodeid;
292 char *tres_usage_out_max_taskid;
293 int cnt = 0;
294 uint32_t tmp32;
295 double tmpd, div = 1024;
296 char *extra = NULL;
297 uint32_t flags = TRES_STR_FLAG_SIMPLE |
298 TRES_STR_FLAG_ALLOW_REAL;
299
300 snprintf(table_name, sizeof(table_name), "\"%s_%s\"",
301 cluster_name, step_table);
302 if (mysql_db_create_table(mysql_conn, table_name,
303 step_table_fields_17_11,
304 ", primary key (job_db_inx, id_step))")
305 == SLURM_ERROR)
306 return SLURM_ERROR;
307
308 xstrfmtcat(tmp, "%s", step_req_inx[0]);
309 for (i = 1; i < STEP_REQ_COUNT; i++) {
310 xstrfmtcat(tmp, ", %s", step_req_inx[i]);
311 }
312
313 query = xstrdup_printf(
314 "select %s from \"%s_%s\"",
315 tmp, cluster_name, step_table);
316 xfree(tmp);
317
318 if (debug_flags & DEBUG_FLAG_DB_QUERY)
319 DB_DEBUG(mysql_conn->conn, "query\n%s", query);
320 result = mysql_db_query_ret(mysql_conn, query, 0);
321 xfree(query);
322
323 if (!result)
324 return SLURM_ERROR;
325
326 while ((row = mysql_fetch_row(result))) {
327 jobacct = jobacctinfo_create(NULL);
328
329 /* Just in case something is already there */
330 _set_tres_value(row[STEP_REQ_TRES_USAGE_IN_MAX],
331 jobacct->tres_usage_in_max);
332 _set_tres_value(row[STEP_REQ_TRES_USAGE_IN_MAX_TASKID],
333 jobacct->tres_usage_in_max_taskid);
334 _set_tres_value(row[STEP_REQ_TRES_USAGE_IN_MAX_NODEID],
335 jobacct->tres_usage_in_max_nodeid);
336 _set_tres_value(row[STEP_REQ_TRES_USAGE_IN_AVE],
337 jobacct->tres_usage_in_tot);
338 _set_tres_value(row[STEP_REQ_TRES_USAGE_OUT_MAX],
339 jobacct->tres_usage_out_max);
340 _set_tres_value(row[STEP_REQ_TRES_USAGE_OUT_MAX_TASKID],
341 jobacct->tres_usage_out_max_taskid);
342 _set_tres_value(row[STEP_REQ_TRES_USAGE_OUT_MAX_NODEID],
343 jobacct->tres_usage_out_max_nodeid);
344 _set_tres_value(row[STEP_REQ_TRES_USAGE_OUT_AVE],
345 jobacct->tres_usage_out_tot);
346
347 /* TRES_CPU */
348 tmp32 = slurm_atoul(row[STEP_REQ_MIN_CPU]);
349 if (tmp32 != NO_VAL) {
350 jobacct->tres_usage_in_min[TRES_ARRAY_CPU] =
351 tmp32;
352 jobacct->tres_usage_in_min[TRES_ARRAY_CPU] *=
353 CPU_TIME_ADJ;
354 jobacct->tres_usage_in_min_nodeid[
355 TRES_ARRAY_CPU] =
356 slurm_atoull(
357 row[STEP_REQ_MIN_CPU_NODE]);
358 jobacct->tres_usage_in_min_taskid[
359 TRES_ARRAY_CPU] =
360 slurm_atoull(
361 row[STEP_REQ_MIN_CPU_TASK]);
362 tmpd = atof(row[STEP_REQ_AVE_CPU]);
363 jobacct->tres_usage_in_tot[TRES_ARRAY_CPU] =
364 (uint64_t)(tmpd * CPU_TIME_ADJ);
365 }
366
367 /* TRES_MEM */
368 tmpd = atof(row[STEP_REQ_MAX_RSS]);
369 if (tmpd) {
370 jobacct->tres_usage_in_max[TRES_ARRAY_MEM] =
371 (uint64_t)(tmpd * div);
372 jobacct->tres_usage_in_max_nodeid[
373 TRES_ARRAY_MEM] =
374 slurm_atoull(
375 row[STEP_REQ_MAX_RSS_NODE]);
376 jobacct->tres_usage_in_max_taskid[
377 TRES_ARRAY_MEM] =
378 slurm_atoull(
379 row[STEP_REQ_MAX_RSS_TASK]);
380 tmpd = atof(row[STEP_REQ_AVE_RSS]);
381 jobacct->tres_usage_in_tot[TRES_ARRAY_MEM] =
382 (uint64_t)(tmpd * div);
383 }
384
385 /* TRES_VMEM */
386 tmpd = atof(row[STEP_REQ_MAX_VSIZE]);
387 if (tmpd) {
388 jobacct->tres_usage_in_max[TRES_ARRAY_VMEM] =
389 (uint64_t)(tmpd * div);
390 jobacct->tres_usage_in_max_nodeid[
391 TRES_ARRAY_VMEM] =
392 slurm_atoull(
393 row[STEP_REQ_MAX_VSIZE_NODE]);
394 jobacct->tres_usage_in_max_taskid[
395 TRES_ARRAY_VMEM] =
396 slurm_atoull(
397 row[STEP_REQ_MAX_VSIZE_TASK]);
398 tmpd = atof(row[STEP_REQ_AVE_VSIZE]);
399 jobacct->tres_usage_in_tot[TRES_ARRAY_VMEM] =
400 (uint64_t)(tmpd * div);
401 }
402
403 /* TRES_PAGES */
404 tmp32 = slurm_atoul(row[STEP_REQ_MAX_PAGES]);
405 if (tmp32) {
406 jobacct->tres_usage_in_max[TRES_ARRAY_PAGES] =
407 tmp32;
408 jobacct->tres_usage_in_max_nodeid[
409 TRES_ARRAY_PAGES] =
410 slurm_atoull(
411 row[STEP_REQ_MAX_PAGES_NODE]);
412 jobacct->tres_usage_in_max_taskid[
413 TRES_ARRAY_PAGES] =
414 slurm_atoull(
415 row[STEP_REQ_MAX_PAGES_TASK]);
416 jobacct->tres_usage_in_tot[TRES_ARRAY_PAGES] =
417 (uint64_t)atof(row[STEP_REQ_AVE_PAGES]);
418 }
419
420 /* TRES_FS_DISK (READ/IN) */
421 tmpd = atof(row[STEP_REQ_MAX_DISK_READ]);
422 if (tmpd) {
423 jobacct->tres_usage_in_max[TRES_ARRAY_FS_DISK] =
424 (uint64_t)(tmpd * div);
425 jobacct->tres_usage_in_max_nodeid[
426 TRES_ARRAY_FS_DISK] =
427 slurm_atoull(
428 row[STEP_REQ_MAX_DISK_READ_NODE]);
429 jobacct->tres_usage_in_max_taskid[
430 TRES_ARRAY_FS_DISK] =
431 slurm_atoull(
432 row[STEP_REQ_MAX_DISK_READ_TASK]);
433 tmpd = atof(row[STEP_REQ_AVE_DISK_READ]);
434 jobacct->tres_usage_in_tot[TRES_ARRAY_FS_DISK] =
435 (uint64_t)(tmpd * div);
436 }
437 /* TRES_FS_DISK (WRITE/OUT) */
438 tmpd = atof(row[STEP_REQ_MAX_DISK_WRITE]);
439 if (tmpd) {
440 jobacct->tres_usage_out_max[
441 TRES_ARRAY_FS_DISK] =
442 (uint64_t)(tmpd * div);
443 jobacct->tres_usage_out_max_nodeid[
444 TRES_ARRAY_FS_DISK] =
445 slurm_atoull(
446 row[STEP_REQ_MAX_DISK_READ_NODE]);
447 jobacct->tres_usage_out_max_taskid[
448 TRES_ARRAY_FS_DISK] =
449 slurm_atoull(
450 row[STEP_REQ_MAX_DISK_READ_TASK]);
451 tmpd = atof(row[STEP_REQ_AVE_DISK_WRITE]);
452 jobacct->tres_usage_out_tot[
453 TRES_ARRAY_FS_DISK] =
454 (uint64_t)(tmpd * div);
455 }
456
457 tres_usage_in_max = assoc_mgr_make_tres_str_from_array(
458 jobacct->tres_usage_in_max, flags, true);
459 tres_usage_in_max_nodeid =
460 assoc_mgr_make_tres_str_from_array(
461 jobacct->tres_usage_in_max_nodeid, flags, true);
462 tres_usage_in_max_taskid =
463 assoc_mgr_make_tres_str_from_array(
464 jobacct->tres_usage_in_max_taskid, flags, true);
465 tres_usage_in_ave = assoc_mgr_make_tres_str_from_array(
466 jobacct->tres_usage_in_tot, flags, true);
467 tres_usage_out_max = assoc_mgr_make_tres_str_from_array(
468 jobacct->tres_usage_out_max, flags, true);
469 tres_usage_out_max_nodeid =
470 assoc_mgr_make_tres_str_from_array(
471 jobacct->tres_usage_out_max_nodeid,
472 flags, true);
473 tres_usage_out_max_taskid =
474 assoc_mgr_make_tres_str_from_array(
475 jobacct->tres_usage_out_max_taskid,
476 flags, true);
477 tres_usage_out_ave = assoc_mgr_make_tres_str_from_array(
478 jobacct->tres_usage_out_tot, flags, true);
479
480 jobacctinfo_destroy(jobacct);
481
482 if (tres_usage_in_max) {
483 xstrfmtcat(extra, "%stres_usage_in_max='%s'",
484 extra ? ", " : "",
485 tres_usage_in_max);
486 xfree(tres_usage_in_max);
487 }
488
489 if (tres_usage_in_max_nodeid) {
490 xstrfmtcat(extra,
491 "%stres_usage_in_max_nodeid='%s'",
492 extra ? ", " : "",
493 tres_usage_in_max_nodeid);
494 xfree(tres_usage_in_max_nodeid);
495 }
496 if (tres_usage_in_max_taskid) {
497 xstrfmtcat(extra,
498 "%stres_usage_in_max_taskid='%s'",
499 extra ? ", " : "",
500 tres_usage_in_max_taskid);
501 xfree(tres_usage_in_max_taskid);
502 }
503 if (tres_usage_in_ave) {
504 xstrfmtcat(extra, "%stres_usage_in_ave='%s'",
505 extra ? ", " : "",
506 tres_usage_in_ave);
507 xfree(tres_usage_in_ave);
508 }
509
510 if (tres_usage_out_max) {
511 xstrfmtcat(extra, "%stres_usage_out_max='%s'",
512 extra ? ", " : "",
513 tres_usage_out_max);
514 xfree(tres_usage_out_max);
515 }
516
517 if (tres_usage_out_max_nodeid) {
518 xstrfmtcat(extra,
519 "%stres_usage_out_max_nodeid='%s'",
520 extra ? ", " : "",
521 tres_usage_out_max_nodeid);
522 xfree(tres_usage_out_max_nodeid);
523 }
524 if (tres_usage_out_max_taskid) {
525 xstrfmtcat(extra,
526 "%stres_usage_out_max_taskid='%s'",
527 extra ? ", " : "",
528 tres_usage_out_max_taskid);
529 xfree(tres_usage_out_max_taskid);
530 }
531 if (tres_usage_out_ave) {
532 xstrfmtcat(extra, "%stres_usage_out_ave='%s'",
533 extra ? ", " : "",
534 tres_usage_out_ave);
535 xfree(tres_usage_out_ave);
536 }
537
538 if (!extra)
539 continue;
540
541 xstrfmtcat(query, "update \"%s_%s\" set %s where job_db_inx=%s and id_step=%s;",
542 cluster_name, step_table, extra,
543 row[STEP_REQ_INX],
544 row[STEP_REQ_STEPID]);
545 xfree(extra);
546
547 if (cnt > 1000) {
548 cnt = 0;
549 if (debug_flags & DEBUG_FLAG_DB_QUERY)
550 DB_DEBUG(mysql_conn->conn, "query\n%s",
551 query);
552 rc = mysql_db_query(mysql_conn, query);
553 xfree(query);
554 if (rc != SLURM_SUCCESS) {
555 error("%s: Can't convert %s_%s info: %m",
556 __func__,
557 cluster_name, step_table);
558 break;
559 }
560 } else
561 cnt++;
562 }
563 mysql_free_result(result);
564 }
565
566 if (query) {
567 if (debug_flags & DEBUG_FLAG_DB_QUERY)
568 DB_DEBUG(mysql_conn->conn, "query\n%s", query);
569
570 rc = mysql_db_query(mysql_conn, query);
571 xfree(query);
572 if (rc != SLURM_SUCCESS)
573 error("%s: Can't convert %s_%s info: %m",
574 __func__, cluster_name, step_table);
575 }
576
577 return rc;
578 }
579
_set_db_curr_ver(mysql_conn_t * mysql_conn)580 static int _set_db_curr_ver(mysql_conn_t *mysql_conn)
581 {
582 char *query;
583 MYSQL_RES *result = NULL;
584 MYSQL_ROW row;
585 int rc = SLURM_SUCCESS;
586
587 if (db_curr_ver != NO_VAL)
588 return SLURM_SUCCESS;
589
590 query = xstrdup_printf("select version from %s", convert_version_table);
591 debug4("%d(%s:%d) query\n%s", mysql_conn->conn,
592 THIS_FILE, __LINE__, query);
593 if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
594 xfree(query);
595 return SLURM_ERROR;
596 }
597 xfree(query);
598 row = mysql_fetch_row(result);
599
600 if (row) {
601 db_curr_ver = slurm_atoul(row[0]);
602 mysql_free_result(result);
603 } else {
604 int tmp_ver = 0;
605 mysql_free_result(result);
606
607 /* no valid clusters, just return */
608 if (as_mysql_total_cluster_list &&
609 !list_count(as_mysql_total_cluster_list))
610 tmp_ver = CONVERT_VERSION;
611
612 query = xstrdup_printf("insert into %s (version) values (%d);",
613 convert_version_table, tmp_ver);
614 debug4("(%s:%d) query\n%s", THIS_FILE, __LINE__, query);
615 rc = mysql_db_query(mysql_conn, query);
616 xfree(query);
617 if (rc != SLURM_SUCCESS)
618 return SLURM_ERROR;
619 db_curr_ver = tmp_ver;
620 }
621
622 return rc;
623 }
624
as_mysql_convert_tables_pre_create(mysql_conn_t * mysql_conn)625 extern int as_mysql_convert_tables_pre_create(mysql_conn_t *mysql_conn)
626 {
627 int rc = SLURM_SUCCESS;
628 ListIterator itr;
629 char *cluster_name;
630
631 xassert(as_mysql_total_cluster_list);
632
633 if ((rc = _set_db_curr_ver(mysql_conn)) != SLURM_SUCCESS)
634 return rc;
635
636 if (db_curr_ver == CONVERT_VERSION) {
637 debug4("%s: No conversion needed, Horray!", __func__);
638 return SLURM_SUCCESS;
639 } else if (backup_dbd) {
640 /*
641 * We do not want to create/check the database if we are the
642 * backup (see Bug 3827). This is only handled on the primary.
643 *
644 * To avoid situations where someone might upgrade the database
645 * through the backup we want to fatal so they know what
646 * happened instead of potentially starting with the older
647 * database.
648 */
649 fatal("Backup DBD can not convert database, please start the primary DBD before starting the backup.");
650 return SLURM_ERROR;
651 }
652
653 if (db_curr_ver < 6) {
654 /*
655 * We have to fake it here to make things work correctly since
656 * the assoc_mgr isn't set up yet.
657 */
658 List tres_list = as_mysql_get_tres(mysql_conn, getuid(), NULL);
659 assoc_mgr_post_tres_list(tres_list);
660 }
661
662 /* make it up to date */
663 itr = list_iterator_create(as_mysql_total_cluster_list);
664 while ((cluster_name = list_next(itr))) {
665 info("pre-converting job table for %s", cluster_name);
666 if ((rc = _convert_job_table_pre(mysql_conn, cluster_name)
667 != SLURM_SUCCESS))
668 break;
669 info("pre-converting step table for %s", cluster_name);
670 if ((rc = _convert_step_table_pre(mysql_conn, cluster_name)
671 != SLURM_SUCCESS))
672 break;
673 }
674 list_iterator_destroy(itr);
675
676 if (db_curr_ver < 6)
677 assoc_mgr_fini(false);
678
679 return rc;
680 }
681
as_mysql_convert_tables_post_create(mysql_conn_t * mysql_conn)682 extern int as_mysql_convert_tables_post_create(mysql_conn_t *mysql_conn)
683 {
684 int rc = SLURM_SUCCESS;
685 return rc;
686 }
687
as_mysql_convert_non_cluster_tables_post_create(mysql_conn_t * mysql_conn)688 extern int as_mysql_convert_non_cluster_tables_post_create(
689 mysql_conn_t *mysql_conn)
690 {
691 int rc = SLURM_SUCCESS;
692
693 if ((rc = _set_db_curr_ver(mysql_conn)) != SLURM_SUCCESS)
694 return rc;
695
696 if (db_curr_ver == CONVERT_VERSION) {
697 debug4("%s: No conversion needed, Horray!", __func__);
698 return SLURM_SUCCESS;
699 }
700
701 if (db_curr_ver < 7) {
702 /*
703 * In 19.05 we changed the name of the TRES bb/cray to be
704 * bb/datawarp.
705 */
706 char *query = xstrdup_printf(
707 "update %s set name='datawarp' where type='bb' and name='cray'",
708 tres_table);
709 rc = mysql_db_query(mysql_conn, query);
710 xfree(query);
711 }
712
713
714 if (rc == SLURM_SUCCESS) {
715 char *query = xstrdup_printf(
716 "update %s set version=%d, mod_time=UNIX_TIMESTAMP()",
717 convert_version_table, CONVERT_VERSION);
718
719 info("Conversion done: success!");
720
721 debug4("(%s:%d) query\n%s", THIS_FILE, __LINE__, query);
722 rc = mysql_db_query(mysql_conn, query);
723 xfree(query);
724 }
725
726 return rc;
727 }
728