Esempio n. 1
0
void
service_info_gclean(gpointer p1, gpointer p2)
{
	(void) p2;
	if (p1)
		service_info_clean((struct service_info_s *) p1);
}
int
services_worker_push(worker_t * worker, GError ** error)
{
	gboolean rc;
	GSList *list_service_info = NULL, *l;


	/*extract the fields packed in the request's parameter */
	request_t *req = (request_t *) worker->data.session;
	rc = service_info_unmarshall(&list_service_info, req->arg, req->arg_size, error);
	
	if (!rc) {
		GSETERROR(error, "Invalid payload (service_info sequence expected)");
		return 0;
	}

	/*push all the services */
	for (l = list_service_info; l; l = l->next) {
		if (!l->data)
			continue;
		if (!manage_service(l->data))
			service_info_clean(l->data);
		l->data = NULL;
	}
	g_slist_free(list_service_info);
	list_service_info = NULL;

	return __respond_message(worker, 1, "OK", error);
}
Esempio n. 3
0
void
gs_free_service(gs_service_t * service)
{
	if (!service)
		return;
	if (service->gss_si)
		service_info_clean(service->gss_si);
	memset(service, 0x00, sizeof(struct gs_service_s));
	g_free(service);
}
Esempio n. 4
0
addr_info_t*
get_rainx_from_conscience(const gchar *nsname, GError **error)
{
	struct service_info_s *si = get_one_namespace_service(nsname, "rainx", error);
	if (!si)
		return NULL;
	struct addr_info_s *ai = g_memdup(&(si->addr), sizeof(struct addr_info_s));
	service_info_clean(si);
	return ai;
}
Esempio n. 5
0
void
service_info_cleanv(struct service_info_s **siv, gboolean content_only)
{
	if (!siv)
		return;
	if (content_only) {
		for (; *siv ;++siv)
			service_info_clean(*siv);
	}
	else {
		service_info_cleanv(siv, TRUE);
		g_free(siv);
	}
}
Esempio n. 6
0
    static enum http_rc_e
