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); }
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); }
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; }
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); } }
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); }
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); }
// 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); }
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); } } }
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); ); }
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; } }
// 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; }