Ejemplo n.º 1
0
struct conscience_srvtype_s *
conscience_get_locked_srvtype(struct conscience_s *conscience, GError ** error,
    const gchar * type, enum mode_e mode, char lock_mode)
{
	struct conscience_srvtype_s *srvtype;

	if (!conscience) {
		GSETERROR(error, "Invalid parameter");
		return NULL;
	}

	/* lock the conscience service-types storage. If an auto-creation is wanted,
	 * and the service type does not exist, we force a lock with writer rights
	 * because the storage itself will be modified during the creation. */
	conscience_lock_srvtypes(conscience, 'r');
	srvtype = conscience_get_srvtype(conscience, error, type, MODE_STRICT);
	if (!srvtype && mode == MODE_AUTOCREATE) {
		conscience_unlock_srvtypes(conscience);

		conscience_lock_srvtypes(conscience, 'w');
		srvtype = conscience_get_srvtype(conscience, error, type, MODE_AUTOCREATE);
	}

	if (!srvtype) {
		GSETERROR(error, "Service type not found, unlocking the conscience");
		conscience_unlock_srvtypes(conscience);
		return NULL;
	}

	/*now lock the service type itself */
	_lock_rw(&(srvtype->rw_lock), lock_mode);
	return srvtype;
}
static void
fill_service_info_score(struct conscience_s *conscience, struct service_info_s *si)
{
	struct conscience_srv_s *srv;
	struct conscience_srvtype_s *srvtype;

	si->score.value = SCORE_UNSET;
	srvtype = conscience_get_srvtype(conscience, NULL, si->type, MODE_STRICT);
	if (srvtype) {
		srv = conscience_srvtype_get_srv(srvtype, (struct conscience_srvid_s*)&(si->addr));
		if (srv)
			si->score.value = srv->score.value;
	}
}
Ejemplo n.º 3
0
/**
 * Find the service in the conscience and set its score to 0, and call
 * zero_service_stats() on the conscience service.
 */
static void
invalidate_conscience_service(struct namespace_data_s *ns_data, struct service_info_s *si)
{
	GError *error;
	struct conscience_srvtype_s *srvtype;
	struct conscience_srv_s *srv;
	struct conscience_srvid_s srvid;

	error = NULL;

	srvtype = conscience_get_srvtype(ns_data->conscience, &error, si->type, MODE_STRICT);
	if (srvtype) {
		memcpy(&(srvid.addr), &(si->addr), sizeof(addr_info_t));
		srv = conscience_srvtype_get_srv(srvtype, &srvid);
		if (srv) {
			srv->score.value = 0;
			zero_service_stats(srv->tags);
		}
	}
	if (error)
		g_error_free(error);
}
Ejemplo n.º 4
0
gboolean
conscience_run_srvtypes(struct conscience_s * conscience, GError ** error, guint32 flags,
    gchar ** names_array, service_callback_f * callback, gpointer udata)
{
	gboolean rc;
	register guint i, max;
	register guint32 real_flags;
	gchar **name;
	GPtrArray *array_srvtypes;

	if (!conscience || !names_array || !callback) {
		GSETERROR(error, "Invalid parameter (conscience=%p names_array=%p callback=%p)",
		    conscience, names_array, callback);
		return FALSE;
	}

	array_srvtypes = g_ptr_array_sized_new(8);
	rc = TRUE;

	/* XXX start of critical version */
	if (flags & SRVTYPE_FLAG_LOCK_ENABLE)
		conscience_lock_srvtypes(conscience, 'r');

	/*We do not run any service type if we are not sure that all exist */
	for (name = names_array; *name; name++) {
		struct conscience_srvtype_s *srvtype;

		srvtype = conscience_get_srvtype(conscience, error, *name, MODE_STRICT);
		if (!srvtype) {
			rc = FALSE;
			GSETCODE(error, 460, "Service type [%s] not managed", *name);
			goto unlock_and_exit;
		}
		g_ptr_array_add(array_srvtypes, srvtype);
	}

	/*we remove the additional call, we just want one call at the end */
	real_flags = flags & ~SRVTYPE_FLAG_ADDITIONAL_CALL;

	for (i = 0, max = array_srvtypes->len; rc && i < max; i++) {
		struct conscience_srvtype_s *srvtype;

		srvtype = g_ptr_array_index(array_srvtypes, i);

		if (flags & SRVTYPE_FLAG_LOCK_ENABLE) {
			/* XXX start of critical section */
			if (flags & SRVTYPE_FLAG_LOCK_WRITER)
				g_static_rw_lock_writer_lock(&(srvtype->rw_lock));
			else
				g_static_rw_lock_reader_lock(&(srvtype->rw_lock));
		}

		rc = conscience_srvtype_run_all(srvtype, error, real_flags, callback, udata);

		if (flags & SRVTYPE_FLAG_LOCK_ENABLE) {
			if (flags & SRVTYPE_FLAG_LOCK_WRITER)
				g_static_rw_lock_writer_unlock(&(srvtype->rw_lock));
			else
				g_static_rw_lock_reader_unlock(&(srvtype->rw_lock));
			/* XXX end of critical section */
		}

		if (!rc) {
			GSETERROR(error, "An error occured while running the services of type [%s]", srvtype->type_name);
			goto unlock_and_exit;
		}
	}

	if (rc && (flags & SRVTYPE_FLAG_ADDITIONAL_CALL))
		rc = callback(NULL, udata);

      unlock_and_exit:

	if (flags & SRVTYPE_FLAG_LOCK_ENABLE)
		conscience_unlock_srvtypes(conscience);
	/* XXX end of critical version */

	g_ptr_array_free(array_srvtypes, TRUE);
	return rc;
}
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;
}