_registration (struct req_args_s *args, enum reg_op_e op, struct json_object *jsrv)
{
    GError *err;

    if (!push_queue)
        return _reply_bad_gateway(args, NEWERROR(CODE_INTERNAL_ERROR, "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);

    if (err) {
        if (err->code == CODE_BAD_REQUEST)
            return _reply_format_error (args, err);
        else
            return _reply_system_error (args, err);
    }

    if (!validate_namespace (si->ns_name)) {
        service_info_clean (si);
        return _reply_system_error (args, NEWERROR (CODE_NAMESPACE_NOTMANAGED,
                    "Unexpected NS"));
    }

    si->score.timestamp = network_server_bogonow(args->rq->client->server);

    if (op == REGOP_PUSH)
        si->score.value = SCORE_UNSET;
    else if (op == REGOP_UNLOCK)
        si->score.value = SCORE_UNLOCK;
    else /* if (op == REGOP_LOCK) */
        si->score.value = CLAMP(si->score.value, SCORE_DOWN, SCORE_MAX);

    gchar *key = service_info_key(si);
    PUSH_DO(lru_tree_insert(push_queue, key, si));
    GString *gstr = g_string_new ("");
    service_info_encode_json (gstr, si);
    return _reply_success_json (args, gstr);
}
Esempio n. 7
0
static char *
_chunk_location_row_xml(const struct loc_context_s *lc, const char *cid,
		const char *prefix)
{
	struct service_info_s *si = NULL;
	GString *result = g_string_new("");
	si = __service_info_from_chunkid(lc, cid);

	if(NULL != si) {
		char *avail = _check_chunk(cid);
		g_string_append_printf(result,
				"%s     <location>\n"
				"%s      <url>%s</url>\n"
				"%s      <stgclass>%s</stgclass>\n"
				"%s      <available>%s</available>\n"
				"%s     </location>\n",
				prefix,
				prefix, cid,
				prefix, service_info_get_stgclass(si, "N/A"),
				prefix, (strlen(avail) > 0) ? "no" : "yes",
				prefix);
		service_info_clean(si);
		g_free(avail);
	} else {
		g_string_append_printf(result,
				"%s     <location>\n"
				"%s      <url>%s</url>\n"
				"%s      <stgclass>N/A</stgclass>\n"
				"%s      <available>no</available>\n"
				"%s     </location>\n",
				prefix,
				prefix, cid,
				prefix,
				prefix,
				prefix);
	}

	return g_string_free(result, FALSE);
}
Esempio n. 8
0
// for test <NS part> from a complete VNS name only
gboolean
service_info_equal_v2(const struct service_info_s * si1, const struct service_info_s * si2)
{
	const gchar *sep = NULL;

    if (si1 == si2)
       return TRUE;

    if (si1 == NULL || si2 == NULL)
       return FALSE;

	// for compare NS part from VNS name, 
	if (NULL != (sep = strchr(si2->ns_name, '.'))) {
		gboolean result = FALSE;
		struct service_info_s *si2_tmp = service_info_dup(si2);
		g_strlcpy(si2_tmp->ns_name, si2->ns_name, sep - si2->ns_name+1);
        //VNS part not used here: = g_strdup(sep+1);
		result = service_info_equal(si1, si2_tmp);
		service_info_clean(si2_tmp);
		return result;
	}

	return service_info_equal(si1, si2);
}
Esempio n. 9
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, NEWERROR(CODE_INTERNAL_ERROR,
        "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) {
        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]) {
        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, NEWERROR (CODE_NAMESPACE_NOTMANAGED,
        "Unexpected NS"));
    }

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

    if (op == REGOP_PUSH)
        si->score.value = SCORE_UNSET;
    else if (op == REGOP_UNLOCK)
        si->score.value = SCORE_UNLOCK;
    else /* if (op == REGOP_LOCK) */
        si->score.value = CLAMP(si->score.value, SCORE_DOWN, SCORE_MAX);

    // TODO follow the DRY principle and factorize this!
    if (flag_cache_enabled) {
        GString *gstr = g_string_new ("");
        service_info_encode_json (gstr, si, TRUE);
        PUSH_DO(lru_tree_insert(push_queue, service_info_key(si), si));
        return _reply_success_json (args, gstr);
    } else {
        CSURL(cs);
        GSList l = {.data = si, .next = NULL};
        if (NULL != (err = conscience_remote_push_services (cs, &l))) {
            service_info_clean (si);
            return _reply_common_error (args, err);
        } else {
            GString *gstr = g_string_new ("");
            service_info_encode_json (gstr, si, TRUE);
            service_info_clean (si);
            return _reply_success_json (args, gstr);
        }
    }
}
Esempio n. 10
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_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);
		);
	}
