static GError* _client_connect(struct gridd_client_s *client) { GError *err = NULL; client->fd = _connect(client->url, &err); if (client->fd < 0) { EXTRA_ASSERT(err != NULL); g_prefix_error(&err, "Connect error: "); return err; } EXTRA_ASSERT(err == NULL); g_get_current_time(&(client->tv_step)); client->step = CONNECTING; return NULL; }
void sqlx_name_dup (struct sqlx_name_mutable_s *dst, const struct sqlx_name_s *src) { EXTRA_ASSERT(dst != NULL && src != NULL); oio_str_replace (&dst->ns, src->ns); oio_str_replace (&dst->base, src->base); oio_str_replace (&dst->type, src->type); }
sqlx_cache_t * sqlx_cache_set_close_hook(sqlx_cache_t *cache, sqlx_cache_close_hook hook) { EXTRA_ASSERT(cache != NULL); cache->close_hook = hook; return cache; }
void hc_resolver_flush_services(struct hc_resolver_s *r) { EXTRA_ASSERT(r != NULL); g_mutex_lock(&r->lock); _lru_flush(r->services.cache); g_mutex_unlock(&r->lock); }
static GError * _m0_remote_m0info (const char *m0, GByteArray *req, GSList **out) { EXTRA_ASSERT (m0 != NULL); EXTRA_ASSERT (out != NULL); GSList *result = NULL; GError *e = gridd_client_exec_and_decode (m0, M0V2_CLIENT_TIMEOUT, req, &result, meta0_info_unmarshall); if (!e) { *out = result; return NULL; } else { g_slist_free_full (result, (GDestroyNotify)meta0_info_clean); *out = NULL; return e; } }
void hc_resolver_set_now(struct hc_resolver_s *r, time_t now) { EXTRA_ASSERT(r != NULL); g_mutex_lock(&r->lock); r->bogonow = now; g_mutex_unlock(&r->lock); }
void hc_resolver_flush_csm0(struct hc_resolver_s *r) { EXTRA_ASSERT(r != NULL); g_mutex_lock(&r->lock); _lru_flush(r->csm0.cache); g_mutex_unlock(&r->lock); }
GError * meta2_backend_init(struct meta2_backend_s **result, struct sqlx_repository_s *repo, const gchar *ns, struct grid_lbpool_s *glp, struct hc_resolver_s *resolver) { GError *err = NULL; struct meta2_backend_s *m2 = NULL; gsize s; EXTRA_ASSERT(result != NULL); EXTRA_ASSERT(glp != NULL); EXTRA_ASSERT(repo != NULL); EXTRA_ASSERT(resolver != NULL); m2 = g_malloc0(sizeof(struct meta2_backend_s)); s = metautils_strlcpy_physical_ns(m2->backend.ns_name, ns, sizeof(m2->backend.ns_name)); if (sizeof(m2->backend.ns_name) <= s) { g_free(m2); return NEWERROR(CODE_BAD_REQUEST, "Namespace too long"); } m2->backend.type = NAME_SRVTYPE_META2; m2->backend.repo = repo; m2->backend.lb = glp; m2->policies = service_update_policies_create(); g_mutex_init(&m2->nsinfo_lock); m2->flag_precheck_on_generate = TRUE; err = sqlx_repository_configure_type(m2->backend.repo, NAME_SRVTYPE_META2, schema); if (NULL != err) { meta2_backend_clean(m2); g_prefix_error(&err, "Backend init error: "); return err; } m2->resolver = resolver; GRID_DEBUG("M2V2 backend created for NS[%s] and repo[%p]", m2->backend.ns_name, m2->backend.repo); *result = m2; return NULL; }
GByteArray* sqlx_pack_QUERY_single(const struct sqlx_name_s *name, const gchar *query, gboolean autocreate) { EXTRA_ASSERT(name != NULL); EXTRA_ASSERT(query != NULL); struct Table *t = calloc(1, sizeof(Table_t)); OCTET_STRING_fromBuf(&(t->name), query, strlen(query)); struct TableSequence *ts = calloc(1, sizeof(TableSequence_t)); asn_sequence_add(&(ts->list), t); GByteArray *req = sqlx_pack_QUERY(name, query, ts, autocreate); asn_DEF_TableSequence.free_struct(&asn_DEF_TableSequence, ts, FALSE); return req; }
static gboolean _load_from_file_attr(struct attr_handle_s *attr_handle, GError ** error) { FILE *stream; struct stat chunk_stats; char lineBuf[8192]; EXTRA_ASSERT(attr_handle != NULL); EXTRA_ASSERT(attr_handle->attr_hash != NULL); /* stat the file */ if (0 > stat(attr_handle->attr_path, &chunk_stats)) { SETERRCODE(error, errno, "Attr file [%s] not found for chunk", attr_handle->attr_path); return FALSE; } stream = fopen(attr_handle->attr_path, "r"); if (!stream) { SETERRCODE(error, errno, "Failed to open stream to file [%s] : %s)", attr_handle->attr_path, strerror(errno)); return FALSE; } while (fgets(lineBuf, sizeof(lineBuf), stream)) { /* Remove trailing \n */ int line_len = strlen(lineBuf); if (lineBuf[line_len-1] == '\n') lineBuf[line_len-1] = '\0'; char **tokens = g_strsplit(lineBuf, ":", 2); if (tokens) { if (*tokens && *(tokens + 1)) { g_hash_table_insert(attr_handle->attr_hash, *tokens, *(tokens + 1)); g_free(tokens); } else g_strfreev(tokens); } } fclose(stream); return TRUE; }
gboolean meta2_backend_initiated(struct meta2_backend_s *m2) { EXTRA_ASSERT(m2 != NULL); g_mutex_lock (&m2->nsinfo_lock); gboolean rc = (NULL != m2->nsinfo); g_mutex_unlock (&m2->nsinfo_lock); return rc; }
GError * oio_events_queue_factory__create_zmq (const char *zurl, struct oio_events_queue_s **out) { EXTRA_ASSERT (zurl != NULL); EXTRA_ASSERT (out != NULL); struct _queue_AGENT_s *self = g_malloc0 (sizeof(*self)); self->vtable = &vtable_AGENT; self->queue = g_async_queue_new (); self->url = g_strdup (zurl); self->max_recv_per_round = 32; self->max_events_in_queue = OIO_EVTQ_MAXPENDING; self->procid = getpid(); *out = (struct oio_events_queue_s *) self; return NULL; }
static void _pool_unmonitor(struct gridd_client_pool_s *pool, int fd) { if (pool->fdmon >= 0) (void) epoll_ctl(pool->fdmon, EPOLL_CTL_DEL, fd, NULL); EXTRA_ASSERT(pool->active_count > 0); -- pool->active_count; pool->active_clients[fd] = NULL; }
void meta2_backend_configure_nsinfo(struct meta2_backend_s *m2, struct namespace_info_s *ni) { EXTRA_ASSERT(m2 != NULL); EXTRA_ASSERT(ni != NULL); struct namespace_info_s *old = NULL, *copy = NULL; copy = namespace_info_dup (ni); g_mutex_lock(&m2->nsinfo_lock); old = m2->nsinfo; m2->nsinfo = copy; g_mutex_unlock(&m2->nsinfo_lock); if (old) namespace_info_free (old); }
GError * network_server_run(struct network_server_s *srv) { struct endpoint_s **pu, *u; time_t now, last_update; GError *err = NULL; /* Sanity checks */ EXTRA_ASSERT(srv != NULL); for (pu=srv->endpointv; (u = *pu) ;pu++) { if (u->fd < 0) return NEWERROR(EINVAL, "DESIGN ERROR : some servers are not open"); } if (!srv->flag_continue) return NULL; for (pu=srv->endpointv; srv->flag_continue && (u = *pu) ;pu++) ARM_ENDPOINT(srv, u, EPOLL_CTL_ADD); ARM_WAKER(srv, EPOLL_CTL_ADD); _server_start_one_worker(srv, FALSE); srv->thread_events = g_thread_new("events", _thread_cb_events, srv); clock_gettime(CLOCK_MONOTONIC_COARSE, &srv->now); last_update = network_server_bogonow(srv); while (srv->flag_continue) { now = network_server_bogonow(srv); if (last_update < now) { _server_update_main_stats(srv); last_update = now; } usleep(_start_necessary_threads(srv) ? 50000 : 500000); clock_gettime(CLOCK_MONOTONIC_COARSE, &srv->now); } network_server_close_servers(srv); /* Wait for all the workers */ while (srv->workers_total) { GRID_DEBUG("Waiting for %u workers to die", srv->workers_total); usleep(200000); clock_gettime(CLOCK_MONOTONIC_COARSE, &srv->now); } srv->thread_first_worker = NULL; /* wait for the first event thread */ if (srv->thread_events) { g_thread_join(srv->thread_events); srv->thread_events = NULL; } ARM_WAKER(srv, EPOLL_CTL_DEL); GRID_DEBUG("Server %p exiting its main loop", srv); return err; }
static void _cnx_notify_close(struct network_server_s *srv) { g_mutex_lock(&srv->lock_threads); EXTRA_ASSERT(srv->cnx_clients > 0); -- srv->cnx_clients; ++ srv->cnx_close; g_mutex_unlock(&srv->lock_threads); }
void network_client_allow_input(struct network_client_s *clt, gboolean v) { EXTRA_ASSERT(clt != NULL); EXTRA_ASSERT(clt->fd >= 0); if (!clt || clt->fd < 0) return; if (!v) { if (!(clt->flags & NETCLIENT_IN_CLOSED)) clt->flags |= NETCLIENT_IN_PAUSED; } else { EXTRA_ASSERT(!(clt->flags & NETCLIENT_IN_CLOSED)); clt->flags &= ~NETCLIENT_IN_PAUSED; } }
GError* meta1_prefixes_load(struct meta1_prefixes_set_s *m1ps, const gchar *ns_name, const gchar *local_url, GArray **updated_prefixes, gboolean *meta0_ok) { GError *err = NULL; EXTRA_ASSERT(m1ps != NULL); EXTRA_ASSERT(ns_name != NULL); EXTRA_ASSERT(local_url != NULL); err = _cache_load_from_ns(m1ps, ns_name, local_url, updated_prefixes, meta0_ok); if (NULL != err) g_prefix_error(&err, "NS loading error : "); else GRID_DEBUG("Prefixes reloaded for NS[%s]", ns_name); return err; }
static gboolean _q_is_stalled (struct oio_events_queue_s *self) { struct _queue_AGENT_s *q = (struct _queue_AGENT_s*) self; EXTRA_ASSERT (q != NULL && q->vtable == &vtable_AGENT); const int l = g_async_queue_length (q->queue); const guint waiting = q->gauge_pending; return (waiting + (guint)(l>0?l:0)) >= q->max_events_in_queue; }
void oio_events_queue__send_overwritable(struct oio_events_queue_s *self, gchar *key, gchar *msg) { EXTRA_ASSERT (msg != NULL); if (VTABLE_HAS(self,struct oio_events_queue_abstract_s*,send_overwritable) && key && *key) { EVTQ_CALL(self,send_overwritable)(self,key,msg); } else {
GSList* meta0_utils_tree_to_list(GTree *byurl) { GSList *result = NULL; EXTRA_ASSERT(byurl != NULL); g_tree_foreach(byurl, _tree2list_traverser, &result); return result; }
static enum service_update_policy_e service_howto_update2(struct service_update_policies_s *pol, const struct hashstr_s *htype) { struct element_s *el; enum service_update_policy_e policy; EXTRA_ASSERT(pol != NULL); EXTRA_ASSERT(htype != NULL); policy = SVCUPD_KEEP; g_mutex_lock(&pol->lock); if (NULL != (el = g_tree_lookup(pol->tree_elements, htype))) policy = el->howto_update; g_mutex_unlock(&pol->lock); return policy; }
gchar* version_dump(GTree *t) { EXTRA_ASSERT(t != NULL); GString *gstr = g_string_new(""); if (t) g_tree_foreach(t, hook_dump, gstr); return g_string_free(gstr, FALSE); }
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; }
static void _q_set_max_pending (struct oio_events_queue_s *self, guint v) { struct _queue_BEANSTALKD_s *q = (struct _queue_BEANSTALKD_s *)self; EXTRA_ASSERT (q != NULL && q->vtable == &vtable_BEANSTALKD); if (q->max_events_in_queue != v) { GRID_INFO("max events in queue set to [%u]", v); q->max_events_in_queue = v; } }
static GError* _client_set_fd(struct gridd_client_s *client, int fd) { EXTRA_ASSERT(client != NULL); EXTRA_ASSERT(client->abstract.vtable == &VTABLE_CLIENT); if (fd >= 0) { switch (client->step) { case NONE: /* ok */ break; case CONNECTING: if (client->request != NULL) return NEWERROR(500, "Request pending"); /* PASSTHROUGH */ case CONNECTED: /* ok */ break; case REQ_SENDING: case REP_READING_SIZE: case REP_READING_DATA: return NEWERROR(500, "Request pending"); case STATUS_OK: case STATUS_FAILED: /* ok */ break; } } /* reset any connection and request */ _client_reset_reply(client); _client_reset_request(client); _client_reset_target(client); /* XXX do not call _client_reset_cnx(), or close the connexion. * It is the responsibility of the caller to manage this, because it * explicitely breaks the pending socket management. */ client->fd = fd; /* CONNECTING instead of CONNECTED helps coping with not yet * completely connected sockets */ client->step = (client->fd >= 0) ? CONNECTING : NONE; return NULL; }
const gchar * path_matching_get_variable (struct path_matching_s *self, const char *name) { EXTRA_ASSERT (self != NULL); EXTRA_ASSERT (name != NULL); gsize l = strlen (name); gchar *key = g_alloca (l+2); memcpy(key, name, l); key[l] = '='; key[l+1] = 0; for (gchar **p = self->vars; *p ;++p) { if (g_str_has_prefix (*p, key)) return (*p) + (l+1); } return NULL; }
static guint _resolver_expire(struct lru_tree_s *lru, time_t oldest) { struct cached_element_s *elt = NULL; struct hashstr_s *k = NULL; guint count = 0; while (lru_tree_get_last(lru, (void**)&k, (void**)&elt)) { EXTRA_ASSERT(k != NULL); EXTRA_ASSERT(elt != NULL); if (oldest <= elt->use) break; lru_tree_steal_last(lru, (void**)&k, (void**)&elt); metautils_pfree0(&k, NULL); metautils_pfree0(&elt, NULL); ++ count; } return count; }
GByteArray* message_marshall_gba_and_clean(MESSAGE m) { GByteArray *result; EXTRA_ASSERT(m != NULL); result = message_marshall_gba(m, NULL); metautils_message_destroy(m); return result; }
static GError* _client_request(struct gridd_client_s *client, GByteArray *req, gpointer ctx, client_on_reply cb) { EXTRA_ASSERT(client != NULL); EXTRA_ASSERT(client->abstract.vtable == &VTABLE_CLIENT); if ( NULL == req) return NEWERROR(CODE_INTERNAL_ERROR, "Invalid parameter"); switch (client->step) { case NONE: case CONNECTING: case CONNECTED: if (client->request != NULL) return NEWERROR(500, "Request already pending"); /* ok */ break; case REQ_SENDING: case REP_READING_SIZE: case REP_READING_DATA: return NEWERROR(500, "Request not terminated"); case STATUS_OK: case STATUS_FAILED: /* ok */ if (client->fd >= 0) client->step = REQ_SENDING; else client->step = CONNECTING; break; } /* if any, reset the last reply */ _client_reset_reply(client); _client_reset_request(client); _client_reset_error(client); /* Now set the new request components */ client->ctx = ctx; client->on_reply = cb; client->request = g_byte_array_ref(req); return NULL; }