// =-=-=-=-=-=-=- // used to allow the resource to determine which host // should provide the requested operation irods::error impostor_resource_redirect_plugin( irods::resource_plugin_context& _ctx, const std::string* _opr, const std::string* _curr_host, irods::hierarchy_parser* _out_parser, float* _out_vote ) { irods::error result = SUCCESS(); // =-=-=-=-=-=-=- // check the context validity irods::error ret = _ctx.valid< irods::file_object >(); if ( ( result = ASSERT_PASS( ret, "Invalid resource context." ) ).ok() ) { // =-=-=-=-=-=-=- // check incoming parameters if ( ( result = ASSERT_ERROR( _opr && _curr_host && _out_parser && _out_vote, SYS_INVALID_INPUT_PARAM, "Invalid input parameter." ) ).ok() ) { // =-=-=-=-=-=-=- // cast down the chain to our understood object type irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() ); // =-=-=-=-=-=-=- // get the name of this resource std::string resc_name; ret = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, resc_name ); if ( ( result = ASSERT_PASS( ret, "Failed in get property for name." ) ).ok() ) { // =-=-=-=-=-=-=- // add ourselves to the hierarchy parser by default _out_parser->add_child( resc_name ); // =-=-=-=-=-=-=- // test the operation to determine which choices to make if ( irods::OPEN_OPERATION == ( *_opr ) || irods::WRITE_OPERATION == ( *_opr ) ) { // =-=-=-=-=-=-=- // call redirect determination for 'get' operation ret = impostor_resource_redirect_open( _ctx.prop_map(), file_obj, resc_name, ( *_curr_host ), ( *_out_vote ) ); result = ASSERT_PASS_MSG( ret, "Failed redirecting for open." ); } else if ( irods::CREATE_OPERATION == ( *_opr ) ) { // =-=-=-=-=-=-=- // call redirect determination for 'create' operation ret = impostor_resource_redirect_create( _ctx.prop_map(), file_obj, resc_name, ( *_curr_host ), ( *_out_vote ) ); result = ASSERT_PASS_MSG( ret, "Failed redirecting for create." ); } else { // =-=-=-=-=-=-=- // must have been passed a bad operation result = ASSERT_ERROR( false, INVALID_OPERATION, "Operation not supported." ); } } } } return result; } // impostor_resource_redirect_plugin
/// =-=-=-=-=-=-=- /// @brief interface to notify of a file modification irods::error round_robin_file_modified( irods::resource_plugin_context& _ctx ) { // =-=-=-=-=-=-=- // get the child resc to call irods::resource_ptr resc; irods::error err = round_robin_get_resc_for_call< irods::file_object >( _ctx, resc ); if ( !err.ok() ) { return PASS( err ); } // =-=-=-=-=-=-=- // call modified on the child err = resc->call( _ctx.comm(), irods::RESOURCE_OP_MODIFIED, _ctx.fco() ); if ( !err.ok() ) { return PASS( err ); } // =-=-=-=-=-=-=- // if file modified is successful then we will update the next // child in the round robin within the database std::string name; _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, name ); std::string next_child; _ctx.prop_map().get< std::string >( NEXT_CHILD_PROP, next_child ); setRoundRobinContextInp_t inp; strncpy( inp.resc_name_, name.c_str(), NAME_LEN ); strncpy( inp.context_, next_child.c_str(), MAX_NAME_LEN ); int status = irods::server_api_call( SET_RR_CTX_AN, _ctx.comm(), &inp, NULL, ( void** ) NULL, NULL ); if ( status < 0 ) { std::stringstream msg; msg << "failed to update round robin context for ["; msg << name << "] with context [" << next_child << "]"; return ERROR( status, msg.str() ); } else { return SUCCESS(); } } // round_robin_file_modified
irods::error round_robin_get_resc_for_call( irods::resource_plugin_context& _ctx, irods::resource_ptr& _resc ) { // =-=-=-=-=-=-=- // check incoming parameters irods::error err = round_robin_check_params< DEST_TYPE >( _ctx ); if ( !err.ok() ) { return PASSMSG( "round_robin_get_resc_for_call - bad resource context", err ); } // =-=-=-=-=-=-=- // get the object's name std::string name; err = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, name ); if ( !err.ok() ) { return PASSMSG( "round_robin_get_resc_for_call - failed to get property 'name'.", err ); } // =-=-=-=-=-=-=- // get the object's hier string boost::shared_ptr< DEST_TYPE > obj = boost::dynamic_pointer_cast< DEST_TYPE >( _ctx.fco() ); std::string hier = obj->resc_hier( ); // =-=-=-=-=-=-=- // get the next child pointer given our name and the hier string err = get_next_child_in_hier( name, hier, _ctx.child_map(), _resc ); if ( !err.ok() ) { return PASSMSG( "round_robin_get_resc_for_call - get_next_child_in_hier failed.", err ); } return SUCCESS(); } // round_robin_get_resc_for_call
// =-=-=-=-=-=-=- // univ_mss__file_rebalance - code which would rebalance the subtree irods::error univ_mss__file_rebalance( irods::resource_plugin_context& _ctx ) { return update_resource_object_count( _ctx.comm(), _ctx.prop_map() ); } // univ_mss__file_rebalancec
// =-=-=-=-=-=-=- // pass_thru_file_rebalance - code which would rebalance the subtree irods::error pass_thru_file_rebalance( irods::resource_plugin_context& _ctx ) { // =-=-=-=-=-=-=- // forward request for rebalance to children irods::error result = SUCCESS(); irods::resource_child_map::iterator itr = _ctx.child_map().begin(); for ( ; itr != _ctx.child_map().end(); ++itr ) { irods::error ret = itr->second.second->call( _ctx.comm(), irods::RESOURCE_OP_REBALANCE, _ctx.fco() ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); result = ret; } } if( !result.ok() ) { return PASS( result ); } return update_resource_object_count( _ctx.comm(), _ctx.prop_map() ); } // pass_thru_file_rebalancec
irods::error random_get_resc_for_call( irods::resource_plugin_context& _ctx, irods::resource_ptr& _resc ) { irods::error result = SUCCESS(); // =-=-=-=-=-=-=- // check incoming parameters irods::error err = random_check_params< DEST_TYPE >( _ctx ); if ( ( result = ASSERT_PASS( err, "Bad resource context." ) ).ok() ) { // =-=-=-=-=-=-=- // get the object's name std::string name; err = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, name ); if ( ( result = ASSERT_PASS( err, "Failed to get property." ) ).ok() ) { // =-=-=-=-=-=-=- // get the object's hier string boost::shared_ptr< DEST_TYPE > dst_obj = boost::dynamic_pointer_cast< DEST_TYPE >( _ctx.fco() ); std::string hier = dst_obj->resc_hier( ); // =-=-=-=-=-=-=- // get the next child pointer given our name and the hier string err = get_next_child_in_hier( name, hier, _ctx.child_map(), _resc ); result = ASSERT_PASS( err, "Get next child failed." ); } } return result; } // random_get_resc_for_call
// =-=-=-=-=-=-=- // unixStageToCache - This routine is for testing the TEST_STAGE_FILE_TYPE. // Just copy the file from filename to cacheFilename. optionalInfo info // is not used. irods::error mock_archive_stagetocache_plugin( irods::resource_plugin_context& _ctx, const char* _cache_file_name ) { irods::error result = SUCCESS(); // =-=-=-=-=-=-=- // Check the operation parameters and update the physical path irods::error ret = unix_check_params_and_path< irods::file_object >( _ctx ); if ( ( result = ASSERT_PASS( ret, "Invalid plugin context." ) ).ok() ) { // =-=-=-=-=-=-=- // get ref to fco irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() ); // =-=-=-=-=-=-=- // get the vault path for the resource std::string path; ret = _ctx.prop_map().get< std::string >( irods::RESOURCE_PATH, path ); if ( ( result = ASSERT_PASS( ret, "Failed to retrieve vault path for resource." ) ).ok() ) { // =-=-=-=-=-=-=- // append the hash to the path as the new 'cache file name' path += "/"; path += fco->physical_path().c_str(); int status = mockArchiveCopyPlugin( fco->mode(), fco->physical_path().c_str(), _cache_file_name ); result = ASSERT_ERROR( status >= 0, status, "Failed copying archive file: \"%s\" to cache file: \"%s\".", fco->physical_path().c_str(), _cache_file_name ); } } return result; } // mock_archive_stagetocache_plugin
/// =-=-=-=-=-=-=- /// @brief used to allow the resource to determine which host /// should provide the requested operation irods::error load_balanced_redirect( irods::resource_plugin_context& _ctx, const std::string* _opr, const std::string* _curr_host, irods::hierarchy_parser* _out_parser, float* _out_vote ) { irods::error result = SUCCESS(); // =-=-=-=-=-=-=- // check incoming parameters irods::error err = load_balanced_check_params< irods::file_object >( _ctx ); if ( ( result = ASSERT_PASS( err, "Invalid resource context." ) ).ok() ) { if ( ( result = ASSERT_ERROR( _opr && _curr_host && _out_parser && _out_vote, SYS_INVALID_INPUT_PARAM, "Invalid parameters." ) ).ok() ) { // =-=-=-=-=-=-=- // get the object's hier string irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() ); std::string hier = file_obj->resc_hier( ); // =-=-=-=-=-=-=- // get the object's hier string std::string name; err = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, name ); if ( ( result = ASSERT_PASS( err, "Failed to get property: \"%s\".", irods::RESOURCE_NAME.c_str() ) ).ok() ) { // =-=-=-=-=-=-=- // add ourselves into the hierarch before calling child resources _out_parser->add_child( name ); // =-=-=-=-=-=-=- // test the operation to determine which choices to make if ( irods::OPEN_OPERATION == ( *_opr ) || irods::WRITE_OPERATION == ( *_opr ) ) { std::string err_msg = "failed in resolve hierarchy for [" + ( *_opr ) + "]"; err = load_balanced_redirect_for_open_operation( _ctx, _opr, _curr_host, _out_parser, _out_vote ); result = ASSERT_PASS( err, err_msg ); } else if ( irods::CREATE_OPERATION == ( *_opr ) ) { // =-=-=-=-=-=-=- // get the next_child resource for create irods::resource_ptr resc; std::string err_msg = "failed in resolve hierarchy for [" + ( *_opr ) + "]"; err = load_balanced_redirect_for_create_operation( _ctx, _opr, _curr_host, _out_parser, _out_vote ); result = ASSERT_PASS( err, err_msg ); } else { // =-=-=-=-=-=-=- // must have been passed a bad operation result = ASSERT_ERROR( false, INVALID_OPERATION, "Operation not supported: \"%s\".", _opr->c_str() ); } } } } return result; } // load_balanced_redirect
// =-=-=-=-=-=-=- /// @brief update the physical path in the file object irods::error unix_check_path( irods::resource_plugin_context& _ctx ) { irods::error result = SUCCESS(); try { irods::data_object_ptr data_obj = boost::dynamic_pointer_cast< irods::data_object >( _ctx.fco() ); // =-=-=-=-=-=-=- // NOTE: Must do this for all storage resources std::string full_path; irods::error ret = mock_archive_generate_full_path( _ctx.prop_map(), data_obj->physical_path(), full_path ); if ( ( result = ASSERT_PASS( ret, "Failed generating full path for object." ) ).ok() ) { data_obj->physical_path( full_path ); } return result; } catch ( const std::bad_cast& ) { return ERROR( SYS_INVALID_INPUT_PARAM, "failed to cast fco to data_object" ); } } // unix_check_path
// =-=-=-=-=-=-=- // unixRedirectPlugin - used to allow the resource to determine which host // should provide the requested operation irods::error pass_thru_redirect_plugin( irods::resource_plugin_context& _ctx, const std::string* _opr, const std::string* _curr_host, irods::hierarchy_parser* _out_parser, float* _out_vote ) { // =-=-=-=-=-=-=- // check incoming parameters irods::error result = SUCCESS(); irods::error ret = pass_thru_check_params( _ctx ); if ( !ret.ok() ) { result = PASSMSG( "pass_thru_redirect_plugin - invalid resource context.", ret ); } if ( !_opr ) { return ERROR( SYS_INVALID_INPUT_PARAM, "pass_thru_redirect_plugin - null operation" ); } if ( !_curr_host ) { return ERROR( SYS_INVALID_INPUT_PARAM, "pass_thru_redirect_plugin - null operation" ); } if ( !_out_parser ) { return ERROR( SYS_INVALID_INPUT_PARAM, "pass_thru_redirect_plugin - null outgoing hier parser" ); } if ( !_out_vote ) { return ERROR( SYS_INVALID_INPUT_PARAM, "pass_thru_redirect_plugin - null outgoing vote" ); } // =-=-=-=-=-=-=- // get the name of this resource std::string resc_name; ret = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, resc_name ); if ( !ret.ok() ) { std::stringstream msg; msg << "pass_thru_redirect_plugin - failed in get property for name"; return ERROR( -1, msg.str() ); } // =-=-=-=-=-=-=- // add ourselves to the hierarchy parser by default _out_parser->add_child( resc_name ); irods::resource_ptr resc; ret = pass_thru_get_first_chid_resc( _ctx.child_map(), resc ); if ( !ret.ok() ) { return PASSMSG( "pass_thru_redirect_plugin - failed getting the first child resource pointer.", ret ); } return resc->call < const std::string*, const std::string*, irods::hierarchy_parser*, float* > ( _ctx.comm(), irods::RESOURCE_OP_RESOLVE_RESC_HIER, _ctx.fco(), _opr, _curr_host, _out_parser, _out_vote ); } // pass_thru_redirect_plugin
// =-=-=-=-=-=-=- // mock_archive_rebalance - code which would rebalance the subtree irods::error mock_archive_rebalance( irods::resource_plugin_context& _ctx ) { return update_resource_object_count( _ctx.comm(), _ctx.prop_map() ); } // mock_archive_file_rebalancec
// =-=-=-=-=-=-=- // interface for POSIX readdir irods::error mock_archive_rename_plugin( irods::resource_plugin_context& _ctx, const char* _new_file_name ) { // =-=-=-=-=-=-=- // Check the operation parameters and update the physical path irods::error result = SUCCESS(); irods::error ret = unix_check_params_and_path< irods::data_object >( _ctx ); if ( ( result = ASSERT_PASS( ret, "Invalid parameters or physical path." ) ).ok() ) { // =-=-=-=-=-=-=- // manufacture a new path from the new file name std::string new_full_path; ret = mock_archive_generate_full_path( _ctx.prop_map(), _new_file_name, new_full_path ); if ( ( result = ASSERT_PASS( ret, "Unable to generate full path for destination file: \"%s\".", _new_file_name ) ).ok() ) { // =-=-=-=-=-=-=- // cast down the hierarchy to the desired object irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() ); // =-=-=-=-=-=-=- // get hashed names for the old path std::string new_hash; ret = make_hashed_path( _ctx.prop_map(), _new_file_name, new_hash ); if ( ( result = ASSERT_PASS( ret, "Failed to gen hashed path" ) ).ok() ) { // =-=-=-=-=-=-=- // make the call to rename int status = rename( fco->physical_path().c_str(), new_hash.c_str() ); // =-=-=-=-=-=-=- // handle error cases int err_status = UNIX_FILE_RENAME_ERR - errno; if ( ( result = ASSERT_ERROR( status >= 0, err_status, "Rename error for \"%s\" to \"%s\", errno = \"%s\", status = %d.", fco->physical_path().c_str(), new_hash.c_str(), strerror( errno ), err_status ) ).ok() ) { fco->physical_path( new_hash ); result.code( status ); } } } } return result; } // mock_archive_rename_plugin
/// =-=-=-=-=-=-=- /// @brief This routine is for testing the TEST_STAGE_FILE_TYPE. /// Just copy the file from filename to cacheFilename. optionalInfo info /// is not used. irods::error univ_mss_file_stage_to_cache( irods::resource_plugin_context& _ctx, const char* _cache_file_name ) { // =-=-=-=-=-=-=- // check context irods::error err = univ_mss_check_param< irods::file_object >( _ctx ); if ( !err.ok() ) { std::stringstream msg; msg << __FUNCTION__; msg << " - invalid context"; return PASSMSG( msg.str(), err ); } // =-=-=-=-=-=-=- // snag a ref to the fco irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() ); std::string filename = fco->physical_path(); // =-=-=-=-=-=-=- // get the script property std::string script; err = _ctx.prop_map().get< std::string >( SCRIPT_PROP, script ); if ( !err.ok() ) { return PASSMSG( __FUNCTION__, err ); } int status = 0; execCmd_t execCmdInp; char cmdArgv[HUGE_NAME_LEN] = ""; execCmdOut_t *execCmdOut = NULL; bzero( &execCmdInp, sizeof( execCmdInp ) ); rstrcpy( execCmdInp.cmd, script.c_str(), LONG_NAME_LEN ); strcat( cmdArgv, "stageToCache" ); strcat( cmdArgv, " '" ); strcat( cmdArgv, filename.c_str() ); strcat( cmdArgv, "' '" ); strcat( cmdArgv, _cache_file_name ); strcat( cmdArgv, "'" ); rstrcpy( execCmdInp.cmdArgv, cmdArgv, HUGE_NAME_LEN ); rstrcpy( execCmdInp.execAddr, "localhost", LONG_NAME_LEN ); status = _rsExecCmd( _ctx.comm(), &execCmdInp, &execCmdOut ); if ( status < 0 ) { status = UNIV_MSS_STAGETOCACHE_ERR - errno; std::stringstream msg; msg << "univ_mss_file_stage_to_cache: staging from ["; msg << _cache_file_name; msg << "] to ["; msg << filename; msg << "] failed."; return ERROR( status, msg.str() ); } return CODE( status ); } // univ_mss_file_stage_to_cache
/// =-=-=-=-=-=-=- /// @brief interface for POSIX mkdir irods::error univ_mss_file_mkdir( irods::resource_plugin_context& _ctx ) { // =-=-=-=-=-=-=- // check context irods::error err = univ_mss_check_param< irods::collection_object >( _ctx ); if ( !err.ok() ) { std::stringstream msg; msg << __FUNCTION__; msg << " - invalid context"; return PASSMSG( msg.str(), err ); } // =-=-=-=-=-=-=- // get the script property std::string script; err = _ctx.prop_map().get< std::string >( SCRIPT_PROP, script ); if ( !err.ok() ) { return PASSMSG( __FUNCTION__, err ); } // =-=-=-=-=-=-=- // snag a ref to the fco irods::collection_object_ptr fco = boost::dynamic_pointer_cast< irods::collection_object >( _ctx.fco() ); std::string dirname = fco->physical_path(); int status = 0; execCmd_t execCmdInp; char cmdArgv[HUGE_NAME_LEN] = ""; execCmdOut_t *execCmdOut = NULL; bzero( &execCmdInp, sizeof( execCmdInp ) ); rstrcpy( execCmdInp.cmd, script.c_str(), LONG_NAME_LEN ); strcat( cmdArgv, "mkdir" ); strcat( cmdArgv, " '" ); strcat( cmdArgv, dirname.c_str() ); strcat( cmdArgv, "'" ); rstrcpy( execCmdInp.cmdArgv, cmdArgv, HUGE_NAME_LEN ); rstrcpy( execCmdInp.execAddr, "localhost", LONG_NAME_LEN ); status = _rsExecCmd( _ctx.comm(), &execCmdInp, &execCmdOut ); if ( status < 0 ) { status = UNIV_MSS_MKDIR_ERR - errno; std::stringstream msg; msg << "univ_mss_file_mkdir - mkdir failed for ["; msg << dirname; msg << "]"; return ERROR( status, msg.str() ); } int mode = getDefDirMode(); fco->mode( mode ); err = univ_mss_file_chmod( _ctx ); return err; } // univ_mss_file_mkdir
/// =-=-=-=-=-=-=- /// @brief interface for POSIX chmod irods::error univ_mss_file_chmod( irods::resource_plugin_context& _ctx ) { // =-=-=-=-=-=-=- // check context irods::error err = univ_mss_check_param< irods::data_object >( _ctx ); if ( !err.ok() ) { std::stringstream msg; msg << __FUNCTION__; msg << " - invalid context"; return PASSMSG( msg.str(), err ); } // =-=-=-=-=-=-=- // get the script property std::string script; err = _ctx.prop_map().get< std::string >( SCRIPT_PROP, script ); if ( !err.ok() ) { return PASSMSG( __FUNCTION__, err ); } // =-=-=-=-=-=-=- // snag a ref to the fco irods::data_object_ptr fco = boost::dynamic_pointer_cast< irods::data_object >( _ctx.fco() ); std::string filename = fco->physical_path(); int mode = fco->mode(); int status = 0; execCmd_t execCmdInp; if ( mode != getDefDirMode() ) { mode = getDefFileMode(); } bzero( &execCmdInp, sizeof( execCmdInp ) ); snprintf( execCmdInp.cmd, sizeof( execCmdInp.cmd ), "%s", script.c_str() ); snprintf( execCmdInp.cmdArgv, sizeof( execCmdInp.cmdArgv ), "chmod '%s' %o", filename.c_str(), mode ); snprintf( execCmdInp.execAddr, sizeof( execCmdInp.execAddr ), "%s", "localhost" ); execCmdOut_t *execCmdOut = NULL; status = _rsExecCmd( &execCmdInp, &execCmdOut ); freeCmdExecOut( execCmdOut ); if ( status < 0 ) { status = UNIV_MSS_CHMOD_ERR - errno; std::stringstream msg; msg << "univ_mss_file_chmod - failed for ["; msg << filename; msg << "]"; return ERROR( status, msg.str() ); } return CODE( status ); } // univ_mss_file_chmod
// =-=-=-=-=-=-=- // unixSyncToArch - This routine is for testing the TEST_STAGE_FILE_TYPE. // Just copy the file from cacheFilename to filename. optionalInfo info // is not used. irods::error mock_archive_synctoarch_plugin( irods::resource_plugin_context& _ctx, char* _cache_file_name ) { irods::error result = SUCCESS(); // =-=-=-=-=-=-=- // Check the operation parameters and update the physical path irods::error ret = unix_check_params_and_path< irods::file_object >( _ctx ); if ( ( result = ASSERT_PASS( ret, "Invalid plugin context." ) ).ok() ) { // =-=-=-=-=-=-=- // get ref to fco irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() ); // =-=-=-=-=-=-=- // get the vault path for the resource std::string path; ret = make_hashed_path( _ctx.prop_map(), fco->physical_path(), path ); if ( ( result = ASSERT_PASS( ret, "Failed to gen hashed path" ) ).ok() ) { // =-=-=-=-=-=-=- // append the hash to the path as the new 'cache file name' rodsLog( LOG_NOTICE, "mock archive :: cache file name [%s]", _cache_file_name ); rodsLog( LOG_NOTICE, "mock archive :: new hashed file name for [%s] is [%s]", fco->physical_path().c_str(), path.c_str() ); // =-=-=-=-=-=-=- // make the directories in the path to the new file std::string new_path = path; std::size_t last_slash = new_path.find_last_of( '/' ); new_path.erase( last_slash ); ret = mock_archive_mkdir_r( new_path.c_str(), 0750 ); if ( ( result = ASSERT_PASS( ret, "Mkdir error for \"%s\".", new_path.c_str() ) ).ok() ) { } // =-=-=-=-=-=-=- // make the copy to the 'archive' int status = mockArchiveCopyPlugin( fco->mode(), _cache_file_name, path.c_str() ); if ( ( result = ASSERT_ERROR( status >= 0, status, "Sync to arch failed." ) ).ok() ) { fco->physical_path( path ); } } } return result; } // mock_archive_synctoarch_plugin
/// =-=-=-=-=-=-=- /// @brief used to allow the resource to determine which host /// should provide the requested operation irods::error round_robin_redirect( irods::resource_plugin_context& _ctx, const std::string* _opr, const std::string* _curr_host, irods::hierarchy_parser* _out_parser, float* _out_vote ) { // =-=-=-=-=-=-=- // check incoming parameters irods::error err = round_robin_check_params< irods::file_object >( _ctx ); if ( !err.ok() ) { return PASSMSG( "round_robin_redirect - bad resource context", err ); } if ( !_opr ) { return ERROR( SYS_INVALID_INPUT_PARAM, "round_robin_redirect - null operation" ); } if ( !_curr_host ) { return ERROR( SYS_INVALID_INPUT_PARAM, "round_robin_redirect - null host" ); } if ( !_out_parser ) { return ERROR( SYS_INVALID_INPUT_PARAM, "round_robin_redirect - null outgoing hier parser" ); } if ( !_out_vote ) { return ERROR( SYS_INVALID_INPUT_PARAM, "round_robin_redirect - null outgoing vote" ); } // =-=-=-=-=-=-=- // get the object's hier string irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() ); std::string hier = file_obj->resc_hier( ); // =-=-=-=-=-=-=- // get the object's hier string std::string name; err = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, name ); if ( !err.ok() ) { return PASSMSG( "failed to get property 'name'.", err ); } // =-=-=-=-=-=-=- // add ourselves into the hierarch before calling child resources _out_parser->add_child( name ); // =-=-=-=-=-=-=- // test the operation to determine which choices to make if ( irods::OPEN_OPERATION == ( *_opr ) || irods::WRITE_OPERATION == ( *_opr ) ) { // =-=-=-=-=-=-=- // get the next child pointer in the hierarchy, given our name and the hier string irods::resource_ptr resc; err = get_next_child_for_open_or_write( name, file_obj, _ctx.child_map(), resc ); if ( !err.ok() ) { (*_out_vote) = 0.0; return PASS( err ); } // =-=-=-=-=-=-=- // forward the redirect call to the child for assertion of the whole operation, // there may be more than a leaf beneath us return resc->call < const std::string*, const std::string*, irods::hierarchy_parser*, float* > ( _ctx.comm(), irods::RESOURCE_OP_RESOLVE_RESC_HIER, _ctx.fco(), _opr, _curr_host, _out_parser, _out_vote ); std::string hier; _out_parser->str( hier ); rodsLog( LOG_DEBUG, "open :: resc hier [%s] vote [%f]", hier.c_str(), _out_vote ); } else if ( irods::CREATE_OPERATION == ( *_opr ) ) { // =-=-=-=-=-=-=- // get the next available child resource irods::resource_ptr resc; irods::error err = get_next_valid_child_resource( _ctx.prop_map(), _ctx.child_map(), resc ); if ( !err.ok() ) { return PASS( err ); } // =-=-=-=-=-=-=- // forward the 'put' redirect to the appropriate child err = resc->call < const std::string*, const std::string*, irods::hierarchy_parser*, float* > ( _ctx.comm(), irods::RESOURCE_OP_RESOLVE_RESC_HIER, _ctx.fco(), _opr, _curr_host, _out_parser, _out_vote ); if ( !err.ok() ) { return PASSMSG( "forward of put redirect failed", err ); } std::string hier; _out_parser->str( hier ); rodsLog( LOG_DEBUG, "round robin - create :: resc hier [%s] vote [%f]", hier.c_str(), _out_vote ); std::string new_hier; _out_parser->str( new_hier ); // =-=-=-=-=-=-=- // update the next_child appropriately as the above succeeded err = update_next_child_resource( _ctx.prop_map() ); if ( !err.ok() ) { return PASSMSG( "update_next_child_resource failed", err ); } return SUCCESS(); } // =-=-=-=-=-=-=- // must have been passed a bad operation std::stringstream msg; msg << "round_robin_redirect - operation not supported ["; msg << ( *_opr ) << "]"; return ERROR( -1, msg.str() ); } // round_robin_redirect
// =-=-=-=-=-=-=- // used to allow the resource to determine which host // should provide the requested operation irods::error univ_mss_file_redirect( irods::resource_plugin_context& _ctx, const std::string* _opr, const std::string* _curr_host, irods::hierarchy_parser* _out_parser, float* _out_vote ) { // =-=-=-=-=-=-=- // check the context validity irods::error ret = _ctx.valid< irods::file_object >(); if ( !ret.ok() ) { std::stringstream msg; msg << __FUNCTION__ << " - resource context is invalid"; return PASSMSG( msg.str(), ret ); } // =-=-=-=-=-=-=- // check incoming parameters if ( !_opr ) { return ERROR( -1, "univ_mss_file_redirect- null operation" ); } if ( !_curr_host ) { return ERROR( -1, "univ_mss_file_redirect- null operation" ); } if ( !_out_parser ) { return ERROR( -1, "univ_mss_file_redirect- null outgoing hier parser" ); } if ( !_out_vote ) { return ERROR( -1, "univ_mss_file_redirect- null outgoing vote" ); } // =-=-=-=-=-=-=- // cast down the chain to our understood object type irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() ); // =-=-=-=-=-=-=- // get the name of this resource std::string resc_name; ret = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, resc_name ); if ( !ret.ok() ) { std::stringstream msg; msg << "univ_mss_file_redirect- failed in get property for name"; return ERROR( -1, msg.str() ); } // =-=-=-=-=-=-=- // add ourselves to the hierarchy parser by default _out_parser->add_child( resc_name ); // =-=-=-=-=-=-=- // test the operation to determine which choices to make if ( irods::OPEN_OPERATION == ( *_opr ) ) { // =-=-=-=-=-=-=- // call redirect determination for 'get' operation return univ_mss_file_redirect_open( _ctx.prop_map(), file_obj, resc_name, ( *_curr_host ), ( *_out_vote ) ); } else if ( irods::CREATE_OPERATION == ( *_opr ) ) { // =-=-=-=-=-=-=- // call redirect determination for 'create' operation return univ_mss_file_redirect_create( _ctx.prop_map(), file_obj, resc_name, ( *_curr_host ), ( *_out_vote ) ); } // =-=-=-=-=-=-=- // must have been passed a bad operation std::stringstream msg; msg << "univ_mss_file_redirect- operation not supported ["; msg << ( *_opr ) << "]"; return ERROR( -1, msg.str() ); } // univ_mss_file_redirect
/// =-=-=-=-=-=-=- /// @brief This routine is for testing the TEST_STAGE_FILE_TYPE. /// Just copy the file from cacheFilename to filename. optionalInfo info /// is not used. irods::error univ_mss_file_sync_to_arch( irods::resource_plugin_context& _ctx, const char* _cache_file_name ) { // =-=-=-=-=-=-=- // check context irods::error err = univ_mss_check_param< irods::file_object >( _ctx ); if ( !err.ok() ) { std::stringstream msg; msg << __FUNCTION__; msg << " - invalid context"; return PASSMSG( msg.str(), err ); } // =-=-=-=-=-=-=- // snag a ref to the fco irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() ); std::string filename = fco->physical_path(); // =-=-=-=-=-=-=- // first create the directory name char dirname[MAX_NAME_LEN] = ""; const char* lastpart = strrchr( filename.c_str(), '/' ); int lenDir = strlen( filename.c_str() ) - strlen( lastpart ); strncpy( dirname, filename.c_str(), lenDir ); // =-=-=-=-=-=-=- // create a context to call the mkdir operation irods::collection_object_ptr coll_obj( new irods::collection_object( dirname, fco->resc_hier(), fco->mode(), 0 ) ); irods::resource_plugin_context context( _ctx.prop_map(), coll_obj, "", _ctx.comm(), _ctx.child_map() ); // =-=-=-=-=-=-=- // create the directory on the MSS int status = 0; err = univ_mss_file_mkdir( context ); execCmdOut_t* execCmdOut = NULL; char cmdArgv[HUGE_NAME_LEN] = ""; execCmd_t execCmdInp; bzero( &execCmdInp, sizeof( execCmdInp ) ); // =-=-=-=-=-=-=- // get the script property std::string script; err = _ctx.prop_map().get< std::string >( SCRIPT_PROP, script ); if ( !err.ok() ) { return PASSMSG( __FUNCTION__, err ); } rstrcpy( execCmdInp.cmd, script.c_str(), LONG_NAME_LEN ); strcat( cmdArgv, "syncToArch" ); strcat( cmdArgv, " " ); strcat( cmdArgv, _cache_file_name ); strcat( cmdArgv, " " ); strcat( cmdArgv, filename.c_str() ); strcat( cmdArgv, "" ); rstrcpy( execCmdInp.cmdArgv, cmdArgv, HUGE_NAME_LEN ); rstrcpy( execCmdInp.execAddr, "localhost", LONG_NAME_LEN ); status = _rsExecCmd( _ctx.comm(), &execCmdInp, &execCmdOut ); if ( status == 0 ) { err = univ_mss_file_chmod( _ctx ); if ( !err.ok() ) { PASSMSG( "univ_mss_file_sync_to_arch - failed.", err ); } } else { status = UNIV_MSS_SYNCTOARCH_ERR - errno; std::stringstream msg; msg << "univ_mss_file_sync_to_arch: copy of ["; msg << _cache_file_name; msg << "] to ["; msg << filename; msg << "] failed."; msg << " stdout buff ["; msg << execCmdOut->stdoutBuf.buf; msg << "] stderr buff ["; msg << execCmdOut->stderrBuf.buf; msg << "] status ["; msg << execCmdOut->status << "]"; return ERROR( status, msg.str() ); } return CODE( status ); } // univ_mss_file_sync_to_arch
// =-=-=-=-=-=-=- // unixRedirectPlugin - used to allow the resource to determine which host // should provide the requested operation irods::error passthru_redirect_plugin( irods::resource_plugin_context& _ctx, const std::string* _opr, const std::string* _curr_host, irods::hierarchy_parser* _out_parser, float* _out_vote ) { // =-=-=-=-=-=-=- // check incoming parameters irods::error result = SUCCESS(); irods::error ret = passthru_check_params( _ctx ); if ( !ret.ok() ) { result = PASSMSG( "passthru_redirect_plugin - invalid resource context.", ret ); } if ( !_opr ) { return ERROR( SYS_INVALID_INPUT_PARAM, "passthru_redirect_plugin - null operation" ); } if ( !_curr_host ) { return ERROR( SYS_INVALID_INPUT_PARAM, "passthru_redirect_plugin - null operation" ); } if ( !_out_parser ) { return ERROR( SYS_INVALID_INPUT_PARAM, "passthru_redirect_plugin - null outgoing hier parser" ); } if ( !_out_vote ) { return ERROR( SYS_INVALID_INPUT_PARAM, "passthru_redirect_plugin - null outgoing vote" ); } // =-=-=-=-=-=-=- // get the name of this resource std::string resc_name; ret = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, resc_name ); if ( !ret.ok() ) { std::stringstream msg; msg << "passthru_redirect_plugin - failed in get property for name"; return ERROR( -1, msg.str() ); } // =-=-=-=-=-=-=- // add ourselves to the hierarchy parser by default _out_parser->add_child( resc_name ); irods::resource_ptr resc; ret = passthru_get_first_child_resc( _ctx.child_map(), resc ); if ( !ret.ok() ) { return PASSMSG( "passthru_redirect_plugin - failed getting the first child resource pointer.", ret ); } irods::error final_ret = resc->call < const std::string*, const std::string*, irods::hierarchy_parser*, float* > ( _ctx.comm(), irods::RESOURCE_OP_RESOLVE_RESC_HIER, _ctx.fco(), _opr, _curr_host, _out_parser, _out_vote ); double orig_vote = *_out_vote; if ( irods::OPEN_OPERATION == ( *_opr ) && _ctx.prop_map().has_entry( READ_WEIGHT_KW ) ) { double read_weight = 1.0; ret = _ctx.prop_map().get<double>( READ_WEIGHT_KW, read_weight ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); } else { ( *_out_vote ) *= read_weight; } } else if ( ( irods::CREATE_OPERATION == ( *_opr ) || irods::WRITE_OPERATION == ( *_opr ) ) && _ctx.prop_map().has_entry( WRITE_WEIGHT_KW ) ) { double write_weight = 1.0; ret = _ctx.prop_map().get<double>( WRITE_WEIGHT_KW, write_weight ); if ( !ret.ok() ) { irods::log( PASS( ret ) ); } else { ( *_out_vote ) *= write_weight; } } rodsLog( LOG_DEBUG, "passthru_redirect_plugin - [%s] : %f - %f", _opr->c_str(), orig_vote, *_out_vote ); return final_ret; } // passthru_redirect_plugin
/// =-=-=-=-=-=-=- /// @brief used to allow the resource to determine which host /// should provide the requested operation irods::error random_redirect( irods::resource_plugin_context& _ctx, const std::string* _opr, const std::string* _curr_host, irods::hierarchy_parser* _out_parser, float* _out_vote ) { irods::error result = SUCCESS(); // =-=-=-=-=-=-=- // check incoming parameters irods::error err = random_check_params< irods::file_object >( _ctx ); if ( ( result = ASSERT_PASS( err, "Invalid resource context." ) ).ok() ) { if ( ( result = ASSERT_ERROR( _opr && _curr_host && _out_parser && _out_vote, SYS_INVALID_INPUT_PARAM, "Invalid parameters." ) ).ok() ) { // =-=-=-=-=-=-=- // get the object's hier string irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() ); std::string hier = file_obj->resc_hier( ); // =-=-=-=-=-=-=- // get the object's hier string std::string name; err = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, name ); if ( ( result = ASSERT_PASS( err, "Failed to get property: \"%s\".", irods::RESOURCE_NAME.c_str() ) ).ok() ) { // =-=-=-=-=-=-=- // add ourselves into the hierarchy before calling child resources _out_parser->add_child( name ); // =-=-=-=-=-=-=- // test the operation to determine which choices to make if ( irods::OPEN_OPERATION == ( *_opr ) || irods::WRITE_OPERATION == ( *_opr ) || irods::UNLINK_OPERATION == ( *_opr )) { // =-=-=-=-=-=-=- // get the next child pointer in the hierarchy, given our name and the hier string irods::resource_ptr resc; err = get_next_child_for_open_or_write( name, file_obj, _ctx.child_map(), resc ); if ( err.ok() ) { // =-=-=-=-=-=-=- // forward the redirect call to the child for assertion of the whole operation, // there may be more than a leaf beneath us err = resc->call< const std::string*, const std::string*, irods::hierarchy_parser*, float* >( _ctx.comm(), irods::RESOURCE_OP_RESOLVE_RESC_HIER, _ctx.fco(), _opr, _curr_host, _out_parser, _out_vote ); result = ASSERT_PASS( err, "Failed calling child operation." ); } else if ( err.code() == REPLICA_NOT_IN_RESC ) { *_out_vote = 0; } else { result = err; } } else if ( irods::CREATE_OPERATION == ( *_opr ) ) { // =-=-=-=-=-=-=- // get the next_child resource for create irods::resource_ptr resc; err = get_next_valid_child_resource( _ctx, _opr, _curr_host, _out_parser, _out_vote ); result = ASSERT_PASS( err, "Failed getting next valid child." ); } else { // =-=-=-=-=-=-=- // must have been passed a bad operation result = ASSERT_ERROR( false, INVALID_OPERATION, "Operation not supported: \"%s\".", _opr->c_str() ); } } } } return result; } // random_redirect
/// =-=-=-=-=-=-=- /// @brief interface for POSIX Stat irods::error univ_mss_file_stat( irods::resource_plugin_context& _ctx, struct stat* _statbuf ) { // =-=-=-=-=-=-=- // check context irods::error err = univ_mss_check_param< irods::data_object >( _ctx ); if ( !err.ok() ) { std::stringstream msg; msg << __FUNCTION__; msg << " - invalid context"; return PASSMSG( msg.str(), err ); } // =-=-=-=-=-=-=- // get the script property std::string script; err = _ctx.prop_map().get< std::string >( SCRIPT_PROP, script ); if ( !err.ok() ) { return PASSMSG( __FUNCTION__, err ); } // =-=-=-=-=-=-=- // snag a ref to the fco irods::data_object_ptr fco = boost::dynamic_pointer_cast< irods::data_object >( _ctx.fco() ); std::string filename = fco->physical_path(); int i, status; execCmd_t execCmdInp; char cmdArgv[HUGE_NAME_LEN] = ""; char splchain1[13][MAX_NAME_LEN], splchain2[4][MAX_NAME_LEN], splchain3[3][MAX_NAME_LEN]; char *outputStr; const char *delim1 = ":\n"; const char *delim2 = "-"; const char *delim3 = "."; execCmdOut_t *execCmdOut = NULL; struct tm mytm; time_t myTime; bzero( &execCmdInp, sizeof( execCmdInp ) ); rstrcpy( execCmdInp.cmd, script.c_str(), LONG_NAME_LEN ); strcat( cmdArgv, "stat" ); strcat( cmdArgv, " '" ); strcat( cmdArgv, filename.c_str() ); strcat( cmdArgv, "' " ); rstrcpy( execCmdInp.cmdArgv, cmdArgv, HUGE_NAME_LEN ); rstrcpy( execCmdInp.execAddr, "localhost", LONG_NAME_LEN ); status = _rsExecCmd( _ctx.comm(), &execCmdInp, &execCmdOut ); if ( status == 0 && NULL != execCmdOut ) { // JMC cppcheck - nullptr if ( execCmdOut->stdoutBuf.buf != NULL ) { outputStr = ( char* )execCmdOut->stdoutBuf.buf; memset( &splchain1, 0, sizeof( splchain1 ) ); strSplit( outputStr, delim1, splchain1 ); _statbuf->st_dev = atoi( splchain1[0] ); _statbuf->st_ino = atoi( splchain1[1] ); _statbuf->st_mode = atoi( splchain1[2] ); _statbuf->st_nlink = atoi( splchain1[3] ); _statbuf->st_uid = atoi( splchain1[4] ); _statbuf->st_gid = atoi( splchain1[5] ); _statbuf->st_rdev = atoi( splchain1[6] ); _statbuf->st_size = atoll( splchain1[7] ); _statbuf->st_blksize = atoi( splchain1[8] ); _statbuf->st_blocks = atoi( splchain1[9] ); for ( i = 0; i < 3; i++ ) { memset( &splchain2, 0, sizeof( splchain2 ) ); memset( &splchain3, 0, sizeof( splchain3 ) ); strSplit( splchain1[10 + i], delim2, splchain2 ); mytm.tm_year = atoi( splchain2[0] ) - 1900; mytm.tm_mon = atoi( splchain2[1] ) - 1; mytm.tm_mday = atoi( splchain2[2] ); strSplit( splchain2[3], delim3, splchain3 ); mytm.tm_hour = atoi( splchain3[0] ); mytm.tm_min = atoi( splchain3[1] ); mytm.tm_sec = atoi( splchain3[2] ); myTime = mktime( &mytm ); switch ( i ) { case 0: _statbuf->st_atime = myTime; break; case 1: _statbuf->st_mtime = myTime; break; case 2: _statbuf->st_ctime = myTime; break; } } } } else { status = UNIV_MSS_STAT_ERR - errno; std::stringstream msg; msg << "univ_mss_file_stat - failed for ["; msg << filename; msg << "]"; return ERROR( status, msg.str() ); } return CODE( status ); } // univ_mss_file_stat
/// =-=-=-=-=-=-=- /// @brief interface for POSIX Stat irods::error univ_mss_file_stat( irods::resource_plugin_context& _ctx, struct stat* _statbuf ) { // =-=-=-=-=-=-=- // check context irods::error err = univ_mss_check_param< irods::data_object >( _ctx ); if ( !err.ok() ) { std::stringstream msg; msg << __FUNCTION__; msg << " - invalid context"; return PASSMSG( msg.str(), err ); } // =-=-=-=-=-=-=- // get the script property std::string script; err = _ctx.prop_map().get< std::string >( SCRIPT_PROP, script ); if ( !err.ok() ) { return PASSMSG( __FUNCTION__, err ); } // =-=-=-=-=-=-=- // snag a ref to the fco irods::data_object_ptr fco = boost::dynamic_pointer_cast< irods::data_object >( _ctx.fco() ); std::string filename = fco->physical_path(); int i, status; execCmd_t execCmdInp; char cmdArgv[HUGE_NAME_LEN] = ""; char *outputStr; const char *delim1 = ":\n"; const char *delim2 = "-"; const char *delim3 = "."; execCmdOut_t *execCmdOut = NULL; struct tm mytm; time_t myTime; bzero( &execCmdInp, sizeof( execCmdInp ) ); rstrcpy( execCmdInp.cmd, script.c_str(), LONG_NAME_LEN ); snprintf( cmdArgv, sizeof( cmdArgv ), "stat '%s' ", filename.c_str() ); rstrcpy( execCmdInp.cmdArgv, cmdArgv, HUGE_NAME_LEN ); rstrcpy( execCmdInp.execAddr, "localhost", LONG_NAME_LEN ); status = _rsExecCmd( &execCmdInp, &execCmdOut ); if ( status == 0 && NULL != execCmdOut ) { // JMC cppcheck - nullptr if ( execCmdOut->stdoutBuf.buf != NULL ) { outputStr = ( char* )execCmdOut->stdoutBuf.buf; std::vector<std::string> output_tokens; boost::algorithm::split( output_tokens, outputStr, boost::is_any_of( delim1 ) ); _statbuf->st_dev = atoi( output_tokens[0].c_str() ); _statbuf->st_ino = atoi( output_tokens[1].c_str() ); _statbuf->st_mode = atoi( output_tokens[2].c_str() ); _statbuf->st_nlink = atoi( output_tokens[3].c_str() ); _statbuf->st_uid = atoi( output_tokens[4].c_str() ); _statbuf->st_gid = atoi( output_tokens[5].c_str() ); _statbuf->st_rdev = atoi( output_tokens[6].c_str() ); _statbuf->st_size = atoll( output_tokens[7].c_str() ); _statbuf->st_blksize = atoi( output_tokens[8].c_str() ); _statbuf->st_blocks = atoi( output_tokens[9].c_str() ); for ( i = 0; i < 3; i++ ) { std::vector<std::string> date_tokens; boost::algorithm::split( date_tokens, output_tokens[10 + i], boost::is_any_of( delim2 ) ); mytm.tm_year = atoi( date_tokens[0].c_str() ) - 1900; mytm.tm_mon = atoi( date_tokens[1].c_str() ) - 1; mytm.tm_mday = atoi( date_tokens[2].c_str() ); std::vector<std::string> time_tokens; boost::algorithm::split( time_tokens, date_tokens[3], boost::is_any_of( delim3 ) ); mytm.tm_hour = atoi( time_tokens[0].c_str() ); mytm.tm_min = atoi( time_tokens[1].c_str() ); mytm.tm_sec = atoi( time_tokens[2].c_str() ); myTime = mktime( &mytm ); switch ( i ) { case 0: _statbuf->st_atime = myTime; break; case 1: _statbuf->st_mtime = myTime; break; case 2: _statbuf->st_ctime = myTime; break; } } } } else { status = UNIV_MSS_STAT_ERR - errno; std::stringstream msg; msg << "univ_mss_file_stat - failed for ["; msg << filename; msg << "]"; freeCmdExecOut( execCmdOut ); return ERROR( status, msg.str() ); } freeCmdExecOut( execCmdOut ); return CODE( status ); } // univ_mss_file_stat
/// =-=-=-=-=-=-=- /// @brief find the next valid child resource for create operation irods::error get_next_valid_child_resource( irods::resource_plugin_context& _ctx, const std::string* _opr, const std::string* _curr_host, irods::hierarchy_parser* _out_parser, float* _out_vote ) { // =-=-=-=-=-=-=- // counter and flag int child_ctr = 0; bool child_found = false; // =-=-=-=-=-=-=- // while we have not found a child and have not // exhausted all the children in the map while ( !child_found && child_ctr < _ctx.child_map().size() ) { // =-=-=-=-=-=-=- // increment child counter child_ctr++; // =-=-=-=-=-=-=- // get the next_child property std::string next_child; irods::error err = _ctx.prop_map().get< std::string >( NEXT_CHILD_PROP, next_child ); if ( !err.ok() ) { return PASSMSG( "get property for 'next_child' failed.", err ); } // =-=-=-=-=-=-=- // get the next_child resource if ( !_ctx.child_map().has_entry( next_child ) ) { std::stringstream msg; msg << "child map has no child by name ["; msg << next_child << "]"; return PASSMSG( msg.str(), err ); } // =-=-=-=-=-=-=- // request our child resource to test it irods::resource_ptr resc = _ctx.child_map()[ next_child ].second; // =-=-=-=-=-=-=- // get the resource's status int resc_status = 0; err = resc->get_property<int>( irods::RESOURCE_STATUS, resc_status ); if ( !err.ok() ) { return PASSMSG( "failed to get property", err ); } // =-=-=-=-=-=-=- // forward the 'put' redirect to the appropriate child err = resc->call < const std::string*, const std::string*, irods::hierarchy_parser*, float* > ( _ctx.comm(), irods::RESOURCE_OP_RESOLVE_RESC_HIER, _ctx.fco(), _opr, _curr_host, _out_parser, _out_vote ); if ( !err.ok() ) { rodsLog( LOG_ERROR, "forward of put redirect failed" ); continue; } if( *_out_vote > 0 ) { // =-=-=-=-=-=-=- // we found a valid child, set out variable child_found = true; } else { // =-=-=-=-=-=-=- // update the next_child as we do not have a valid child yet err = update_next_child_resource( _ctx.prop_map() ); if ( !err.ok() ) { return PASSMSG( "update_next_child_resource failed", err ); } } } // while // =-=-=-=-=-=-=- // return appropriately if ( child_found ) { return SUCCESS(); } else { return ERROR( NO_NEXT_RESC_FOUND, "no valid child found" ); } } // get_next_valid_child_resource
irods::error impostor_resource_rebalance_plugin( irods::resource_plugin_context& _ctx ) { return update_resource_object_count( _ctx.comm(), _ctx.prop_map() ); } // impostor_resource_rebalance_plugin
/// =-=-=-=-=-=-=- /// @brief interface for POSIX rename irods::error univ_mss_file_rename( irods::resource_plugin_context& _ctx, const char* _new_file_name ) { // =-=-=-=-=-=-=- // check context irods::error err = univ_mss_check_param< irods::file_object >( _ctx ); if ( !err.ok() ) { std::stringstream msg; msg << __FUNCTION__; msg << " - invalid context"; return PASSMSG( msg.str(), err ); } // =-=-=-=-=-=-=- // get the script property std::string script; err = _ctx.prop_map().get< std::string >( SCRIPT_PROP, script ); if ( !err.ok() ) { return PASSMSG( __FUNCTION__, err ); } // =-=-=-=-=-=-=- // snag a ref to the fco irods::file_object_ptr fco = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() ); std::string filename = fco->physical_path(); // =-=-=-=-=-=-=- // first create the directory name char dirname[MAX_NAME_LEN] = ""; const char* lastpart = strrchr( _new_file_name, '/' ); int lenDir = strlen( _new_file_name ) - strlen( lastpart ); strncpy( dirname, _new_file_name, lenDir ); // =-=-=-=-=-=-=- // create a context to call the mkdir operation irods::collection_object_ptr coll_obj( new irods::collection_object( dirname, fco->resc_hier(), fco->mode(), 0 ) ); irods::resource_plugin_context context( _ctx.prop_map(), coll_obj, "", _ctx.comm(), _ctx.child_map() ); // =-=-=-=-=-=-=- // create the directory on the MSS int status = 0; err = univ_mss_file_mkdir( context ); execCmd_t execCmdInp; bzero( &execCmdInp, sizeof( execCmdInp ) ); snprintf( execCmdInp.cmd, sizeof( execCmdInp.cmd ), "%s", script.c_str() ); snprintf( execCmdInp.cmdArgv, sizeof( execCmdInp.cmdArgv ), "mv '%s' '%s'", filename.c_str(), _new_file_name ); snprintf( execCmdInp.execAddr, sizeof( execCmdInp.execAddr ), "%s", "localhost" ); execCmdOut_t *execCmdOut = NULL; status = _rsExecCmd( &execCmdInp, &execCmdOut ); freeCmdExecOut( execCmdOut ); if ( status < 0 ) { status = UNIV_MSS_RENAME_ERR - errno; std::stringstream msg; msg << "univ_mss_file_rename - failed for ["; msg << filename; msg << "]"; return ERROR( status, msg.str() ); } return CODE( status ); } // univ_mss_file_rename
/// =-=-=-=-=-=-=- /// @brief interface to notify of a file modification irods::error round_robin_file_modified( irods::resource_plugin_context& _ctx ) { // =-=-=-=-=-=-=- // get the child resc to call irods::resource_ptr resc; irods::error err = round_robin_get_resc_for_call< irods::file_object >( _ctx, resc ); if ( !err.ok() ) { return PASS( err ); } // =-=-=-=-=-=-=- // call modified on the child err = resc->call( _ctx.comm(), irods::RESOURCE_OP_MODIFIED, _ctx.fco() ); if ( !err.ok() ) { return PASS( err ); } // =-=-=-=-=-=-=- // get the operation property, if it is a create op then we need // to update the next child in the context string std::string operation; err = _ctx.prop_map().get< std::string >( OPERATION_PROP, operation ); if( err.ok() && irods::CREATE_OPERATION == operation ) { // =-=-=-=-=-=-=- // update the next_child appropriately as the above succeeded err = update_next_child_resource( _ctx.prop_map() ); if ( !err.ok() ) { return PASSMSG( "update_next_child_resource failed", err ); } // =-=-=-=-=-=-=- // if file modified is successful then we will update the next // child in the round robin within the database std::string name; _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, name ); std::string next_child; _ctx.prop_map().get< std::string >( NEXT_CHILD_PROP, next_child ); setRoundRobinContextInp_t inp; snprintf( inp.resc_name_, sizeof( inp.resc_name_ ), "%s", name.c_str() ); snprintf( inp.context_, sizeof( inp.context_ ), "%s", next_child.c_str() ); int status = irods::server_api_call( SET_RR_CTX_AN, _ctx.comm(), &inp, NULL, ( void** ) NULL, NULL ); if ( status < 0 ) { std::stringstream msg; msg << "failed to update round robin context for ["; msg << name << "] with context [" << next_child << "]"; return ERROR( status, msg.str() ); } } // if get prop return SUCCESS(); } // round_robin_file_modified