static void _mark_service_state(const gchar *ns_name, const gchar *srv_key, gboolean is_up) { struct namespace_data_s *ns_data; struct service_info_s *si; ns_data = g_hash_table_lookup(namespaces, ns_name); if (!ns_data) return; if (is_up) { si = g_hash_table_lookup(ns_data->local_services, srv_key); if (!si) { /*service was DOWN*/ si = g_hash_table_lookup(ns_data->down_services, srv_key); if (si && (si = service_info_dup(si))) { g_hash_table_remove(ns_data->down_services, srv_key); g_hash_table_insert(ns_data->local_services, g_strdup(srv_key), si); INFO("Service [%s/%s] now UP", ns_name, srv_key); } } else { si->score.timestamp = g_get_real_time() / 1000000; DEBUG("Service [%s/%s] still UP", ns_name, srv_key); } /*ensure the UP tag on TRUE*/ if (si) { service_tag_set_value_boolean(service_info_ensure_tag(si->tags,"tag.up"), TRUE); si->score.timestamp = g_get_real_time() / 1000000; } } else { si = g_hash_table_lookup(ns_data->down_services, srv_key); if (!si) { /*service was maybe UP*/ si = g_hash_table_lookup(ns_data->local_services, srv_key); if (si && (si = service_info_dup(si))) { g_hash_table_remove(ns_data->local_services, srv_key); g_hash_table_insert(ns_data->down_services, g_strdup(srv_key), si); si->score.value = -2; } INFO("Service [%s/%s] now DOWN", ns_name, srv_key); } else { DEBUG("Service [%s/%s] still DOWN", ns_name, srv_key); si->score.value = -2; } /*was it UP or not, we ensure it has ZERO stats and the right flags*/ if (si) { service_tag_set_value_boolean(service_info_ensure_tag(si->tags,"tag.up"), FALSE); zero_service_stats(si->tags); invalidate_conscience_service(ns_data, si); DEBUG("Service [%s/%s] zeroed, invalidated, marked down", ns_name, srv_key); } } }
GError* meta2_backend_poll_service(struct meta2_backend_s *m2, const gchar *type, struct service_info_s **si) { struct grid_lb_iterator_s *iter; EXTRA_ASSERT(m2 != NULL); EXTRA_ASSERT(type != NULL); EXTRA_ASSERT(si != NULL); if (!(iter = grid_lbpool_get_iterator(m2->backend.lb, type))) return NEWERROR(CODE_SRVTYPE_NOTMANAGED, "no such service"); struct lb_next_opt_ext_s opt_ext; memset(&opt_ext, 0, sizeof(opt_ext)); opt_ext.req.distance = 0; opt_ext.req.max = 1; opt_ext.req.duplicates = TRUE; opt_ext.req.stgclass = NULL; opt_ext.req.strict_stgclass = TRUE; struct service_info_s **siv = NULL; if (!grid_lb_iterator_next_set2(iter, &siv, &opt_ext)) return NEWERROR(CODE_SRVTYPE_NOTMANAGED, "no service available"); *si = service_info_dup(siv[0]); service_info_cleanv(siv, FALSE); return NULL; }
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; }
// 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, 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); ); }