int meta2_filter_action_create_container(struct gridd_filter_ctx_s *ctx, struct gridd_reply_ctx_s *reply) { (void) reply; struct m2v2_create_params_s params = {NULL,NULL,NULL,0}; struct meta2_backend_s *m2b = meta2_filter_ctx_get_backend(ctx); struct hc_url_s *url = meta2_filter_ctx_get_url(ctx); GError *err = NULL; int retry = 2; params.storage_policy = meta2_filter_ctx_get_param(ctx, NAME_MSGKEY_STGPOLICY); params.version_policy = meta2_filter_ctx_get_param(ctx, NAME_MSGKEY_VERPOLICY); params.local = (meta2_filter_ctx_get_param(ctx, NAME_MSGKEY_LOCAL) != NULL); gchar **headers = metautils_message_get_field_names (reply->request); GPtrArray *tmp = g_ptr_array_new (); for (gchar **p=headers; *p ;++p) { if (!g_str_has_prefix(*p, NAME_MSGKEY_PREFIX_PROPERTY)) continue; g_ptr_array_add (tmp, g_strdup((*p) + sizeof(NAME_MSGKEY_PREFIX_PROPERTY) - 1)); g_ptr_array_add (tmp, metautils_message_extract_string_copy (reply->request, *p)); } params.properties = (gchar**) metautils_gpa_to_array (tmp, TRUE); g_strfreev (headers); headers = NULL; retry: err = meta2_backend_create_container(m2b, url, ¶ms); if (err != NULL && err->code == CODE_REDIRECT && retry-- > 0 && !g_strcmp0(err->message, meta2_backend_get_local_addr(m2b))) { GRID_WARN("Redirecting on myself!?! Retrying request immediately"); g_clear_error(&err); hc_decache_reference_service(m2b->resolver, url, NAME_SRVTYPE_META2); goto retry; } g_strfreev (params.properties); params.properties = NULL; if (!err) return FILTER_OK; meta2_filter_ctx_set_error(ctx, err); return FILTER_KO; }
GError * gridd_client_exec4 (const gchar *to, gdouble seconds, GByteArray *req, GByteArray ***out) { if (!to) { g_byte_array_unref (req); return NEWERROR(CODE_INTERNAL_ERROR, "No target"); } GPtrArray *tmp = NULL; if (out) tmp = g_ptr_array_new(); struct gridd_client_s *client = gridd_client_create(to, req, (out ? tmp : NULL), out ? (client_on_reply)_cb_exec4 : NULL); g_byte_array_unref (req); if (!client) { if (tmp) g_ptr_array_free (tmp, TRUE); return NEWERROR(CODE_INTERNAL_ERROR, "client creation"); } if (seconds > 0.0) gridd_client_set_timeout (client, seconds); GError *err = gridd_client_run (client); gridd_client_free (client); if (!err && out) { *out = (GByteArray**) metautils_gpa_to_array (tmp, TRUE); tmp = NULL; } if (tmp) { g_ptr_array_set_free_func (tmp, (GDestroyNotify)g_byte_array_unref); g_ptr_array_free (tmp, TRUE); tmp = NULL; } return err; }
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; }