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 #include "ObjMapMgr.h"
00044 #include "ObjectManager.h"
00045 #include "DiskMgr.h"
00046 #include "RioError.h"
00047
00048
00049 #include "Object.pvt"
00050
00051 #include <stddef.h>
00052 #include <string.h>
00053 #include <errno.h>
00054 #include <time.h>
00055 #include <sys/types.h>
00056 #include <sys/stat.h>
00057 #include <fcntl.h>
00058 #include <dirent.h>
00059 #include <unistd.h>
00060 #include <stdlib.h>
00061
00062
00063 ObjMapMgr::ObjMapMgr()
00064 {
00065 m_used = 0;
00066 m_n = 0;
00067 m_BlockSize = 0;
00068 m_MaxReplications = 0;
00069 m_UseReplications = 0;
00070 m_DiskMgr = NULL;
00071 m_log = NULL;
00072 pthread_mutex_init( &m_mutexmeta, NULL );
00073 pthread_mutex_init( &m_mutexfast, NULL );
00074 }
00075
00076
00077 ObjMapMgr::~ObjMapMgr()
00078 {
00079 pthread_mutex_destroy(&m_mutexmeta);
00080 pthread_mutex_destroy(&m_mutexfast);
00081 }
00082
00083
00084 int ObjMapMgr::Initialize( int Size,
00085 unsigned int BlockSize,
00086 int MaxReplications, int UseReplications,
00087 DiskMgr *DiskMgr,
00088 ostream *LogStream)
00089 {
00090 if( sizeof( ObjectHeader ) != OBJHDRSIZE )
00091 {
00092 (*LogStream) << "ObjMapMgr.Initialize sizeof(ObjectHeader) "
00093 << sizeof(ObjectHeader) << " not " << OBJHDRSIZE << " \n";
00094 return -1;
00095 }
00096
00097 m_BlockSize = BlockSize;
00098
00099
00100
00101
00102
00103 m_MaxReplications = MaxReplications;
00104 m_UseReplications = UseReplications;
00105
00106 m_DiskMgr = DiskMgr;
00107 m_log = LogStream;
00108
00109
00110 m_n = Size;
00111 m_used = 0;
00112
00113 return S_OK;
00114 }
00115
00116
00117 int ObjMapMgr::Start()
00118 {
00119 return S_OK;
00120 }
00121
00122
00123 int ObjMapMgr::Stop()
00124 {
00125
00126 return S_OK;
00127 }
00128
00129
00130
00131 int ObjMapMgr::createobject(char *name)
00132 {
00133 int handle, nbytes, rc, error = 0;
00134 ObjectHeader header;
00135
00136 pthread_mutex_lock(&m_mutexmeta);
00137
00138 handle = open( name, O_RDWR | O_CREAT | O_EXCL, 0700 );
00139 if( handle == -1 )
00140 {
00141 error = errno;
00142 }
00143
00144 if( handle == -1 )
00145 {
00146 (*m_log) << "Create object failed " << strerror(errno) << endl;
00147 switch (error)
00148 {
00149 case EEXIST:
00150 rc = ERROR_OBJECTMANAGER + ERROR_OBJECT_EXISTS;
00151 goto unlockret;
00152
00153 case EISDIR:
00154 case ENAMETOOLONG:
00155 case ENOENT:
00156 case ENOTDIR:
00157 rc = ERROR_OBJECTMANAGER + ERROR_INVALID_OBJECTNAME;
00158 goto unlockret;
00159
00160 default:
00161 rc = ERROR_OBJECTMANAGER + ERROR_OBJECT_OPEN_FAILED;
00162 goto unlockret;
00163 }
00164 }
00165
00166 memset(&header, 0, sizeof(header));
00167 memcpy(header.Signature, ObjectSignatureValue, sizeof(header.Signature));
00168 header.Type = ObjectInfo::FILE_TYPE_DATA;
00169 header.nRep = m_UseReplications;
00170 header.BlockSize = m_BlockSize;
00171 header.nBlocks = 0;
00172 header.Size = 0;
00173
00174 header.nullmd5 = true;
00175
00176 nbytes = write( handle, &header, sizeof( header ));
00177 if( nbytes != sizeof( header ) )
00178 {
00179 close( handle );
00180 rc = ERROR_OBJECTMANAGER + ERROR_OBJECT_METADATA_WRITE;
00181 goto unlockret;
00182 }
00183 close( handle );
00184 rc = S_OK;
00185
00186 unlockret:
00187 pthread_mutex_unlock( &m_mutexmeta );
00188
00189 return rc;
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199 int ObjMapMgr::Open( char* Name, RioAccess Access, RioObject **Object )
00200 {
00201 int rc, nBytes = 0;
00202 off_t offset = 0;
00203 off_t readl = 0;
00204
00205 RioObject *op = new RioObject( this );
00206
00207 char *namep = new char[ strlen( Name ) + 1 ];
00208
00209 if( ( op == 0 ) || ( namep == 0 ) )
00210 {
00211 delete op;
00212 delete [] namep;
00213 return ERROR_OBJECTMANAGER + ERROR_MEMORY;
00214 }
00215
00216 strcpy(namep, Name);
00217 op->o_Name = namep;
00218
00219 pthread_mutex_lock( &m_mutexmeta );
00220
00221 m_used++;
00222
00223 rc = open( op->o_Name, O_RDWR );
00224 if( rc == -1 )
00225 {
00226 #ifdef RIO_DEBUG2
00227 RioErr << "ObjMapMgr: [Warning] Could not open " << op->o_Name
00228 << " with RDRW permissions. Trying to open it with RDONLY "
00229 << "permission" << endl;
00230 #endif
00231
00232 rc = open( op->o_Name, O_RDONLY );
00233 if( rc == -1 ){
00234 int error = errno;
00235 delete op;
00236 pthread_mutex_unlock(&m_mutexmeta);
00237 switch( error )
00238 {
00239 case EISDIR:
00240 case EACCES:
00241 case ENAMETOOLONG:
00242 case ENOENT:
00243 case ENOTDIR:
00244 return ERROR_OBJECTMANAGER + ERROR_INVALID_OBJECTNAME;
00245
00246 default:
00247 return ERROR_OBJECTMANAGER + ERROR_OBJECT_OPEN_FAILED;
00248 }
00249 }
00250 }
00251
00252 char *info = myInfo();
00253 (*m_log) << info << " Object Manager: opening object " << Name
00254 << ". active objs " << m_used << endl;
00255 free( info );
00256
00257
00258 op->o_FileHandle = rc;
00259
00260
00261 int nbytes = read( op->o_FileHandle, &op->o_Hdr, sizeof( op->o_Hdr ));
00262
00263 if( nbytes != sizeof( op->o_Hdr ) )
00264 {
00265 rc = 1;
00266 goto err;
00267 }
00268 if( op->o_Hdr.BlockSize != m_BlockSize )
00269 {
00270 rc = 2;
00271 goto err;
00272 }
00273 if( memcmp( op->o_Hdr.Signature, ObjectSignatureValue,
00274 sizeof( ObjectSignatureValue )))
00275 {
00276 rc = 3;
00277 goto err;
00278 }
00279 op->o_HdrValid = 1;
00280
00281 offset = lseek( op->o_FileHandle, 0, SEEK_END );
00282 if( offset == (off_t) -1 )
00283 {
00284 rc = 4;
00285 goto err;
00286 }
00287 if( ( unsigned ) offset != ( sizeof( op->o_Hdr )
00288 + op->o_Hdr.nBlocks * op->o_Hdr.nRep * sizeof( RioDiskBlock ) ) )
00289 {
00290 rc = 5;
00291 goto err;
00292 }
00293 if( ( (op->o_Hdr.Size + m_BlockSize - 1) / m_BlockSize ) !=
00294 op->o_Hdr.nBlocks
00295 )
00296 {
00297 rc = 6;
00298
00299
00300
00301
00302 RioErr << "ObjMapMgr.Open: metadata corrupt for " << op->o_Name;
00303 RioErr << ".Changing number of blocks from " << op->o_Hdr.nBlocks;
00304
00305 op->o_Hdr.nBlocks = ( op->o_Hdr.Size + m_BlockSize - 1 ) / m_BlockSize;
00306
00307 RioErr << " to " << op->o_Hdr.nBlocks << endl;
00308
00309 op->SaveObject();
00310
00311 }
00312
00313 op->o_Map = new RioDiskBlock[ op->o_Hdr.nBlocks * op->o_Hdr.nRep ];
00314 if( op->o_Map == 0 )
00315 {
00316 rc = 7;
00317 goto err;
00318 }
00319 op->o_nMapBlocks = op->o_Hdr.nBlocks;
00320
00321 offset = lseek( op->o_FileHandle, sizeof( op->o_Hdr ), SEEK_SET );
00322 if( offset == (off_t) -1 )
00323 {
00324 rc = 8;
00325 goto err;
00326 }
00327
00328 readl = op->o_Hdr.nBlocks * op->o_Hdr.nRep * sizeof( RioDiskBlock );
00329 nBytes = read( op->o_FileHandle, op->o_Map, readl );
00330 if( nBytes != readl )
00331 {
00332 rc = 9;
00333 goto err;
00334 }
00335 op->o_MapValid = 1;
00336
00337 pthread_mutex_lock( &m_mutexfast );
00338 op->o_Locked = 0;
00339 pthread_mutex_unlock( &m_mutexfast );
00340
00341
00342 *Object = op;
00343
00344
00345
00346 unsigned int VideoRate, VideoRateHeader;
00347 VideoRateHeader = op->o_Hdr.VideoRate;
00348
00349 pthread_mutex_unlock( &m_mutexmeta );
00350
00351 op->GetVideoRate( &VideoRate );
00352
00353 #ifdef RIO_DEBUG2
00354 RioErr << "ObjMapMgr.Open taxa de transferencia do objeto "
00355 << Name << ": lida = " << VideoRateHeader
00356 << ", alterada = " << VideoRate << endl;
00357 #endif
00358
00359 return S_OK;
00360
00361 err:
00362 RioErr << "ObjMapMgr.Open: metadata corrupt code " << rc
00363 << " for " << op->o_Name << endl;
00364 RioErr << " offset " << offset << " readl " << readl
00365 << " nBytes " << nBytes << endl;
00366 op->PrintHdr();
00367 delete op;
00368 pthread_mutex_unlock(&m_mutexmeta);
00369 return ERROR_OBJECTMANAGER + ERROR_OBJECT_METADATA_CORRUPTED;
00370 }
00371
00372
00373 RioObject::RioObject( ObjMapMgr *mgr )
00374 {
00375
00376 o_mgr = mgr;
00377 o_Name = NULL;
00378 o_FileHandle = -1;
00379 o_DeleteOnClose = false;
00380 o_MapChanged = false;
00381 o_MapValid = false;
00382 o_nMapBlocks = 0;
00383 o_Map = NULL;
00384 o_HdrValid = false;
00385 o_Locked = 1;
00386 memset( (char *)&o_Hdr, 0, sizeof( o_Hdr ) );
00387 }
00388
00389
00390
00391
00392
00393 RioObject::~RioObject()
00394 {
00395 int rc;
00396 pthread_mutex_lock( &o_mgr->m_mutexfast );
00397 if( o_FileHandle != -1 )
00398 {
00399 close(o_FileHandle);
00400 }
00401 delete [] o_Map;
00402 o_mgr->m_used--;
00403 pthread_mutex_unlock( &o_mgr->m_mutexfast );
00404
00405
00406 if( o_DeleteOnClose && ( o_Hdr.Size == 0 ) )
00407 {
00408 rc = unlink( o_Name );
00409 if( rc )
00410 {
00411 (*o_mgr->m_log) << "~RioObject unlink for " << o_Name << ": "
00412 << strerror(errno) << endl;
00413 }
00414 }
00415
00416 delete [] o_Name;
00417 }
00418
00419
00420
00421
00422 int RioObject::Close()
00423 {
00424 time_t t;
00425
00426
00427
00428
00429
00430
00431 pthread_mutex_lock( &o_mgr->m_mutexmeta );
00432 time( &t );
00433 if( t == ( time_t ) - 1 )
00434 {
00435 (*o_mgr->m_log) << "RioObject.Close: time failed "
00436 << strerror(errno) << endl;
00437 }
00438 else
00439 {
00440 o_Hdr.LastWrite = t;
00441 }
00442
00443
00444 if( close( o_FileHandle ) )
00445 {
00446 pthread_mutex_unlock( &o_mgr->m_mutexmeta );
00447 (*o_mgr->m_log) << "ObjMapMgr.Close: close failed "
00448 << strerror(errno) << endl;
00449 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED;
00450 }
00451 pthread_mutex_unlock( &o_mgr->m_mutexmeta );
00452
00453 return S_OK;
00454 }
00455
00456
00457 int RioObject::MarkDelete()
00458 {
00459 int rc;
00460
00461 rc = SetSize(0, NULL, 0);
00462 if( rc )
00463 return rc;
00464 o_DeleteOnClose = 1;
00465 return 0;
00466 }
00467
00468 int RioObject::GetSize( RioObjectSize *Size )
00469 {
00470 *Size = o_Hdr.Size;
00471 return S_OK;
00472 }
00473
00474 int RioObject::GetType( short *Type)
00475 {
00476 *Type = o_Hdr.Type;
00477 return S_OK;
00478 }
00479
00480 int RioObject::GetnBlocks( RioBlock *nBlocks )
00481 {
00482 *nBlocks = o_Hdr.nBlocks;
00483 return S_OK;
00484 }
00485
00486
00487
00488
00489
00490 int RioObject::GetBlockMap ( RioBlock first, RioBlock nBlocks,
00491 RioDiskBlock *blocks )
00492 {
00493 pthread_mutex_lock( &o_mgr->m_mutexfast );
00494 if( o_Locked )
00495 {
00496 pthread_mutex_unlock( &o_mgr->m_mutexfast );
00497 return ERROR_OBJECTMANAGER + ERROR_OBJECT_OPEN_FAILED;
00498 }
00499
00500 if( ( first + nBlocks ) > o_Hdr.nBlocks )
00501 {
00502 pthread_mutex_unlock( &o_mgr->m_mutexfast );
00503 return ERROR_OBJECTMANAGER + ERROR_INVALID_LOGICAL_BLOCK;
00504 }
00505
00506 memcpy( blocks, o_Map + first, nBlocks * sizeof( RioDiskBlock ));
00507
00508 pthread_mutex_unlock( &o_mgr->m_mutexfast );
00509 return S_OK;
00510 }
00511
00512
00513
00514
00515
00516
00517
00518 int RioObject::MapBlock( RioBlock Block, int RepBits, int *numrep,
00519 RioDiskBlock *reps )
00520 {
00521 int rc = 0;
00522 int i, num;
00523 RioDiskBlock *p;
00524
00525 num = 0;
00526 pthread_mutex_lock( &( o_mgr->m_mutexfast ) );
00527
00528 if( o_Locked || !o_MapValid )
00529 {
00530 rc = ERROR_OBJECTMANAGER + ERROR_OBJECT_OPEN_FAILED;
00531 goto ret;
00532 }
00533
00534 if( Block >= o_Hdr.nBlocks )
00535 {
00536 rc = ERROR_OBJECTMANAGER + ERROR_INVALID_LOGICAL_BLOCK;
00537 goto ret;
00538 }
00539
00540 p = &o_Map[ o_Hdr.nRep * Block ];
00541 for( i = 0; i < o_Hdr.nRep; i++, p++, RepBits >>= 1 )
00542 {
00543 if( RepBits & 1 )
00544 continue;
00545 if( p->disk == 0 )
00546 continue;
00547 memcpy( (char *) reps, (char *) p, sizeof( RioDiskBlock ));
00548 reps++;
00549 num++;
00550 }
00551 ret:
00552 pthread_mutex_unlock( &( o_mgr->m_mutexfast ) );
00553 *numrep = num;
00554 if( num == 0 )
00555 {
00556
00557 return ERROR_RIOOBJECT+ERROR_INVALID_PHYSICAL_BLOCK;
00558 }
00559 return rc;
00560 }
00561
00562
00563
00564
00565
00566 int RioObject::SetSize( RioObjectSize Size, char *md5sum,
00567 unsigned long long int ExcludeStorages )
00568 {
00569 int result = S_OK;
00570 int result2;
00571
00572 RioBlock nBlocks;
00573
00574
00575
00576
00577
00578 pthread_mutex_lock(&o_mgr->m_mutexmeta);
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589 nBlocks = ( Size + ( o_Hdr.BlockSize - 1 )) / o_Hdr.BlockSize;
00590
00591
00592 if( nBlocks == o_Hdr.nBlocks )
00593 {
00594 pthread_mutex_unlock( &o_mgr->m_mutexmeta );
00595 return S_OK;
00596 }
00597
00598 if( nBlocks > o_Hdr.nBlocks )
00599 {
00600 result = Extend( nBlocks, ExcludeStorages );
00601 }
00602 else
00603 {
00604 result = Truncate( nBlocks );
00605 }
00606
00607
00608
00609
00610
00611
00612 if( FAILED( result ) )
00613 {
00614 (*o_mgr->m_log)<< "Set Size Failed." << endl;
00615
00616
00617 if( o_Hdr.nBlocks > nBlocks )
00618 {
00619
00620 if( ( o_Hdr.nBlocks * o_Hdr.BlockSize ) < o_Hdr.Size )
00621 {
00622 Size = o_Hdr.nBlocks * o_Hdr.BlockSize;
00623 }
00624 else
00625 {
00626 Size = o_Hdr.Size;
00627 }
00628 }
00629
00630 if( o_Hdr.nBlocks < nBlocks )
00631 {
00632
00633 Size = o_Hdr.nBlocks * o_Hdr.BlockSize;
00634 }
00635 }
00636
00637
00638 o_Hdr.Size = Size;
00639
00640
00641 if( md5sum == NULL )
00642 o_Hdr.nullmd5 = true;
00643 else
00644 {
00645 o_Hdr.nullmd5 = false;
00646 unsigned char md5_16bytes[16];
00647 for( int i = 0; i < 16; i++ )
00648 {
00649 if( md5sum[2*i] <= '9' )
00650 md5sum[2*i] -= '0';
00651 else
00652 md5sum[2*i] -= ('a' - 10 );
00653
00654 if( md5sum[2*i+1] <= '9' )
00655 md5sum[2*i+1] -= '0';
00656 else
00657 md5sum[2*i+1] -= ('a' - 10 );
00658
00659 md5_16bytes[i] = ((md5sum[2*i] << 4 ) | md5sum[2*i+1]);
00660 }
00661 memcpy( o_Hdr.md5sum, md5_16bytes, 16 );
00662 }
00663
00664
00665 result2 = SaveObject();
00666 pthread_mutex_unlock(&o_mgr->m_mutexmeta);
00667
00668 if( FAILED( result ) )
00669 return result;
00670 else
00671 return result2;
00672 }
00673
00674
00675
00676
00677 int RioObject::SaveObject()
00678 {
00679 int n, nbytes;
00680 int rc;
00681
00682 n = lseek( o_FileHandle, 0, SEEK_SET );
00683 if( n != 0 )
00684 {
00685 rc = 1;
00686 goto err;
00687 }
00688
00689 n = write( o_FileHandle, &o_Hdr, sizeof( o_Hdr ));
00690 if( n != sizeof( o_Hdr ) )
00691 {
00692 rc = 2;
00693 goto err;
00694 }
00695
00696 if( o_MapChanged )
00697 {
00698 nbytes = o_Hdr.nRep * o_Hdr.nBlocks * sizeof( RioDiskBlock );
00699 n = write(o_FileHandle, o_Map, nbytes);
00700 if( n != nbytes )
00701 {
00702 rc = 3;
00703 goto err;
00704 }
00705
00706 nbytes += sizeof( o_Hdr );
00707 rc = ftruncate( o_FileHandle, nbytes );
00708 if( rc )
00709 {
00710 rc = 4;
00711 goto err;
00712 }
00713 }
00714
00715 o_MapChanged = 0;
00716 return S_OK;
00717
00718 err:
00719 RioErr << "RioObject.SaveHeader failed for " << o_Name
00720 << " code " << rc << " " << strerror(errno) << endl;
00721 return ERROR_OBJECTMANAGER + ERROR_OBJECT_METADATA_WRITE;
00722 }
00723
00724
00725 void RioObject::PrintHdr()
00726 {
00727 RioErr << "o_Hdr nRep " << o_Hdr.nRep
00728 << " BlockSize " << o_Hdr.BlockSize
00729 << " nBlocks " << o_Hdr.nBlocks
00730 << " Size " << o_Hdr.Size
00731 << " VideoRate " << o_Hdr.VideoRate
00732 << endl;
00733 }
00734
00735
00736
00737
00738
00739
00740 int RioObject::Extend( RioBlock nBlocks, unsigned long long int ExcludeStorages )
00741 {
00742 RioDiskBlock *newmap, *newp;
00743 RioBlock n;
00744 int rc = 0;
00745
00746 pthread_mutex_lock( &o_mgr->m_mutexfast );
00747
00748
00749 if( o_nMapBlocks >= nBlocks ) goto diskalloc;
00750
00751 newmap = new RioDiskBlock[ nBlocks * o_Hdr.nRep ];
00752 if( newmap == 0 )
00753 {
00754 pthread_mutex_unlock( &o_mgr->m_mutexfast );
00755 return ERROR_MEMORY;
00756 }
00757
00758 memset(newmap, 0, nBlocks * o_Hdr.nRep * sizeof( RioDiskBlock ));
00759 memcpy(newmap, o_Map, o_Hdr.nBlocks * o_Hdr.nRep * sizeof( RioDiskBlock ));
00760 delete [] o_Map;
00761 o_Map = newmap;
00762 o_nMapBlocks = nBlocks;
00763
00764 diskalloc:
00765
00766 for( n = o_Hdr.nBlocks; n < nBlocks; n++ )
00767 {
00768 newp = o_Map + ( n * o_Hdr.nRep );
00769 rc = o_mgr->m_DiskMgr->AllocMult( o_Hdr.nRep, newp, ExcludeStorages );
00770 if( rc )
00771 goto quit;
00772 o_Hdr.nBlocks = n + 1;
00773 }
00774
00775 for( n = 0; n < o_Hdr.nBlocks; n++ )
00776 {
00777 newp = o_Map + (n * o_Hdr.nRep);
00778 if( newp->disk == 0 )
00779 {
00780 RioErr << "ObjMapMgr:Extend block " << n << " null" << endl;
00781 abort();
00782 }
00783 }
00784
00785 quit:
00786
00787 o_MapChanged = 1;
00788 pthread_mutex_unlock( &o_mgr->m_mutexfast );
00789
00790 SaveObject();
00791
00792 o_mgr->m_DiskMgr->Confirm();
00793
00794 return rc;
00795 }
00796
00797
00798
00799
00800
00801
00802
00803
00804 int RioObject::Truncate( RioBlock nBlocks )
00805 {
00806 RioBlock n;
00807 RioDiskBlock *rep;
00808 int rc = 0;
00809 int i;
00810
00811 pthread_mutex_lock( &o_mgr->m_mutexfast );
00812
00813
00814 o_MapChanged = 1;
00815
00816 for( n = o_Hdr.nBlocks; n > nBlocks; n-- )
00817 {
00818 rep = &o_Map[ ( n - 1 ) * o_Hdr.nRep ];
00819
00820
00821
00822 for( i = o_Hdr.nRep-1; i >= 0; i-- )
00823 {
00824 rc = o_mgr->m_DiskMgr->Free( &rep[i] );
00825 if( rc )
00826 goto quit;
00827 }
00828
00829
00830
00831 o_Hdr.nBlocks = n - 1;
00832
00833 }
00834
00835 quit:
00836
00837 pthread_mutex_unlock(&o_mgr->m_mutexfast);
00838
00839 SaveObject();
00840
00841 o_mgr->m_DiskMgr->Confirm();
00842
00843 return rc;
00844 }
00845
00846
00847
00848
00849 int RioObject::GetObjectName( char *ObjectName )
00850 {
00851
00852
00853 strcpy( ObjectName, o_Name );
00854 return S_OK;
00855 }
00856
00857
00858
00859
00860
00861
00862
00863
00864 int RioObject::GetVideoRate( unsigned int *VideoRate )
00865 {
00866
00867 pthread_mutex_lock(&o_mgr->m_mutexmeta);
00868 if ( o_Hdr.VideoRate == 0 )
00869
00870
00871 *VideoRate = DEFAULTVIDEORATE;
00872 else
00873 *VideoRate = o_Hdr.VideoRate;
00874
00875 pthread_mutex_unlock(&o_mgr->m_mutexmeta);
00876 return S_OK;
00877 }
00878
00879
00880
00881
00882 int RioObject::SetVideoRate( unsigned int VideoRate )
00883 {
00884 int result;
00885
00886 pthread_mutex_lock(&o_mgr->m_mutexmeta);
00887 o_Hdr.VideoRate = VideoRate;
00888 result = SaveObject();
00889
00890 pthread_mutex_unlock(&o_mgr->m_mutexmeta);
00891 return result;
00892 }
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902 int RioObject::ReallocBlocks( RioBlock Block,
00903 unsigned long long int ExcludeStorages )
00904 {
00905 RioDiskBlock *PosLastBlock, *NewBlocks;
00906 int i, TotalBlocks, PosNewBlock, StorageId, rc = 0;
00907 unsigned long long int ExcludeStoragesNewBlocs;
00908
00909 if( Block >= o_nMapBlocks )
00910 return ERROR_DISKMGR + ERROR_INVALID_BLOCK;
00911 else
00912 {
00913
00914
00915 ExcludeStoragesNewBlocs = ExcludeStorages;
00916
00917
00918
00919 NewBlocks = new RioDiskBlock[ o_Hdr.nRep ];
00920 if( NewBlocks == NULL )
00921 return ERROR_DISKMGR + ERROR_MEMORY;
00922
00923 pthread_mutex_lock( &o_mgr->m_mutexmeta );
00924
00925 pthread_mutex_lock( &o_mgr->m_mutexfast );
00926
00927
00928 PosLastBlock= o_Map + ( Block * o_Hdr.nRep );
00929
00930
00931 TotalBlocks = 0;
00932 #ifdef RIO_DEBUG2
00933 RioErr << "RioObject::ReallocBlocks existem " << o_Hdr.nRep
00934 << " replicacoes para o bloco " << Block << endl;
00935 #endif
00936 for( i = 0; i < o_Hdr.nRep; i++ )
00937 {
00938 if( PosLastBlock[ i ].disk > 0 )
00939 {
00940 StorageId = ( PosLastBlock[ i ].disk - 1 ) / SNode::sn_maxdisks;
00941 #ifdef RIO_DEBUG2
00942 RioErr << "RioObject::ReallocBlocks verificando a replicacao "
00943 << i + 1 << " do disco " << PosLastBlock[ i ].disk
00944 << " e o bloco " << PosLastBlock[ i ].block
00945 << " do servidor de armazenamento com a ID " << StorageId
00946 << endl;
00947 #endif
00948
00949
00950 if( ( ExcludeStorages & ( 1ull << StorageId ) ) != 0 )
00951 {
00952 #ifdef RIO_DEBUG2
00953 RioErr << "RioObject::ReallocBlocks o bloco "
00954 << PosLastBlock[ i ].block << " associado ao disco "
00955 << PosLastBlock[ i ].disk << " precisa ser "
00956 << "realocado" << endl;
00957 #endif
00958
00959 TotalBlocks++;
00960
00961
00962
00963 rc = o_mgr->m_DiskMgr->Free( &PosLastBlock[ i ] );
00964 if( rc )
00965 {
00966 #ifdef RIO_DEBUG2
00967 RioErr << "RioObject::ReallocBlocks erro ao remover o "
00968 << "bloco " << PosLastBlock[ i ].block
00969 << " associado ao disco "
00970 << PosLastBlock[ i ].disk << ". Abortando o "
00971 << "processo de realocacao" << endl;
00972 #endif
00973 break;
00974 }
00975
00976
00977 PosLastBlock[ i ].disk = -1;
00978 }
00979 else
00980 {
00981
00982
00983 #ifdef RIO_DEBUG2
00984 RioErr << "RioObject::ReallocBlocks o bloco "
00985 << PosLastBlock[ i ].block << " associado ao disco "
00986 << PosLastBlock[ i ].disk << " esta ok. Igonrando "
00987 << "os discos do storage com a ID " << StorageId
00988 << " ao escolher os novos blocos fisicos" << endl;
00989 #endif
00990 ExcludeStoragesNewBlocs = ExcludeStoragesNewBlocs |
00991 ( 1ull << StorageId );
00992 }
00993 }
00994 #ifdef RIO_DEBUG2
00995 else
00996 RioErr << "RioObject::ReallocBlocks o disco da replicacao "
00997 << i + 1 << " do vetor de replicacoes possui a ID "
00998 << "invalida " << PosLastBlock[ i ].disk << endl;
00999 #endif
01000 }
01001
01002 if( ( !rc ) && ( TotalBlocks != 0 ) )
01003 {
01004
01005
01006
01007 rc = o_mgr->m_DiskMgr->AllocMult( TotalBlocks, NewBlocks,
01008 ExcludeStoragesNewBlocs );
01009
01010 if( !rc )
01011 {
01012
01013
01014 PosNewBlock = 0;
01015 for( i = 0; i < o_Hdr.nRep; i++ )
01016 {
01017 if( PosLastBlock[ i ].disk == -1 )
01018 {
01019 #ifdef RIO_DEBUG2
01020 RioErr << "RioObject::ReallocBlocks realocando o bloco "
01021 << " da replicacao " << i + 1 << endl;
01022 #endif
01023
01024
01025 if( PosNewBlock >= TotalBlocks )
01026 {
01027
01028
01029 #ifdef RIO_DEBUG2
01030 RioErr << "RioObject::ReallocBlocks numero "
01031 << "insuficiente de realocacoes ("
01032 << TotalBlocks << ")" << endl;
01033 #endif
01034 rc = ERROR_DISKMGR + ERROR_UNEXPECTED;
01035 break;
01036 }
01037 else
01038 {
01039
01040
01041 PosLastBlock[ i ].disk = NewBlocks[ PosNewBlock ].
01042 disk;
01043 PosLastBlock[ i ].block = NewBlocks[ PosNewBlock ].
01044 block;
01045
01046 #ifdef RIO_DEBUG2
01047 RioErr << "RioObject::ReallocBlocks novo bloco "
01048 << "associado a realocacao " << i + 1
01049 << ": disco = " << PosLastBlock[ i ].disk
01050 << ", bloco = " << PosLastBlock[ i ].block
01051 << endl;
01052 #endif
01053
01054 PosNewBlock++;
01055 }
01056 }
01057 #ifdef RIO_DEBUG2
01058 else if( PosLastBlock[ i ].disk == 0 )
01059 RioErr << "RioObject::ReallocBlocks a replicacao "
01060 << i + 1 << " possui o disco com a ID "
01061 << "reservada 0" << endl;
01062 #endif
01063 }
01064 }
01065 #ifdef RIO_DEBUG2
01066 else
01067 {
01068 RioErr << "RioObject::ReallocBlocks erro 0x" << hex
01069 << ( unsigned int ) rc << dec << " ao executar a "
01070 << "funcao AllocMult" << endl;
01071 }
01072 #endif
01073 }
01074 else if( TotalBlocks == 0 )
01075 {
01076
01077
01078 #ifdef RIO_DEBUG2
01079 RioErr << "RioObject::ReallocBlocks a funcao foi chamada mas nao "
01080 << "foi necessaria a realocacao dos blocos" << endl;
01081 #endif
01082
01083 pthread_mutex_unlock( &o_mgr->m_mutexfast );
01084
01085 pthread_mutex_unlock( &o_mgr->m_mutexmeta );
01086
01087 delete NewBlocks;
01088
01089 return ERROR_DISKMGR + ERROR_UNEXPECTED;
01090 }
01091 #ifdef RIO_DEBUG2
01092 else
01093 {
01094 RioErr << "RioObject::ReallocBlocks erro 0x" << hex
01095 << ( unsigned int ) rc << dec << " ao executar a funcao "
01096 << "Free" << endl;
01097 }
01098 #endif
01099
01100
01101
01102
01103
01104 for( i = 0; i < o_Hdr.nRep; i++ )
01105 if( PosLastBlock[ i ].disk == -1 )
01106 {
01107 #ifdef RIO_DEBUG2
01108 RioErr << "RioObject::ReallocBlocks a replicacao "
01109 << i + 1 << " possui o disco com a ID invalida -1. "
01110 << "Mudando a ID para 0 para permitir a remocao do "
01111 << "objeto associado ao bloco logico " << Block << endl;
01112 #endif
01113 PosLastBlock[ i ].disk = 0;
01114 rc = ERROR_DISKMGR + ERROR_UNEXPECTED;
01115 }
01116
01117
01118 o_MapChanged = 1;
01119
01120
01121 pthread_mutex_unlock( &o_mgr->m_mutexfast );
01122
01123 SaveObject();
01124
01125
01126 pthread_mutex_unlock( &o_mgr->m_mutexmeta );
01127
01128
01129 o_mgr->m_DiskMgr->Confirm();
01130
01131
01132 delete NewBlocks;
01133
01134 return rc;
01135 }
01136 }
01137
01138
01139 int ObjMapMgr::GetObjectInfo( char* Name, ObjectInfo* ObjectInfo )
01140 {
01141 struct stat mystat;
01142
01143 if( stat( Name, &mystat ) )
01144 return ERROR_OBJECTMANAGER + ERROR_OBJECT_OPEN_FAILED;
01145
01146 if( S_ISREG( mystat.st_mode ) )
01147 {
01148 ObjectInfo->setType( ObjectInfo::FILE_TYPE_DATA );
01149 }
01150 else if(S_ISDIR(mystat.st_mode))
01151 {
01152 ObjectInfo->setType( ObjectInfo::FILE_TYPE_DIRECTORY );
01153 }
01154 else return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED;
01155
01156 struct tm LastWrite;
01157 AccessTime LastModificationTime;
01158
01159
01160 localtime_r(&mystat.st_ctime, &LastWrite);
01161 LastModificationTime.Year = LastWrite.tm_year+1900;
01162 LastModificationTime.Month = LastWrite.tm_mon+1;
01163 LastModificationTime.DayOfWeek = LastWrite.tm_wday;
01164 LastModificationTime.Day = LastWrite.tm_mday;
01165 LastModificationTime.Hour = LastWrite.tm_hour;
01166 LastModificationTime.Minute = LastWrite.tm_min;
01167
01168 ObjectInfo->setTime( LastModificationTime );
01169
01170 if( ObjectInfo->isDir() )
01171 ObjectInfo->setPermission( 0777 );
01172 else
01173 ObjectInfo->setPermission( 0666 );
01174
01175 if( !ObjectInfo->isDir() )
01176 {
01177 int Handle;
01178 pthread_mutex_lock( &m_mutexmeta );
01179
01180 Handle = open( Name, O_RDWR );
01181 if( Handle == -1 )
01182 {
01183 RioErr << "ObjMapMgr: [Warning] Could not open " << Name
01184 << " with RDRW permissions. Trying to open it with "
01185 << "RDONLY permission" << endl;
01186 Handle = open( Name, O_RDONLY );
01187 if( Handle == -1 )
01188 {
01189 pthread_mutex_unlock( &m_mutexmeta );
01190 if(errno == ENOENT)
01191 return ERROR_OBJECTMANAGER + ERROR_INVALID_OBJECTNAME;
01192 return ERROR_OBJECTMANAGER + ERROR_OBJECT_OPEN_FAILED;
01193 }
01194 }
01195
01196 ObjectHeader header;
01197 int nbytes;
01198
01199
01200 nbytes = read( Handle, &header, sizeof( header ));
01201 pthread_mutex_unlock( &m_mutexmeta );
01202
01203 if( ( nbytes != sizeof( header )) || (header.BlockSize != m_BlockSize) ||
01204 ( memcmp( header.Signature, ObjectSignatureValue,
01205 sizeof(ObjectSignatureValue))) )
01206 {
01207 close(Handle);
01208 (*m_log) << "ObjMapMgr.GetObjectInfo(): "
01209 << "Object metadata is corrupted" << endl;
01210 return ERROR_OBJECTMANAGER + ERROR_OBJECT_METADATA_CORRUPTED;
01211 }
01212
01213
01214 close(Handle);
01215
01216
01217 ObjectInfo->setSize( header.Size );
01218
01219
01220 if( header.nullmd5 )
01221 ObjectInfo->setMd5sum( NULL );
01222 else
01223 {
01224 char hexmd5sum[33];
01225 char hex[17] = "0123456789abcdef";
01226 for( int i = 0; i < 16; ++i )
01227 {
01228 hexmd5sum[2*i] = hex[ ((unsigned char)header.md5sum[i]) >> 4 ];
01229 hexmd5sum[2*i + 1] = hex[ ((unsigned char)header.md5sum[i]) & 15 ];
01230 }
01231 hexmd5sum[32] = '\0';
01232 ObjectInfo->setMd5sum( hexmd5sum );
01233 }
01234
01235
01236
01237 if( header.VideoRate == 0 )
01238
01239 ObjectInfo->setVideoRate( DEFAULTVIDEORATE );
01240 else
01241 ObjectInfo->setVideoRate( header.VideoRate );
01242
01243 }
01244 else
01245 {
01246 ObjectInfo->setSize( 0 );
01247
01248 ObjectInfo->setMd5sum( NULL );
01249
01250
01251
01252 ObjectInfo->setVideoRate( 0 );
01253 }
01254
01255
01256 ObjectInfo->setOwner( "NoUser" );
01257 ObjectInfo->setGroup( "NoGroup" );
01258
01259 return S_OK;
01260 }
01261