コード例 #1
0
ファイル: services_task_check.c プロジェクト: korween/oio-sds
static void
_mark_service_state(const gchar *ns_name, const gchar *srv_key, gboolean is_up)
{
	struct namespace_data_s *ns_data;
	struct service_info_s *si;

	ns_data = g_hash_table_lookup(namespaces, ns_name);
	if (!ns_data)
		return;
	
	if (is_up) {
		si = g_hash_table_lookup(ns_data->local_services, srv_key);
		if (!si) {
			/*service was DOWN*/
			si = g_hash_table_lookup(ns_data->down_services, srv_key);
			if (si && (si = service_info_dup(si))) {
				g_hash_table_remove(ns_data->down_services, srv_key);
				g_hash_table_insert(ns_data->local_services, g_strdup(srv_key), si);
				INFO("Service [%s/%s] now UP", ns_name, srv_key);
			}
		}
		else {
			si->score.timestamp = g_get_real_time() / 1000000;
			DEBUG("Service [%s/%s] still UP", ns_name, srv_key);
		}

		/*ensure the UP tag on TRUE*/
		if (si) {
			service_tag_set_value_boolean(service_info_ensure_tag(si->tags,"tag.up"), TRUE);
			si->score.timestamp = g_get_real_time() / 1000000;
		}
	}
	else {
		si = g_hash_table_lookup(ns_data->down_services, srv_key);
		if (!si) {
			/*service was maybe UP*/
			si = g_hash_table_lookup(ns_data->local_services, srv_key);
			if (si && (si = service_info_dup(si))) {
				g_hash_table_remove(ns_data->local_services, srv_key);
				g_hash_table_insert(ns_data->down_services, g_strdup(srv_key), si);
				si->score.value = -2;
			}
			INFO("Service [%s/%s] now DOWN", ns_name, srv_key);
		}
		else {
			DEBUG("Service [%s/%s] still DOWN", ns_name, srv_key);
			si->score.value = -2;
		}

		/*was it UP or not, we ensure it has ZERO stats and the right flags*/
		if (si) {
			service_tag_set_value_boolean(service_info_ensure_tag(si->tags,"tag.up"), FALSE);
			zero_service_stats(si->tags);
			invalidate_conscience_service(ns_data, si);
			DEBUG("Service [%s/%s] zeroed, invalidated, marked down", ns_name, srv_key);
		}
	}
}
コード例 #2
0
ファイル: utils_service_info.c プロジェクト: rootfs/oio-sds
void
service_tag_copy(struct service_tag_s *dst, struct service_tag_s *src)
{
	if (!dst || !src)
		return;

	g_strlcpy(dst->name, src->name, sizeof(dst->name));

	switch (src->type) {
	case STVT_I64:
		service_tag_set_value_i64(dst, src->value.i);
		return;
	case STVT_REAL:
		service_tag_set_value_float(dst, src->value.r);
		return;
	case STVT_BOOL:
		service_tag_set_value_boolean(dst, src->value.b);
		return;
	case STVT_STR:
		service_tag_set_value_string(dst, src->value.s);
		return;
	case STVT_BUF:
		service_tag_set_value_string(dst, src->value.buf);
		return;
	}
}
コード例 #3
0
static struct service_tag_s *
_srvtag_load_json (const gchar *name, struct json_object *obj)
{
	struct service_tag_s *tag = g_malloc0(sizeof(struct service_tag_s));
	g_strlcpy(tag->name, name, sizeof(tag->name));
	if (json_object_is_type(obj, json_type_int)) {
		service_tag_set_value_i64(tag, json_object_get_int64(obj));
	} else if (json_object_is_type(obj, json_type_string)) {
		service_tag_set_value_string(tag, json_object_get_string(obj));
	} else if (json_object_is_type(obj, json_type_double)) {
		service_tag_set_value_float(tag, json_object_get_double(obj));
	} else if (json_object_is_type(obj, json_type_boolean)) {
		service_tag_set_value_boolean(tag, json_object_get_boolean(obj));
	} else {
		service_tag_set_value_boolean(tag, FALSE);
	}
	return tag;
}
コード例 #4
0
ファイル: services_task_check.c プロジェクト: korween/oio-sds
static void
_detect_obsolete_services(struct namespace_data_s *ns_data)
{
	guint counter;
	time_t time_now, time_down, time_broken;
	GHashTableIter s_iterator;
	gpointer s_k, s_v;
	gchar *str_key;
	struct service_info_s *si;


	time_now = g_get_real_time()/1000000;
	time_down = time_now - 5;
	time_broken = time_now - 30;
	counter = 0;
	
	if (!ns_data->configured) {
		return;
	}

	/*move services from UP to DOWN */
	g_hash_table_iter_init(&s_iterator, ns_data->local_services);
	while (g_hash_table_iter_next(&s_iterator, &s_k, &s_v)) {
		str_key = s_k;
		si = s_v;
		si->score.value = -2;/*score not set*/
		if (si->score.timestamp < time_down) {
			gchar str_addr[STRLEN_ADDRINFO];

			addr_info_to_string(&(si->addr),str_addr,sizeof(str_addr));
			DEBUG("Timeout on service [%s/%s/%s] (%"G_GINT32_FORMAT" < %ld) --> DOWN",
				si->ns_name, si->type, str_addr, si->score.timestamp, time_down);

			g_hash_table_iter_steal(&s_iterator);
			g_hash_table_insert(ns_data->down_services, str_key, si);

			invalidate_conscience_service(ns_data,si);
			zero_service_stats(si->tags);
			service_tag_set_value_boolean(service_info_ensure_tag(si->tags,"tag.up"), FALSE);

			counter++;
		}
	}

	/*remove services DOWN from a long time ago */
	g_hash_table_iter_init(&s_iterator, ns_data->down_services);
	while (g_hash_table_iter_next(&s_iterator, &s_k, &s_v)) {
		str_key = s_k;
		si = s_v;
		si->score.value = -2;/*score not set*/
		if (si->score.timestamp < time_broken) {
			gchar str_addr[STRLEN_ADDRINFO];

			addr_info_to_string(&(si->addr),str_addr,sizeof(str_addr));
			DEBUG("Service obsolete [%s/%s/%s] --> DELETED", si->ns_name, si->type, str_addr);

			g_hash_table_iter_remove(&s_iterator);
			counter++;
		}
		else
			zero_service_stats(si->tags);
	}

	if (counter)
		DEBUG("[task_id=%s] %u services states have changed", TASK_ID, counter);
}
コード例 #5
0
ファイル: cs_actions.c プロジェクト: shiditime/oio-sds
static enum http_rc_e
_registration (struct req_args_s *args, enum reg_op_e op, struct json_object *jsrv)
{
	GError *err;

	if (!jsrv || !json_object_is_type (jsrv, json_type_object))
		return _reply_common_error (args, BADREQ("Expected: json object"));

	if (!push_queue)
		return _reply_bad_gateway(args, SYSERR("Service upstream disabled"));

	if (NULL != (err = _cs_check_tokens(args)))
		return _reply_notfound_error (args, err);

	struct service_info_s *si = NULL;
	err = service_info_load_json_object (jsrv, &si, TRUE);

	if (err) {
		g_prefix_error (&err, "JSON error: ");
		if (err->code == CODE_BAD_REQUEST)
			return _reply_format_error (args, err);
		else
			return _reply_system_error (args, err);
	}

	if (!si->type[0]) {
		service_info_clean (si);
		return _reply_format_error (args, BADREQ("Service type not specified"));
	}

	if (!si->ns_name[0]) {
		GRID_TRACE2("%s NS forced to %s", __FUNCTION__, si->ns_name);
		g_strlcpy (si->ns_name, nsname, sizeof(si->ns_name));
	} else if (!validate_namespace (si->ns_name)) {
		service_info_clean (si);
		return _reply_format_error (args, BADNS());
	}

	gchar *k = service_info_key (si);
	STRING_STACKIFY(k);
	GRID_TRACE2("%s op=%s score=%d key=[%s]", __FUNCTION__,
			_regop_2str(op), si->score.value, k);

	switch (op) {
		case REGOP_PUSH:
			si->score.value = SCORE_UNSET;
			if (!service_is_known (k)) {
				service_learn (k);
				service_tag_set_value_boolean (service_info_ensure_tag (
							si->tags, NAME_TAGNAME_RAWX_FIRST), TRUE);
			}
			break;
		case REGOP_LOCK:
			si->score.value = CLAMP(si->score.value, SCORE_DOWN, SCORE_MAX);
			break;
		case REGOP_UNLOCK:
			si->score.value = SCORE_UNLOCK;
			break;
		default:
			g_assert_not_reached();
	}

	if (cs_expire_local_services > 0) {
		struct service_info_s *v = service_info_dup (si);
		v->score.timestamp = oio_ext_monotonic_seconds ();
		PUSH_DO(
			const struct service_info_s *si0 = lru_tree_get(srv_registered, k);
			if (si0) v->score.value = si0->score.value;
			lru_tree_insert (srv_registered, g_strdup(k), v);
		);
	}
コード例 #6
0
static gboolean
manage_service(struct service_info_s *si)
{
	GError *error_local;
	struct service_info_s *old_si = NULL;
	struct service_tag_s *tag_first = NULL;
	struct namespace_data_s *ns_data;
	gsize key_size;
	gchar key[LIMIT_LENGTH_SRVTYPE + STRLEN_ADDRINFO], str_addr[STRLEN_ADDRINFO];


	if (!si) {
		ERROR("Invalid parameter");
		return FALSE;
	}

	key_size = agent_get_service_key(si, key, sizeof(key));
	grid_addrinfo_to_string(&(si->addr), str_addr, sizeof(str_addr));

	/*this service must refer to known namespace and service type*/
	error_local = NULL;
	if (!(ns_data = get_namespace(si->ns_name, &error_local))) {
		ERROR("Namespace unavailable for service [ns=%s type=%s addr=%s] : %s",
			si->ns_name, si->type, str_addr, gerror_get_message(error_local));
		if (error_local)
			g_error_free(error_local);
		return FALSE;
	}

	/*Info trace when a service of a new type is used */
	if (error_local)
		g_error_free(error_local);
	if (!conscience_get_srvtype(ns_data->conscience, &error_local, si->type, MODE_STRICT)) {
		/*to avoid traces flooding, if the service already exists, no trace is sent */
		if (!g_hash_table_lookup(ns_data->local_services, key)
				&& !g_hash_table_lookup(ns_data->down_services, key)) {
			INFO("New service type discovered [ns=%s type=%s addr=%s]", ns_data->name, si->type, str_addr);
		}
	}

	/*replace MACRO tags by their true values */
	if (error_local)
		g_clear_error(&error_local);

	metautils_srvinfo_ensure_tags (si);

	si->score.value = SCORE_UNSET;
	si->score.timestamp = oio_ext_real_time() / G_TIME_SPAN_SECOND;

	/*then keep the score */
	g_hash_table_remove(ns_data->down_services, key);

	/* save first lauched tag if still in old si */
	old_si = g_hash_table_lookup(ns_data->local_services, key);
	if (old_si != NULL) {
		tag_first = service_info_get_tag(old_si->tags, NAME_TAGNAME_RAWX_FIRST);
		if (tag_first != NULL)
			service_tag_set_value_boolean(service_info_ensure_tag(si->tags, NAME_TAGNAME_RAWX_FIRST), tag_first->value.b);
	}

	service_tag_set_value_boolean(service_info_ensure_tag(si->tags, "tag.up"), TRUE);
	g_hash_table_insert(ns_data->local_services, g_strndup(key, key_size), si);

	DEBUG("Service registration [ns=%s type=%s addr=%s]", ns_data->name, si->type, str_addr);

	if (error_local)
		g_error_free(error_local);
	return TRUE;
}