GError*
meta1_backend_services_set(struct meta1_backend_s *m1,
                           struct oio_url_s *url, const char *packedurl,
                           gboolean autocreate, gboolean force)
{
    struct meta1_service_url_s *m1url;
    if (!(m1url = meta1_unpack_url(packedurl)))
        return NEWERROR(CODE_BAD_REQUEST, "Invalid URL");

    struct sqlx_sqlite3_s *sq3 = NULL;
    GError *err = _open_and_lock(m1, url, M1V2_OPENBASE_MASTERONLY, &sq3);
    if (err) {
        g_free(m1url);
        return err;
    }

    struct sqlx_repctx_s *repctx = NULL;
    if (!(err = sqlx_transaction_begin(sq3, &repctx))) {
        if (!(err = __info_user(sq3, url, autocreate, NULL)))
            err = __save_service(sq3, url, m1url, force);
        if (!(err = sqlx_transaction_end(repctx, err)))
            __notify_services_by_cid(m1, sq3, url);
    }

    sqlx_repository_unlock_and_close_noerror(sq3);
    g_free(m1url);

    /* XXX JFS: ugly quirk until we find a pretty way to distinguish the
     * commit errors (e.g. it can fail because of a replication error or
     * a constraint violation) */
    if (err && NULL != strstr(err->message, "UNIQUE"))
        err->code = CODE_SRV_ALREADY;

    return err;
}
static struct meta1_service_url_s *
__poll_services(struct meta1_backend_s *m1, guint replicas,
                struct compound_type_s *ct, guint seq,
                struct meta1_service_url_s **used, GError **err)
{
    GRID_DEBUG("Polling %u [%s]", replicas, ct->fulltype);

    // ----------------------------------------------------------------------
    GPtrArray *ids = g_ptr_array_new_with_free_func(g_free);
    oio_location_t *avoid = __locations_from_m1srvurl(used);
    oio_location_t *known = NULL;
    if (ct->req.k && !strcmp(ct->req.k, NAME_TAGNAME_USER_IS_SERVICE)) {
        gchar srvurl[64] = {0};
        g_snprintf(srvurl, sizeof(srvurl), "1||%s|", ct->req.v);
        struct meta1_service_url_s *inplace[2] = {
            meta1_unpack_url(srvurl), NULL
        };
        /* If ct->req.v is not an addr, known will contain NULL */
        // FIXME: this should be in `avoid` instead of `known`
        // but avoids are compared without the location mask
        known = __locations_from_m1srvurl(inplace);
        meta1_service_url_clean(inplace[0]);
    }
    void _on_id(oio_location_t loc, const char *id)
    {
        (void)loc;
        g_ptr_array_add(ids, g_strdup(id));
    }
Exemple #3
0
static GError *
_m1_action (struct req_args_s *args, gchar ** m1v,
	GError * (*hook) (const gchar * m1))
{
	for (gchar ** pm1 = m1v; *pm1; ++pm1) {
		struct meta1_service_url_s *m1 = meta1_unpack_url (*pm1);
		if (!m1)
			continue;
		if (0 != g_ascii_strcasecmp(m1->srvtype, "meta1")) {
			meta1_service_url_clean (m1);
			continue;
		}

		struct addr_info_s m1a;
		if (!grid_string_to_addrinfo (m1->host, NULL, &m1a)) {
			GRID_INFO ("Invalid META1 [%s] for [%s]",
				m1->host, hc_url_get (args->url, HCURL_WHOLE));
			meta1_service_url_clean (m1);
			continue;
		}

		GError *err = hook (m1->host);
		meta1_service_url_clean (m1);
		if (!err)
			return NULL;
		else if (err->code == CODE_REDIRECT)
			g_clear_error (&err);
		else {
			g_prefix_error (&err, "META1 error: ");
			return err;
		}
	}
	return NEWERROR (CODE_UNAVAILABLE, "No meta1 answered");
}
GError*
meta1_backend_services_config(struct meta1_backend_s *m1,
                              struct oio_url_s *url, const char *packedurl)
{
    struct meta1_service_url_s *m1url;
    if (!(m1url = meta1_unpack_url(packedurl)))
        return NEWERROR(CODE_BAD_REQUEST, "Invalid URL");

    GRID_DEBUG("About to reconfigure [%s] [%"G_GINT64_FORMAT"] [%s] [%s]",
               m1url->srvtype, m1url->seq, m1url->host, m1url->args);

    struct sqlx_sqlite3_s *sq3 = NULL;
    GError *err = _open_and_lock(m1, url, M1V2_OPENBASE_MASTERONLY, &sq3);
    if (err) {
        g_free(m1url);
        return err;
    }

    struct sqlx_repctx_s *repctx = NULL;
    if (!(err = sqlx_transaction_begin(sq3, &repctx))) {
        if (!(err = __info_user(sq3, url, FALSE, NULL)))
            err = __configure_service(sq3, url, m1url);
        if (!(err = sqlx_transaction_end(repctx, err)))
            __notify_services_by_cid(m1, sq3, url);
    }

