Exemplo n.º 1
0
GError *
meta1_backend_user_info(struct meta1_backend_s *m1,
                        struct hc_url_s *url, gchar ***result)
{
    struct sqlx_sqlite3_s *sq3 = NULL;
    GError *err = _open_and_lock(m1, url, SQLX_OPEN_MASTERSLAVE, &sq3);
    if (!err) {
        struct hc_url_s **urls = NULL;
        if (!(err = __info_user(sq3, url, FALSE, &urls))) {
            if (result) {
                if (!urls)
                    *result = g_malloc0(sizeof(struct hc_url_s*));
                else {
                    *result = g_malloc0(sizeof(gchar*) * (1+g_strv_length((gchar**)urls)));
                    for (int i=0; urls[i] ; ++i)
                        (*result)[i] = g_strdup(hc_url_get(urls[i], HCURL_WHOLE));
                }
            }
        }
        hc_url_cleanv (urls);
        sqlx_repository_unlock_and_close_noerror(sq3);
    }

    return err;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
GError *
meta1_backend_services_link (struct meta1_backend_s *m1,
                             struct oio_url_s *url, const char *srvtype,
                             gboolean dryrun, gboolean autocreate,
                             gchar ***result)
{
    struct sqlx_sqlite3_s *sq3 = NULL;
    GError *err = _open_and_lock(m1, url, M1V2_OPENBASE_MASTERONLY, &sq3);
    if (err) return err;

    struct sqlx_repctx_s *repctx = NULL;
    if (!(err = sqlx_transaction_begin(sq3, &repctx))) {
        gboolean renewed = FALSE;
        if (!(err = __info_user(sq3, url, autocreate, NULL))) {
            enum m1v2_getsrv_e mode = dryrun ? M1V2_GETSRV_DRYRUN : M1V2_GETSRV_REUSE;
            err = __get_container_service(sq3, url, srvtype, m1, mode, result, &renewed);
            if (NULL != err)
                g_prefix_error(&err, "Query error: ");
        }
        if (!(err = sqlx_transaction_end(repctx, err))) {
            if (renewed)
                __notify_services_by_cid(m1, sq3, url);
        }
    }

    sqlx_repository_unlock_and_close_noerror(sq3);
    return err;
}
Exemplo n.º 4
0
GError *
meta1_backend_services_list(struct meta1_backend_s *m1,
                            struct oio_url_s *url, const char *srvtype, gchar ***result)
{
    struct sqlx_sqlite3_s *sq3 = NULL;
    GError *err = _open_and_lock(m1, url, M1V2_OPENBASE_MASTERSLAVE, &sq3);
    if (err) return err;

    struct sqlx_repctx_s *repctx = NULL;
    if (!(err = sqlx_transaction_begin(sq3, &repctx))) {
        if (!(err = __info_user(sq3, url, FALSE, NULL))) {
            struct meta1_service_url_s **uv = NULL;
            err = __get_container_all_services(sq3, url, srvtype, &uv);
            if (NULL != err)
                g_prefix_error(&err, "Query error: ");
            else {
                struct meta1_service_url_s **expanded;
                expanded = expand_urlv(uv);
                *result = pack_urlv(expanded);
                meta1_service_url_cleanv(expanded);
                meta1_service_url_cleanv(uv);
            }
        }
        err = sqlx_transaction_end(repctx, err);
    }

    sqlx_repository_unlock_and_close_noerror(sq3);
    return err;
}
Exemplo n.º 5
0
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;
}
GError *
meta1_backend_set_container_properties(struct meta1_backend_s *m1,
		struct oio_url_s *url, gchar **props, gboolean flush)
{
	EXTRA_ASSERT(props != NULL);

	GError *err;
	if (NULL != (err = __check_property_format(props))) {
		g_prefix_error(&err, "Malformed properties: ");
		return err;
	}

	struct sqlx_sqlite3_s *sq3 = NULL;
	err = _open_and_lock(m1, url, M1V2_OPENBASE_MASTERONLY, &sq3);
	if (err) return err;

	struct sqlx_repctx_s *repctx = NULL;
	if (!(err = sqlx_transaction_begin(sq3, &repctx))) {
		if (!(err = __info_user(sq3, url, FALSE, NULL))) {
			if (flush) {
				err = __del_container_properties(sq3, url, NULL);
				if (err) g_prefix_error(&err, "Flush error: ");
			}
			if (!err) {
				err = __set_container_properties(sq3, url, props);
				if (err) g_prefix_error(&err, "Set error: ");
			}
		}
		err = sqlx_transaction_end(repctx, err);
	}

