diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/vmpi/vmpi_transfer/vmpi_transfer.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/vmpi/vmpi_transfer/vmpi_transfer.cpp')
| -rw-r--r-- | utils/vmpi/vmpi_transfer/vmpi_transfer.cpp | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/utils/vmpi/vmpi_transfer/vmpi_transfer.cpp b/utils/vmpi/vmpi_transfer/vmpi_transfer.cpp new file mode 100644 index 0000000..fadf3fd --- /dev/null +++ b/utils/vmpi/vmpi_transfer/vmpi_transfer.cpp @@ -0,0 +1,172 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include <windows.h> +#include "vmpi.h" +#include "vmpi_transfer.h" +#include "cmdlib.h" +#include "tier0/icommandline.h" +#include "vmpi_tools_shared.h" +#include "tools_minidump.h" +#include <conio.h> + + +void MyDisconnectHandler( int procID, const char *pReason ) +{ + Error( "Premature disconnect.\n" ); +} + +void DownloadFile( const char *pCachePath, const char *pRemoteFileBase, const char *pFilename ) +{ + // Setup local and remote filenames. + char remoteFilename[MAX_PATH]; + char localFilename[MAX_PATH]; + V_ComposeFileName( pRemoteFileBase, pFilename, remoteFilename, sizeof( remoteFilename ) ); + V_ComposeFileName( pCachePath, pFilename, localFilename, sizeof( localFilename ) ); + + // Read the file in. + FileHandle_t fpSrc = g_pFileSystem->Open( remoteFilename, "rb" ); + if ( fpSrc == FILESYSTEM_INVALID_HANDLE ) + { + Error( "Unable to open %s on master.\n", remoteFilename ); + } + + unsigned int fileSize = g_pFileSystem->Size( fpSrc ); + CUtlVector<char> data; + data.SetSize( fileSize ); + g_pFileSystem->Read( data.Base(), fileSize, fpSrc ); + g_pFileSystem->Close( fpSrc ); + + // Now write the file to disk. + FILE *fpDest = fopen( localFilename, "wb" ); + if ( !fpDest ) + { + Error( "Can't open %s for writing.\n", localFilename ); + } + fwrite( data.Base(), 1, data.Count(), fpDest ); + fclose( fpDest ); + +Warning( "Got file: %s\n", pFilename ); +} + +#if 0 +SpewRetval_t MySpewFunc( SpewType_t spewType, const tchar *pMsg ) +{ + printf( "%s", pMsg ); + if ( spewType == SPEW_ERROR ) + { + printf( "\nWaiting for keypress to quit...\n" ); + getch(); + TerminateProcess( GetCurrentProcess(), 1 ); + } + + return SPEW_CONTINUE; +} +#endif + +int RunVMPITransferWorker( int argc, char **argv ) +{ + if ( !VMPI_Init( argc, argv, NULL, MyDisconnectHandler, VMPI_RUN_NETWORKED, true ) ) + { + return 1; + } + + SetupToolsMinidumpHandler( VMPI_ExceptionFilter ); + + if ( !FileSystem_Init( ".", 0, FS_INIT_COMPATIBILITY_MODE ) ) + return 1; + + ICommandLine *pCommandLine = CommandLine(); + + // Look for the cache path and file base args. + const char *pCachePath = pCommandLine->ParmValue( "-CachePath", (char*)NULL ); + if ( !pCachePath ) + Error( "No -CachePath specified." ); + + const char *pRemoteFileBase = pCommandLine->ParmValue( "-mpi_filebase", (char*)NULL ); + if ( !pRemoteFileBase ) + Error( "No -mpi_filebase specified." ); + + // Now just ask the master for each file. + for ( int i=1; i < pCommandLine->ParmCount()-1; i++ ) + { + const char *pParm = pCommandLine->GetParm( i ); + if ( V_stricmp( pParm, "-mpi_file" ) == 0 ) + { + const char *pNextParm = pCommandLine->GetParm( i+1 ); + DownloadFile( pCachePath, pRemoteFileBase, pNextParm ); + ++i; + } + } + + // Ok, we're done. Write the status file so the service knows all the files are ready to go. + char statusFilename[MAX_PATH]; + V_ComposeFileName( pCachePath, "ReadyToGo.txt", statusFilename, sizeof( statusFilename ) ); + FILE *fp = fopen( statusFilename, "wb" ); + fclose( fp ); + + return 0; +} + + +// In this mode, we just initialize VMPI appropriately, and it'll host out the specified files. +// The command line to vmpi_transfer is -PatchHost -PatchDirectory <directory> +// Sample: vmpi_transfer -PatchHost -mpi_PatchDirectory \\fileserver\vmpi\patch1 -mpi_PatchWorkers <count> <ip1> <ip2>... +// Then it'll tell those workers to connect and it'll send them the files in the specified directory. +int RunVMPITransferMaster( int argc, char **argv ) +{ + // Since we didn't use -mpi_worker on the command line, VMPI will init as the master. + // We put a special character in front of the dependency filename, which tells it the dependencies + // consist of every file in the specified directory. + VMPI_Init_PatchMaster( argc, argv ); + + if ( !FileSystem_Init( ".", 0, FS_INIT_COMPATIBILITY_MODE ) ) + return 1; + + Msg( "Hosting patch files. Press ESC to exit. " ); + while ( 1 ) + { + VMPI_DispatchNextMessage( 100 ); + if ( kbhit() ) + { + if ( getch() == 27 ) + break; + } + } + + return 0; +} + + +// --------------------------------------------------------------------------------- // +// Purpose: This app is used by vmpi_service to acquire the executables for +// a VMPI job. When the service is asked to join a job, it runs this program +// to connect to the VMPI master and download all the exes for the job. +// +// This app is ALSO used to do patches. vmpi_browser_services runs it with a list +// of machines it wants to patch. Then it runs as the VMPI master and instead of +// broadcasting its presence, it sends messages to the specific list of machines. +// --------------------------------------------------------------------------------- // +int main( int argc, char **argv ) +{ + InstallSpewFunction(); + CommandLine()->CreateCmdLine( argc, argv ); + + int ret; + if ( CommandLine()->FindParm( "-PatchHost" ) == 0 ) + { + ret = RunVMPITransferWorker( argc, argv ); + } + else + { + ret = RunVMPITransferMaster( argc, argv ); + } + + CmdLib_Cleanup(); + return ret; +} + + |