static GError * __get_container_service2(struct sqlx_sqlite3_s *sq3, struct oio_url_s *url, struct compound_type_s *ct, struct meta1_backend_s *m1, enum m1v2_getsrv_e mode, gchar ***result, gboolean *renewed) { GError *err = NULL; struct meta1_service_url_s **used = NULL; enum service_update_policy_e policy; guint replicas; struct service_update_policies_s *pol; if (!(pol = meta1_backend_get_svcupdate(m1))) return NEWERROR(CODE_POLICY_NOT_SATISFIABLE, "Bad NS/Policy pair"); policy = service_howto_update(pol, ct->baretype); replicas = service_howmany_replicas(pol, ct->baretype); replicas = (replicas > 0 ? replicas : 1); // Patches the constraint on the service type (if not set in the request) // by the constraint set in the NS-wide storage policy. compound_type_update_arg(ct, pol, FALSE); /* This special "tag" is used for services types that are to be linked * to containers belonging to other services (e.g. there is a container * for each rawx in the special "_RDIR" account). It tells the load * balancer to compare the location of linked service against the * location of the container owner. */ if (ct->req.k && !strcmp(ct->req.k, NAME_TAGNAME_USER_IS_SERVICE) && (!ct->req.v || !ct->req.v[0])) { oio_str_replace(&(ct->req.v), oio_url_get(url, OIOURL_USER)); } err = __get_container_all_services(sq3, url, ct->type, &used); if (NULL != err) { g_prefix_error(&err, "Preliminary lookup error : "); return err; } if (used && !*used) { g_free(used); used = NULL; } if (used && (mode != M1V2_GETSRV_RENEW)) { /* Only keep the services UP, if not forced to renew */ struct meta1_service_url_s **up = __get_services_up(m1, used); if (up && *up) { *result = pack_urlv(up); meta1_service_url_cleanv(up); meta1_service_url_cleanv(used); return NULL; } meta1_service_url_cleanv(up); } if (used && (mode == M1V2_GETSRV_REUSE || policy == SVCUPD_KEEP)) { /* Services used but unavailable, but we are told to reuse */ *result = pack_urlv(used); meta1_service_url_cleanv(used); return err; } /* No service available, poll a new one */ struct meta1_service_url_s *m1_url = NULL; gint seq = urlv_get_max_seq(used); seq = (seq<0 ? 1 : seq+1); if (NULL != (m1_url = __poll_services(m1, replicas, ct, seq, used, &err))) { if (mode != M1V2_GETSRV_DRYRUN) { if (NULL == err) { if (policy == SVCUPD_REPLACE) err = __delete_service(sq3, url, ct->type); if (NULL == err) err = __save_service(sq3, url, m1_url, TRUE); } } if (!err && result) { struct meta1_service_url_s **unpacked = expand_url(m1_url); *result = pack_urlv(unpacked); meta1_service_url_cleanv(unpacked); if (renewed) *renewed = TRUE; } g_free(m1_url); } meta1_service_url_cleanv(used); return err; }
static GError * __get_container_service2(struct sqlx_sqlite3_s *sq3, struct oio_url_s *url, struct compound_type_s *ct, struct meta1_backend_s *m1, enum m1v2_getsrv_e mode, gchar ***result, gboolean *renewed) { GError *err = NULL; struct meta1_service_url_s **used = NULL; enum service_update_policy_e policy; guint replicas; struct service_update_policies_s *pol; if (!(pol = meta1_backend_get_svcupdate(m1))) return NEWERROR(CODE_POLICY_NOT_SATISFIABLE, "Bad NS/Policy pair"); policy = service_howto_update(pol, ct->baretype); replicas = service_howmany_replicas(pol, ct->baretype); replicas = (replicas > 0 ? replicas : 1); // Patches the constraint on the service type (if not set in the request) // by the constraint set in the NS-wide storage policy. compound_type_update_arg(ct, pol, FALSE); err = __get_container_all_services(sq3, url, ct->type, &used); if (NULL != err) { g_prefix_error(&err, "Preliminary lookup error : "); return err; } if (used && !*used) { g_free(used); used = NULL; } if (used && (mode != M1V2_GETSRV_RENEW)) { /* Only keep the services UP, if not forced to renew */ struct meta1_service_url_s **up = __get_services_up(m1, used); if (up && *up) { *result = pack_urlv(up); meta1_service_url_cleanv(up); meta1_service_url_cleanv(used); return NULL; } meta1_service_url_cleanv(up); } if (used && (mode == M1V2_GETSRV_REUSE || policy == SVCUPD_KEEP)) { /* Services used but unavailable, but we are told to reuse */ *result = pack_urlv(used); meta1_service_url_cleanv(used); return err; } /* No service available, poll a new one */ struct meta1_service_url_s *m1_url = NULL; gint seq = urlv_get_max_seq(used); seq = (seq<0 ? 1 : seq+1); if (NULL != (m1_url = __poll_services(m1, replicas, ct, seq, used, &err))) { if (mode != M1V2_GETSRV_DRYRUN) { if (NULL == err) { if (policy == SVCUPD_REPLACE) err = __delete_service(sq3, url, ct->type); if (NULL == err) err = __save_service(sq3, url, m1_url, TRUE); } } if (!err && result) { struct meta1_service_url_s **unpacked = expand_url(m1_url); *result = pack_urlv(unpacked); meta1_service_url_cleanv(unpacked); if (renewed) *renewed = TRUE; } g_free(m1_url); } meta1_service_url_cleanv(used); return err; }