1 /*****************************************************************************\
2 * as_mysql_federation.c - functions dealing with federations.
3 *****************************************************************************
4 *
5 * Copyright (C) 2016 SchedMD LLC.
6 * Written by Brian Christiansen <brian@schedmd.com>
7 *
8 * This file is part of Slurm, a resource management program.
9 * For details, see <https://slurm.schedmd.com/>.
10 * Please also read the included file: DISCLAIMER.
11 *
12 * Slurm is free software; you can redistribute it and/or modify it under
13 * the terms of the GNU General Public License as published by the Free
14 * Software Foundation; either version 2 of the License, or (at your option)
15 * any later version.
16 *
17 * In addition, as a special exception, the copyright holders give permission
18 * to link the code of portions of this program with the OpenSSL library under
19 * certain conditions as described in each individual source file, and
20 * distribute linked combinations including the two. You must obey the GNU
21 * General Public License in all respects for all of the code used other than
22 * OpenSSL. If you modify file(s) with this exception, you may extend this
23 * exception to your version of the file(s), but you are not obligated to do
24 * so. If you do not wish to do so, delete this exception statement from your
25 * version. If you delete this exception statement from all source files in
26 * the program, then also delete it here.
27 *
28 * Slurm is distributed in the hope that it will be useful, but WITHOUT ANY
29 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
30 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
31 * details.
32 *
33 * You should have received a copy of the GNU General Public License along
34 * with Slurm; if not, write to the Free Software Foundation, Inc.,
35 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
36 \*****************************************************************************/
37
38 #include "as_mysql_federation.h"
39 #include "as_mysql_cluster.h"
40
41 char *fed_req_inx[] = {
42 "t1.name",
43 "t1.flags",
44 };
45 enum {
46 FED_REQ_NAME,
47 FED_REQ_FLAGS,
48 FED_REQ_COUNT
49 };
50
_setup_federation_cond_limits(slurmdb_federation_cond_t * fed_cond,char ** extra)51 static int _setup_federation_cond_limits(slurmdb_federation_cond_t *fed_cond,
52 char **extra)
53 {
54 int set = 0;
55 ListIterator itr = NULL;
56 char *object = NULL;
57
58 if (!fed_cond)
59 return 0;
60
61 if (fed_cond->with_deleted)
62 xstrcat(*extra, " where (t1.deleted=0 || t1.deleted=1)");
63 else
64 xstrcat(*extra, " where t1.deleted=0");
65
66 if (fed_cond->cluster_list
67 && list_count(fed_cond->cluster_list)) {
68 set = 0;
69 xstrcat(*extra, " && (");
70 itr = list_iterator_create(fed_cond->cluster_list);
71 while ((object = list_next(itr))) {
72 if (set)
73 xstrcat(*extra, " || ");
74 xstrfmtcat(*extra, "t2.name='%s'", object);
75 set = 1;
76 }
77 list_iterator_destroy(itr);
78 xstrcat(*extra, ")");
79 }
80
81 if (fed_cond->federation_list
82 && list_count(fed_cond->federation_list)) {
83 set = 0;
84 xstrcat(*extra, " && (");
85 itr = list_iterator_create(fed_cond->federation_list);
86 while ((object = list_next(itr))) {
87 if (set)
88 xstrcat(*extra, " || ");
89 xstrfmtcat(*extra, "t1.name='%s'", object);
90 set = 1;
91 }
92 list_iterator_destroy(itr);
93 xstrcat(*extra, ")");
94 }
95
96 return set;
97 }
98
_setup_federation_rec_limits(slurmdb_federation_rec_t * fed,char ** cols,char ** vals,char ** extra)99 static int _setup_federation_rec_limits(slurmdb_federation_rec_t *fed,
100 char **cols, char **vals, char **extra)
101 {
102 if (!fed)
103 return SLURM_ERROR;
104
105 if (!(fed->flags & FEDERATION_FLAG_NOTSET)) {
106 uint32_t flags;
107 xstrcat(*cols, ", flags");
108 if (fed->flags & FEDERATION_FLAG_REMOVE) {
109 flags = fed->flags & ~FEDERATION_FLAG_REMOVE;
110 xstrfmtcat(*vals, ", (flags & ~%u)", flags);
111 xstrfmtcat(*extra, ", flags=(flags & ~%u)", flags);
112 } else if (fed->flags & FEDERATION_FLAG_ADD) {
113 flags = fed->flags & ~FEDERATION_FLAG_ADD;
114 xstrfmtcat(*vals, ", (flags | %u)", flags);
115 xstrfmtcat(*extra, ", flags=(flags | %u)", flags);
116 } else {
117 flags = fed->flags;
118 xstrfmtcat(*vals, ", %u", flags);
119 xstrfmtcat(*extra, ", flags=%u", flags);
120 }
121 }
122
123 return SLURM_SUCCESS;
124 }
125
126 /*
127 * Remove all clusters from federation.
128 * IN: mysql_conn - mysql connection
129 * IN: fed - fed to remove clusters from
130 * IN: exceptions - list of clusters to not remove.
131 */
_remove_all_clusters_from_fed(mysql_conn_t * mysql_conn,const char * fed,List exceptions)132 static int _remove_all_clusters_from_fed(mysql_conn_t *mysql_conn,
133 const char *fed, List exceptions)
134 {
135 int rc = SLURM_SUCCESS;
136 char *query = NULL;
137 char *exception_names = NULL;
138
139 if (exceptions && list_count(exceptions)) {
140 char *tmp_name;
141 ListIterator itr;
142
143 itr = list_iterator_create(exceptions);
144 while ((tmp_name = list_next(itr)))
145 xstrfmtcat(exception_names, "%s'%s'",
146 (exception_names) ? "," : "",
147 tmp_name);
148 list_iterator_destroy(itr);
149 }
150
151 xstrfmtcat(query, "UPDATE %s "
152 "SET federation='', fed_id=0, fed_state=%u "
153 "WHERE federation='%s' and deleted=0",
154 cluster_table, CLUSTER_FED_STATE_NA, fed);
155 if (exception_names)
156 xstrfmtcat(query, " AND name NOT IN (%s)", exception_names);
157
158 if (debug_flags & DEBUG_FLAG_FEDR)
159 DB_DEBUG(mysql_conn->conn, "query\n%s", query);
160
161 rc = mysql_db_query(mysql_conn, query);
162 xfree(query);
163 if (rc)
164 error("Failed to remove all clusters from federation %s", fed);
165
166 if (exception_names)
167 xfree(exception_names);
168
169 return rc;
170 }
171
_remove_clusters_from_fed(mysql_conn_t * mysql_conn,List clusters)172 static int _remove_clusters_from_fed(mysql_conn_t *mysql_conn, List clusters)
173 {
174 int rc = SLURM_SUCCESS;
175 char *query = NULL;
176 char *name = NULL;
177 char *names = NULL;
178 ListIterator itr = NULL;
179
180 xassert(clusters);
181
182 itr = list_iterator_create(clusters);
183 while ((name = list_next(itr)))
184 xstrfmtcat(names, "%s'%s'", names ? "," : "", name );
185
186 xstrfmtcat(query, "UPDATE %s "
187 "SET federation='', fed_id=0, fed_state=%u "
188 "WHERE name IN (%s) and deleted=0",
189 cluster_table, CLUSTER_FED_STATE_NA, names);
190
191 if (debug_flags & DEBUG_FLAG_FEDR)
192 DB_DEBUG(mysql_conn->conn, "query\n%s", query);
193
194 rc = mysql_db_query(mysql_conn, query);
195 xfree(query);
196 if (rc)
197 error("Failed to remove clusters %s from federation", names);
198 xfree(names);
199
200 return rc;
201 }
202
_add_clusters_to_fed(mysql_conn_t * mysql_conn,List clusters,const char * fed)203 static int _add_clusters_to_fed(mysql_conn_t *mysql_conn, List clusters,
204 const char *fed)
205 {
206 int rc = SLURM_SUCCESS;
207 char *query = NULL;
208 char *name = NULL;
209 char *names = NULL;
210 char *indexes = NULL;
211 ListIterator itr = NULL;
212 int last_id = -1;
213
214 xassert(fed);
215 xassert(clusters);
216
217 itr = list_iterator_create(clusters);
218 while ((name = list_next(itr))) {
219 int id;
220 if ((rc = as_mysql_get_fed_cluster_id(mysql_conn, name, fed,
221 last_id, &id)))
222 goto end_it;
223 last_id = id;
224 xstrfmtcat(indexes, "WHEN name='%s' THEN %d ", name, id);
225 xstrfmtcat(names, "%s'%s'", names ? "," : "", name);
226 }
227
228 /* Keep the same fed_state if the cluster isn't changing feds.
229 * Also note that mysql evaluates from left to right and uses the
230 * updated column values in case statements. So the check for federation
231 * in the fed_state case statement must happen before fed_state is set
232 * or the federation will always equal the federation in the case
233 * statement. */
234 xstrfmtcat(query, "UPDATE %s "
235 "SET "
236 "fed_state = CASE WHEN federation='%s' THEN fed_state ELSE %u END, "
237 "fed_id = CASE %s END, "
238 "federation='%s' "
239 "WHERE name IN (%s) and deleted=0",
240 cluster_table, fed, CLUSTER_FED_STATE_ACTIVE, indexes, fed,
241 names);
242
243 if (debug_flags & DEBUG_FLAG_FEDR)
244 DB_DEBUG(mysql_conn->conn, "query\n%s", query);
245
246 rc = mysql_db_query(mysql_conn, query);
247 if (rc)
248 error("Failed to add clusters %s to federation %s",
249 names, fed);
250
251 end_it:
252 xfree(query);
253 xfree(names);
254 xfree(indexes);
255 list_iterator_destroy(itr);
256
257 return rc;
258 }
259
_assign_clusters_to_federation(mysql_conn_t * mysql_conn,const char * federation,List cluster_list)260 static int _assign_clusters_to_federation(mysql_conn_t *mysql_conn,
261 const char *federation,
262 List cluster_list)
263 {
264 int rc = SLURM_SUCCESS;
265 List add_list = NULL;
266 List rem_list = NULL;
267 ListIterator itr = NULL;
268 bool clear_clusters = false;
269 slurmdb_cluster_rec_t *tmp_cluster = NULL;
270
271 xassert(federation);
272 xassert(cluster_list);
273
274 if (!cluster_list || !federation) {
275 rc = SLURM_ERROR;
276 goto end_it;
277 }
278
279 add_list = list_create(xfree_ptr);
280 rem_list = list_create(xfree_ptr);
281
282 itr = list_iterator_create(cluster_list);
283 while ((tmp_cluster = list_next(itr))) {
284 if (!tmp_cluster->name)
285 continue;
286 if (tmp_cluster->name[0] == '-')
287 list_append(rem_list, xstrdup(tmp_cluster->name + 1));
288 else if (tmp_cluster->name[0] == '+')
289 list_append(add_list, xstrdup(tmp_cluster->name + 1));
290 else {
291 list_append(add_list, xstrdup(tmp_cluster->name));
292 clear_clusters = true;
293 }
294 }
295 list_iterator_destroy(itr);
296
297 if (clear_clusters &&
298 (rc = _remove_all_clusters_from_fed(mysql_conn, federation,
299 add_list)))
300 goto end_it;
301 if (!clear_clusters &&
302 list_count(rem_list) &&
303 (rc = _remove_clusters_from_fed(mysql_conn, rem_list)))
304 goto end_it;
305 if (list_count(add_list) &&
306 (rc = _add_clusters_to_fed(mysql_conn, add_list, federation)))
307 goto end_it;
308
309 end_it:
310 list_destroy(add_list);
311 list_destroy(rem_list);
312
313 return rc;
314 }
315
as_mysql_add_federations(mysql_conn_t * mysql_conn,uint32_t uid,List federation_list)316 extern int as_mysql_add_federations(mysql_conn_t *mysql_conn, uint32_t uid,
317 List federation_list)
318 {
319 ListIterator itr = NULL;
320 int rc = SLURM_SUCCESS;
321 slurmdb_federation_rec_t *object = NULL;
322 char *cols = NULL, *vals = NULL, *extra = NULL, *query = NULL,
323 *tmp_extra = NULL;
324 time_t now = time(NULL);
325 char *user_name = NULL;
326 int affect_rows = 0;
327 int added = 0;
328
329 if (check_connection(mysql_conn) != SLURM_SUCCESS)
330 return ESLURM_DB_CONNECTION;
331
332 if (!is_user_min_admin_level(mysql_conn, uid, SLURMDB_ADMIN_SUPER_USER))
333 return ESLURM_ACCESS_DENIED;
334
335 user_name = uid_to_string((uid_t) uid);
336
337 itr = list_iterator_create(federation_list);
338 while ((object = list_next(itr))) {
339 if (object->cluster_list &&
340 (list_count(federation_list) > 1)) {
341 xfree(user_name);
342 error("Clusters can only be assigned to one "
343 "federation");
344 errno = ESLURM_FED_CLUSTER_MULTIPLE_ASSIGNMENT;
345 return ESLURM_FED_CLUSTER_MULTIPLE_ASSIGNMENT;
346 }
347
348 xstrcat(cols, "creation_time, mod_time, name");
349 xstrfmtcat(vals, "%ld, %ld, '%s'", now, now, object->name);
350 xstrfmtcat(extra, ", mod_time=%ld", now);
351
352 _setup_federation_rec_limits(object, &cols, &vals, &extra);
353
354 xstrfmtcat(query,
355 "insert into %s (%s) values (%s) "
356 "on duplicate key update deleted=0%s",
357 federation_table, cols, vals, extra);
358 if (debug_flags & DEBUG_FLAG_FEDR)
359 DB_DEBUG(mysql_conn->conn, "query\n%s", query);
360 rc = mysql_db_query(mysql_conn, query);
361 xfree(query);
362 if (rc != SLURM_SUCCESS) {
363 error("Couldn't add federation %s", object->name);
364 xfree(cols);
365 xfree(vals);
366 xfree(extra);
367 added = 0;
368 break;
369 }
370
371 affect_rows = last_affected_rows(mysql_conn);
372 if (!affect_rows) {
373 debug2("nothing changed %d", affect_rows);
374 xfree(cols);
375 xfree(vals);
376 xfree(extra);
377 continue;
378 }
379
380 if (object->cluster_list &&
381 _assign_clusters_to_federation(mysql_conn, object->name,
382 object->cluster_list)) {
383 xfree(cols);
384 xfree(vals);
385 xfree(extra);
386 xfree(user_name);
387 return SLURM_ERROR;
388 }
389
390 /* Add Transaction */
391 /* we always have a ', ' as the first 2 chars */
392 tmp_extra = slurm_add_slash_to_quotes(extra+2);
393
394 xstrfmtcat(query,
395 "insert into %s "
396 "(timestamp, action, name, actor, info) "
397 "values (%ld, %u, '%s', '%s', '%s');",
398 txn_table, now, DBD_ADD_FEDERATIONS,
399 object->name, user_name, tmp_extra);
400 xfree(cols);
401 xfree(vals);
402 xfree(tmp_extra);
403 xfree(extra);
404 debug4("%d(%s:%d) query\n%s",
405 mysql_conn->conn, THIS_FILE, __LINE__, query);
406
407 rc = mysql_db_query(mysql_conn, query);
408 xfree(query);
409 if (rc != SLURM_SUCCESS) {
410 error("Couldn't add txn");
411 } else {
412 added++;
413 }
414 }
415 list_iterator_destroy(itr);
416 xfree(user_name);
417
418 if (!added)
419 reset_mysql_conn(mysql_conn);
420 else
421 as_mysql_add_feds_to_update_list(mysql_conn);
422
423 return rc;
424 }
425
as_mysql_get_federations(mysql_conn_t * mysql_conn,uid_t uid,slurmdb_federation_cond_t * federation_cond)426 extern List as_mysql_get_federations(mysql_conn_t *mysql_conn, uid_t uid,
427 slurmdb_federation_cond_t *federation_cond)
428 {
429 char *query = NULL;
430 char *extra = NULL;
431 char *tmp = NULL;
432 List federation_list = NULL;
433 int i=0;
434 MYSQL_RES *result = NULL;
435 MYSQL_ROW row;
436 slurmdb_federation_rec_t *fed = NULL;
437
438 if (check_connection(mysql_conn) != SLURM_SUCCESS)
439 return NULL;
440
441 if (!federation_cond) {
442 xstrcat(extra, " where t1.deleted=0");
443 goto empty;
444 }
445
446 _setup_federation_cond_limits(federation_cond, &extra);
447
448 empty:
449
450 xfree(tmp);
451 i=0;
452 xstrfmtcat(tmp, "%s", fed_req_inx[i]);
453 for(i = 1; i < FED_REQ_COUNT; i++) {
454 xstrfmtcat(tmp, ", %s", fed_req_inx[i]);
455 }
456
457 query = xstrdup_printf(
458 "select distinct %s from %s as t1 "
459 "left join %s as t2 on t1.name=t2.federation and t2.deleted=0"
460 "%s order by t1.name",
461 tmp, federation_table, cluster_table, extra);
462 xfree(tmp);
463 xfree(extra);
464
465 if (debug_flags & DEBUG_FLAG_FEDR)
466 DB_DEBUG(mysql_conn->conn, "query\n%s", query);
467 if (!(result = mysql_db_query_ret(
468 mysql_conn, query, 0))) {
469 xfree(query);
470 return NULL;
471 }
472 xfree(query);
473
474 federation_list = list_create(slurmdb_destroy_federation_rec);
475
476 while ((row = mysql_fetch_row(result))) {
477 slurmdb_cluster_cond_t clus_cond;
478 List tmp_list = NULL;
479 fed = xmalloc(sizeof(slurmdb_federation_rec_t));
480 list_append(federation_list, fed);
481
482 fed->name = xstrdup(row[FED_REQ_NAME]);
483 fed->flags = slurm_atoul(row[FED_REQ_FLAGS]);
484
485 /* clusters in federation */
486 slurmdb_init_cluster_cond(&clus_cond, 0);
487 clus_cond.federation_list = list_create(xfree_ptr);
488 list_append(clus_cond.federation_list, xstrdup(fed->name));
489
490 tmp_list = as_mysql_get_clusters(mysql_conn, uid, &clus_cond);
491 FREE_NULL_LIST(clus_cond.federation_list);
492 if (!tmp_list) {
493 error("Unable to get federation clusters");
494 continue;
495 }
496 fed->cluster_list = tmp_list;
497 }
498 mysql_free_result(result);
499
500 return federation_list;
501 }
502
as_mysql_modify_federations(mysql_conn_t * mysql_conn,uint32_t uid,slurmdb_federation_cond_t * fed_cond,slurmdb_federation_rec_t * fed)503 extern List as_mysql_modify_federations(
504 mysql_conn_t *mysql_conn, uint32_t uid,
505 slurmdb_federation_cond_t *fed_cond,
506 slurmdb_federation_rec_t *fed)
507 {
508 List ret_list = NULL;
509 int rc = SLURM_SUCCESS;
510 int req_inx = 0;
511 char *object = NULL;
512 char *vals = NULL, *extra = NULL, *query = NULL,
513 *name_char = NULL, *fed_items = NULL;
514 char *tmp_char1 = NULL, *tmp_char2 = NULL;
515 time_t now = time(NULL);
516 MYSQL_RES *result = NULL;
517 MYSQL_ROW row;
518
519 if (!fed_cond || !fed) {
520 error("we need something to change");
521 return NULL;
522 }
523
524 if (check_connection(mysql_conn) != SLURM_SUCCESS)
525 return NULL;
526
527 if (!is_user_min_admin_level(mysql_conn, uid,
528 SLURMDB_ADMIN_SUPER_USER)) {
529 errno = ESLURM_ACCESS_DENIED;
530 return NULL;
531 }
532
533 /* force to only do non-deleted federations */
534 fed_cond->with_deleted = 0;
535 _setup_federation_cond_limits(fed_cond, &extra);
536 _setup_federation_rec_limits(fed, &tmp_char1, &tmp_char2, &vals);
537 xfree(tmp_char1);
538 xfree(tmp_char2);
539
540 if (!extra ||
541 (!vals && (!fed->cluster_list || !list_count(fed->cluster_list)))) {
542 xfree(extra);
543 xfree(vals);
544 errno = SLURM_NO_CHANGE_IN_DATA;
545 error("Nothing to change");
546 return NULL;
547 }
548
549 if (fed->cluster_list &&
550 fed_cond->federation_list &&
551 (list_count(fed_cond->federation_list) > 1)) {
552 xfree(extra);
553 xfree(vals);
554 error("Clusters can only be assigned to one federation");
555 errno = ESLURM_FED_CLUSTER_MULTIPLE_ASSIGNMENT;
556 return NULL;
557 }
558
559 /* Select records that are going to get updated.
560 * 1 - to be able to report what is getting updated
561 * 2 - to create an update object to let the controller know. */
562 xstrfmtcat(fed_items, "%s", fed_req_inx[req_inx]);
563 for(req_inx = 1; req_inx < FED_REQ_COUNT; req_inx++) {
564 xstrfmtcat(fed_items, ", %s", fed_req_inx[req_inx]);
565 }
566
567 xstrfmtcat(query, "select %s from %s as t1 %s;",
568 fed_items, federation_table, extra);
569 xfree(fed_items);
570
571 if (debug_flags & DEBUG_FLAG_FEDR)
572 DB_DEBUG(mysql_conn->conn, "query\n%s", query);
573 if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
574 xfree(query);
575 xfree(vals);
576 xfree(extra);
577 error("no result given for %s", extra);
578 return NULL;
579 }
580 xfree(extra);
581
582 ret_list = list_create(xfree_ptr);
583 while ((row = mysql_fetch_row(result))) {
584 object = xstrdup(row[0]);
585
586 list_append(ret_list, object);
587 if (!name_char) {
588 xstrfmtcat(name_char, "(name='%s'", object);
589 } else {
590 xstrfmtcat(name_char, " || name='%s'", object);
591 }
592 }
593 mysql_free_result(result);
594
595 if (fed->cluster_list &&
596 (_assign_clusters_to_federation(mysql_conn, object,
597 fed->cluster_list))) {
598 xfree(vals);
599 xfree(name_char);
600 xfree(query);
601 FREE_NULL_LIST(ret_list);
602 return NULL;
603 }
604
605 if (!list_count(ret_list)) {
606 errno = SLURM_NO_CHANGE_IN_DATA;
607 if (debug_flags & DEBUG_FLAG_FEDR)
608 DB_DEBUG(mysql_conn->conn,
609 "didn't effect anything\n%s", query);
610 xfree(vals);
611 xfree(name_char);
612 xfree(query);
613 return ret_list;
614 }
615 xfree(query);
616 xstrcat(name_char, ")");
617
618 if (vals) {
619 char *user_name = uid_to_string((uid_t) uid);
620 rc = modify_common(mysql_conn, DBD_MODIFY_FEDERATIONS, now,
621 user_name, federation_table,
622 name_char, vals, NULL);
623 xfree(user_name);
624 }
625 xfree(name_char);
626 xfree(vals);
627
628 if (rc == SLURM_ERROR) {
629 error("Couldn't modify federation");
630 FREE_NULL_LIST(ret_list);
631 ret_list = NULL;
632 } else
633 as_mysql_add_feds_to_update_list(mysql_conn);
634
635 return ret_list;
636 }
637
as_mysql_remove_federations(mysql_conn_t * mysql_conn,uint32_t uid,slurmdb_federation_cond_t * fed_cond)638 extern List as_mysql_remove_federations(mysql_conn_t *mysql_conn, uint32_t uid,
639 slurmdb_federation_cond_t *fed_cond)
640 {
641 List ret_list = NULL;
642 int rc = SLURM_SUCCESS;
643 char *extra = NULL, *query = NULL, *name_char = NULL;
644 time_t now = time(NULL);
645 char *user_name = NULL;
646 MYSQL_RES *result = NULL;
647 MYSQL_ROW row;
648
649 if (!fed_cond) {
650 error("we need something to change");
651 return NULL;
652 }
653
654 if (check_connection(mysql_conn) != SLURM_SUCCESS)
655 return NULL;
656
657 if (!is_user_min_admin_level(
658 mysql_conn, uid, SLURMDB_ADMIN_SUPER_USER)) {
659 errno = ESLURM_ACCESS_DENIED;
660 return NULL;
661 }
662
663 /* force to only do non-deleted federations */
664 fed_cond->with_deleted = 0;
665 _setup_federation_cond_limits(fed_cond, &extra);
666
667 if (!extra) {
668 error("Nothing to remove");
669 return NULL;
670 }
671
672 query = xstrdup_printf("select name from %s as t1 %s;",
673 federation_table, extra);
674 xfree(extra);
675 if (!(result = mysql_db_query_ret( mysql_conn, query, 0))) {
676 xfree(query);
677 return NULL;
678 }
679 rc = 0;
680 ret_list = list_create(xfree_ptr);
681
682 if (!mysql_num_rows(result)) {
683 mysql_free_result(result);
684 errno = SLURM_NO_CHANGE_IN_DATA;
685 if (debug_flags & DEBUG_FLAG_FEDR)
686 DB_DEBUG(mysql_conn->conn,
687 "didn't effect anything\n%s", query);
688 xfree(query);
689 return ret_list;
690 }
691 xfree(query);
692
693 user_name = uid_to_string((uid_t) uid);
694 while ((row = mysql_fetch_row(result))) {
695 char *object = xstrdup(row[0]);
696 list_append(ret_list, object);
697
698 if ((rc = _remove_all_clusters_from_fed(mysql_conn, object,
699 NULL)))
700 break;
701
702 xfree(name_char);
703 xstrfmtcat(name_char, "name='%s'", object);
704
705 if ((rc = remove_common(mysql_conn, DBD_REMOVE_FEDERATIONS, now,
706 user_name, federation_table, name_char,
707 NULL, NULL, ret_list, NULL)))
708 break;
709 }
710 mysql_free_result(result);
711 xfree(user_name);
712 xfree(name_char);
713
714 if (rc != SLURM_SUCCESS) {
715 FREE_NULL_LIST(ret_list);
716 return NULL;
717 } else
718 as_mysql_add_feds_to_update_list(mysql_conn);
719
720 return ret_list;
721 }
722
as_mysql_add_feds_to_update_list(mysql_conn_t * mysql_conn)723 extern int as_mysql_add_feds_to_update_list(mysql_conn_t *mysql_conn)
724 {
725 int rc = SLURM_ERROR;
726 List feds = as_mysql_get_federations(mysql_conn, 0, NULL);
727
728 /* Even if there are no feds, need to send an empty list for the case
729 * that all feds were removed. The controller needs to know that it was
730 * removed from a federation. */
731 if (feds &&
732 ((rc = addto_update_list(mysql_conn->update_list,
733 SLURMDB_UPDATE_FEDS, feds))
734 != SLURM_SUCCESS)) {
735 FREE_NULL_LIST(feds);
736 }
737 return rc;
738 }
739