Exemplo n.º 1
0
static service_info_t *
_find_matching_rawx(GSList *rawx, GSList *used_loc, gint64 distance,
		const gchar *stg_class, GSList **rawx_garbage)
{
	GRID_DEBUG("Searching rawx distant of %"G_GINT64_FORMAT
			" with storage class '%s'", distance, stg_class);
	GSList *l = NULL;
	gchar loc[1024];
	struct service_tag_s * loc_tag = NULL;
	GRID_DEBUG("Checking for an available rawx in a list of %d elements",
			g_slist_length(rawx));
	for (l = rawx; l && l->data; l = l->next) {
		GRID_DEBUG("Checking one rawx...");
		/* ensure service score */
		if(((service_info_t*)l->data)->score.value <= 0) {
			GRID_DEBUG("Rawx score <= 0");
			continue;
		}
		/* ensure not spotted as unreachable */
		if(_is_rawx_in_garbage((service_info_t*)l->data, *rawx_garbage)) {
			GRID_DEBUG("Rawx already in unreachable list");
			continue;
		}
		/* check rawx reachable */
		if(!is_rawx_reachable((service_info_t*)l->data)) {
			GRID_DEBUG("Rawx unreachable");
			*rawx_garbage = g_slist_prepend(*rawx_garbage, l->data);
			continue;
		}

		/* check rawx has appropriate storage class (strictly) */
		if (!service_info_check_storage_class(l->data, stg_class)) {
			GRID_DEBUG(MSG_DONT_MATCH_CRITERIA, "storage class");
			continue;
		}

		/* ensure distance match with our policy */
		bzero(loc, sizeof(loc));
		loc_tag = service_info_get_tag(((service_info_t*)l->data)->tags, NAME_TAGNAME_RAWX_LOC);
		GRID_DEBUG("service tag extracted");
		if(!loc_tag) {
			if(distance > 1) {
				continue;
			}
			return ((service_info_t*)l->data);
		}
		service_tag_get_value_string(loc_tag, loc, sizeof(loc), NULL);
		if(__test_location(loc, used_loc, distance)) {
			return ((service_info_t*)l->data);
		} else {
			GRID_DEBUG(MSG_DONT_MATCH_CRITERIA, "distance");
		}
	}
	return NULL;
}
const gchar *
service_info_get_tag_value(const struct service_info_s *si,
		const gchar *name, const gchar *def)
{
	struct service_tag_s *tag;

	if (!si || !si->tags)
		return def;
	if (!(tag = service_info_get_tag(si->tags, name)))
		return def;
	if (tag->type == STVT_STR)
		return tag->value.s;
	if (tag->type == STVT_BUF)
		return tag->value.buf;
	return def;
}
Exemplo n.º 3
0
struct service_tag_s *
service_info_ensure_tag(GPtrArray * a, const gchar * name)
{
	struct service_tag_s *srvtag;

	if (!a || !name)
		return NULL;
	srvtag = service_info_get_tag(a, name);
	if (!srvtag) {
		srvtag = g_malloc0(sizeof(struct service_tag_s));
		g_strlcpy(srvtag->name, name, sizeof(srvtag->name));
		g_ptr_array_add(a, srvtag);
		srvtag->type = STVT_BOOL;
		srvtag->value.b = FALSE;
	}

	return srvtag;
}
Exemplo n.º 4
0
/**
 * @return TRUE if "agent_check" tag is missing or is true,
 *   false otherwise
 */
static gboolean
_agent_check_enabled(struct service_info_s *si)
{
	if (!si)
		return FALSE;
	gboolean srv_check_enabled = TRUE;
	service_tag_t *tag = service_info_get_tag(si->tags,
			NAME_TAGNAME_AGENT_CHECK);
	if (tag) {
		GError *err = NULL;
		if (tag->type == STVT_BOOL) {
			service_tag_get_value_boolean(tag, &srv_check_enabled, &err);
		} else {
			gchar buf[64] = {0};
			service_tag_get_value_string(tag, buf, sizeof(buf), &err);
			srv_check_enabled = metautils_cfg_get_bool(buf, TRUE);
		}
		g_clear_error(&err);
	}
	return srv_check_enabled;
}
Exemplo n.º 5
0
gboolean
fill_scanning_info_for_chunk_checker(struct volume_scanning_info_s *scanning_info, service_info_t * service_info,
    struct integrity_loop_config_s *config, GError ** error)
{
	gchar volume_path[LIMIT_LENGTH_VOLUMENAME];
	struct chunk_checker_data_s cc_data;
        struct service_tag_s *tag = NULL;

        CHECK_ARG_POINTER(scanning_info, error);
        CHECK_ARG_POINTER(service_info, error);
        CHECK_ARG_POINTER(config, error);

