00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include "ObjectManager.h"
00048 #include "RioError.h"
00049 #include "DiskMgr.h"
00050 #include "UserManager.h"
00051
00052 #include <string.h>
00053 #include <errno.h>
00054 #include <sys/types.h>
00055 #include <sys/stat.h>
00056 #include <fcntl.h>
00057 #include <unistd.h>
00058
00059 #include "stdio.h"
00060
00061
00062 #include "Object.pvt"
00063
00064 #ifdef USE_GRID
00065
00066
00067 #include <sys/time.h>
00068
00069
00070
00071
00072 #define MAX_OBJECT_EXTENSIONS 5
00073 #endif
00074
00075 const char* const LOGFILE = "RIOObjectManager.log";
00076
00077
00078
00079
00080
00081
00082 CObjectManager::CObjectManager()
00083 {
00084
00085 m_MaxReplications = 0;
00086 m_UseReplications = 0;
00087 m_initialized = false;
00088 m_started = false;
00089 m_FileRoot = NULL;
00090 m_BlockSize = 0;
00091 m_ObjMapMgr = NULL;
00092 m_DiskMgr = NULL;
00093 m_UserManager = NULL;
00094
00095 #ifdef USE_GRID
00096
00097 pthread_mutex_init( &m_mutex_filelist, NULL );
00098 pthread_mutex_init( &m_mutex_gridcopy, NULL );
00099
00100 m_StartListFiles = NULL;
00101 m_NextSearchFile = NULL;
00102 #endif
00103
00104 }
00105
00106
00107 CObjectManager::~CObjectManager()
00108 {
00109 if( m_FileRoot != NULL )
00110 delete[] m_FileRoot;
00111 m_FileRoot = 0;
00112
00113 if( m_log.is_open() )
00114 m_log.close();
00115
00116 #ifdef USE_GRID
00117
00118 DeleteFileList();
00119
00120 pthread_mutex_destroy( &m_mutex_filelist );
00121 pthread_mutex_destroy( &m_mutex_gridcopy );
00122 #endif
00123
00124
00125 if( m_ObjMapMgr != NULL )
00126 delete m_ObjMapMgr;
00127 m_ObjMapMgr = NULL;
00128 }
00129
00130 int CObjectManager::Reset()
00131 {
00132 m_BlockSize = 0;
00133 m_initialized = false;
00134 m_started = false;
00135
00136 if( m_FileRoot != NULL )
00137 delete[] m_FileRoot;
00138 m_FileRoot = 0;
00139
00140
00141 if( m_ObjMapMgr != NULL )
00142 delete m_ObjMapMgr;
00143 m_ObjMapMgr = NULL;
00144
00145 return S_OK;
00146 }
00147
00148 int CObjectManager::Initialize( ObjectManagerConfig * Config )
00149 {
00150 int result;
00151
00152 if( Config->GenerateLogs )
00153 {
00154
00155 char LogFileName[ MaxPathSize ];
00156
00157 strcpy( LogFileName, Config->LogsDirectory );
00158 strcat( LogFileName, LOGFILE );
00159 m_log.open( LogFileName );
00160 if( !m_log.is_open() )
00161 return ERROR_OBJECTMANAGER + ERROR_LOGFILE ;
00162 }
00163
00164 if( m_initialized )
00165 {
00166 if( m_log.is_open() )
00167 m_log << "Initialize(): Tried to initialize component "
00168 << " already initialized" << endl;
00169 return ERROR_OBJECTMANAGER + ERROR_INITIALIZED;
00170 }
00171
00172 if( ( strlen( Config->FileRoot ) + 1 ) > MaxPathSize )
00173 {
00174 if( m_log.is_open() )
00175 m_log << "CObjectManager::Initialize(). FileRoot name size too "
00176 << "large: " << Config->FileRoot << " ("
00177 << strlen( Config->FileRoot ) << ")" << endl;
00178 return ERROR_OBJECTMANAGER + ERROR_LARGE_ROOTNAME;
00179 }
00180
00181 m_FileRoot = new char[ strlen( Config->FileRoot ) + 1 ];
00182 strcpy( m_FileRoot, Config->FileRoot );
00183
00184 m_BlockSize = Config->BlockSize;
00185 m_MaxReplications = Config->MaxReplications;
00186 m_UseReplications = Config->UseReplications;
00187 m_DiskMgr = Config->c_DiskMgr;
00188 m_UserManager = Config->UserManager;
00189
00190 m_ObjMapMgr = new ObjMapMgr;
00191 if( m_ObjMapMgr == 0 )
00192 {
00193 if( m_log.is_open() )
00194 m_log << "CObjectManager::Initialize() new ObjMapMgr failed."
00195 << endl;
00196 return ERROR_OBJECTMANAGER + ERROR_MEMORY;
00197 }
00198
00199
00200 result = m_ObjMapMgr->Initialize( Config->MaxNhandle, m_BlockSize,
00201 m_MaxReplications, m_UseReplications,
00202 m_DiskMgr, &m_log );
00203 if( FAILED( result ) )
00204 return result;
00205
00206 #ifdef USE_GRID
00207
00208
00209 result = CreateFileList();
00210
00211 if( result != 0 )
00212 {
00213 if( m_log.is_open() )
00214 m_log << "CObjectManager::Initialize() CreateFileList failed."
00215 << endl;
00216 return result;
00217 }
00218
00219
00220 PrintFileList();
00221 #endif
00222
00223 m_initialized = true;
00224
00225 return S_OK;
00226 }
00227
00228 int CObjectManager::Start()
00229 {
00230 HRESULT result;
00231
00232
00233 if( !m_initialized )
00234 {
00235 if( m_log.is_open() )
00236 m_log << "Start(): Component not initiallized" << endl;
00237
00238 return ERROR_OBJECTMANAGER + ERROR_NOT_INITIALIZED;
00239 }
00240
00241
00242 if( m_started )
00243 {
00244 if( m_log.is_open() )
00245 m_log << "Start(): Component already started" << endl;
00246
00247 return( ERROR_OBJECTMANAGER + ERROR_STARTED );
00248 }
00249
00250
00251 result = m_ObjMapMgr->Start();
00252 if( FAILED( result ) )
00253 return result;
00254
00255 m_started = true;
00256
00257 return S_OK;
00258 }
00259
00260
00261 int CObjectManager::Stop()
00262 {
00263 int result;
00264
00265
00266 if( !m_started )
00267 {
00268 if( m_log.is_open() )
00269 m_log << "Stop(): Component not started" << endl;
00270
00271 return( ERROR_OBJECTMANAGER + ERROR_NOT_STARTED );
00272 }
00273
00274
00275 result = m_ObjMapMgr->Stop();
00276 if( FAILED( result ) )
00277 return result;
00278
00279 m_started = false;
00280
00281 return S_OK;
00282 }
00283
00284
00285
00286
00287
00288
00289
00290 int CObjectManager::Create( char *Path, short Type )
00291 {
00292 int rc;
00293 char name[ 2*MaxPathSize+1 ];
00294
00295 #ifdef USE_GRID
00296
00297 struct stat FileStat;
00298 #endif
00299
00300 *name = '\0';
00301
00302 if( ( rc = PathToFile( Path, name, sizeof( name ) ) ) )
00303 return rc;
00304
00305 switch( Type )
00306 {
00307 case ObjectInfo::FILE_TYPE_DIRECTORY:
00308 rc = createdirectory( name );
00309 if( rc )
00310 return rc;
00311 break;
00312
00313 case ObjectInfo::FILE_TYPE_DATA:
00314 rc = m_ObjMapMgr->createobject( name );
00315
00316 if( rc )
00317 return rc;
00318
00319 #ifdef USE_GRID
00320
00321
00322
00323
00324
00325
00326
00327 RemoveFile( Path );
00328
00329 rc = stat( name, &FileStat );
00330
00331 if( rc )
00332 {
00333
00334
00335 unlink( name );
00336 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED;
00337 }
00338
00339
00340 rc = InsertFile( Path, FileStat.st_atime );
00341
00342 if( rc )
00343 {
00344
00345
00346
00347 unlink( name );
00348 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED;
00349 }
00350
00351
00352 PrintFileList();
00353
00354 #endif
00355
00356 break;
00357
00358 default:
00359 return ERROR_OBJECTMANAGER + ERROR_INVALID_OBJECT_TYPE;
00360 }
00361
00362
00363 return S_OK;
00364 }
00365
00366
00367
00368 int CObjectManager::createdirectory( char *name )
00369 {
00370 int error = 0;
00371 int status;
00372
00373 status = mkdir( name, 0700 );
00374
00375 if( status )
00376 error = errno;
00377
00378 if( status )
00379 {
00380 switch( error )
00381 {
00382 case EEXIST:
00383 return ERROR_OBJECTMANAGER + ERROR_OBJECT_EXISTS;
00384
00385 case ENOENT:
00386 case ENAMETOOLONG:
00387 case ENOTDIR:
00388 return ERROR_OBJECTMANAGER + ERROR_INVALID_OBJECTNAME;
00389 }
00390 }
00391
00392 return S_OK;
00393 }
00394
00395
00396
00397 int CObjectManager::SetDefaultPermissions( char *path )
00398 {
00399 return S_OK;
00400 }
00401
00402
00403
00404 int CObjectManager::Rename( char *OldPath, char *NewPath )
00405 {
00406 int rc;
00407 int error;
00408 char oldname[ 2*MaxPathSize+1 ];
00409 char newname[ 2*MaxPathSize+1 ];
00410
00411 *oldname = '\0';
00412 *newname = '\0';
00413
00414 if( ( rc = PathToFile( OldPath, oldname, sizeof( oldname ) ) ) )
00415 return rc;
00416
00417 if( ( rc = PathToFile( NewPath, newname, sizeof( newname ) ) ) )
00418 return rc;
00419
00420 if( ( rc = rename( oldname, newname ) ) != 0 )
00421 error = errno;
00422
00423 #ifdef USE_GRID
00424
00425 if( !rc )
00426 {
00427
00428 rc = RenameFile( OldPath, NewPath );
00429
00430 if( rc )
00431 {
00432
00433
00434 rename( newname, oldname );
00435
00436 return ERROR_OBJECTMANAGER + ERROR_OBJECT_OPEN_FAILED;
00437 }
00438
00439
00440 PrintFileList();
00441 return S_OK;
00442 }
00443 #else
00444 if( !rc )
00445 return S_OK;
00446 #endif
00447 else
00448 {
00449
00450
00451
00452
00453
00454 return ERROR_OBJECTMANAGER + ERROR_OBJECT_OPEN_FAILED;
00455 }
00456 }
00457
00458
00459
00460 int CObjectManager::Delete( char* ObjectPath )
00461 {
00462 int rc;
00463 struct stat mystat;
00464 char name[ 2 *MaxPathSize+1 ];
00465
00466 *name = '\0';
00467
00468 if( ( rc = PathToFile( ObjectPath, name, sizeof( name ) ) ) )
00469 return rc;
00470
00471 rc = stat( name, &mystat );
00472 if( rc )
00473 {
00474 #ifdef RIO_DEBUG2
00475 if( m_log.is_open() )
00476 m_log << "Could not find file " << name << endl;
00477 #endif
00478
00479 return ERROR_OBJECTMANAGER + ERROR_INVALID_OBJECTNAME;
00480 }
00481
00482 if( S_ISDIR( mystat.st_mode ) )
00483 {
00484 #ifdef RIO_DEBUG2
00485 if( m_log.is_open() )
00486 m_log << "Delete directory " << name << endl;
00487 #endif
00488
00489 return RemoveDirectory( name );
00490 }
00491 else
00492 if( S_ISREG( mystat.st_mode ) )
00493 {
00494 #ifdef RIO_DEBUG2
00495 if( m_log.is_open() )
00496 m_log << "Delete object " << name << endl;
00497 #endif
00498
00499 #ifdef USE_GRID
00500
00501 rc = RemoveObject( name );
00502
00503 if( rc )
00504 return rc;
00505
00506
00507
00508 rc = RemoveFile( ObjectPath );
00509
00510 if( rc )
00511 return rc;
00512
00513
00514 PrintFileList();
00515 return S_OK;
00516 #else
00517 return RemoveObject( name );
00518 #endif
00519 }
00520
00521 return ERROR_OBJECTMANAGER + ERROR_INVALID_OBJECTNAME;
00522 }
00523
00524
00525 int CObjectManager::RemoveDirectory( char *DirectoryName )
00526 {
00527
00528 int status;
00529 status = rmdir( DirectoryName );
00530
00531 if( !status )
00532 {
00533 #ifdef RIO_DEBUG2
00534 if( m_log.is_open() )
00535 m_log << "Delete directory success"<< endl;
00536 #endif
00537
00538 return S_OK;
00539 }
00540 else
00541 {
00542 #ifdef RIO_DEBUG2
00543 if( m_log.is_open() )
00544 m_log << "Delete directory failed"<< endl;
00545 #endif
00546
00547 return ERROR_OBJECTMANAGER + ERROR_OBJECT_REMOVE_FAILED;
00548 }
00549 }
00550
00551
00552 int CObjectManager::RemoveObject( char* ObjectName )
00553 {
00554 RioObject *Object;
00555 int rc;
00556
00557
00558 rc = m_ObjMapMgr->Open( ObjectName, RIO_READ_ACCESS | RIO_WRITE_ACCESS,
00559 &Object );
00560
00561 if( FAILED( rc ) )
00562 return rc;
00563
00564 rc = Object->MarkDelete();
00565
00566 delete Object;
00567
00568 return rc;
00569 }
00570
00571
00572 int CObjectManager::Open( char *ObjectName, RioAccess Access,
00573 RioObject **Object )
00574 {
00575 int rc;
00576 char name[ 2*MaxPathSize+1 ];
00577
00578 #ifdef USE_GRID
00579
00580
00581
00582 char AuxObjectName[ 2*MaxPathSize+1 ];
00583
00584
00585
00586
00587 char AuxName[ 2*MaxPathSize+1 ];
00588
00589
00590
00591 char *ObjectExtensions[ MAX_OBJECT_EXTENSIONS ] = { ".tgif", ".zip",
00592 ".index", ".keyword",
00593 ".xml"};
00594 RioObject *AuxObject = NULL;
00595 unsigned int rca;
00596 unsigned int i;
00597 #endif
00598
00599 *name = '\0';
00600
00601 if( ( rc = PathToFile( ObjectName, name, sizeof( name ) ) ) )
00602 return rc;
00603
00604 #ifdef USE_GRID
00605
00606 pthread_mutex_lock( &m_mutex_filelist );
00607
00608 rc = m_ObjMapMgr->Open( name, Access, Object );
00609
00610 if( rc )
00611 {
00612
00613 pthread_mutex_unlock( &m_mutex_filelist );
00614
00615
00616
00617 pthread_mutex_lock( &m_mutex_gridcopy );
00618
00619
00620
00621
00622 rc = m_ObjMapMgr->Open( name, Access, Object );
00623
00624 if( rc )
00625 {
00626
00627
00628 CopyGridFile( ObjectName );
00629
00630
00631
00632 pthread_mutex_lock( &m_mutex_filelist );
00633
00634
00635 if( m_log.is_open() )
00636 m_log << "CObjectManager::Open tentando abrir o arquivo "
00637 << name << " associado ao objeto " << ObjectName << endl;
00638 rc = m_ObjMapMgr->Open( name, Access, Object );
00639
00640 if( rc )
00641 {
00642
00643
00644 pthread_mutex_unlock( &m_mutex_filelist );
00645 pthread_mutex_unlock( &m_mutex_gridcopy );
00646 return rc;
00647 }
00648
00649
00650
00651 rc = IncrementOpenFileCounter( ObjectName );
00652
00653 pthread_mutex_unlock( &m_mutex_filelist );
00654
00655 PrintFileList();
00656
00657 if( rc )
00658 {
00659
00660
00661
00662 delete Object;
00663 pthread_mutex_unlock( &m_mutex_gridcopy );
00664 return rc;
00665 }
00666
00667
00668
00669 if( ( strlen( ObjectName ) >= 4 ) &&
00670 ( strcmp( &ObjectName[ strlen( ObjectName )-4 ], ".mpg" )
00671 == 0) )
00672 {
00673
00674 if( m_log.is_open() )
00675 m_log << "CObjectManager:: o arquivo " << ObjectName
00676 << " e .mpg. Baixando os arquivos relacionados a "
00677 << "ele." << endl;
00678
00679
00680 for( i = 0; i < MAX_OBJECT_EXTENSIONS; i++ )
00681 {
00682
00683 strncpy( AuxObjectName, ObjectName,
00684 strlen( ObjectName )-4 );
00685
00686
00687
00688 AuxObjectName[ strlen( ObjectName )-4 ] = 0;
00689
00690 strcat( AuxObjectName, ObjectExtensions[ i ] );
00691 *AuxName = '\0';
00692
00693 if( (rca = PathToFile( AuxObjectName, AuxName,
00694 sizeof( AuxName ) ) ) )
00695 {
00696
00697 if( m_log.is_open() )
00698 m_log << "CObjectManager::Open nao foi possivel "
00699 << "converter o nome " << AuxObjectName
00700 << " (erro " << rca << ")" << endl;
00701 }
00702 else
00703 {
00704
00705
00706 if( m_log.is_open() )
00707 m_log << "CObjectManager::Open tentando abrir o "
00708 << "arquivo " << AuxName << " associado ao "
00709 << "arquivo " << name << endl;
00710
00711 rca = m_ObjMapMgr->Open( AuxName, Access, &AuxObject );
00712
00713 if( rca )
00714 {
00715
00716
00717 CopyGridFile( AuxObjectName );
00718 }
00719 else
00720 {
00721
00722
00723 delete AuxObject;
00724 }
00725
00726 }
00727
00728 }
00729
00730 }
00731 else
00732 {
00733
00734 if( m_log.is_open() )
00735 m_log << "CObjectManager:: o arquivo " << ObjectName
00736 << " nao e um .mpg. " << endl;
00737
00738 }
00739
00740
00741
00742 pthread_mutex_unlock( &m_mutex_gridcopy );
00743 }
00744 else
00745 {
00746
00747
00748 pthread_mutex_unlock( &m_mutex_gridcopy );
00749
00750
00751 pthread_mutex_lock( &m_mutex_filelist );
00752
00753
00754 rc = IncrementOpenFileCounter( ObjectName );
00755
00756
00757 pthread_mutex_unlock( &m_mutex_filelist );
00758
00759 PrintFileList();
00760
00761 if( rc )
00762 {
00763
00764
00765
00766 delete Object;
00767 return rc;
00768 }
00769
00770 }
00771
00772 }
00773 else
00774 {
00775
00776
00777 rc = IncrementOpenFileCounter( ObjectName );
00778
00779 pthread_mutex_unlock( &m_mutex_filelist );
00780
00781 PrintFileList();
00782
00783 if( rc )
00784 {
00785
00786
00787
00788 delete Object;
00789 return rc;
00790 }
00791
00792 }
00793
00794 return S_OK;
00795 #else
00796 return m_ObjMapMgr->Open( name, Access, Object );
00797 #endif
00798 }
00799
00800
00801 int CObjectManager::GetObjectInfo( char *ObjectName, ObjectInfo *ObjectInfo )
00802 {
00803 int rc;
00804 char name [ 2*MaxPathSize+1 ];
00805 *name = '\0';
00806
00807 if( ( rc = PathToFile( ObjectName, name, sizeof( name ) ) ) )
00808 return rc;
00809
00810 return m_ObjMapMgr->GetObjectInfo( name, ObjectInfo );
00811 }
00812
00813
00814 int CObjectManager::ExistDirectory( char *ObjectName )
00815 {
00816 int rc;
00817 struct stat mystat;
00818 char name[ 2*MaxPathSize+1 ];
00819 *name = '\0';
00820
00821 if( ( rc = PathToFile( ObjectName, name, sizeof( name ) ) ) )
00822 return rc;
00823
00824 rc = stat( name, &mystat );
00825 if( ( rc == 0 ) && ( S_ISDIR( mystat.st_mode ) ) )
00826 return S_OK;
00827
00828 return ERROR_OBJECTMANAGER + ERROR_INVALID_OBJECTNAME;
00829 }
00830
00831
00832
00833
00834
00835
00836
00837 int CObjectManager::PathToFile( const char *Path, char *FileName,
00838 const int MaxSize )
00839 {
00840 int len = strlen( Path );
00841
00842 if( ( len + strlen( m_FileRoot ) + 2 ) > ( unsigned ) MaxSize )
00843 return ERROR_PATHNAME_TOOLARGE;
00844
00845 if( len == 0 )
00846 {
00847 strcpy( FileName, m_FileRoot );
00848 return S_OK;
00849 }
00850
00851 strcpy( FileName, m_FileRoot );
00852 strcat( FileName, "/" );
00853 strcat( FileName, Path );
00854
00855 return S_OK;
00856 }
00857
00858
00859
00860 int CObjectManager::StrToPath( const char* Str, char* PathName,
00861 const int MaxSize )
00862 {
00863 const char *si;
00864 const char *dirs;
00865 char *so;
00866 char *sl;
00867 int len;
00868 char FullPathName[ MaxPathSize + 10 ];
00869 *FullPathName = '\0';
00870
00871 *PathName = '\0';
00872
00873
00874
00875
00876 dirs = Str;
00877 so = FullPathName;
00878 sl = so + MaxPathSize;
00879 while( *dirs != '\0' )
00880 {
00881 while( *dirs == '/' )
00882 dirs++;
00883
00884 for( si = dirs; *si != '\0' && *si != '/'; si++ )
00885 ;
00886
00887 len = si - dirs;
00888
00889 if( len == 0 )
00890 {
00891 dirs = si;
00892 }
00893 else
00894 if( ( len == 1 ) && ( *dirs == '.' ) )
00895 dirs = si;
00896 else
00897 if( ( len == 2 ) && ( dirs[ 0 ] == '.' ) &&
00898 ( dirs[ 1 ] == '.' ) )
00899 {
00900 dirs = si;
00901
00902 if( so <= FullPathName )
00903
00904 return ERROR_OBJECTMANAGER + ERROR_PATHNAME_BADSYNTAX;
00905 do
00906 {
00907 so--;
00908 }while( ( so >= FullPathName ) && ( *so != '/' ) );
00909
00910
00911 if( so < FullPathName )
00912 {
00913 so++;
00914 if( strcmp( so, FullPathName ) == 0 )
00915 {
00916 FullPathName[ 0 ] = '\0';
00917 }
00918 so--;
00919 }
00920 }
00921 else
00922 {
00923
00924 if( so != FullPathName )
00925 *so++ = '/';
00926 if( ( so+len ) > sl )
00927 return ERROR_OBJECTMANAGER + ERROR_PATHNAME_TOOLARGE;
00928 memcpy( so, dirs, len );
00929 so += len;
00930 dirs += len;
00931 }
00932 }
00933 *so++ = '\0';
00934
00935 if( ( so - FullPathName ) > MaxSize )
00936 return ERROR_OBJECTMANAGER + ERROR_PATHNAME_TOOLARGE;
00937
00938 strcpy( PathName, FullPathName );
00939
00940 return S_OK;
00941 }
00942
00943
00944
00945 int CObjectManager::FirstObject( char* DirectoryPath, RioDirectory **Directory,
00946 int* IsDirectory, int BufferSize,
00947 char* ObjectName )
00948 {
00949 int rc = 0;
00950
00951 RioDirectory *op = new RioDirectory( this );
00952 if( op == 0 )
00953 return ERROR_OBJECTMANAGER + ERROR_MEMORY;
00954
00955 if( ( rc = PathToFile( DirectoryPath, op->o_DirectoryName,
00956 sizeof( op->o_DirectoryName ) ) ) )
00957 return rc;
00958
00959
00960
00961
00962
00963 op->o_dir = opendir( op->o_DirectoryName );
00964 if( op->o_dir == NULL )
00965 {
00966
00967 int error = errno;
00968 delete op;
00969 if( error == ENOENT )
00970 return ERROR_OBJECTMANAGER + ERROR_INVALID_DIRECTORYNAME;
00971 }
00972
00973 *Directory = op;
00974
00975
00976 return op->NextObject( IsDirectory, BufferSize, ObjectName );
00977 }
00978
00979 #ifdef USE_GRID
00980
00981 FileList *CObjectManager::SearchFile( char *FileName )
00982 {
00983 FileList *File;
00984
00985
00986
00987 File = m_StartListFiles;
00988
00989
00990
00991
00992 while( ( File != NULL ) && ( strcmp( File->FileName, FileName ) != 0) )
00993 File = File->NextFile;
00994
00995
00996 return File;
00997 }
00998
00999
01000 int CObjectManager::IncrementOpenFileCounter( char *FileName )
01001 {
01002 FileList *File;
01003
01004
01005
01006 File = SearchFile( FileName );
01007
01008
01009
01010
01011 if( File == NULL )
01012
01013 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED;
01014
01015
01016 File->NumReferences++;
01017 return S_OK;
01018 }
01019
01020
01021 int CObjectManager::InsertFile( char *FileName, time_t LastAccess )
01022 {
01023 FileList *NewFile;
01024 FileList *FileP;
01025 FileList *FileA;
01026
01027 pthread_mutex_lock( &m_mutex_filelist );
01028
01029 NewFile = new FileList;
01030
01031 if( NewFile == NULL )
01032 {
01033
01034
01035 pthread_mutex_unlock( &m_mutex_filelist );
01036 return ERROR_OBJECTMANAGER + ERROR_MEMORY;
01037 }
01038
01039 NewFile->FileName = new char[ strlen( FileName )+1 ];
01040
01041 if( NewFile->FileName == NULL )
01042 {
01043
01044
01045 delete NewFile;
01046
01047 pthread_mutex_unlock( &m_mutex_filelist );
01048 return ERROR_OBJECTMANAGER + ERROR_MEMORY;
01049 }
01050
01051
01052
01053 NewFile->LastAccess = LastAccess;
01054 NewFile->NumReferences = 0;
01055 strcpy( NewFile->FileName, FileName );
01056
01057
01058 FileP = NULL;
01059 FileA = m_StartListFiles;
01060
01061 while( ( FileA != NULL ) && ( FileA->LastAccess <= LastAccess ) )
01062 {
01063 FileP = FileA;
01064 FileA = FileA->NextFile;
01065 }
01066
01067
01068
01069
01070 NewFile->NextFile = FileA;
01071 NewFile->PreviousFile = FileP;
01072
01073 if( FileP == NULL )
01074 m_StartListFiles = NewFile;
01075 else
01076 FileP->NextFile = NewFile;
01077
01078 if( FileA != NULL )
01079 FileA->PreviousFile = NewFile;
01080
01081
01082
01083
01084 if( (m_NextSearchFile == NULL ) ||
01085 ( m_NextSearchFile->LastAccess > LastAccess ) )
01086 m_NextSearchFile = NewFile;
01087
01088
01089 pthread_mutex_unlock( &m_mutex_filelist );
01090 return S_OK;
01091 }
01092
01093
01094 int CObjectManager::RemoveFile( char *FileName )
01095 {
01096 FileList *File;
01097
01098 pthread_mutex_lock( &m_mutex_filelist );
01099
01100
01101 File = SearchFile( FileName );
01102
01103 if( File == NULL )
01104 {
01105
01106 pthread_mutex_unlock( &m_mutex_filelist );
01107
01108 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED;
01109 }
01110
01111
01112
01113
01114
01115 if( m_NextSearchFile == File )
01116 m_NextSearchFile = File->NextFile;
01117
01118
01119 if( File->PreviousFile == NULL )
01120 m_StartListFiles = File->NextFile;
01121 else
01122 File->PreviousFile->NextFile = File->NextFile;
01123
01124 if( File->NextFile != NULL )
01125 File->NextFile->PreviousFile = File->PreviousFile;
01126
01127 if( File->FileName != NULL )
01128 delete[] File->FileName;
01129
01130 delete File;
01131
01132 pthread_mutex_unlock( &m_mutex_filelist );
01133 return S_OK;
01134 }
01135
01136
01137 int CObjectManager::RenameFile( char *OldFileName, char *NewFileName )
01138 {
01139 FileList *File;
01140 char *NewName;
01141
01142 pthread_mutex_lock( &m_mutex_filelist );
01143
01144
01145 File = SearchFile( OldFileName );
01146
01147 if( File == NULL )
01148 {
01149
01150 pthread_mutex_unlock( &m_mutex_filelist );
01151
01152 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED;
01153 }
01154 NewName = new char[ strlen( NewFileName )+1 ];
01155
01156 if( NewName == NULL )
01157 {
01158
01159
01160 pthread_mutex_unlock( &m_mutex_filelist );
01161 return ERROR_OBJECTMANAGER + ERROR_MEMORY;
01162 }
01163
01164
01165 strcpy( NewName, NewFileName );
01166
01167 delete[] File->FileName;
01168
01169
01170 File->FileName = NewName;
01171
01172 pthread_mutex_unlock( &m_mutex_filelist );
01173 return S_OK;
01174 }
01175
01176
01177 int CObjectManager::ChangeLastAccess( char *FileName, time_t LastAccess )
01178 {
01179 FileList *File;
01180 FileList *FileA;
01181 FileList *FileP;
01182
01183 pthread_mutex_lock( &m_mutex_filelist );
01184
01185 File = SearchFile( FileName );
01186
01187 if( File == NULL )
01188 {
01189
01190 pthread_mutex_unlock( &m_mutex_filelist );
01191
01192 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED;
01193 }
01194
01195 if( File->NumReferences == 0 )
01196 {
01197
01198 pthread_mutex_unlock( &m_mutex_filelist );
01199
01200
01201
01202 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED;
01203 }
01204
01205
01206 File->NumReferences--;
01207
01208
01209
01210
01211
01212
01213 if( ( m_NextSearchFile == NULL ) ||
01214 ( m_NextSearchFile->LastAccess > LastAccess ) )
01215 m_NextSearchFile = File;
01216
01217
01218
01219
01220
01221
01222
01223 if( ( File->LastAccess != LastAccess ) &&
01224 ( ( ( File->PreviousFile != NULL ) &&
01225 ( File->PreviousFile->LastAccess > LastAccess ) ) ||
01226 ( ( File->NextFile != NULL ) &&
01227 ( File->NextFile->LastAccess <= LastAccess ) ) ) )
01228 {
01229
01230
01231 if( File->PreviousFile == NULL )
01232 m_StartListFiles = File->NextFile;
01233 else
01234 File->PreviousFile->NextFile = File->NextFile;
01235
01236 if( File->NextFile != NULL )
01237 File->NextFile->PreviousFile = File->PreviousFile;
01238
01239 if( ( File->PreviousFile != NULL ) &&
01240 ( File->PreviousFile->LastAccess > LastAccess) )
01241 {
01242
01243
01244 FileP = File->PreviousFile;
01245 FileA = File->PreviousFile->PreviousFile;
01246
01247 while( ( FileA != NULL ) && ( FileA->LastAccess > LastAccess ) )
01248 {
01249 FileP = FileA;
01250 FileA = FileA->PreviousFile;
01251 }
01252
01253 File->PreviousFile = FileA;
01254 File->NextFile = FileP;
01255 FileP->PreviousFile = File;
01256
01257 if( FileA == NULL )
01258 m_StartListFiles = File;
01259 else
01260 FileA->NextFile = File;
01261
01262 }
01263 else
01264 {
01265
01266
01267 FileP = File->NextFile;
01268 FileA = File->NextFile->NextFile;
01269
01270 while( (FileA != NULL ) && ( FileA->LastAccess <= LastAccess ) )
01271 {
01272 FileP = FileA;
01273 FileA = FileA->NextFile;
01274 }
01275
01276 File->PreviousFile = FileP;
01277 File->NextFile = FileA;
01278 FileP->NextFile = File;
01279
01280 if( FileA != NULL )
01281 FileA->PreviousFile = File;
01282
01283 }
01284
01285 }
01286
01287
01288
01289 File->LastAccess = LastAccess;
01290
01291 pthread_mutex_unlock( &m_mutex_filelist );
01292 return S_OK;
01293 }
01294
01295
01296 int CObjectManager::ChooseFile( bool *FileFound, char **FileName )
01297 {
01298 FileList *File;
01299
01300 pthread_mutex_lock( &m_mutex_filelist );
01301
01302
01303 File = m_NextSearchFile;
01304
01305 *FileFound = false;
01306 *FileName = NULL;
01307
01308 while( ( File != NULL ) && ( !*FileFound ) )
01309 {
01310 m_log << "CObjectManager::ChooseFile Verifying file " << File->FileName
01311 << ", LastAccess = " << File->LastAccess << ", NumReferences = "
01312 << File->NumReferences << endl;
01313
01314
01315
01316
01317 if( ( File->NumReferences == 0 ) && ( strlen( File->FileName ) >= 4 ) &&
01318 ( strcmp( &File->FileName[ strlen( File->FileName )-4 ],
01319 ".mpg" ) == 0 ) )
01320 {
01321 *FileFound = true;
01322 *FileName = File->FileName;
01323 m_NextSearchFile = File->NextFile;
01324 }
01325
01326 File = File->NextFile;
01327 }
01328
01329
01330 pthread_mutex_unlock( &m_mutex_filelist );
01331 return S_OK;
01332 }
01333
01334
01335 int CObjectManager::FreeDiskSpace( unsigned int FileSize )
01336 {
01337 unsigned int FreeBlocks;
01338 unsigned int NumberOfStorageNodes;
01339 unsigned int TotalBlocks;
01340 unsigned int i;
01341 int j;
01342 int NumberOfFreeSpace;
01343 bool FileFound;
01344 bool CantRemoveFiles;
01345 char *FileName;
01346 RioStorageNodeInfo StorageNodeInfo;
01347 NumberOfFreeSpace = 0;
01348
01349 TotalBlocks = ( FileSize + m_BlockSize - 1 ) / m_BlockSize;
01350
01351
01352 pthread_mutex_lock( &m_mutex_filelist );
01353 m_NextSearchFile = m_StartListFiles;
01354
01355 pthread_mutex_unlock( &m_mutex_filelist );
01356
01357 CantRemoveFiles = false;
01358
01359 m_DiskMgr->GetNumberOfStorageNodes( &NumberOfStorageNodes );
01360
01361 if( (unsigned int) m_UseReplications > NumberOfStorageNodes )
01362
01363
01364 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED;
01365
01366
01367 if( m_log.is_open() )
01368 m_log << "CObjectManager::FreeDiskSpace File Size = " << FileSize
01369 << ", Freeblocks needed " << TotalBlocks << endl;
01370
01371 while( ( NumberOfFreeSpace < m_UseReplications ) && ( !CantRemoveFiles ) )
01372 {
01373
01374
01375
01376
01377
01378 NumberOfFreeSpace = 0;
01379
01380
01381
01382 for( i = 0; i < NumberOfStorageNodes; i++ )
01383 {
01384
01385 FreeBlocks = 0;
01386
01387
01388 m_DiskMgr->GetStorageNodeInfo( i, &StorageNodeInfo );
01389
01390
01391
01392 for( j = 0; j < StorageNodeInfo.NumberOfDisks; j++ )
01393 FreeBlocks = FreeBlocks +
01394 StorageNodeInfo.Disks[ j ].NumberOfFreeBlocks;
01395
01396 if( m_log.is_open() )
01397 m_log << "CObjectManager::FreeDiskSpace " << FreeBlocks
01398 << " freeblocks in Storage " << i+1 << endl;
01399
01400
01401
01402
01403 if( FreeBlocks >= TotalBlocks )
01404 NumberOfFreeSpace++;
01405
01406 }
01407
01408
01409
01410
01411 if( NumberOfFreeSpace < m_UseReplications )
01412 {
01413 ChooseFile( &FileFound, &FileName );
01414
01415
01416 if( FileFound )
01417 {
01418
01419 if( m_log.is_open() )
01420 m_log << "CObjectManager::FreeDiskSpace File " << FileName
01421 << " deleted." << endl;
01422
01423
01424 Delete( FileName );
01425 }
01426 else
01427
01428
01429 CantRemoveFiles = true;
01430
01431 }
01432
01433 }
01434
01435
01436
01437
01438 if( CantRemoveFiles )
01439 {
01440
01441 if( m_log.is_open() )
01442 m_log << "CObjectManager::FreeDiskSpace Cannot free " << TotalBlocks
01443 << " blocks in " << m_UseReplications << " Storage Servers"
01444 << endl;
01445
01446
01447
01448
01449
01450 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED;
01451 }
01452 else
01453 return S_OK;
01454
01455 }
01456
01457
01458 int CObjectManager::CopyGridFile( char *ObjectName )
01459 {
01460
01461 char Command[ 2*MaxPathSize+1 ];
01462
01463
01464
01465 char LocalFileName[ 2*MaxPathSize+1 ];
01466
01467
01468 struct stat FileStat;
01469 unsigned int i;
01470 int rc;
01471
01472
01473 struct timeval inicio;
01474 struct timeval fim;
01475
01476
01477 strcpy( Command, "./CopyGridFile.sh " );
01478 strcat( Command, ObjectName );
01479
01480 if( m_log.is_open() )
01481 m_log << "CObjectManager::CopyGridFile executando o comando system "
01482 << "o parametro " << Command << endl;
01483
01484
01485 gettimeofday( &inicio, NULL );
01486
01487 rc = system( Command );
01488
01489 gettimeofday( &fim, NULL );
01490
01491
01492
01493 if( m_log.is_open() )
01494 m_log << "CObjectManager::CopyGridFile tempo para executar o comando "
01495 << "system(" << Command << "): "
01496 << ( (double)( fim.tv_sec-inicio.tv_sec ) +
01497 (double)( fim.tv_usec-inicio.tv_usec ) / 1000000.0 )
01498 << " seconds." << endl;
01499
01500 if ( !rc )
01501 {
01502
01503
01504 strcpy( LocalFileName, ObjectName );
01505
01506 for( i = 0; i < strlen( ObjectName ); i++ )
01507
01508 if( LocalFileName[ i ] == '/' )
01509 LocalFileName[ i ] = '.';
01510
01511
01512 rc = stat( LocalFileName, &FileStat );
01513
01514 if( rc )
01515 {
01516
01517
01518
01519 remove( LocalFileName );
01520 }
01521 else
01522 {
01523
01524
01525
01526 gettimeofday( &inicio, NULL );
01527
01528 rc = FreeDiskSpace( FileStat.st_size );
01529
01530 gettimeofday( &fim, NULL );
01531
01532
01533
01534 if( m_log.is_open() )
01535 m_log << "CObjectManager::CopyGridFile tempo para executar a "
01536 << "funcao FreeDiskSpace( " << FileStat.st_size << " ): "
01537 << ( (double)( fim.tv_sec-inicio.tv_sec ) +
01538 (double)( fim.tv_usec-inicio.tv_usec ) / 1000000.0 )
01539 << " seconds." << endl;
01540
01541 if( rc )
01542 {
01543
01544
01545
01546
01547 remove( LocalFileName );
01548 }
01549 else
01550 {
01551
01552
01553
01554 strcpy( Command, "./CopyLocalFile.sh " );
01555 strcat( Command, ObjectName );
01556
01557 if( m_log.is_open() )
01558 m_log << "CObjectManager::CopyGridFile executando o "
01559 << "comando system com o parametro " << Command
01560 << endl;
01561
01562
01563 gettimeofday( &inicio, NULL );
01564
01565
01566 system( Command );
01567
01568 gettimeofday( &fim, NULL );
01569
01570
01571
01572 if( m_log.is_open() )
01573 m_log << "CObjectManager::CopyGridFile tempo para executar "
01574 << "o comando system( " << Command << " ): " <<
01575 ( (double)( fim.tv_sec-inicio.tv_sec ) +
01576 (double)( fim.tv_usec-inicio.tv_usec ) / 1000000.0 )
01577 << " seconds." << endl;
01578
01579 }
01580
01581 }
01582
01583 }
01584
01585 return S_OK;
01586 }
01587
01588
01589 int CObjectManager::DeleteFileList()
01590 {
01591 FileList *File;
01592 FileList *NextFile;
01593
01594 File = m_StartListFiles;
01595
01596
01597
01598
01599 while( File != NULL )
01600 {
01601
01602
01603 NextFile = File->NextFile;
01604
01605 if( File->FileName != NULL )
01606
01607
01608 delete[] File->FileName;
01609
01610
01611 delete File;
01612
01613
01614
01615 File = NextFile;
01616 }
01617
01618
01619
01620
01621 m_StartListFiles = NULL;
01622 m_NextSearchFile = NULL;
01623 return S_OK;
01624 }
01625
01626
01627 int CObjectManager::InsertDirectoryFiles( char *PathName )
01628 {
01629 int status1;
01630 int status2;
01631 RioDirectory *Directory;
01632 char FileName[ 2*MaxPathSize+1 ];
01633 char RioPathFileName[ 2*MaxPathSize+1 ];
01634 char PathFileName[ 2*MaxPathSize+1 ];
01635 int IsDirectory;
01636 struct stat FileStat;
01637
01638 status1 = FirstObject( PathName, &Directory, &IsDirectory, 2 * MaxPathSize,
01639 FileName );
01640
01641 if( ( status1 != 0 ) && ( status1 != (int) ( ERROR_OBJECTMANAGER +
01642 ERROR_NO_MORE_OBJECTS ) ) )
01643 return status1;
01644
01645 while( !status1 )
01646 {
01647
01648
01649
01650
01651
01652 if( strlen( PathName ) + strlen( FileName ) + 1 > 2 * MaxPathSize )
01653 {
01654
01655
01656 delete Directory;
01657 return ERROR_PATHNAME_TOOLARGE;
01658 }
01659
01660
01661
01662 if( strlen( PathName ) != 0)
01663 {
01664 strcpy( RioPathFileName, PathName );
01665 strcat( RioPathFileName, "/" );
01666 strcat( RioPathFileName, FileName );
01667 }
01668 else
01669 strcpy( RioPathFileName, FileName );
01670
01671
01672
01673
01674
01675
01676 status2 = PathToFile( RioPathFileName, PathFileName, 2 * MaxPathSize );
01677
01678 if( status2 )
01679 {
01680
01681
01682 delete Directory;
01683 return status2;
01684 }
01685
01686
01687
01688
01689
01690 status2 = stat( PathFileName, &FileStat );
01691
01692 if( status2 )
01693 {
01694
01695
01696 delete Directory;
01697 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED;
01698 }
01699
01700 if ( S_ISREG(FileStat.st_mode) )
01701 {
01702
01703
01704
01705 status2 = InsertFile( RioPathFileName, FileStat.st_atime );
01706
01707 if( status2 )
01708 {
01709
01710
01711
01712 delete Directory;
01713 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED;
01714 }
01715 } else if( S_ISDIR(FileStat.st_mode ) )
01716 {
01717
01718
01719
01720 status2 = InsertDirectoryFiles( RioPathFileName );
01721
01722 if( status2 )
01723
01724
01725
01726
01727 return status2;
01728
01729 }
01730 else
01731 {
01732
01733
01734 delete Directory;
01735 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED;
01736 }
01737
01738
01739
01740 status1 = Directory->NextObject( &IsDirectory, 2 * MaxPathSize,
01741 FileName );
01742
01743 }
01744
01745
01746
01747 delete Directory;
01748
01749
01750
01751
01752 if( status1 != (int) ( ERROR_OBJECTMANAGER + ERROR_NO_MORE_OBJECTS ) )
01753 return status1;
01754 else
01755 return S_OK;
01756
01757 }
01758
01759 int CObjectManager::CreateFileList()
01760 {
01761
01762
01763
01764 if( m_StartListFiles != NULL )
01765 DeleteFileList();
01766
01767
01768 m_StartListFiles = NULL;
01769
01770
01771
01772 return InsertDirectoryFiles( "" );
01773 }
01774
01775 int CObjectManager::PrintFileList()
01776
01777 {
01778 FileList *File;
01779
01780 pthread_mutex_lock( &m_mutex_filelist );
01781
01782
01783 File = m_StartListFiles;
01784
01785
01786 if( m_log.is_open() )
01787 m_log << "CObjectManager::PrintFileList() FileList "<< endl;
01788
01789
01790
01791
01792 while( File != NULL )
01793 {
01794
01795
01796
01797 if( m_log.is_open() )
01798 m_log << "CObjectManager::PrintFileList() File " << File->FileName
01799 << ", Last Access Time = " << File->LastAccess
01800 << ", Open count = " << File->NumReferences << endl;
01801
01802 File = File->NextFile;
01803 }
01804
01805
01806 pthread_mutex_unlock( &m_mutex_filelist );
01807 return S_OK;
01808 }
01809
01810 #endif
01811
01812
01813
01814
01815
01816
01817
01818 RioDirectory::RioDirectory( CObjectManager *mgr )
01819 {
01820 o_mgr = mgr;
01821 o_dir = NULL;
01822
01823
01824 memset( (char *)&o_work, 0, sizeof( struct dirent ) );
01825 o_direntry = &o_work;
01826 o_DirectoryName[ 0 ] = '\0';
01827 o_extra[ 0 ] = '\0';
01828 }
01829
01830 RioDirectory::~RioDirectory()
01831 {
01832 Close();
01833 }
01834
01835 void RioDirectory::Close()
01836 {
01837 if( o_dir != 0 )
01838 {
01839 if( closedir( o_dir ) )
01840 {
01841 (o_mgr->m_log) << "RioDirectory.Close: "
01842 << "closedir failed " << strerror( errno )
01843 << " for " << o_DirectoryName << endl;
01844 }
01845 o_dir = 0;
01846 }
01847 }
01848
01849
01850 int RioDirectory::NextObject( int* IsDirectory, int BufferSize,
01851 char* ObjectName )
01852 {
01853 struct dirent *dp;
01854 int rc;
01855
01856 while( 1 )
01857 {
01858 rc = readdir_r( o_dir, o_direntry, &dp );
01859 if( rc != 0 )
01860 {
01861 o_mgr->m_log << "NextObject: readdir_r failed "
01862 << strerror( errno ) << endl;
01863 return ERROR_OBJECTMANAGER + ERROR_DIRECTORY_READ_FAILED;
01864 }
01865
01866 if( dp == NULL )
01867 return ERROR_OBJECTMANAGER + ERROR_NO_MORE_OBJECTS;
01868
01869 if( ( int ) strlen( dp->d_name ) >= BufferSize )
01870 return ERROR_OBJECTMANAGER + ERROR_NAMEBUFFER_OVERFLOW;
01871
01872 if( ( strcmp( dp->d_name, "." ) == 0 ) ||
01873 ( strcmp( dp->d_name, ".." ) == 0 ) )
01874 continue;
01875
01876
01877
01878
01879
01880
01881 char *pos = strrchr( dp->d_name, '.' );
01882 if( pos )
01883 if( ( strcmp( pos+1, "cactimes" ) == 0 ) ||
01884 ( strcmp( pos+1, "cacinf" ) == 0) )
01885 continue;
01886
01887
01888 break;
01889 }
01890
01891 strcpy( ObjectName, dp->d_name );
01892
01893
01894
01895
01896
01897 if( 0 )
01898 *IsDirectory = true;
01899 else
01900 *IsDirectory = false;
01901
01902 return S_OK;
01903 }