Example #1
0
void
meta0_backend_migrate(struct meta0_backend_s *m0)
{
	GError *err = NULL;
	struct sqlx_sqlite3_s *handle=NULL;
	struct sqlx_sqlite3_s *oldhandle=NULL;

	struct sqlx_name_s n;
	n.base = m0->ns;
	n.type = NAME_SRVTYPE_META0;
	n.ns = m0->ns;
	err = sqlx_repository_open_and_lock(m0->repository, &n, SQLX_OPEN_LOCAL, &handle, NULL);
	if ( err )
	{
		// check if the erreur message is the ENOENT message ; DB doesn't exist
		if  (  (strstr(err->message, strerror(ENOENT)) != NULL) ) {
			g_clear_error(&err);
			err = NULL;
			err = sqlx_repository_open_and_lock(m0->repository, &n, SQLX_OPEN_LOCAL|SQLX_OPEN_CREATE,&handle, NULL);
			if( !err ) {
				// Migration (1.7 -> 1.8) from old meta0 database

				n.base = m0->id;
				err = sqlx_repository_open_and_lock(m0->repository, &n, SQLX_OPEN_LOCAL, &oldhandle,NULL);
				if ( ! err ) {
					GRID_INFO("Start Migrate meta0 database");
					err = sqlx_repository_backup_base(oldhandle,handle);
					if ( err ) {
						GRID_ERROR("Failed to migrate meta0 database : (%d) %s",err->code,err->message);
					} else {
						sqlx_repository_unlock_and_close_noerror(oldhandle);
						// APPLY schema
						gint rc;
						char *errmsg = NULL;
						rc = sqlite3_exec(handle->db, META0_SCHEMA, NULL, NULL, &errmsg);
						if (rc != SQLITE_OK && rc != SQLITE_DONE)  {
							GRID_WARN("Failed to apply schema (%d) %s %s",rc,sqlite3_errmsg(handle->db), errmsg);
						}
						if(errmsg != NULL)
							g_free(errmsg);

						// set table version
						GRID_INFO("Update version in database");
						sqlx_admin_inc_all_versions(handle, 2);
					}

				} else {
					// database 1.7  doesn't existe ; new grid
					g_clear_error(&err);
					err = NULL;
				}
			} else {
				GRID_ERROR("Failed to create meta0 database :(%d) %s",err->code,err->message);
			}
		}
	}
	if ( handle)
		sqlx_repository_unlock_and_close_noerror(handle);

}
Example #2
0
static GError*
_open_and_lock(struct meta0_backend_s *m0, enum m0v2_open_type_e how,
		struct sqlx_sqlite3_s **handle)
{
	GError *err = NULL;

	EXTRA_ASSERT(m0 != NULL);
	EXTRA_ASSERT(handle != NULL);

	/* Now open/lock the base in a way suitable for our op */
	guint flag = m0_to_sqlx(how);
	struct sqlx_name_s n = {.base=m0->ns, .type=NAME_SRVTYPE_META0, .ns=m0->ns};
	err = sqlx_repository_open_and_lock(m0->repository, &n, flag, handle, NULL);

	if (err != NULL) {
		if (!CODE_IS_REDIRECT(err->code))
			g_prefix_error(&err, "Open/Lock error: ");
		return err;
	}

	EXTRA_ASSERT(*handle != NULL);
	GRID_TRACE("Opened and locked [%s/%s]", m0->id, NAME_SRVTYPE_META0);

	return NULL;
}

static void
_unlock_and_close(struct sqlx_sqlite3_s *sq3)
{
	EXTRA_ASSERT(sq3 != NULL);
	sqlx_admin_save_lazy (sq3);
	sqlx_repository_unlock_and_close_noerror(sq3);
}
Example #3
0
static void
_round_open_close (void)
{
	sqlx_repository_t *repo = NULL;
	GError *err;

	err = sqlx_repository_init("/tmp", NULL, &repo);
	g_assert_no_error (err);
	g_assert_true (sqlx_repository_running (repo));
	err = sqlx_repository_configure_type(repo, type, SCHEMA);
	g_assert_no_error (err);
	sqlx_repository_set_locator (repo, _locator, NULL);

	for (int i=0; i<5 ;i++) {
		struct sqlx_sqlite3_s *sq3 = NULL;
		struct sqlx_name_s n = { .base = name, .type = type, .ns = nsname, };

		err = sqlx_repository_open_and_lock(repo, &n, SQLX_OPEN_LOCAL, &sq3, NULL);
		g_assert_no_error (err);
		g_assert_nonnull (sq3);

		err = sqlx_repository_unlock_and_close(sq3);
		g_assert_no_error (err);
	}

	sqlx_repository_clean(repo);
}
GError*
_open_and_lock(struct meta1_backend_s *m1, struct oio_url_s *url,
		enum m1v2_open_type_e how, struct sqlx_sqlite3_s **handle)
{
	EXTRA_ASSERT(m1 != NULL);
	EXTRA_ASSERT(url != NULL);
	EXTRA_ASSERT(handle != NULL);