Esempio n. 11
0
static void
sqlx_service_specific_fini(void)
{
	// soft stop
	if (SRV.gtq_reload)
		grid_task_queue_stop(SRV.gtq_reload);
	if (SRV.gtq_register)
		grid_task_queue_stop(SRV.gtq_register);
	if (SRV.gtq_admin)
		grid_task_queue_stop(SRV.gtq_admin);

	if (SRV.server) {
		network_server_close_servers(SRV.server);
		network_server_stop(SRV.server);
	}

	if (SRV.thread_reload)
		g_thread_join(SRV.thread_reload);
	if (SRV.thread_register)
		g_thread_join(SRV.thread_register);
	if (SRV.thread_admin)
		g_thread_join(SRV.thread_admin);
	if (SRV.thread_client)
		g_thread_join(SRV.thread_client);
	if (SRV.thread_queue)
		g_thread_join(SRV.thread_queue);

	if (SRV.repository) {
		sqlx_repository_stop(SRV.repository);
		struct sqlx_cache_s *cache = sqlx_repository_get_cache(SRV.repository);
		if (cache)
			sqlx_cache_expire(cache, G_MAXUINT, 0);
	}
	if (SRV.election_manager)
		election_manager_exit_all(SRV.election_manager, 0, TRUE);
	if (SRV.sync)
		sqlx_sync_close(SRV.sync);

	// Cleanup
	if (SRV.gtq_admin)
		grid_task_queue_destroy(SRV.gtq_admin);
	if (SRV.gtq_reload)
		grid_task_queue_destroy(SRV.gtq_reload);
	if (SRV.gtq_register)
		grid_task_queue_destroy(SRV.gtq_register);

	if (SRV.server)
		network_server_clean(SRV.server);
	if (SRV.dispatcher)
		gridd_request_dispatcher_clean(SRV.dispatcher);
	if (SRV.repository)
		sqlx_repository_clean(SRV.repository);
	if (SRV.election_manager)
		election_manager_clean(SRV.election_manager);
	if (SRV.sync)
		sqlx_sync_clear(SRV.sync);
	if (SRV.resolver)
		hc_resolver_destroy(SRV.resolver);

	if (SRV.gsr_reqtime)
		grid_single_rrd_destroy(SRV.gsr_reqtime);
	if (SRV.gsr_reqcounter)
		grid_single_rrd_destroy(SRV.gsr_reqcounter);

	if (SRV.custom_tags)
		g_slist_free_full(SRV.custom_tags, g_free);
	if (SRV.si)
		service_info_clean(SRV.si);
	if (SRV.announce)
		g_string_free(SRV.announce, TRUE);
	if (SRV.url)
		g_string_free(SRV.url, TRUE);
	if (SRV.zk_url)
		oio_str_clean(&SRV.zk_url);

	if (SRV.clients_pool)
		gridd_client_pool_destroy (SRV.clients_pool);

	if (SRV.lb)
		grid_lbpool_destroy (SRV.lb);

	if (SRV.events_queue)
		oio_events_queue__destroy (SRV.events_queue);

	if (SRV.nsinfo)
		namespace_info_free(SRV.nsinfo);
	if (all_options) {
		g_free (all_options);
		all_options = NULL;
	}
}
Esempio n. 12
0
// TODO: convert this to use metautils' common_main
int
main(int argc, char ** argv)
{
	int rc = 1;
	service_info_t *service = NULL;
	setenv("GS_DEBUG_ENABLE", "0", TRUE);

	supervisor_children_init();

	do {
		GError *err = NULL;
		regex_tag = g_regex_new("((stat|tag)\\.([^.=\\s]+))\\s*=\\s*(.*)",
				G_REGEX_CASELESS|G_REGEX_EXTENDED, 0, &err);
		if (!regex_tag) {
			FATAL("Cannot compile tag regex: %s", err->message);
			g_clear_error(&err);
			exit(-1);
		}
		regex_svc = g_regex_new("([^|]*)\\|([^|]*)\\|(.*)",
				G_REGEX_CASELESS, 0, &err);
		if (!regex_svc) {
			FATAL("Cannot compile svc regex: %s", err->message);
			g_clear_error(&err);
			exit(-1);
		}
	} while (0);

	static struct option long_options[] = {
		{"svc-id", 1, 0, 'i'},
		{"monitor", 1, 0, 'm'},
		{"svc-cmd", 1, 0, 'c'},
		{"syslog-id", 1, 0, 's'},
		{"auto-restart-children", 0, 0, 'a'},
		{"monitor-period", 1, 0, 'p'},
		{"no-tcp-check", 0, 0, 'n'},
		{"tag", 1, 0, 't'},
		{0, 0, 0, 0}
	};

	int c;
	int option_index = 0;
	gchar *optarg2 = NULL;
	gchar **kv = NULL;
	while (-1 != (c = getopt_long(argc, argv, "ac:i:m:np:s:t:",
			long_options, &option_index))) {
		switch (c) {
		case 'i':
			g_strlcpy(svc_id, optarg, sizeof(svc_id)-1);
			break;
		case 'm':
			g_strlcpy(svc_mon, optarg, sizeof(svc_mon)-1);
			break;
		case 'c':
			g_strlcpy(svc_cmd, optarg, sizeof(svc_cmd)-1);
			break;
		case 'n':
			kv = g_malloc0(3 * sizeof(gchar*));
			kv[0] = g_strdup("tag.agent_check");
			kv[1] = g_strdup("false");
			custom_tags = g_slist_prepend(custom_tags, kv);
			break;
		case 'a':
			auto_restart_children = TRUE;
			break;
		case 'p':
			monitor_period = strtoll(optarg, NULL, 10);
			break;
		case 's':
			g_strlcpy(syslog_id, optarg, sizeof(syslog_id)-1);
			break;
		case 't':
			if (!g_str_has_prefix(optarg, "tag."))
				optarg2 = g_strdup_printf("tag.%s", optarg);
			else
				optarg2 = g_strdup(optarg);
			kv = g_strsplit(optarg2, "=", 2);
			if (kv && g_strv_length(kv) == 2) {
				custom_tags = g_slist_prepend(custom_tags, kv);
			} else {
				g_printerr("Invalid tag, must contain '=': %s", optarg);
				g_strfreev(kv);
				kv = NULL;
			}
			g_free(optarg2);
			optarg2 = NULL;
			break;
		default:
			g_printerr("Unexpected option: %c\n", c);
			break;
		}
		option_index = 0;
	}

	if (argc <= 1 || strlen(svc_id) == 0 || strlen(svc_cmd) == 0) {
		g_printerr("Usage: %s\n", argv[0]);
		g_printerr("Mandatory options:\n");
		g_printerr("\t-i\t--svc-id <NS|type|ip:port>\n"
				"\t-c\t--svc-cmd </service/cmd/to/launch>\n\n"
				"Other options:\n"
				"\t-m\t--monitor </script/to/monitor>\n"
				"\t-p\t--monitor-period <seconds>\n"
				"\t-s\t--syslog-id <syslog-id>\n"
				"\t-t\t--tag <key=val>\n"
				"\t-a\t--auto-restart-children\n"
				"\t-n\t--no-tcp-check\n");
		return 1;
	}

	if (*syslog_id) {
		logger_init_level(GRID_LOGLVL_INFO);
		logger_syslog_open();
		g_log_set_default_handler(logger_syslog, NULL);
	}

	GError *error = NULL;
	if (!supervisor_children_register(CHILD_KEY, svc_cmd, &error)) {
		g_printerr("Child registration failure:\n\t%s\n", gerror_get_message(error));
		goto label_error;
	}

	if (0 != supervisor_children_set_limit(CHILD_KEY, SUPERV_LIMIT_THREAD_STACK, 8192 * 1024))
		WARN("Limit on thread stack size cannot be set: %s", strerror(errno));
	if (0 != supervisor_children_set_limit(CHILD_KEY, SUPERV_LIMIT_MAX_FILES, 32 * 1024))
		WARN("Limit on max opened files cannot be set: %s", strerror(errno));
	if (0 != supervisor_children_set_limit(CHILD_KEY, SUPERV_LIMIT_CORE_SIZE, -1))
		WARN("Limit on core file size cannot be set: %s", strerror(errno));

	supervisor_children_set_respawn(CHILD_KEY, FALSE);
	supervisor_children_set_working_directory(CHILD_KEY, "/tmp");
	supervisor_preserve_env(CHILD_KEY);

	service = g_malloc0(sizeof(service_info_t));
	if (0 != init_srvinfo(svc_id, service)) {
		g_printerr("Internal error: failed to init srvinfo\n");
		goto label_error;
	}

	freopen("/dev/null", "r", stdin);

	NOTICE("%s restarted, pid=%d", argv[0], getpid());

	signal(SIGQUIT, sighandler_supervisor);
	signal(SIGTERM, sighandler_supervisor);
	signal(SIGINT,  sighandler_supervisor);
	signal(SIGPIPE, sighandler_supervisor);
	signal(SIGUSR1, sighandler_supervisor);
	signal(SIGUSR2, sighandler_supervisor);
	signal(SIGCHLD, sighandler_supervisor);

	monitoring_loop(service);

	rc = 0;

label_error:
	g_slist_free_full(custom_tags, (GDestroyNotify) g_strfreev);
	service_info_clean(service);
	supervisor_children_cleanall();
	return rc;
}