/// =-=-=-=-=-=-=- /// @brief get the next resource shared pointer given this resources name /// as well as the file object irods::error get_next_child_for_open_or_write( const std::string& _name, irods::file_object_ptr& _file_obj, irods::resource_child_map& _cmap, irods::resource_ptr& _resc ) { // =-=-=-=-=-=-=- // set up iteration over physical objects std::vector< irods::physical_object > objs = _file_obj->replicas(); std::vector< irods::physical_object >::iterator itr = objs.begin(); // =-=-=-=-=-=-=- // check to see if the replica is in this resource, if one is requested for ( ; itr != objs.end(); ++itr ) { // =-=-=-=-=-=-=- // run the hier string through the parser irods::hierarchy_parser parser; parser.set_string( itr->resc_hier() ); // =-=-=-=-=-=-=- // find this resource in the hier if ( !parser.resc_in_hier( _name ) ) { continue; } // =-=-=-=-=-=-=- // if we have a hit, get the resc ptr to the next resc return get_next_child_in_hier( _name, itr->resc_hier(), _cmap, _resc ); } // for itr std::string msg( "no replica found in resc [" ); msg += _name + "]"; return ERROR( REPLICA_NOT_IN_RESC, msg ); } // get_next_child_for_open_or_write
/// =-=-=-=-=-=-=- /// @brief function to handle resolving the hier given votes of the /// root resources for an open operation static error resolve_hier_for_open_or_write_without_keyword( rsComm_t* _comm, irods::file_object_ptr _file_obj, const std::string& _oper, std::string& _out_hier ) { // =-=-=-=-=-=-=- // build a list of root hiers for all // the repls we have in the list std::map< std::string, float > root_map; // =-=-=-=-=-=-=- // grid throught the list, get the root of the hiers and // place it into the map std::vector< physical_object > repls = _file_obj->replicas(); for ( size_t i = 0; i < repls.size(); ++i ) { // =-=-=-=-=-=-=- // extract the root resource from the hierarchy hierarchy_parser parser; parser.set_string( repls[ i ].resc_hier() ); std::string root_resc; parser.first_resc( root_resc ); root_map[ root_resc ] = 0.0; } // for i // =-=-=-=-=-=-=- // grind through the map and get a vote for each root // cache that and keep track of the max std::string max_hier; float max_vote = -1.0; std::map< std::string, float >::iterator itr = root_map.begin(); for ( ; itr != root_map.end(); ++itr ) { // =-=-=-=-=-=-=- // request the vote float vote = 0.0; std::string voted_hier; irods::error ret = request_vote_for_file_object( _comm, _oper.c_str(), itr->first, _file_obj, voted_hier, vote ); if ( ret.ok() ) { // =-=-=-=-=-=-=- // assign the vote to the root itr->second = vote; // =-=-=-=-=-=-=- // keep track of max vote, hier and resc name if ( vote > max_vote ) { max_vote = vote; max_hier = voted_hier; } } } // for itr // =-=-=-=-=-=-=- // if we have a max vote of 0.0 then // this is an error double diff = ( max_vote - 0.00000001 ); if ( diff <= 0.0 ) { return ERROR( HIERARCHY_ERROR, "no valid resource found for data object" ); } // =-=-=-=-=-=-=- // set out variables _out_hier = max_hier; return SUCCESS(); } // resolve_hier_for_open_or_write_without_keyword
/// =-=-=-=-=-=-=- /// @brief function to handle resolving the hier given the fco and /// resource keyword for create or open depending on the keyword static error resolve_hier_for_create_or_open( rsComm_t* _comm, irods::file_object_ptr _file_obj, const char* _key_word, dataObjInp_t* _data_obj_inp, std::string& _out_hier ) { // =-=-=-=-=-=-=- // regardless we need to resolve the appropriate resource // to do the voting so search the repls for the proper resc std::vector< physical_object > repls = _file_obj->replicas(); bool kw_match_found = false; if ( _key_word ) { // =-=-=-=-=-=-=- // we have a kw present, compare against all the repls for a match for ( size_t i = 0; i < repls.size(); ++i ) { // =-=-=-=-=-=-=- // extract the root resource from the hierarchy std::string root_resc; hierarchy_parser parser; parser.set_string( repls[ i ].resc_hier() ); parser.first_resc( root_resc ); // =-=-=-=-=-=-=- // if we have a match then set open & break, otherwise continue if ( root_resc == _key_word ) { _file_obj->resc_hier( repls[ i ].resc_hier() ); kw_match_found = true; break; } } // for i // =-=-=-=-=-=-=- // if a match is found, resolve it and get the hier string if ( kw_match_found ) { float vote = 0.0; error ret = request_vote_for_file_object( _comm, WRITE_OPERATION, _key_word, _file_obj, _out_hier, vote ); if ( 0.0 == vote ) { if ( ret.code() == 0 ) { ret.code( -1 ); } ret.status( false ); } return PASS( ret ); } // if kw_match_found // =-=-=-=-=-=-=- // NOTE:: if a kw match is not found is this an // error or is falling through acceptable } // =-=-=-=-=-=-=- // either no kw match or no kw, so pick one... return resolve_hier_for_create( _comm, _file_obj, _key_word, _data_obj_inp, _out_hier ); } // resolve_hier_for_create_or_open
/// =-=-=-=-=-=-=- /// @brief function to handle resolving the hier given the fco and /// resource keyword static error resolve_hier_for_create( rsComm_t* _comm, irods::file_object_ptr _file_obj, const char* _key_word, dataObjInp_t* _data_obj_inp, std::string& _out_hier ) { // =-=-=-=-=-=-=- // handle the create operation // check for incoming requested destination resource first std::string resc_name; if ( !_key_word ) { // =-=-=-=-=-=-=- // this is a 'create' operation and no resource is specified, // query the server for the default or other resource to use rescGrpInfo_t* grp_info = 0; int status = getRescGrpForCreate( _comm, _data_obj_inp, &grp_info ); if ( status < 0 || !grp_info || !grp_info->rescInfo ) { // =-=-=-=-=-=-=- // clean up memory delete grp_info->rescInfo; delete grp_info; return ERROR( status, "failed in getRescGrpForCreate" ); } resc_name = grp_info->rescInfo->rescName; // =-=-=-=-=-=-=- // clean up memory delete grp_info->rescInfo; delete grp_info; } else { resc_name = _key_word; } // =-=-=-=-=-=-=- // set the resc hier given the root resc name _file_obj->resc_hier( resc_name ); // =-=-=-=-=-=-=- // get a vote and hier for the create float vote = 0.0; error ret = request_vote_for_file_object( _comm, CREATE_OPERATION, resc_name, _file_obj, _out_hier, vote ); if ( 0.0 == vote ) { if ( ret.code() == 0 ) { ret.code( -1 ); } ret.status( false ); } return PASS( ret ); } // resolve_hier_for_create
// =-=-=-=-=-=-=- // redirect_get - code to determine redirection for get operation irods::error univ_mss_file_redirect_open( irods::plugin_property_map& _prop_map, irods::file_object_ptr _file_obj, const std::string& _resc_name, const std::string& _curr_host, float& _out_vote ) { // =-=-=-=-=-=-=- // determine if the resource is down int resc_status = 0; irods::error get_ret = _prop_map.get< int >( irods::RESOURCE_STATUS, resc_status ); if ( !get_ret.ok() ) { return PASSMSG( "univ_mss_file_redirect_open - failed to get 'status' property", get_ret ); } // =-=-=-=-=-=-=- // if the status is down, vote no. if ( INT_RESC_STATUS_DOWN == resc_status ) { _out_vote = 0.0; return SUCCESS(); } // =-=-=-=-=-=-=- // get the resource host for comparison to curr host std::string host_name; get_ret = _prop_map.get< std::string >( irods::RESOURCE_LOCATION, host_name ); if ( !get_ret.ok() ) { return PASSMSG( "univ_mss_file_redirect_open - failed to get 'location' property", get_ret ); } // =-=-=-=-=-=-=- // set a flag to test if were at the curr host, if so we vote higher bool curr_host = ( _curr_host == host_name ); // =-=-=-=-=-=-=- // make some flags to clairify decision making bool need_repl = ( _file_obj->repl_requested() > -1 ); // =-=-=-=-=-=-=- // set up variables for iteration irods::error final_ret = SUCCESS(); std::vector< irods::physical_object > objs = _file_obj->replicas(); std::vector< irods::physical_object >::iterator itr = objs.begin(); // =-=-=-=-=-=-=- // initially set vote to 0.0 _out_vote = 0.0; // =-=-=-=-=-=-=- // check to see if the replica is in this resource, if one is requested for ( ; itr != objs.end(); ++itr ) { // =-=-=-=-=-=-=- // run the hier string through the parser and get the last // entry. std::string last_resc; irods::hierarchy_parser parser; parser.set_string( itr->resc_hier() ); parser.last_resc( last_resc ); // =-=-=-=-=-=-=- // more flags to simplify decision making bool repl_us = ( _file_obj->repl_requested() == itr->repl_num() ); bool resc_us = ( _resc_name == last_resc ); // =-=-=-=-=-=-=- // success - correct resource and dont need a specific // replication, or the repl nums match if ( resc_us ) { if ( !need_repl || ( need_repl && repl_us ) ) { if ( curr_host ) { _out_vote = 1.0; } else { _out_vote = 0.5; } break; } } // if resc_us } // for itr return SUCCESS(); } // redirect_get
// =-=-=-=-=-=-=- // redirect_open - code to determine redirection for open operation irods::error impostor_resource_redirect_open( irods::plugin_property_map& _prop_map, irods::file_object_ptr _file_obj, const std::string& _resc_name, const std::string& _curr_host, float& _out_vote ) { irods::error result = SUCCESS(); // =-=-=-=-=-=-=- // initially set a good default _out_vote = 0.0; // =-=-=-=-=-=-=- // determine if the resource is down int resc_status = 0; irods::error get_ret = _prop_map.get< int >( irods::RESOURCE_STATUS, resc_status ); if ( ( result = ASSERT_PASS( get_ret, "Failed to get \"status\" property." ) ).ok() ) { // =-=-=-=-=-=-=- // if the status is down, vote no. if ( INT_RESC_STATUS_DOWN != resc_status ) { // =-=-=-=-=-=-=- // get the resource host for comparison to curr host std::string host_name; get_ret = _prop_map.get< std::string >( irods::RESOURCE_LOCATION, host_name ); if ( ( result = ASSERT_PASS( get_ret, "Failed to get \"location\" property." ) ).ok() ) { // =-=-=-=-=-=-=- // set a flag to test if were at the curr host, if so we vote higher bool curr_host = ( _curr_host == host_name ); // =-=-=-=-=-=-=- // make some flags to clarify decision making bool need_repl = ( _file_obj->repl_requested() > -1 ); // =-=-=-=-=-=-=- // set up variables for iteration irods::error final_ret = SUCCESS(); std::vector< irods::physical_object > objs = _file_obj->replicas(); std::vector< irods::physical_object >::iterator itr = objs.begin(); // =-=-=-=-=-=-=- // check to see if the replica is in this resource, if one is requested for ( ; itr != objs.end(); ++itr ) { // =-=-=-=-=-=-=- // run the hier string through the parser and get the last // entry. std::string last_resc; irods::hierarchy_parser parser; parser.set_string( itr->resc_hier() ); parser.last_resc( last_resc ); // =-=-=-=-=-=-=- // more flags to simplify decision making bool repl_us = ( _file_obj->repl_requested() == itr->repl_num() ); bool resc_us = ( _resc_name == last_resc ); bool is_dirty = ( itr->is_dirty() != 1 ); // =-=-=-=-=-=-=- // success - correct resource and don't need a specific // replication, or the repl nums match if ( resc_us ) { // =-=-=-=-=-=-=- // if a specific replica is requested then we // ignore all other criteria if ( need_repl ) { if ( repl_us ) { _out_vote = 1.0; } else { // =-=-=-=-=-=-=- // repl requested and we are not it, vote // very low _out_vote = 0.25; } } else { // =-=-=-=-=-=-=- // if no repl is requested consider dirty flag if ( is_dirty ) { // =-=-=-=-=-=-=- // repl is dirty, vote very low _out_vote = 0.25; } else { // =-=-=-=-=-=-=- // if our repl is not dirty then a local copy // wins, otherwise vote middle of the road if ( curr_host ) { _out_vote = 1.0; } else { _out_vote = 0.5; } } } rodsLog( LOG_DEBUG, "open :: resc name [%s] curr host [%s] resc host [%s] vote [%f]", _resc_name.c_str(), _curr_host.c_str(), host_name.c_str(), _out_vote ); break; } // if resc_us } // for itr } } else { result.code( SYS_RESC_IS_DOWN ); result = PASS( result ); } } return result; } // impostor_resource_redirect_open