    sqlx_repository_unlock_and_close_noerror(sq3);
    g_free(m1url);
    return err;
}
Exemple #5
0
gchar *
meta1_strurl_get_address(const gchar *str)
{
	struct meta1_service_url_s *u = meta1_unpack_url(str);
	gchar *s = g_strdup(u->host);
	g_free(u);
	return s;
}
static struct meta1_service_url_s *
__poll_services(struct meta1_backend_s *m1, guint replicas,
                struct compound_type_s *ct, guint seq,
                struct meta1_service_url_s **used, GError **err)
{
    struct grid_lb_iterator_s *iter = NULL;
    struct service_info_s **siv = NULL;

    GRID_DEBUG("Polling %u [%s]", replicas, ct->fulltype);

    if (!(*err = _get_iterator(m1, ct, &iter))) {
        struct lb_next_opt_ext_s opt;
        memset(&opt, 0, sizeof(opt));
        opt.req.distance = MACRO_COND(replicas>1,1,0);
        opt.req.max = replicas;
        opt.req.duplicates = FALSE;
        opt.req.stgclass = NULL;
        opt.req.strict_stgclass = TRUE;
        opt.srv_forbidden = __srvinfo_from_m1srvurl(m1->lb, ct->baretype, used);

        if (ct->req.k && !strcmp(ct->req.k, NAME_TAGNAME_USER_IS_SERVICE)) {
            gchar *srvurl = g_strdup_printf("1||%s|", ct->req.v);
            struct meta1_service_url_s *inplace[2] = {
                meta1_unpack_url(srvurl), NULL
            };
            /* If ct->req.v is not an addr, srv_inplace will contain NULL */
            opt.srv_inplace = __srvinfo_from_m1srvurl(m1->lb, NULL, inplace);
            opt.req.distance = 1;
            meta1_service_url_clean(inplace[0]);
            g_free(srvurl);
        } else {
            opt.filter.hook = _filter_tag;
            opt.filter.data = ct;
        }

        if (!grid_lb_iterator_next_set2(iter, &siv, &opt)) {
            EXTRA_ASSERT(siv == NULL);
            *err = NEWERROR(CODE_POLICY_NOT_SATISFIABLE, "No service available");
        }

        grid_lb_iterator_clean(iter);
        iter = NULL;
        g_slist_free_full(opt.srv_forbidden, (GDestroyNotify)service_info_clean);
        g_slist_free_full(opt.srv_inplace, (GDestroyNotify)service_info_clean);
    }

    if(NULL != *err)
        return NULL;

    struct meta1_service_url_s *m1u = _siv_to_url (siv);
    service_info_cleanv(siv, FALSE);
    siv = NULL;
    g_strlcpy(m1u->srvtype, ct->type, sizeof(m1u->srvtype));
    m1u->seq = seq;
    return m1u;
}
Exemple #7
0
gboolean
meta1_strurl_get_address(const gchar *str, struct addr_info_s *dst)
{
	gboolean rc;
	struct meta1_service_url_s *u;

	u = meta1_unpack_url(str);
	rc = meta1_url_get_address(u, dst);
	g_free(u);

	return rc;
}
Exemple #8
0
static GString *
_pack_m1url_list (GString *gstr, gchar ** urlv)
{
	if (!gstr)
		gstr = g_string_new ("");
	g_string_append_c (gstr, '[');
	for (gchar ** v = urlv; v && *v; v++) {
		struct meta1_service_url_s *m1 = meta1_unpack_url (*v);
		meta1_service_url_encode_json (gstr, m1);
		meta1_service_url_clean (m1);
		if (*(v + 1))
			g_string_append_c (gstr, ',');
	}
	g_string_append_c (gstr, ']');
	return gstr;
}
Exemple #9
0
static void
cli_action(void)
{
	/* Use the client to get a sqlx service */
	GRID_DEBUG("Locating [%s] CID[%s]", oio_url_get(url, OIOURL_WHOLE),
			oio_url_get(url, OIOURL_HEXID));

	gchar **srvurlv = NULL;
	GError *err = hc_resolve_reference_service(resolver, url, type, &srvurlv);
	if (err != NULL) {
		GRID_ERROR("Services resolution error: (%d) %s", err->code, err->message);
		grid_main_set_status(1);
		return;
	}

	if (!srvurlv || !*srvurlv) {
		GRID_ERROR("Services resolution error: (%d) %s", 0, "No service found");
		grid_main_set_status(1);
		return;
	}

	for (gchar **s=srvurlv; *s ;s++)
		GRID_DEBUG("Located [%s]", *s);

	gint rc = 0;
	for (gchar **s=srvurlv; !rc && *s ;s++) {
		struct meta1_service_url_s *surl;
		if (!(surl = meta1_unpack_url(*s)))
			g_printerr("Invalid service URL from meta1 [%s]\n", *s);
		else {
			if (!g_ascii_strcasecmp("destroy", query[0])) {
				rc = do_destroy2(surl);
			} else {
				rc = do_queryv(surl);
			}
			g_free(surl);
		}
	}

	g_strfreev(srvurlv);
}