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 parse_output(const gchar *cmd, service_info_t *si) { int fd; FILE *stream_in; gchar line[1024]; gchar cmd_with_args[4096] = {0,0,0}; g_snprintf(cmd_with_args, sizeof(cmd_with_args), "%s %s", cmd, svc_id); INFO("Executing [%s]", cmd_with_args); if (0 > (fd = command_get_pipe(cmd_with_args))) { WARN("Exec failed: %s", strerror(errno)); return; } if (!(stream_in = fdopen(fd, "r"))) { WARN("fdopen failed: %s", strerror(errno)); metautils_pclose(&fd); return; } while (!feof(stream_in) && !ferror(stream_in)) { GMatchInfo *mi = NULL; bzero(line, sizeof(line)); if (!fgets(line, sizeof(line), stream_in)) { break; } /* chomp the line */ my_chomp(line); if (!g_regex_match(regex_tag, line, 0, &mi)) { NOTICE("Unrecognized pattern for output line [%s]", line); } else { struct service_tag_s *tag; gchar *str_type, *str_name, *str_value; str_name = g_match_info_fetch(mi, 1); str_type = g_match_info_fetch(mi, 2); str_value = g_match_info_fetch(mi, 4); if (!g_ascii_strcasecmp(str_type, "tag")) { tag = service_info_ensure_tag(si->tags, str_name); service_tag_set_value_string(tag, str_value); } else if (!g_ascii_strcasecmp(str_type, "stat")) { gdouble dval; dval = g_ascii_strtod(str_value, NULL); tag = service_info_ensure_tag(si->tags, str_name); service_tag_set_value_float(tag, dval); } g_free(str_value); g_free(str_type); g_free(str_name); } g_match_info_free(mi); } fclose(stream_in); }
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; }
struct service_tag_s * conscience_srv_ensure_tag(struct conscience_srv_s *service, const gchar * name) { return service && name ? service_info_ensure_tag(service->tags,name) : NULL; }