static GError * __get_container_service(struct sqlx_sqlite3_s *sq3, struct oio_url_s *url, const char *srvtype, struct meta1_backend_s *m1, enum m1v2_getsrv_e mode, gchar ***result, gboolean *renewed) { GError *err = NULL; struct compound_type_s ct; if (NULL != (err = compound_type_parse(&ct, srvtype))) return err; err = __get_container_service2(sq3, url, &ct, m1, mode, result, renewed); compound_type_clean(&ct); return err; }
static GError* _get_iterator2(struct meta1_backend_s *m1, const char *srvtype, struct grid_lb_iterator_s **result) { struct compound_type_s ct = {0}; *result = NULL; GError *err = compound_type_parse(&ct, srvtype); if (NULL != err) { g_prefix_error(&err, "Type parsing error: "); return err; } err = _get_iterator(m1, &ct, result); if (err) g_prefix_error(&err, "LB error: "); compound_type_clean(&ct); return err; }
GError* meta1_backend_services_relink(struct meta1_backend_s *m1, struct oio_url_s *url, const char *kept, const char *replaced, gboolean dryrun, gchar ***out) { GError *err = NULL; struct meta1_service_url_s **ukept = NULL, **urepl = NULL; /* fields to be prefetched */ struct grid_lb_iterator_s *iterator = NULL; struct compound_type_s ct; memset (&ct, 0, sizeof(ct)); ukept = __parse_and_expand (kept); urepl = __parse_and_expand (replaced); /* Sanity checks: we must receive at least one service */ if ((!ukept || !*ukept) && (!urepl || !*urepl)) { err = NEWERROR (CODE_BAD_REQUEST, "Missing URL set"); goto out; } /* Sanity check : all the services must have the same <seq,type> */ struct meta1_service_url_s *ref = ukept && *ukept ? *ukept : *urepl; for (struct meta1_service_url_s **p = ukept; p && *p ; ++p) { if (0 != _sorter(p, &ref)) { err = NEWERROR(CODE_BAD_REQUEST, "Mismatch in URL set (%s)", "kept"); goto out; } } for (struct meta1_service_url_s **p = urepl; p && *p ; ++p) { if (0 != _sorter(p, &ref)) { err = NEWERROR(CODE_BAD_REQUEST, "Mismatch in URL set (%s)", "kept"); goto out; } } /* prefetch some fields from the backend: the compound type (so it is * parsed only once), the iterator (so we can already poll services, out * of the sqlite3 transaction) */ if (NULL != (err = compound_type_parse(&ct, ref->srvtype))) { err = NEWERROR(CODE_BAD_REQUEST, "Invalid service type"); goto out; } if (NULL != (err = _get_iterator (m1, &ct, &iterator))) { err = NEWERROR(CODE_BAD_REQUEST, "Service type not managed"); goto out; } /* Call the backend logic now */ struct sqlx_sqlite3_s *sq3 = NULL; struct sqlx_repctx_s *repctx = NULL; if (!(err = _open_and_lock(m1, url, M1V2_OPENBASE_MASTERONLY, &sq3))) { if (!(err = sqlx_transaction_begin(sq3, &repctx))) { if (!(err = __info_user(sq3, url, FALSE, NULL))) { struct m1v2_relink_input_s in = { .m1 = m1, .sq3 = sq3, .url = url, .iterator = iterator, .ct = &ct, .kept = ukept, .replaced = urepl, .dryrun = dryrun }; err = __relink_container_services(&in, out); } if (!(err = sqlx_transaction_end(repctx, err))) { if (!dryrun) __notify_services_by_cid(m1, sq3, url); } } sqlx_repository_unlock_and_close_noerror(sq3); } out: meta1_service_url_cleanv (ukept); meta1_service_url_cleanv (urepl); grid_lb_iterator_clean (iterator); compound_type_clean (&ct); return err; }