	bzero(volume_path, sizeof(volume_path));
	bzero(scanning_info, sizeof(*scanning_info));
	bzero(&cc_data, sizeof(cc_data));

        tag = service_info_get_tag(service_info->tags, NAME_TAGNAME_RAWX_VOL);
        if (tag == NULL) {
                GSETERROR(error, "Failed to retrieve tag [%s]", NAME_TAGNAME_RAWX_VOL);
                return FALSE;
        }

        /* Fill volume_path */
        if (!service_tag_get_value_string(tag, volume_path, sizeof(volume_path), error)) {
                GSETERROR(error, "Failed to extract string value from tag [%s]", NAME_TAGNAME_RAWX_VOL);
                return FALSE;
        }

        /* Fill callback and callback data */
	scanning_info->volume_path = g_strdup(volume_path);
        scanning_info->file_action = check_chunk_and_sleep;
	scanning_info->dir_exit = sleep_after_directory;

	cc_data.volume_path = g_strdup(volume_path);
        cc_data.sleep_time = config->chunk_checker_sleep_time;
	cc_data.si = service_info_dup(service_info);
	scanning_info->callback_data = g_memdup(&cc_data, sizeof(cc_data));

        return TRUE;
}
Exemplo n.º 6
0
static gboolean
_filter_tag(struct service_info_s *si, gpointer u)
{
    struct compound_type_s *ct = u;

    EXTRA_ASSERT(ct != NULL);
    if (!ct->req.k)
        return TRUE;

    struct service_tag_s *tag = service_info_get_tag(si->tags, ct->req.k);
    if (NULL == tag)
        return FALSE;

    switch (tag->type) {
    case STVT_BUF:
        return !fnmatch(ct->req.v, tag->value.buf, 0);
    case STVT_STR:
        return !fnmatch(ct->req.v, tag->value.s, 0);
    default:
        return FALSE;
    }
}
Exemplo n.º 7
0
static void
_extract_location(gpointer data, gpointer udata)
{
	GRID_DEBUG("extracting services locations");
	struct service_tag_s * loc_tag = NULL;
	gchar loc[1024];
	GSList **used_loc = (GSList **) udata;

	bzero(loc, sizeof(loc));

	if(data)
		loc_tag = service_info_get_tag(((service_info_t*)data)->tags, NAME_TAGNAME_RAWX_LOC);

	GRID_DEBUG("service tag extracted");
	if(!loc_tag)
		return;

	service_tag_get_value_string(loc_tag, loc, sizeof(loc), NULL);

	if(strlen(loc) > 0)
		*used_loc = g_slist_prepend(*used_loc, g_strdup(loc));
}
Exemplo n.º 8
0
static void
allservice_check_start_HT(struct namespace_data_s *ns_data, GHashTable *ht)
{
	gsize offset;
	struct taskdata_checksrv_s td_scheme;
	GHashTableIter iter_serv;
	gpointer k, v;


	g_hash_table_iter_init(&iter_serv, ht);
	while (g_hash_table_iter_next(&iter_serv, &k, &v)) {
		struct service_info_s *si = v;
		gboolean srv_check_enabled = TRUE;

		/* Services can disable TCP checks (enabled by default) */
		service_tag_t *tag = service_info_get_tag(si->tags,
				NAME_TAGNAME_AGENT_CHECK);
		if (tag) {
			GError *err = NULL;
			if (tag->type == STVT_BOOL) {
				service_tag_get_value_boolean(tag, &srv_check_enabled, &err);
			} else {
				gchar buf[64] = {0};
				service_tag_get_value_string(tag, buf, sizeof(buf), &err);
				srv_check_enabled = metautils_cfg_get_bool(buf, TRUE);
			}
			g_clear_error(&err);
		}

		memset(&td_scheme, 0x00, sizeof(td_scheme));
		offset = g_snprintf(td_scheme.task_name, sizeof(td_scheme.task_name), "%s.", TASK_ID);
		addr_info_to_string(&(si->addr), td_scheme.task_name+offset, sizeof(td_scheme.task_name)-offset);
		g_strlcpy(td_scheme.ns_name, ns_data->name, sizeof(td_scheme.ns_name)-1);

		if (!srv_check_enabled) {
			GRID_DEBUG("Task [%s] disabled by "
					NAME_TAGNAME_AGENT_CHECK, td_scheme.task_name);
		} else if (!is_task_scheduled(td_scheme.task_name)) {
			GError *error_local = NULL;
			task_t *task = NULL;
			struct taskdata_checksrv_s *task_data;


			agent_get_service_key(si, td_scheme.srv_key, sizeof(td_scheme.srv_key));
			g_strlcpy(td_scheme.srv_key, (gchar*)k, sizeof(td_scheme.srv_key)-1);

			/* prepare the task structure */
			task_data = g_memdup(&td_scheme, sizeof(td_scheme));
			if (!task_data) {
				ERROR("Memory allocation failure");
				continue;
			}

			task = create_task(period_check_services, td_scheme.task_name);
			task = set_task_callbacks(task, _check_tcp_service_task,
					g_free, task_data);
			if (!task) {
				ERROR("Memory allocation failure");
				continue;
			}
			
			/* now start the task! */
			if (add_task_to_schedule(task, &error_local))
				INFO("Task started: %s", td_scheme.task_name);
			else {
				ERROR("Failed to add task to scheduler [%s] : %s", td_scheme.task_name, gerror_get_message(error_local));
				g_free(task);
			}
			if (error_local)
				g_clear_error(&error_local);
		}
	}
}
Exemplo n.º 9
0
struct conscience_srv_s *
conscience_srvtype_refresh(struct conscience_srvtype_s *srvtype, struct service_info_s *si)
{
	g_assert_nonnull (srvtype);
	g_assert_nonnull (si);

	struct conscience_srvid_s srvid;
	memcpy(&(srvid.addr), &(si->addr), sizeof(addr_info_t));

	struct service_tag_s *tag_first =
		service_info_get_tag(si->tags, NAME_TAGNAME_RAWX_FIRST);
	gboolean really_first = FALSE;

	/*register the service if necessary */
	struct conscience_srv_s *p_srv = conscience_srvtype_get_srv(srvtype, &srvid);
	if (!p_srv) {
		p_srv = conscience_srvtype_register_srv(srvtype, NULL, &srvid);
		g_assert_nonnull (p_srv);
		really_first = tag_first && tag_first->type == STVT_BOOL && tag_first->value.b;
	}

	/* refresh the tags: create missing, replace existing
	 * (but the tags are not flushed before) */
	if (si->tags) {
		TRACE("Refreshing tags for srv [%.*s]",
				(int)(LIMIT_LENGTH_SRVDESCR), p_srv->description);
		const guint max = si->tags->len;
		for (guint i = 0; i < max; i++) {
			struct service_tag_s *tag = g_ptr_array_index(si->tags, i);
			if (tag == tag_first) continue;
			struct service_tag_s *orig = conscience_srv_ensure_tag(p_srv, tag->name);
			service_tag_copy(orig, tag);
		}
	}

	p_srv->score.timestamp = oio_ext_monotonic_seconds ();
	if (si->score.value == SCORE_UNSET || si->score.value == SCORE_UNLOCK) {
		if (really_first) {
			GRID_TRACE2("SRV first [%s]", p_srv->description);
			p_srv->score.value = 0;
			p_srv->locked = TRUE;
		} else {
			if (si->score.value == SCORE_UNLOCK) {
				if (p_srv->locked) {
					GRID_TRACE2("SRV unlocked [%s]", p_srv->description);
					p_srv->locked = FALSE;
					p_srv->score.value = CLAMP (p_srv->score.value, SCORE_DOWN, SCORE_MAX);
				} else {
					GRID_TRACE2("SRV already unlocked [%s]", p_srv->description);
				}
			} else { /* UNSET, a.k.a. regular computation */
				if (p_srv->locked) {
					GRID_TRACE2("SRV untouched [%s]", p_srv->description);
				} else {
					GError *err = NULL;
					if (!conscience_srv_compute_score(p_srv, &err)) {
						GRID_TRACE2("SRV error [%s]: (%d) %s", p_srv->description, err->code, err->message);
						g_clear_error (&err);
					} else {
						GRID_TRACE2("SRV refreshed [%s]", p_srv->description);
					}
				}
			}
		}
	} else { /* LOCK */
		p_srv->score.value = CLAMP(si->score.value, SCORE_DOWN, SCORE_MAX);
		if (p_srv->locked) {
			GRID_TRACE2("SRV already locked [%s]", p_srv->description);
		} else {
			p_srv->locked = TRUE;
			GRID_TRACE2("SRV locked [%s]", p_srv->description);
		}
	}

	return p_srv;
}
Exemplo n.º 10
0
struct service_tag_s *
conscience_srv_get_tag(struct conscience_srv_s *service,
                       const gchar * name)
{
    return service ? service_info_get_tag(service->tags,name) : NULL;
}
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;
}
Exemplo n.º 12
0
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_get_tag(si->tags, "tag.id")) {
		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, ns_name, 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 (ttl_expire_local_services > 0 && op != REGOP_UNLOCK) {
		struct service_info_s *v = service_info_dup (si);
		v->score.timestamp = oio_ext_monotonic_seconds ();
		REG_WRITE(
			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);
		);
	}