	GRID_TRACE2("%s(%p,%p,%d,%p)", __FUNCTION__, (void*)m1,
			oio_url_get (url, OIOURL_HEXID), how, (void*)handle);

	if (!oio_url_has (url, OIOURL_HEXID))
		return NEWERROR (CODE_BAD_REQUEST, "Partial URL (missing HEXID)");
	if (!m1b_check_ns_url (m1, url))
		return NEWERROR(CODE_NAMESPACE_NOTMANAGED, "Invalid NS");

	gchar base[5];
	const guint8 *cid = oio_url_get_id(url);
	g_snprintf(base, sizeof(base), "%02X%02X", cid[0], cid[1]);

	if (!meta1_prefixes_is_managed(m1->prefixes, cid))
		return NEWERROR(CODE_RANGE_NOTFOUND, "prefix [%s] not managed", base);

	/* Now open/lock the base in a way suitable for our op */
	struct sqlx_name_s n = {.base=base, .type=NAME_SRVTYPE_META1, .ns=m1->ns_name};
	GError *err = sqlx_repository_open_and_lock(m1->repo, &n, m1_to_sqlx(how), handle, NULL);

	if (err != NULL) {
		if (!CODE_IS_REDIRECT(err->code))
			g_prefix_error(&err, "Open/Lock error: ");  
		return err;
	}

	EXTRA_ASSERT(*handle != NULL);
	GRID_TRACE("Opened and locked [%s][%s] -> [%s][%s]",
			base, NAME_SRVTYPE_META1,
			(*handle)->name.base, (*handle)->name.type);
	return NULL;
}

GError*
__create_user(struct sqlx_sqlite3_s *sq3, struct oio_url_s *url)
{
	if (!oio_url_has_fq_container (url))
		return NEWERROR(CODE_BAD_REQUEST, "Partial URL");

	static const gchar *sql = "INSERT INTO users ('cid','account','user') VALUES (?,?,?)";

	GError *err = NULL;
	sqlite3_stmt *stmt = NULL;
	int rc;

	EXTRA_ASSERT(sq3 != NULL);
	EXTRA_ASSERT(sq3->db != NULL);

	/* Prepare the statement */
	sqlite3_prepare_debug(rc, sq3->db, sql, -1, &stmt, NULL);
	if (rc != SQLITE_OK)
		err = M1_SQLITE_GERROR(sq3->db, rc);
	else {
		sqlite3_bind_blob(stmt, 1, oio_url_get_id(url), oio_url_get_id_size(url), NULL);
		sqlite3_bind_text(stmt, 2, oio_url_get(url, OIOURL_ACCOUNT), -1, NULL);
		sqlite3_bind_text(stmt, 3, oio_url_get(url, OIOURL_USER), -1, NULL);

		/* Run the results */
		do { rc = sqlite3_step(stmt); } while (rc == SQLITE_ROW);

		if (rc != SQLITE_OK && rc != SQLITE_DONE) {
			err = M1_SQLITE_GERROR(sq3->db, rc);
			if (rc == SQLITE_CONSTRAINT) {
				g_prefix_error(&err, "Already created? ");
				err->code = CODE_CONTAINER_EXISTS;
			}
		}

		sqlite3_finalize_debug(rc, stmt);
	}

	if (err)
		GRID_DEBUG("User creation failed : (%d) %s", err->code, err->message);

	return err;
}

GError*
__info_user(struct sqlx_sqlite3_s *sq3, struct oio_url_s *url, gboolean ac,
		struct oio_url_s ***result)
{
	GError *err = NULL;
	sqlite3_stmt *stmt = NULL;
	GPtrArray *gpa;
	int rc;
	gboolean found;

	EXTRA_ASSERT(sq3 != NULL);
	EXTRA_ASSERT(sq3->db != NULL);
	EXTRA_ASSERT(url != NULL);

retry:
	/* Prepare the statement */
	sqlite3_prepare_debug(rc, sq3->db, "SELECT account,user FROM users WHERE cid = ?", -1, &stmt, NULL);
	if (rc != SQLITE_OK)
		return M1_SQLITE_GERROR(sq3->db, rc);
	(void) sqlite3_bind_blob(stmt, 1, oio_url_get_id (url), oio_url_get_id_size (url), NULL);

