Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}