Exemple #1
0
// TODO: factorize the two following functions
enum http_rc_e
action_admin_meta0_list(struct req_args_s *args)
{
	GError *err = NULL;
	GSList *m0_lst = NULL;
	GSList *m1_lst = NULL;
	GString *json = NULL;

	err = conscience_get_services(NS(), NAME_SRVTYPE_META0, FALSE, &m0_lst);
	if (!err) {
		for (GSList *l = m0_lst; l; l = l->next) {
			g_clear_error(&err);
			service_info_t *m0 = l->data;
			gchar m0_url[STRLEN_ADDRINFO] = {0};
			grid_addrinfo_to_string(&(m0->addr), m0_url, sizeof(m0_url));

			err = meta0_remote_get_meta1_all(m0_url, &m1_lst);

			if (!err || !CODE_IS_NETWORK_ERROR(err->code))
				break;
		}
		g_slist_free_full(m0_lst, (GDestroyNotify)service_info_clean);
	}

	if (m1_lst) {
		json = _m0_mapping_from_m1_list(m1_lst);
		meta0_utils_list_clean(m1_lst);
		return _reply_json(args, HTTP_CODE_OK, "OK", json);
	}
	return _reply_common_error(args, err);
}
Exemple #2
0
static GError*
_unref_meta1(gchar **urls)
{

	GError *error = NULL;
	GSList *prefixByMeta1 = meta0_utils_array_to_list(context->array_meta1_by_prefix);
	guint8 *prefix_mask = g_malloc0(8192);

	for(;*urls;urls++) {
		addr_info_t addr;
		GRID_DEBUG("unref url %s",*urls);

		grid_string_to_addrinfo(*urls,NULL,&addr);

		GSList *l=prefixByMeta1;
		for (;l;l=l->next) {
                        struct meta0_info_s *m0info;
                        if (!(m0info = l->data))
                                continue;	

			if (addr_info_equal(&(m0info->addr),&addr)) {

				guint16 *p, *max;
                                p = (guint16*) m0info->prefixes;
                                max = (guint16*) (m0info->prefixes + m0info->prefixes_size);
                                for (; p<max; p++) {
					if (_is_treat_prefix(prefix_mask,(guint8*)p) ) {
						GRID_WARN("prefix %02X%02X manage by two meta1 present in the request",((guint8*)p)[0],((guint8*)p)[1]);
						error = NEWERROR(0, "prefix %02X%02X manage by two meta1 present in the request",((guint8*)p)[0],((guint8*)p)[1]);
						goto errorLabel;
					}
					_treat_prefix(prefix_mask,(guint8*)p);
                                }
			}
		}
		struct meta0_assign_meta1_s *aM1=NULL;

		aM1=g_hash_table_lookup(context->map_meta1_ref,*urls);
		if( !aM1) {
			aM1 = g_malloc0(sizeof(struct meta0_assign_meta1_s));

			aM1->addr=g_strdup(*urls);
			aM1->score=0;
			aM1->used=FALSE;

			g_hash_table_insert(context->map_meta1_ref,strdup(*urls),aM1);
		} else {
			aM1->used=FALSE;
		}
	}

errorLabel :
	meta0_utils_list_clean(prefixByMeta1);
	g_free(prefix_mask);

	return error;
}
Exemple #3
0
static GError *
_init_assign(gchar *ns_name, GList **working_m1list,GSList **unref_m1list)
{ 
	GError *error = NULL;
	GSList *m1_list = NULL;

	m1_list = list_namespace_services(ns_name, "meta1", &error);
	if (!m1_list) {
		if ( error) {
			GRID_ERROR("failed to init meta1 service list :(%d) %s", error->code, error->message);
			goto errorLabel;
		}
	}
	GRID_INFO("nb m1 cs %d",g_slist_length(m1_list));
	if ( context->replica > g_slist_length(m1_list)) {
		GRID_ERROR("Number of meta1 services [%d] less than number of replication [%d]",g_slist_length(m1_list),context->replica);
		error = NEWERROR(EINVAL, "Number of meta1 services [%d] less than number of replication [%d]",g_slist_length(m1_list),context->replica);
		goto errorLabel;
	}
	if ( context->replica <= 0 ) {
		GRID_ERROR("Invalid replica number [%d]",context->replica);
		error = NEWERROR(EINVAL, "Invalid replica number [%d]",context->replica);
		goto errorLabel;
	}

	// Duplicate the current prefix distribution and build a List
	GSList *prefixByMeta1 = meta0_utils_array_to_list(context->array_meta1_by_prefix);

	GSList *l=NULL;
	for (;m1_list;m1_list=m1_list->next) {

		struct meta0_assign_meta1_s *aM1;
		struct service_info_s *sInfo;
		gchar url[128];
		url[0] = '\0';

		aM1 = g_malloc0(sizeof(struct meta0_assign_meta1_s));

		sInfo=m1_list->data;

		grid_addrinfo_to_string(&(sInfo->addr), url, sizeof(url));
		aM1->addr=g_strdup(url);
		aM1->score=0;
		aM1->available=FALSE;
		aM1->used=TRUE;

		l = prefixByMeta1;
		for (;l;l=l->next) {
			struct meta0_info_s *m0info;
			if (!(m0info = l->data))
				continue;
			if (addr_info_equal(&(m0info->addr),&(sInfo->addr))) {
				guint16 *p, *max;
				guint i=0;
				GArray *pfx = g_array_new(FALSE, FALSE, 2);
				p = (guint16*) m0info->prefixes;
				max = (guint16*) (m0info->prefixes + m0info->prefixes_size);
				for (; p<max; p++) {
					i++;
					pfx=g_array_append_vals(pfx,(guint8*)p,1);
				}
				aM1->assignPrefixes=pfx;
				aM1->score=i;
				GRID_DEBUG("aM1 %s , score %d",aM1->addr,aM1->score);
				prefixByMeta1=g_slist_remove(prefixByMeta1,m0info);
				meta0_info_clean(m0info);

				break;
			}
		}
		struct meta0_assign_meta1_s *m1ref = g_hash_table_lookup(context->map_meta1_ref,aM1->addr);

		if ( m1ref && !m1ref->used) {
			// unref meta1
			aM1->used=FALSE;
			if (aM1->score != 0 ) {
				// meta1 refer always prefixe
				*unref_m1list=g_slist_prepend(*unref_m1list,aM1);
			}
		} else {
			*working_m1list = g_list_prepend(*working_m1list,aM1);
		}
		g_hash_table_insert(context->working_map_meta1_ref,strdup(aM1->addr),aM1);
	}

	GRID_TRACE("len working %d, len reste pref %d",g_list_length(*working_m1list),g_slist_length(prefixByMeta1));
	guint nb_M1 = g_list_length(*working_m1list) + g_slist_length(prefixByMeta1);

	//defined the average assign score
	if (nb_M1 == 0 ) {
		GRID_ERROR("No Meta1 available");
		error = NEWERROR(0, "No Meta1 service available");
		goto errorLabel;
	}

	context->avgscore = (65536* context->replica)/nb_M1; 
	GRID_DEBUG("average meta1 score %d",context->avgscore);

	GList *work = g_list_first(*working_m1list);
	for (;work;work=work->next) {
		struct meta0_assign_meta1_s *aM1 = work->data;
		if ( aM1->score > context->avgscore) {
			aM1->available=TRUE;
		}
	}

	GRID_DEBUG("init meta1 list, find %d meta1",g_list_length(*working_m1list));
	GRID_DEBUG("init unref meta1 list, find %d meta1",g_slist_length(*unref_m1list));

	meta0_utils_list_clean(prefixByMeta1);

errorLabel :
	if (m1_list) {
		g_slist_foreach(m1_list, service_info_gclean, NULL);
		g_slist_free(m1_list);
	}

	return error;
}