	/* Run the results */
	found = FALSE;
 	gpa = result ? g_ptr_array_new() : NULL;
	do { if (SQLITE_ROW == (rc = sqlite3_step(stmt))) {
		found = TRUE;
		if (!gpa) continue;
		struct oio_url_s *u = oio_url_empty ();
		oio_url_set (u, OIOURL_NS, oio_url_get (url, OIOURL_NS));
		oio_url_set (u, OIOURL_ACCOUNT, (char*)sqlite3_column_text(stmt, 0));
		oio_url_set (u, OIOURL_USER, (char*)sqlite3_column_text(stmt, 1));
		oio_url_set (u, OIOURL_HEXID, oio_url_get (url, OIOURL_HEXID));
		g_ptr_array_add(gpa, u);
	} } while (rc == SQLITE_ROW);

	if (rc != SQLITE_DONE && rc != SQLITE_OK) {
		err = M1_SQLITE_GERROR(sq3->db, rc);
		g_prefix_error(&err, "DB error: ");
	}

	sqlite3_finalize_debug(rc,stmt);
	stmt = NULL;

	if (err) {
		if (gpa) {
			g_ptr_array_set_free_func (gpa, (GDestroyNotify)oio_url_clean);
			g_ptr_array_free (gpa, TRUE);
		}
		return err;
	}

	if (!found) {
		if (gpa) g_ptr_array_free (gpa, TRUE);
		if (ac) {
			ac = FALSE; /* do not retry */
			err = __create_user (sq3, url);
			if (!err) goto retry;
		}
		return NEWERROR(CODE_USER_NOTFOUND, "no such container");
	}
	if (gpa)
		*result = (struct oio_url_s**) metautils_gpa_to_array(gpa, TRUE);
	return NULL;
}
Example #5
0
static GError *
m2b_open(struct meta2_backend_s *m2, struct oio_url_s *url,
		enum m2v2_open_type_e how, struct sqlx_sqlite3_s **result)
{
	GError *err = NULL;
	struct sqlx_sqlite3_s *sq3 = NULL;

	EXTRA_ASSERT(url != NULL);
	EXTRA_ASSERT(result != NULL);
	EXTRA_ASSERT(m2 != NULL);
	EXTRA_ASSERT(m2->backend.repo != NULL);

	/* TODO */
	gboolean no_peers = FALSE;
	if (no_peers) {
		how &= ~M2V2_OPEN_REPLIMODE;
		how |= M2V2_OPEN_LOCAL|M2V2_OPEN_NOREFCHECK;
	}

	struct sqlx_name_mutable_s n;
	sqlx_name_fill (&n, url, NAME_SRVTYPE_META2, 1);
	err = sqlx_repository_open_and_lock(m2->backend.repo,
			sqlx_name_mutable_to_const(&n), m2_to_sqlx(how), &sq3, NULL);
	sqlx_name_clean (&n);

	if (NULL != err) {
		if (err->code == CODE_CONTAINER_NOTFOUND)
			err->domain = GQ();
		return err;
	}

	sq3->no_peers = how & (M2V2_OPEN_LOCAL|M2V2_OPEN_NOREFCHECK);

	// XXX If the container is being deleted, this is sad ...
	// This MIGHT happen if a cache is present (and this is the
	// common case for m2v2), because the deletion will happen
	// when the base exit the cache.
	// In facts this SHOULD NOT happend because a base being deleted
	// is closed with an instruction to exit the cache immediately.
	// TODO FIXME this is maybe a good place for an assert().
	if (sq3->deleted) {
		err = NEWERROR(CODE_CONTAINER_FROZEN, "destruction pending");
		m2b_close(sq3);
		return err;
	}

	// Complete URL with full VNS and container name
	void set(gchar *k, int f) {
		if (oio_url_has(url, f))
			return;
		gchar *s = sqlx_admin_get_str (sq3, k);
		if (s) {
			oio_url_set (url, f, s);
			g_free (s);
		}
	}
	set (SQLX_ADMIN_NAMESPACE, OIOURL_NS);
	set (SQLX_ADMIN_ACCOUNT, OIOURL_ACCOUNT);
	set (SQLX_ADMIN_USERNAME, OIOURL_USER);
	set (SQLX_ADMIN_USERTYPE, OIOURL_TYPE);

	*result = sq3;
	return NULL;
}