	sqlx_repository_unlock_and_close_noerror(sq3);
	return err;
}
Exemplo n.º 7
0
GError*
meta1_backend_services_unlink(struct meta1_backend_s *m1,
		struct oio_url_s *url, const char *srvtype, gchar **urlv)
{
	GError *err = __check_backend_events (m1);
	if (err) return err;

	EXTRA_ASSERT(srvtype != NULL);
	struct sqlx_sqlite3_s *sq3 = NULL;
	err = _open_and_lock(m1, url, M1V2_OPENBASE_MASTERONLY, &sq3);
	if (err) return err;

	struct sqlx_repctx_s *repctx = NULL;
	if (!(err = sqlx_transaction_begin(sq3, &repctx))) {
		if (!(err = __info_user(sq3, url, FALSE, NULL))) {
			err = __del_container_services(sq3, url, srvtype, urlv);
			if (NULL != err)
				g_prefix_error(&err, "Query error: ");
		}
		if (!(err = sqlx_transaction_end(repctx, err)))
			__notify_services_by_cid(m1, sq3, url);
	}

	sqlx_repository_unlock_and_close_noerror(sq3);
	return err;
}
Exemplo n.º 8
0
GError *
meta1_backend_user_destroy(struct meta1_backend_s *m1,
                           struct hc_url_s *url, gboolean force)
{
    struct sqlx_sqlite3_s *sq3 = NULL;
    GError *err = _open_and_lock(m1, url, SQLX_OPEN_MASTERONLY, &sq3);
    if (!err) {
        gboolean done = FALSE;
        if (!(err = __info_user(sq3, url, FALSE, NULL)))
            err = __destroy_container(sq3, url, force, &done);
        if (NULL != err)
            g_prefix_error(&err, "Query error: ");
        sqlx_repository_unlock_and_close_noerror(sq3);
    }

    return err;
}
Exemplo n.º 9
0
static void
__notify_services_by_cid(struct meta1_backend_s *m1, struct sqlx_sqlite3_s *sq3,
                         struct oio_url_s *url)
{
    struct oio_url_s **urls = NULL;
    sqlx_exec (sq3->db, "BEGIN");
    GError *err = __info_user(sq3, url, FALSE, &urls);
    if (!err) {
        oio_url_set (urls[0], OIOURL_NS, m1->ns_name);
        err = __notify_services(m1, sq3, url);
    }
    sqlx_exec (sq3->db, "ROLLBACK");
    oio_url_cleanv (urls);

    if (err) {
        GRID_WARN("Failed to notify the services for [%s]: %s",
                  oio_url_get(url, OIOURL_HEXID), err->message);
        g_clear_error(&err);
    }
}
GError *
meta1_backend_get_container_properties(struct meta1_backend_s *m1,
		struct oio_url_s *url, gchar **names, gchar ***result)
{
	EXTRA_ASSERT(result != NULL);

	struct sqlx_sqlite3_s *sq3 = NULL;
	GError *err = _open_and_lock(m1, url, M1V2_OPENBASE_MASTERSLAVE, &sq3);
	if (err) return err;

	struct sqlx_repctx_s *repctx = NULL;
	if (!(err = sqlx_transaction_begin(sq3, &repctx))) {
		if (!(err = __info_user(sq3, url, FALSE, NULL))) {
			err = __get_container_properties(sq3, url, names, result);
			if (err) g_prefix_error(&err, "Lookup error: ");
		}
		err = sqlx_transaction_end(repctx, err);
	}

	sqlx_repository_unlock_and_close_noerror(sq3);
	return err;
}
Exemplo n.º 11
0
GError *
meta1_backend_user_create(struct meta1_backend_s *m1,
                          struct hc_url_s *url)
{
    EXTRA_ASSERT(url != NULL);
    if (!hc_url_has_fq_container (url))
        return NEWERROR(CODE_BAD_REQUEST, "Partial URL");

    struct sqlx_sqlite3_s *sq3 = NULL;
    GError *err = _open_and_lock(m1, url, SQLX_OPEN_MASTERONLY, &sq3);
    if (!err) {
        if (!(err = __info_user(sq3, url, FALSE, NULL)))
            err = NEWERROR(CODE_CONTAINER_EXISTS, "User already created");
        else {
            g_clear_error(&err);
            if (NULL != (err = __create_user(sq3, url)))
                g_prefix_error(&err, "Query error: ");
        }
        sqlx_repository_unlock_and_close_noerror(sq3);
    }

    return err;
}
Exemplo n.º 12
0
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;
}