DiskMgr Class Reference

#include <DiskMgr.h>

Public Member Functions

 DiskMgr ()
 ~DiskMgr ()
int Initialize (DiskMgrConfig *Config)
int BuildNode (char *hostname, bool Connect)
int Start ()
int Stop ()
int CleanUp ()
int AllocMult (int numReplicas, RioDiskBlock *rep, unsigned long long int ExcludeStorages)
int Alloc (RioDiskBlock *rep, unsigned long long int ExcludeStorages)
int Free (RioDiskBlock *rep)
int Reset ()
int Confirm ()
int Format ()
void SendStorageNode (EventStorageRequest *event, u16 DiskId)
int GetNumberOfStorageNodes (unsigned int *NumberOfStorageNodes)
int GetStorageNodeInfo (unsigned int StorageNodeIndex, RioStorageNodeInfo *StorageNodeInfo)
int GetDiskStorageNodeInfo (unsigned int DiskId, RioStorageNodeInfo *StorageNodeInfo)
int GetMaxNumberOfDisks ()
int GetNumberOfActiveDisks (unsigned int *NumberOfDisks)
int GetDiskName (unsigned int DiskId, char *DiskName)
int GetDiskServiceTime (EventStorageRequest *event, u16 DiskId)
unsigned int GetDiskNumberOfFreeBlocks (unsigned int DiskId)
int GetStorageServersAddress (SOCKADDR_IN *ServerAddress)
 Funcao para obter todos os enderecos (pares IP e porta) dos Storage Servers (que estao listados no arquivo RIOdisk.cfg).
int SendStorageNodeByIP (EventStorageRequest *event, u32 StorageIP)
 Nova funcao, usada pelo gerenciamento de logs, para colocar um evento na fila de eventos (com mensagens a serem enviadas) ao servidor de armazenamento identificado pelo IP dado com parametro.
int GetNumberOfReplications (void)
 Nova funcao para obter o numero de replicacoes de cada bloco.
int GetNumberOfNeededDisks (unsigned int *NumberOfDisks)
 Nova funcao para retornar o numero minimo de discos necessarios para inicializar as estruturas do servidor.

Private Member Functions

int ReadConfiguration ()
void BuildAlloc ()
bool CheckDiskAlloc (int num, RioDiskBlock *rep, int choice)
int LoadDisksBitMaps (unsigned int StorageId)
 Nova funcao para carregar os BitMaps dos discos associados a um servidor de armazenamento.
int FreeSalvedBlocks (const char *StorageName)
 Nova funcao para liberar os blocos salvos no arquivo de um servidor de armazenamento.

Private Attributes

int m_BlockSize
int m_MaxDisks
int m_MaxReps
char * m_MetaRoot
CRouterm_Router
CSystemManagerm_SystemManager
int m_cntAllocMult
int m_cntAllocRetry
int m_cntAllocFail
pthread_mutex_t m_mutex
int m_numDisks
Disk ** m_disks
int m_NumberOfActiveDisks
int m_NumberOfStorageNodes
ofstream m_log
int m_diskanum
Disk ** m_diska
Diskm_disklist
SNodem_nodelist
pthread_t m_thread
int m_termflag
char * m_ConfigsDirectory
unsigned int m_MaxAttempts
unsigned int m_TimeBetweenAttempts
unsigned long long int m_storagesnotfull
bool m_IsFormatting

Friends

class Disk
class SNode

Detailed Description

Definition at line 37 of file DiskMgr.h.


Constructor & Destructor Documentation

DiskMgr::DiskMgr (  ) 

Definition at line 71 of file DiskMgr.cpp.

00072 {
00073     m_disks = 0;
00074 
00075     m_BlockSize     = 0;
00076     m_MaxDisks      = 0;
00077     m_MetaRoot      = NULL;
00078     m_Router        = NULL;
00079     m_SystemManager = NULL;
00080     m_thread        = 0;
00081     m_termflag      = 0;
00082     // m_log does not need to be initialized
00083 
00084     // ### should do this differently: numDisks should not count disk 0
00085     m_numDisks  = 1; // reserve disk 0
00086     m_MaxReps   = 0; // vou testar a leitura do MaxReps direto do system.cfg
00087 
00088     m_cntAllocMult = m_cntAllocRetry = m_cntAllocFail = 0;
00089 
00090     pthread_mutex_init( &m_mutex, NULL );
00091 
00092     m_diska     = 0;
00093     m_diskanum  = 0;
00094 
00095     m_disklist  = 0;
00096     m_nodelist  = 0;
00097 
00098 
00099     m_NumberOfActiveDisks = 0;
00100     m_NumberOfStorageNodes = 0;
00101     // ------------------------------------------------------------------------
00102 }

DiskMgr::~DiskMgr (  ) 

Definition at line 104 of file DiskMgr.cpp.

00105 {
00106     int i;
00107     SNode *np;
00108 
00109     // Remove as estruturas usadas pelos discos.
00110     if( m_disks )
00111     {
00112         for( i = 0; i <= m_MaxDisks; i++ )
00113         {
00114             if( m_disks[i] )
00115             {
00116                 delete m_disks[i];
00117                 m_disks[i] = 0;
00118             }
00119         }
00120         delete [] m_disks;
00121         m_disks = 0;
00122     }
00123     if( m_diska )
00124     {
00125         delete [] m_diska;
00126         m_diska = 0;
00127     }
00128     
00129     // Remove as estruturas usadas pelos servidores de armazenamento.
00130     while( m_nodelist != NULL )
00131     {
00132         np = m_nodelist->sn_link;
00133         delete m_nodelist;
00134         m_nodelist = np;
00135     }
00136     
00137     pthread_mutex_destroy( &m_mutex );
00138 
00139     if( m_log.is_open() ) m_log.close();
00140     // ------------------------------------------------------------------------
00141 }


Member Function Documentation

int DiskMgr::Alloc ( RioDiskBlock rep,
unsigned long long int  ExcludeStorages 
)

Definition at line 1016 of file DiskMgr.cpp.

01017 {
01018     return AllocMult( 1, rep, ExcludeStorages );
01019 }

int DiskMgr::AllocMult ( int  numReplicas,
RioDiskBlock rep,
unsigned long long int  ExcludeStorages 
)

Definition at line 841 of file DiskMgr.cpp.

00843 {
00844     int i, x, rc;
00845     Disk *dp;
00846     int cntretry = 0; 
00847     int maxretry = ( SNode::sn_maxdisks + 1 ) * numReplicas; 
00848     unsigned long long int storages_disp;
00849     // do GetMaxDisks, que comeca com 1 e vai somando SNode::sn_maxdisks a cada 
00850     // no
00851     int numStorages = ( m_numDisks - 1 ) / SNode::sn_maxdisks;
00852 
00853     // o numero de replicas nao pode ser maior que o numero de storages
00854     if( numReplicas > numStorages ) numReplicas = numStorages;
00855 
00856     // be sure all output values are first invalid
00857     for( i = 0; i < numReplicas; i++ )
00858     {
00859         memset(&rep[i], 0, sizeof(RioDiskBlock));
00860     }
00861 
00862     // now allocate a block for each replication
00863     // Inicializa o vetor com os servidores de armazenamento que podem ser
00864     // usados. Este valor sera o complemento da uniao (com um ou binario) do
00865     // complemento do vetor de bits m_storagesnotfull, que define os servidores
00866     // de armazenamento que possuem espaco em pelo menos um dos seus discos, com
00867     // o vetor de bits ExcludeStorages, cujos bits indicam (se forem iguais a 
00868     // 1), os servidores de armazenamento (cujos identificadores sao estes bits)
00869     // que nao podem ser usados ao alocar os blocos fisicos.
00870     // 
00871     // Obs:
00872     //
00873     // 1) Note que, devido ao usarmos o complemento de m_storagesnotfull, todos 
00874     // os bits associados aos identificadores nao usados serao ignorados, pois 
00875     // serao 0 neste vetor.
00876     //
00877     // 2) Se um servidor de armazenamento ficar inativo durante a execucao de
00878     // allocmult, ele pode ser utilizado caso isso ocorra apos ou durante a 
00879     // chamada da funcao CheckDiskAlloc chamada dentro do laco a seguir apos
00880     // escolhermos um bloco fisico para uma das replicacoes. Neste caso, o
00881     // erro fara com que os blocos sejam realocados, o que fara com que a funcao
00882     // AllocMult seja novamente chamada.
00883     storages_disp = ~ ( ExcludeStorages | ( ~m_storagesnotfull ) );
00884     
00885     for( i = 0; i < numReplicas; i++ )
00886     {
00887         m_cntAllocMult++;
00888       retry:
00889         // Verifica se temos um storage para cada replica.
00890  
00891         #ifdef __GENERATE_DISKLOG
00892         if( m_log.is_open() )
00893         {
00894             m_log << "Tentando obter um disco de um storage " << endl;
00895         }
00896         #endif             
00897 
00898         #ifdef RIO_DEBUG2
00899         RioErr << "DiskMgr::AllocMult storages que nao podem ser usados "
00900                << "(ExcludeStorages = ";
00901         for( int p = MAXNUMSTORAGES - 1; p >= 0 ; p--)
00902         {
00903            unsigned int q = ( ExcludeStorages >> p ) & 1ull; 
00904            RioErr << q;
00905         }
00906         RioErr << ")" << endl;
00907         RioErr << "DiskMgr::AllocMult storages cujos discos nao estao cheios "
00908                << "(m_storagesnotfull = ";
00909         for( int p = MAXNUMSTORAGES - 1; p >= 0 ; p--)
00910         {
00911            unsigned int q = ( m_storagesnotfull >> p ) & 1ull; 
00912            RioErr << q;
00913         }
00914         RioErr << ")" << endl;
00915         RioErr << "DiskMgr::AllocMult storages que pode ser usados "
00916                << "(storages_disp = ";    
00917         for( int p = MAXNUMSTORAGES - 1; p >= 0 ; p--)
00918         {
00919             unsigned int q = ( storages_disp >> p ) & 1ull; 
00920             RioErr << q;
00921         }
00922         RioErr << ")" << endl;
00923         #endif
00924 
00925         // Verifica se ainda existem servidores de armazenamento que podem ser
00926         // usados. Se isso nao for possivel, entao nao temos espaco disponivel 
00927         // para alocar blocos fisicos para todas as replicas. Note que isso pode
00928         // ser devido a falta real de espaco nos discos, ou devido a alguns dos
00929         // servidores de armazenamento (e portanto, os seus discos) estarem
00930         // indisponiveis no momento. 
00931         if( storages_disp == 0 )
00932             return ERROR_DISKMGR + ERROR_DISKFULL;
00933 
00934         do
00935         {
00936 
00937            x = RandomNumber( m_diskanum );
00938            dp = m_diska[x];
00939 
00940            #ifdef __GENERATE_DISKLOG
00941            if( m_log.is_open() ) 
00942            {
00943                m_log << "DiskMgr::AllocMult replicacao " << i+1 << ", x = " 
00944                      << x << ", dp->d_diskid = " << dp->d_diskid 
00945                      << ", numero de blocos (do disco) = " 
00946                      << dp->d_BitMap.nFree() << ", storages_disp = "; 
00947 
00948                for(int p = MAXNUMSTORAGES - 1; p >= 0 ; p--)
00949                {
00950                    unsigned int q = ( storages_disp >> p ) & 1ull; 
00951                    m_log << q;
00952                }            
00953 
00954                m_log << endl;
00955            }
00956            #endif         
00957 
00958         }
00959 
00960         while( !( storages_disp & 
00961                 (1ull << ( ( dp->d_diskid - 1 ) / SNode::sn_maxdisks ) ) ) );
00962         if( CheckDiskAlloc( i, rep, dp->d_diskid ) )
00963         {
00964             // pick a random block on this disk
00965             rc = dp->d_BitMap.AllocSeq(RandomNumber(dp->d_ntot), &rep[i].block);
00966             if( rc != 0 )
00967                 return rc;
00968             rep[ i ].disk = dp->d_diskid;
00969 
00970             #ifdef __GENERATE_DISKLOG
00971             if( m_log.is_open() )
00972                 m_log << " AllocMult:: Chose Disk " << rep[ i ].disk
00973                       << " block " << rep[ i ].block << endl;
00974             #endif
00975 
00976             storages_disp -= ( 1ull << ( ( dp->d_diskid - 1 ) / 
00977                                          SNode::sn_maxdisks ) );
00978             continue;
00979         }
00980         else
00981         {
00982             m_cntAllocRetry++;
00983             cntretry++;
00984 
00985             #ifdef __GENERATE_DISKLOG
00986             if( m_log.is_open() ) 
00987             {
00988                 m_log << "DiskMgr::AllocMult disco " << dp->d_diskid 
00989                       <<  " incorreto. Possivel erro de implementacao."
00990                       << endl;          
00991                 m_log << "DiskMgr::AllocMult Failed for disk " << dp->d_diskid
00992                       << " try " << cntretry << " from " << maxretry << endl;
00993             }
00994             #endif
00995 
00996             if( cntretry < maxretry )
00997             {
00998                 // try rebuilding array every few retries
00999                 BuildAlloc();
01000                 // Remove os servidores cujos discos podem ter ficado cheios
01001                 // devido a realocacao parcial. Note que se um disco nao puder 
01002                 // ser usado, isso sera detectado ao chamarmos a funcao
01003                 // CheckDiskAlloc apos o laco de escolhe do bloco fisico.
01004                 storages_disp = storages_disp & m_storagesnotfull;
01005                 goto retry;
01006             }
01007             m_cntAllocFail++;
01008 
01009             return ERROR_DISKMGR + ERROR_UNEXPECTED;
01010         }
01011     }
01012     return 0;
01013 }

void DiskMgr::BuildAlloc (  )  [private]

Definition at line 702 of file DiskMgr.cpp.

00703 {
00704     Disk *dp;
00705     int i = 0;
00706     // Variavel usada para contabilizar o numero de servidores de armazenamento 
00707     // ativos. Cada bit em um indicara um servidor de armazenamento com pelo 
00708     // menos um disco disponivel.
00709     m_storagesnotfull = 0;
00710 
00711     for( dp = m_disklist; dp != 0; dp = dp->d_link )
00712     {
00713         if( dp->d_status & Disk::STAT_ALLOC && dp->d_BitMap.nFree() > 0 )
00714         {
00715             m_diska[i] = dp;
00716             i++;
00717             m_storagesnotfull = m_storagesnotfull | 
00718                             (1ull << ( ( dp->d_diskid - 1 ) / 
00719                                        SNode::sn_maxdisks ) );
00720         }
00721     }
00722     m_diskanum = i;
00723     
00724     #ifdef __GENERATE_DISKLOG
00725     // Imprime o vetor m_storagesnotfull
00726     if( m_log.is_open() )
00727         m_log << "DiskMgr::BuildAlloc m_storagesnotfull = "
00728     for( i = MAXNUMSTORAGES - 1; i >= 0; i-- ) 
00729     {
00730       unsigned int q = ( m_storagesnotfull >> i ) & 1ull;
00731       if( m_log.is_open() )
00732           m_log << q;
00733     }
00734     if( m_log.is_open() )
00735         m_log << endl;
00736     #endif    
00737     
00738 }

int DiskMgr::BuildNode ( char *  hostname,
bool  Connect 
)

Definition at line 421 of file DiskMgr.cpp.

00422 {
00423     SNode               *np;
00424     int                  rc;
00425     EventStorageRequest *event;
00426     pthread_attr_t       attribtx;
00427     pthread_attr_t       attribrx;
00428 
00429     #ifdef RIO_DEBUG1
00430     RioErr << "### [DiskMgr - BuildNode] Start" << endl;
00431     #endif
00432  
00433     // first see if duplicate node
00434     // ### in future would want to compare uuid of node?
00435     for( np = m_nodelist; np != 0; np = np->sn_link )
00436     {
00437         if( strcmp( np->sn_hostname, hostname ) == 0 )
00438         {
00439             if( m_log.is_open() )
00440                 m_log <<"DiskMgr.BuildNode duplicate node for "
00441                       << hostname << endl;
00442 
00443             //#ifdef RIO_DEBUG1
00444             m_log << "### [DiskMgr - BuildNode] Finish1" << endl;
00445             //#endif
00446 
00447             return -1;
00448         }
00449     }
00450 
00451     np = new SNode( this, hostname );
00452 
00453     if( ( np == 0 ) || ( np->sn_hostname == 0 ) )
00454     {
00455         RioErr << " error memory (could not create object)." << endl;
00456         delete np;
00457 
00458         #ifdef RIO_DEBUG1
00459         RioErr << "### [DiskMgr - BuildNode] Finish2" << endl;
00460         #endif
00461 
00462         return ERROR_MEMORY;
00463     }
00464 
00465     np->sn_IPaddress.Host = vsiGetIPaddress( hostname );
00466     np->sn_IPaddress.Port = htons( 5101 );
00467 
00468     // ------------------------------------------------------------------------
00469 
00470     if( Connect )
00471     {
00472         // ### following might hang and delay current thread
00473         rc = np->sn_socket.Connect( &np->sn_IPaddress );
00474 
00475         if( rc )
00476         {
00477             RioErr << " connect failed for " << np->sn_hostname << ": " 
00478                    << GetErrorDescription(rc) << endl;
00479             // ----------------------------------------------------------------
00480             delete np;
00481 
00482             RioErr << "### [DiskMgr - BuildNode] Depois do delete" << endl;
00483   
00484             #ifdef RIO_DEBUG1
00485             RioErr << "### [DiskMgr - BuildNode] Finish3" << endl;
00486             #endif
00487 
00488             return -1;
00489         }
00490 
00491         // Informa que a conexao foi feita com sucesso.
00492         np->sn_isenabled = true;
00493         // Nao precisamos, neste caso, enviar o evento ao Router.
00494         np->sn_sendevent = false;
00495 
00496     }
00497     else
00498     {
00499         // Informa que a conexao nao esta habilitada.
00500         np->sn_isenabled = false;
00501         // Precisamos, neste caso, enviar o evento ao Router.
00502         np->sn_sendevent = true;
00503         // Cria um evento para informar ao Router que o servidor de 
00504         // armazenamento ainda nao foi inicializado.
00505         // Gera um evento para informar ao router que o servidor de 
00506         // armazenamento nao foi inicializado ainda
00507         EventStorageDown* event;
00508         event = ( EventStorageDown * ) EventManager.New( EventTypeStorageDown );
00509 
00510         event->StorageId = ( m_numDisks - 1 ) / SNode::sn_maxdisks;
00511         // Neste caso, que o servidor ainda nao foi inicializado, nao devemos
00512         // limpar as filas.
00513         event->EmptyStorageQueue = false;
00514 
00515         RioErr << "Failed to connect to the storage " << np->sn_hostname 
00516                << endl; 
00517 
00518         #ifdef RIO_DEBUG2
00519         RioErr << "DiskMgr::BuildNode enviando a mensagem "
00520                << "EventStorageDown ao Router do servidor de "
00521                << "armazenamento com a ID " << event->StorageId << endl;
00522         #endif       
00523 
00524         m_Router->Put( ( Event * ) event );
00525     }
00526 
00527     // ### assign diskid numbers to max disks on this node..
00528     // (should really be matching uuid's from disks with metadata table
00529     // (kept by DiskMgr {which doesn't yet exist}
00530     np->sn_diskidorg = m_numDisks;
00531     m_numDisks += SNode::sn_maxdisks;
00532 
00533     m_NumberOfStorageNodes++;
00534     
00535     pthread_attr_init( &attribtx );
00536     pthread_attr_init( &attribrx );
00537     pthread_attr_setstacksize( &attribtx, 2*PTHREAD_STACK_MIN );
00538     pthread_attr_setstacksize( &attribrx, 2*PTHREAD_STACK_MIN );
00539 
00540     if( pthread_create( &np->sn_txthread, &attribtx,
00541                         &SNode::txthreadep, (void *)np)
00542       )
00543     {
00544         if( m_log.is_open() )
00545             m_log << "tx pthread_create failed for "  << hostname
00546                   << " error: " << strerror(errno) << endl;
00547 
00548         RioErr  << " tx pthread_create failed for " << hostname << endl;
00549         // --------------------------------------------------------------------
00550         #ifdef RIO_DEBUG1
00551         RioErr << "### [DiskMgr - BuildNode] Finish4" << endl;
00552         #endif
00553 
00554         return -1;
00555     }
00556 
00557     if( pthread_create( &np->sn_rxthread, &attribrx,
00558                         &SNode::rxthreadep, (void *)np)
00559       )
00560     {
00561         if( m_log.is_open() )
00562             m_log << "rx pthread_create failed for " << hostname
00563                   << " error: "  << strerror(errno)  << endl;
00564 
00565         RioErr  << "rx pthread_create failed for " << hostname << endl;
00566         // --------------------------------------------------------------------
00567         #ifdef RIO_DEBUG1
00568         RioErr << "### [DiskMgr - BuildNode] Finish5" << endl;
00569         #endif
00570 
00571         return -1;
00572     }
00573     
00574     if( Connect )
00575     {
00576     
00577         // Mensagem enviada para enviar, a cada servidor de armazenamento,
00578         // o tamanho do bloco usado pelo servidor de despacho.
00579     
00580         event = (EventStorageRequest*) EventManager.New( 
00581                                                       EventTypeStorageRequest );
00582         event->StorageRequest.Header.Type  = MSG_RSS_INITIALIZATION_REQ;
00583         event->StorageRequest.Header.Size  = SizeMsgRSSInitializationReq;
00584         event->StorageRequest.Header.Token = RSS_TOKEN_ROUTER;
00585         MsgRSSInitializationReq* msg = & ( event->StorageRequest.
00586                                            Initialization );  
00587         msg->BlockSize = m_BlockSize;
00588         np->sn_sendqueue.Put( ( Event* ) event );
00589     
00590     }
00591 
00592     struct in_addr address;
00593     address.s_addr = np->sn_IPaddress.Host;
00594 
00595     AddNodeEvent *it_event = new AddNodeEvent( np->sn_hostname, inet_ntoa( address ) ); 
00596     m_SystemManager->PostITEvent( (MonitorEvent *)it_event );
00597 
00598     #ifdef RIO_DEBUG1
00599     RioErr << "### [DiskMgr - BuildNode] Finish6" << endl;
00600     #endif
00601     
00602     return 0;
00603 }

bool DiskMgr::CheckDiskAlloc ( int  num,
RioDiskBlock rep,
int  choice 
) [private]

Definition at line 742 of file DiskMgr.cpp.

00743 {
00744     Disk *dp, *rd;
00745     int j;
00746     bool isEnabled;
00747 
00748     if( ( choice > m_MaxDisks ) || ( num > m_MaxReps ) )
00749     {
00750         #ifdef __GENERATE_DISKLOG
00751         if( m_log.is_open() )
00752             m_log << "DiskMgr::CheckDiskAlloc invalid input, choice "
00753                   << choice << " num " << num << endl;
00754         #endif          
00755         return false;
00756     }
00757 
00758     dp = m_disks[choice];
00759 
00760     if( dp == 0 ) 
00761     {
00762         #ifdef __GENERATE_DISKLOG
00763         if( m_log.is_open() )
00764             m_log << "DiskMgr::CheckDiskAlloc dp = 0" << endl;
00765         #endif          
00766         return false;
00767     }
00768     if( ( dp->d_status & Disk::STAT_ALLOC ) == 0 )
00769     {
00770         #ifdef __GENERATE_DISKLOG
00771         if( m_log.is_open() )
00772             m_log << "DiskMgr.CheckDiskAlloc ( dp->d_status & " 
00773                   << "Disk::STAT_ALLOC ) == 0 (" << dp->d_status << ")" << endl;
00774         #endif          
00775         return false;
00776     }
00777     if( dp->d_BitMap.nFree() <=  0 )
00778     {
00779         #ifdef __GENERATE_DISKLOG
00780         if( m_log.is_open() )
00781             m_log << "DiskMgr.CheckDiskAlloc dp->d_Bitmap.nFree() <= 0" 
00782                   << "(" << dp->d_BitMap.nFree() << ")" << endl;
00783         #endif          
00784         return false;
00785     }
00786    
00787     // Verifica se o storage associado ao disco esta temporariamente 
00788     // desabilitado.
00789     // Obtem o mutex para o acesso exclusivo a sn_isenabled.
00790     pthread_mutex_lock( &dp->d_node->sn_mutex );
00791     // Obtemo valor atual de sn_isenabled.
00792     isEnabled = dp->d_node->sn_isenabled;
00793     // Libera o mutex para o acesso exclusivo a sn_isenabled.
00794     pthread_mutex_unlock( &dp->d_node->sn_mutex );
00795     if( !isEnabled )
00796     {
00797         #ifdef __GENERATE_DISKLOG
00798         if( m_log.is_open() )
00799             m_log << "DiskMgr.CheckDiskAlloc dp->d_node->sn_isenabled = false" 
00800                   << endl;
00801         #endif          
00802         RioErr << "DiskMgr.CheckDiskAlloc dp->d_node->sn_isenabled = false" 
00803                << endl;
00804         return false;
00805     }
00806 
00807     // so far this disk looks ok, now check the other entries
00808     // in the replication list for affinity with this disk
00809     // assume that all the disk numbers in the replications
00810     // are valid (at least inbounds on m_disks).
00811     for( j = 0; j < num; j++ )
00812     {
00813         rd = m_disks[rep[j].disk];
00814         if( rd == 0 )
00815             continue;
00816         if( rd->d_node == dp->d_node ) 
00817         {
00818             #ifdef __GENERATE_DISKLOG
00819             if( m_log.is_open() )
00820                 m_log << "DiskMgr.CheckDiskAlloc rd->d_node == dp->d_node" 
00821                       << "(0x" << hex << ( unsigned int ) rd->d_node << ", 0x" 
00822                       << ( unsigned int ) dp->d_node << dec << ")" << endl;
00823             #endif          
00824             return false;
00825         }
00826     }
00827     return true;
00828 }

int DiskMgr::CleanUp (  ) 

Definition at line 143 of file DiskMgr.cpp.

00144 {
00145     return 0;
00146 }

int DiskMgr::Confirm (  ) 

Definition at line 685 of file DiskMgr.cpp.

00686 {
00687     Disk *dp;
00688     int rc = 0;
00689     int rc2;
00690 
00691     for( dp = m_disklist; dp != 0; dp = dp->d_link )
00692     {
00693         rc2 = dp->d_BitMap.Confirm();
00694         if( rc2 && !rc )
00695             rc = rc2;
00696     }
00697     return rc;
00698 }

int DiskMgr::Format (  ) 

Definition at line 606 of file DiskMgr.cpp.

00607 {
00608     Disk *dp;
00609     int rc = 0;
00610     int rc2;
00611     unsigned int junk;
00612 
00613     for( dp = m_disklist; dp != 0; dp = dp->d_link )
00614     {
00615         rc2 = dp->d_BitMap.Format();
00616         // preallocate block 0, 1
00617         if( !rc2 )
00618         {
00619             rc2 = dp->d_BitMap.AllocSeq( 0, &junk );
00620         }
00621         if( !rc2 )
00622         {
00623             rc2 = dp->d_BitMap.AllocSeq( 1, &junk );
00624         }
00625         if( rc2 && !rc )
00626             rc = rc2;
00627     }
00628 
00629     if( !rc )
00630     {
00631         Confirm();
00632         BuildAlloc();
00633     }
00634     else 
00635     { 
00636         RioErr << "\n\n\n***************ERRO NO FORMAT!!!!*********" << endl;
00637     }
00638 
00639     return rc;
00640 }

int DiskMgr::Free ( RioDiskBlock rep  ) 

Definition at line 1022 of file DiskMgr.cpp.

01023 {
01024     Disk *dp;
01025 
01026     // Freeing a null block pointer is a nop
01027     if( ( rep->disk == 0 ) && ( rep->block == 0 ) )
01028     {
01029         return 0;
01030     }
01031     if( ( rep->disk < 0 ) || ( rep->disk > m_MaxDisks ) )
01032     {
01033         // should not occur
01034         if( m_log.is_open() ) m_log << "DiskMgr.Free - invalid disk number "
01035               << rep->disk << endl;
01036         return ERROR_DISKMGR + ERROR_INVALID_DISK;
01037     }
01038     dp = m_disks[rep->disk];
01039     if( dp == 0 )
01040     {
01041         // Agora, com a implementacao que permite o reinicio dos servidores, e
01042         // possivel que o disco ainda nao tenha sido aberto porque o servidor
01043         // de armazenamento que o possui ainda nao inicializou. Como ainda nao
01044         // sabemos quantos discos pertencem a este servidor de armazenamento,
01045         // vamos verificar se o disco esta dentro da faixa de possiveis discos
01046         // de um servidor de armazenamento. Se ele estiver, e se o servidor de
01047         // armazenamento ainda nao tiver inicializado (pois ele ja pode ter
01048         // inicializado e o disco nao ser valido), vamos salvar a informacao em
01049         // um arquivo, associado a este servidor, com os blocos que devem ser
01050         // liberados quando o inicializarmos pela primeira vez. Em caso 
01051         // contrario, deveremos gerar o erro ERROR_INVALID_DISK (o erro 
01052         // retornado atualmente, ERROR_DISK_OPEN, somente seria correto se, 
01053         // por algum motivo, um dos discos de um servidor de armazenamento 
01054         // estiver inacessivel).
01055         SNode *sp, *spsb;
01056         bool SaveBlock;
01057         SaveBlock = false;
01058         spsb = NULL;
01059         for( sp = m_nodelist; sp != 0; sp = sp->sn_link )
01060         {
01061             // Verifica se o identificador do disco esta dentro dos possiveis
01062             // identificadores do servidor de armazenamento e, neste caso, se
01063             // o servidor ainda nao inicializou nenhuma vez.
01064             if( ( rep->disk >= sp->sn_diskidorg ) && 
01065                 ( rep->disk < ( sp->sn_diskidorg + SNode::sn_maxdisks ) ) )
01066             {
01067                 if( ( !sp->sn_restart ) && ( !sp->sn_isenabled ) )
01068                 {
01069                     SaveBlock = true;
01070                     spsb = sp;
01071                 }
01072                 break;
01073             }  
01074             
01075         }
01076         // Verifica se precisamos salvar o bloco no arquivo com os blocos do 
01077         // servidor de armazenamento associado ao disco, ou se devemos gerar um
01078         // erro.
01079         if( SaveBlock )
01080         {
01081             char FreeBlocksFileName[ 2 * MaxPathSize + 1 ];
01082             int FreeBlocksFile;
01083             int BytesWroten;
01084             int error;
01085 
01086             // Indica que existe blocos a serem liberados.
01087             spsb->sn_readfreeblocksfile = true;
01088             // Compoe o nome do arquivo com os blocos a serem liberados quando o
01089             // servidor de armazenamento inicializar.
01090             // Adiciona o diretorio de configuracao (este e o unico caminho que
01091             // temos. Sera que devemos usa-lo?).
01092             strcpy( FreeBlocksFileName, m_MetaRoot );
01093             // Adiciona a "/" ao final do arquivo, se ela nao existir.
01094             if( m_MetaRoot[ strlen( m_MetaRoot ) - 1 ] != '/' )
01095                 strcat( FreeBlocksFileName, "/" );
01096             // Adiciona o prefixo "FreeBlocks-" ao nome do arquivo.
01097             strcat( FreeBlocksFileName, "FreeBlocks-" );
01098             // Adiciona, finalmente, o nome do servidor de armazenamento
01099             strcat( FreeBlocksFileName, spsb->sn_hostname );
01100             #ifdef RIO_DEBUG2        
01101             RioErr << "DiskMgr::Free detectado que o servidor " 
01102                    << spsb->sn_hostname << " nao foi ainda inicializado. "
01103                    << "Salvando o bloco " << rep->block << " associado ao " 
01104                    << "disco " << rep->disk << " no arquivo " 
01105                    << FreeBlocksFileName << " com os blocos a serem liberados "
01106                    << " deste servidor" << endl;
01107             #endif       
01108             // Tenta abrir o arquivo com os discos a serem liberados.
01109             FreeBlocksFile = open( FreeBlocksFileName, O_WRONLY | O_APPEND | 
01110                                                        O_CREAT, 0700 );
01111             if( FreeBlocksFile < 0 )
01112             {
01113                 #ifdef RIO_DEBUG2
01114                 RioErr << "DiskMgr::Free erro " << errno << " (" 
01115                        << strerror( errno ) << ") ao abrir o arquivo " 
01116                        << FreeBlocksFileName << " com os blocos a serem salvos "
01117                        << "do servidor de armazenamento " << spsb->sn_hostname
01118                        << endl;
01119                 #endif       
01120                 return ERROR_DISKMGR + ERROR_OPEN_FREEBLOCKS_FILE;       
01121             }   
01122             // Salva o bloco no arquivo com os blocos.
01123             BytesWroten = write( FreeBlocksFile, rep, sizeof( RioDiskBlock ) );
01124             error = errno;
01125             close( FreeBlocksFile );       
01126             if( BytesWroten < 0 ) // Se ocorreu um erro ao salvar no arquivo.
01127             {
01128                 #ifdef RIO_DEBUG2
01129                 RioErr << "DiskMgr::Free erro " << error << " (" 
01130                        << strerror( error ) << " ao gravar no arquivo " 
01131                        << FreeBlocksFileName << " com os blocos a serem salvos "
01132                        << "do servidor de armazenamento " << spsb->sn_hostname
01133                        << endl;
01134                 #endif       
01135                 return ERROR_DISKMGR + ERROR_OPEN_FREEBLOCKS_FILE;       
01136             }
01137             else if( BytesWroten != sizeof( RioDiskBlock ) ) // Se nao foi 
01138                                                              // possivel salvar
01139                                                              // um bloco.
01140             {
01141                 #ifdef RIO_DEBUG2
01142                 RioErr << "DiskMgr::Free foram gravados " << BytesWroten 
01143                        << " bytes ao inves de " << sizeof( RioDiskBlock )
01144                        << " bytes no arquivo " << FreeBlocksFileName 
01145                        << " com os blocos a serem salvos  do servidor de "
01146                        << "armazenamento " << spsb->sn_hostname << endl;
01147                 #endif
01148                 return ERROR_DISKMGR + ERROR_OPEN_FREEBLOCKS_FILE;       
01149             }
01150             else // Se o bloco foi salvo com sucesso, entao retornamos que 
01151                  // nenhum erro ocorreu.
01152                 return S_OK; 
01153               
01154         }
01155         else
01156         {
01157             #ifdef RIO_DEBUG2
01158             RioErr << "DiskMgr::Free Foi detectado que o bloco " << rep->block 
01159                    << " associado ao disco " << rep->disk << " e invalido" 
01160                    << endl;
01161             #endif       
01162             return ERROR_DISKMGR + ERROR_INVALID_DISK;
01163         }
01164     }
01165     
01166     dp->d_BitMap.Free( rep->block );
01167 
01168     // If the disk was previously full Rebuild array to include disk
01169     // since it now has available space
01170     if( dp->d_BitMap.nFree() == 1 )
01171     {
01172         BuildAlloc();
01173     }
01174     memset(rep, 0, sizeof(RioDiskBlock));
01175     return 0;
01176 }

int DiskMgr::FreeSalvedBlocks ( const char *  StorageName  )  [private]

Nova funcao para liberar os blocos salvos no arquivo de um servidor de armazenamento.

Estes blocos foram salvos porque, ao libera-los, o servidor de armazenamento ainda nao tinha inicializado e, em consequencia disso, os BitMaps dos seus discos ainda nao tinham sido carregados.

Parameters:
StorageName nome da maquina com o servidor de armazenamento.
Returns:
S_OK se nenhum erro ocorreu ao liberar os blocos do arquivo, ou diferente de S_OK caso algum erro ocorra ao liberar os blocos do arquivo.

Definition at line 1492 of file DiskMgr.cpp.

01493 {
01494     char FreeBlocksFileName[ 2 * MaxPathSize + 1 ];
01495     int FreeBlocksFile;
01496     int BytesRead;
01497     int error;
01498     RioDiskBlock Block;
01499 
01500     // Compoe o nome do arquivo com os blocos a serem liberados.
01501     // Adiciona o diretorio de configuracao (este e o unico caminho que temos. 
01502     // Sera que devemos usa-lo?).
01503     strcpy( FreeBlocksFileName, m_MetaRoot );
01504     // Adiciona a "/" ao final do arquivo, se ela nao existir.
01505     if( m_MetaRoot[ strlen( m_MetaRoot ) - 1 ] != '/' )
01506         strcat( FreeBlocksFileName, "/" );
01507     // Adiciona o prefixo "FreeBlocks-" ao nome do arquivo.
01508     strcat( FreeBlocksFileName, "FreeBlocks-" );
01509     // Adiciona, finalmente, o nome do servidor de armazenamento
01510     strcat( FreeBlocksFileName, StorageName );
01511     #ifdef RIO_DEBUG2
01512     RioErr << "DiskMgr::FreeSalvedBlocks liberando todos os blocos salvos no "
01513            << "arquivo " << FreeBlocksFileName << " associados aos discos do "
01514            << "servidor " << StorageName << endl;
01515     #endif       
01516     // Tenta abrir o arquivo com os discos a serem liberados.
01517     FreeBlocksFile = open( FreeBlocksFileName, O_RDONLY );
01518     if( FreeBlocksFile < 0 )
01519     {
01520         #ifdef RIO_DEBUG2
01521         RioErr << "DiskMgr::FreeSalvedBlocks erro " << errno << " (" 
01522                << strerror( errno ) << " ao abrir o arquivo " 
01523                << FreeBlocksFileName << " com os blocos a serem salvos do "
01524                << "do servidor de armazenamento " << StorageName << endl;
01525         #endif       
01526         RioErr << "Reading blocks file " << FreeBlocksFileName << ": Failed" 
01527                << endl;  
01528         return ERROR_DISKMGR + ERROR_OPEN_FREEBLOCKS_FILE;       
01529     } 
01530     // Enquanto existirem blocos, le estes blocos do arquivo e os remove do 
01531     // disco que o contem.
01532     while( ( BytesRead = read( FreeBlocksFile, &Block, 
01533              sizeof( RioDiskBlock ) ) ) == sizeof( RioDiskBlock ) )
01534     {
01535         // Remove o bloco lido do arquivo.
01536         #ifdef RIO_DEBUG2
01537         RioErr << "DiskMgr::FreeSalvedBlocks removendo o bloco "  
01538                << Block.block << " associado ao disco " << Block.disk 
01539                << " lido do arquivo com os blocos " << FreeBlocksFileName
01540                << ": ";
01541         #endif       
01542         if( m_disks[ Block.disk ] != NULL )
01543         {
01544             #ifdef RIO_DEBUG2
01545             RioErr << "OK" << endl;
01546             #endif
01547             // O disco existe, logo podemos liberar o bloco.
01548             m_disks[ Block.disk ]->d_BitMap.Free( Block.block );
01549         }
01550         else
01551         {
01552             // O disco nao existe, vamos somente gerar um aviso informando do 
01553             // erro.
01554             #ifdef RIO_DEBUG2
01555             RioErr << "Falhou. O disco " << Block.disk << " nao foi "
01556                    << " inicializado." << endl;
01557             #endif
01558             RioErr << "Warning in read blocks file " << FreeBlocksFileName 
01559                    << ": disk " << Block.disk << " of fisical block "
01560                    << Block.block << " is invalid" << endl; 
01561         }
01562     }
01563     error = errno;
01564     close( FreeBlocksFile );
01565     if( BytesRead < 0 ) // Ocorreu um erro ao ler um dos blocos.
01566     {
01567         #ifdef RIO_DEBUG2
01568         RioErr << "DiskMgr::FreeSalvedBlocks erro " << error << " (" 
01569                << strerror( error ) << " ao ler do arquivo "
01570                << FreeBlocksFileName << " com os blocos a serem salvos do "
01571                << "servidor de armazenamento " << StorageName << endl;
01572         #endif
01573         RioErr << "Reading blocks file " << FreeBlocksFileName << ": Failed" 
01574                << endl;  
01575         return ERROR_DISKMGR + ERROR_OPEN_FREEBLOCKS_FILE;       
01576     }
01577     else if( BytesRead > 0 ) // Lemos menos bytes do que deviamos
01578     {
01579         #ifdef RIO_DEBUG2
01580         RioErr << "DiskMgr::FreeSalvedBlocks foram lidos " << BytesRead 
01581                << " bytes ao inves de " << sizeof( RioDiskBlock ) 
01582                << " bytes do arquivo " << FreeBlocksFileName
01583                << " com os blocos a serem salvos  do servidor de "
01584                << "armazenamento " << StorageName << endl;
01585         #endif       
01586         RioErr << "Reading blocks file " << FreeBlocksFileName << ": Failed" 
01587                << endl;  
01588         return ERROR_DISKMGR + ERROR_OPEN_FREEBLOCKS_FILE;       
01589     }
01590     else // A remocao dos blocos foi feita com sucesso.
01591     {
01592         #ifdef RIO_DEBUG2
01593         RioErr << "DiskMgr::FreeSalvedBlocks removendo o arquivo " 
01594                << FreeBlocksFileName << " com os blocos do disco " << endl;
01595         #endif
01596         RioErr << "Reading blocks file " << FreeBlocksFileName << ": Ok" 
01597                << endl;  
01598         // Confirma as alteracoes nos discos.
01599         Confirm();       
01600         // Reconstroi o mapa dos discos.
01601         BuildAlloc();
01602         // Remove o arquivo com os blocos
01603         remove( FreeBlocksFileName );
01604         return S_OK;
01605     }
01606 }

int DiskMgr::GetDiskName ( unsigned int  DiskId,
char *  DiskName 
)

Definition at line 1269 of file DiskMgr.cpp.

01270 {
01271     #ifdef RIO_DEBUG2
01272     if( m_log.is_open() ) m_log << "DiskMgr: GetDiskName " << DiskId <<endl;
01273     #endif
01274     if( m_disks[DiskId] != NULL )
01275         return m_disks[DiskId]->GetName( DiskName );
01276     else
01277     {
01278         // O disco ainda nao foi criado. Inicializamos entao com a string
01279         // vazia.
01280         DiskName[ 0 ] = 0;
01281         return 0;
01282     }    
01283 }

unsigned int DiskMgr::GetDiskNumberOfFreeBlocks ( unsigned int  DiskId  ) 

Definition at line 1254 of file DiskMgr.cpp.

01255 {
01256     #ifdef RIO_DEBUG2
01257     if( m_log.is_open() )
01258         m_log << "DiskMgr: GetDiskNumberOfFreeBlocks disk " << DiskId <<endl;
01259     #endif
01260 
01261     if( m_disks[DiskId] != NULL )
01262        return m_disks[DiskId]->GetNumberOfFreeBlocks();
01263     else // O disco ainda nao foi inicializado. Retornamos entao 0.
01264        return 0;
01265 }

int DiskMgr::GetDiskServiceTime ( EventStorageRequest event,
u16  DiskId 
)

Definition at line 1201 of file DiskMgr.cpp.

01202 {
01203     if( DiskId > m_MaxDisks )
01204     {
01205         #ifdef RIO_DEBUG2
01206         RioErr << "DiskMgr ERROR: GetDiskServiceTime request to invalid disk: "
01207                << DiskId << endl;
01208         #endif
01209         EventManager.Free((Event*) event);
01210         return -1;
01211     }
01212 
01213     if( m_disks[DiskId] == 0 )
01214     {
01215         #ifdef RIO_DEBUG2
01216         RioErr << "DiskMgr ERROR: GetDiskServiceTime request to inactive disk: "
01217                << DiskId << endl;
01218         #endif
01219         EventManager.Free((Event*)event);
01220         return -1;
01221     }
01222     m_disks[DiskId]->GetServiceTime( event );
01223     return 0;
01224 }

int DiskMgr::GetDiskStorageNodeInfo ( unsigned int  DiskId,
RioStorageNodeInfo StorageNodeInfo 
)

Definition at line 1328 of file DiskMgr.cpp.

01330 {
01331     unsigned int SNId;
01332 
01333     #ifdef RIO_DEBUG2
01334     if( m_log.is_open() ) m_log << "DiskMgr: GetDiskStorageNodeInfo DiskId "
01335           << DiskId << endl;
01336     #endif
01337 
01338     //Each build node has at most sn_maxdisks (using MAXSTORAGEDISKSARRAY equal 
01339     //4) disks
01340     //The disks of first Node (0) are 1, 2, 3 and 4
01341     //The disks of second Node (1) are 5, 6, 7 and 8 and so on ...
01342     //Therefore, a simple division gives us the desired storage node id
01343     SNId = ( DiskId - 1 ) / SNode::sn_maxdisks;
01344 
01345     GetStorageNodeInfo( SNId, StorageNodeInfo );
01346     return 0;
01347 }

int DiskMgr::GetMaxNumberOfDisks (  ) 

Definition at line 265 of file DiskMgr.cpp.

00266 {
00267     return m_numDisks;
00268 }

int DiskMgr::GetNumberOfActiveDisks ( unsigned int *  NumberOfDisks  ) 

Definition at line 1230 of file DiskMgr.cpp.

01231 {
01232     *NumberOfDisks = m_NumberOfActiveDisks;
01233     #ifdef RIO_DEBUG2
01234     if( m_log.is_open() ) m_log << "DiskMgr: GetNumberOfActiveDisks = "
01235           << m_NumberOfActiveDisks << endl;
01236     #endif
01237     return 0;
01238 }

int DiskMgr::GetNumberOfNeededDisks ( unsigned int *  NumberOfDisks  ) 

Nova funcao para retornar o numero minimo de discos necessarios para inicializar as estruturas do servidor.

O valor retornado sera a soma do numero descrito a seguir para cada um dos servidores de armazenamento. Para cada servidor de armazenamento, se ele tiver inicializado antes do servidor de gerenciamento o valor sera o numero de disco deste servidor e, em caso contrario, o numero maximo de discos, ou seja, SNode::sn_maxdisks = MAXSTORAGEDISKSARRAY

Returns:
Numero maximo de discos a serem usados.

Definition at line 1610 of file DiskMgr.cpp.

01611 {
01612     SNode *np;
01613     unsigned int NeededDisks;
01614     bool IsEnabled;
01615     
01616     NeededDisks = 0;
01617 
01618     // Vamos percorrer a lista com os servidores de armazenamento. Se o servidor
01619     // nao estiver inicializado usaremos, como o seu numero de discos, o numero
01620     // maximo, isto e, SNode::sn_maxdisks e, em caso contrario, usaremos o seu
01621     // numero de discos.
01622     for( np = m_nodelist; ( np != 0 ); np = np->sn_link )
01623     {
01624         // Obtem o mutex para o acesso exclusivo a sn_isenabled.
01625         pthread_mutex_lock( &np->sn_mutex );
01626         // Obtemo valor atual de sn_isenabled.
01627         IsEnabled = np->sn_isenabled;
01628         // Libera o mutex para o acesso exclusivo a sn_isenabled.
01629         pthread_mutex_unlock( &np->sn_mutex );
01630         if( IsEnabled )
01631            NeededDisks = NeededDisks + np->sn_disks;
01632         else
01633            NeededDisks = NeededDisks + SNode::sn_maxdisks;
01634     }
01635     
01636     *NumberOfDisks = NeededDisks;
01637     
01638     return S_OK;
01639 }

int DiskMgr::GetNumberOfReplications ( void   ) 

Nova funcao para obter o numero de replicacoes de cada bloco.

Returns:
numero de replicacoes para cada bloco.

Definition at line 1428 of file DiskMgr.cpp.

01429 {
01430     return m_MaxReps;
01431 }

int DiskMgr::GetNumberOfStorageNodes ( unsigned int *  NumberOfStorageNodes  ) 

Definition at line 1241 of file DiskMgr.cpp.

01242 {
01243     *NumberOfStorageNodes = m_NumberOfStorageNodes;
01244     #ifdef RIO_DEBUG2
01245     if( m_log.is_open() )
01246         m_log << "DiskMgr: GetNumberOfStorageNodes = " << m_NumberOfStorageNodes
01247               << endl;
01248     #endif
01249     return 0;
01250 }

int DiskMgr::GetStorageNodeInfo ( unsigned int  StorageNodeIndex,
RioStorageNodeInfo StorageNodeInfo 
)

Definition at line 1286 of file DiskMgr.cpp.

01288 {
01289     SNode *np;
01290     unsigned int i = 0;
01291 
01292     #ifdef RIO_DEBUG2
01293     if( m_log.is_open() ) m_log << "DiskMgr: GetStorageNodeInfo StorageIndex "
01294           << StorageNodeIndex << endl;
01295     #endif
01296 
01297     for(i = 0, np = m_nodelist;(( np != 0 ) && ( i != StorageNodeIndex )); i++)
01298     {
01299         np = np->sn_link;
01300     }
01301     strcpy( StorageNodeInfo->Hostname, np->sn_hostname );
01302     StorageNodeInfo->NumberOfDisks = np->sn_disks;
01303 
01304     int disk_index;
01305 
01306     for( i = 0; i < ( unsigned int ) np->sn_disks; i++ ) {
01307         //Each build node has at most sn_maxdisks (using MAXSTORAGEDISKSARRAY 
01308         //equal 4) disks. 
01309         //The disks of first Node are 1, 2, 3 and 4
01310         //The disks of second Node are 5, 6, 7 and 8 and so on ...
01311         disk_index = StorageNodeIndex * SNode::sn_maxdisks + 1 + i;
01312 
01313         np->sn_mgr->GetDiskName( disk_index,
01314                                  &StorageNodeInfo->Disks[i].DiskName[0] );
01315         StorageNodeInfo->Disks[i].Size = np->sn_disksize[i];
01316         StorageNodeInfo->Disks[i].NumberOfFreeBlocks =
01317                            np->sn_mgr->GetDiskNumberOfFreeBlocks( disk_index );
01318     }
01319 
01320     #ifdef RIO_DEBUG2
01321     if( m_log.is_open() ) m_log << "Host "<< np->sn_hostname << endl;
01322     #endif
01323     return 0;
01324 }

int DiskMgr::GetStorageServersAddress ( SOCKADDR_IN ServerAddress  ) 

Funcao para obter todos os enderecos (pares IP e porta) dos Storage Servers (que estao listados no arquivo RIOdisk.cfg).

Parameters:
ServerAddress vetor de estruturas SOCKADDR_IN que armazenara, em cada uma de suas entradas, um par IP, porta de um Storage Server.
Returns:
0 (pois algumas funcoes da classe DiskMgr retornam um valor, mesmo que seja sempre igual a 0).

Definition at line 1358 of file DiskMgr.cpp.

01359 {
01360     SNode *np;
01361     unsigned int i = 0;
01362 
01363     // Inicializa o ponteiro para a estrutura que descreve o primeiro Storage
01364     // Server desta lista.
01365     np = m_nodelist;
01366     
01367     // Varre a lista para cada um dos Storage Serves.
01368     while ( np != 0 ) {
01369         // Atualiza a proxima entrada livre do vetor com o IP e a porta do
01370         // Storage Server cujas informacoes estao na estrutura apontada pelo
01371         // ponteiro np. A porta UDP foi fixada na porta STORAGESERVERUDPPORT
01372         // para podermos dar suporte aos clientes atras de NAT.
01373         ServerAddress[ i ].sin_family = AF_INET;
01374         ServerAddress[ i ].sin_port = htons( STORAGESERVERUDPPORT );
01375         ServerAddress[ i ].sin_addr.s_addr = np->sn_IPaddress.Host;
01376         i++; 
01377         np = np->sn_link;
01378     }
01379 
01380     return 0;
01381 }

int DiskMgr::Initialize ( DiskMgrConfig Config  ) 

Definition at line 151 of file DiskMgr.cpp.

00152 {
00153     int i;
00154     int rc;
00155 
00156     if( Config->GenerateLogs )
00157     {
00158         // Variavel usada para compor o nome do arquivo com o log.
00159         char LogFileName[ MaxPathSize ];
00160         // Compoe o nome do arquivo com o log.
00161         strcpy( LogFileName, Config->LogsDirectory );
00162         strcat( LogFileName, LOGFILE ); 
00163         m_log.open( LogFileName );
00164         if( !m_log.is_open() )
00165         {
00166             return ERROR_OBJECTMANAGER + ERROR_LOGFILE;
00167         }
00168     }
00169 
00170      if( m_log.is_open() )
00171         m_log << " --- DiskMgr.Initialize" << endl;
00172 
00173     m_BlockSize       = Config->BlockSize;
00174     m_MaxDisks        = Config->MaxDisks;
00175     m_MetaRoot        = Config->MetaRoot;
00176     m_Router          = Config->router;
00177     m_SystemManager   = Config->manager;
00178     m_MaxReps         = Config->MaxReps;
00179     // O diretorio recebido no parametro Config da funcao (que contera o 
00180     // arquivo RIOdisk.cfg no subdiretorio /etc) e usdo pela funcao 
00181     // ReadConfiguration, para que ela possa ler o arquivo da localizacao 
00182     // correta. 
00183     m_ConfigsDirectory = Config->ConfigsDirectory;
00184     // Inicializa os novos campos usados para fazermos mais de uma tentativa
00185     // ao conectarmos com os servidores de armazenamento definidos em 
00186     // RIOdisk.cfg.
00187     m_MaxAttempts = Config->MaxAttempts;
00188     m_TimeBetweenAttempts = Config->TimeBetweenAttempts;
00189     // Inicializa a variavel booleana que indica se estamos formatando os discos
00190     // do RIO.
00191     m_IsFormatting = Config->IsFormatting;
00192     
00193     m_disks = new Disk*[m_MaxDisks + 1];
00194     if( m_disks == NULL )
00195     {
00196         if( m_log.is_open() )
00197             m_log << "new failed " << endl;
00198 
00199         abort();
00200     }
00201 
00202     m_diska = new Disk*[m_MaxDisks + 1];
00203     if( m_diska == NULL )
00204     {
00205         if( m_log.is_open() )
00206             m_log << "new failed " << endl;
00207 
00208         abort();
00209     }
00210     for( i = 0; i <= m_MaxDisks; i++ )
00211     {
00212         m_disks[i] = 0;
00213         m_diska[i] = 0;
00214     }
00215 
00216     rc = ReadConfiguration();
00217 
00218     // if there were errors do not continue ----------------
00219     if( rc )
00220     {
00221         m_log << "Error reading configuration." << endl;
00222         return rc;
00223     }
00224     // ------------------------------------------------------------------------
00225 
00226     // ### now wait a while for the storage nodes to be contacted
00227     // ### and reply etc...
00228 
00229     // ### wait 1 second until the number of allocatable disks
00230     //     stops changing (and is > 0)
00231     int numactivedisks, prevdisks;
00232     Disk *dp;
00233     numactivedisks = 0;
00234     do {
00235         prevdisks = numactivedisks;
00236         sleep(1);
00237         numactivedisks = 0;
00238         for( dp = m_disklist; dp != 0; dp = dp->d_link )
00239         {
00240             if( dp->d_status & Disk::STAT_ALLOC )
00241             {
00242                 numactivedisks++;
00243             }
00244         }
00245         if( m_log.is_open() ) m_log << "diskmgr.init delaying - disks so far: "
00246               << numactivedisks << " previous " << prevdisks
00247               << endl;
00248     //} while(( numactivedisks == 0 ) || ( numactivedisks != prevdisks));
00249     } while( numactivedisks != prevdisks );
00250     RioErr << "      Number of active disks: " << numactivedisks << "."  
00251            << endl;
00252     m_NumberOfActiveDisks = numactivedisks;
00253     // ------------------------------------------------------------------------
00254 
00255     return rc;
00256 }

int DiskMgr::LoadDisksBitMaps ( unsigned int  StorageId  )  [private]

Nova funcao para carregar os BitMaps dos discos associados a um servidor de armazenamento.

Esta funcao e usada para carragar os BitMaps do disco associados a um servidor de armazenamento que inicializou depois do servidor de gerenciamento, pois neste caso estes BitMaps nao vao ter sido carragados pela funcao Start da classe DiskMgr.

Parameters:
StorageId identificador do servidor de armazenamento. servidor de armazenamento.
Returns:
S_OK se nenhum erro ocorreu ao carragar os bitmaps ou o codigo de erro caso nao tenha sido possivel carragar um dos bitmaps.

Definition at line 1438 of file DiskMgr.cpp.

01439 {
01440     Disk *dp;
01441     int rc = 0;
01442     int rc2;
01443     unsigned int DiskStorageId;
01444 
01445     // Obtem o mutex para o acesso exclusivo as estruturas do disco.
01446     pthread_mutex_lock( &m_mutex );
01447 
01448     for( dp = m_disklist; dp != 0; dp = dp->d_link )
01449     {
01450         DiskStorageId = ( dp->d_node->sn_diskidorg - 1 ) / SNode::sn_maxdisks;
01451         if( StorageId ==  DiskStorageId )
01452         {
01453             
01454             #ifdef RIO_DEBUG2
01455             RioErr << "DiskMgr::LoadDisksBitMaps tentando carregar o BitMap "
01456                    << " do disco com a ID " << dp->d_diskid << " associado ao "
01457                    << "servidor de armazenamento com a ID " << DiskStorageId
01458                    << endl;
01459             #endif       
01460             
01461             rc2 = dp->d_BitMap.Load();
01462             if( rc2 && !rc )
01463                 rc = rc2;
01464             
01465             #ifdef RIO_DEBUG2    
01466             RioErr << "DiskMgr::LoadDisksBitMaps a carga do BitMap executou " 
01467                    << "com o erro rc2 = " << rc2 << endl;
01468             #endif           
01469         }
01470     }
01471     // to test if an error happened before call BuildAlloc
01472     if( rc )
01473     {
01474         // Libera o mutex para o acesso exclusivo as estruturas do disco.
01475         pthread_mutex_unlock( &m_mutex );
01476         
01477         return rc;
01478     }
01479     // ------------------------------------------------------------------------
01480     BuildAlloc();
01481 
01482     // Libera o mutex para o acesso exclusivo as estruturas do disco.
01483     pthread_mutex_unlock( &m_mutex );
01484 
01485     return 0;
01486 }

int DiskMgr::ReadConfiguration (  )  [private]

Definition at line 299 of file DiskMgr.cpp.

00300 {
00301     int rc = 0;
00302     char *nodename = 0;
00303     // Variavel usada para compor o nome do arquivo com a configuracao dos
00304     // discos
00305     char ConfigFileName[ MaxPathSize ];
00306     // Mudanca para que o servidor espere (por algum tempo) pela inicializacao
00307     // do storage.
00308     int rc2;
00309     unsigned int Attempts;
00310     // Numero de storages lidos (nao pode ser maior do que 
00311     // sizeof(unsigned long long int) * 8, pois a funcao AllocMult usa um vetor
00312     // de bits com o tamanho do valor deste comando sizeof para evitar, ao
00313     // usarmos replicacao, que duas copias de um mesmo bloco estejam no mesmo
00314     // storage.
00315     unsigned int NumStorages;
00316     
00317     cout << endl << "   Reading DiskMgr configuration "
00318          << CONFIGNAME << " ... ";
00319 
00320     token tok;
00321 //    tok.setcerr(&cout);
00322 
00323     // Alteracao para ler o arquivo de configuracao de um diretorio qualquer,
00324     // diferente de onde o servidor esta. 
00325     // Compoe o nome do arquivo com a configuracao dos discos.
00326     strcpy( ConfigFileName, m_ConfigsDirectory );
00327     strcat( ConfigFileName, CONFIGNAME );
00328 
00329     if( tok.openfile( ConfigFileName ) )
00330     {
00331         m_log << "erro no tok.openfile " << CONFIGNAME << endl;
00332         return 1;
00333     }
00334     
00335     NumStorages = 0;
00336 
00337     int word;
00338     while( ( word = tok.parseline( mykeys ) ) >= 0 )
00339     {
00340         switch( word )
00341         {
00342             case k_disk:
00343                 m_log << "erro k_disk." << endl;
00344                 tok.emsg("not yet implemented");
00345                 break;
00346 
00347             case k_node:
00348                 if( tok.getstrnew( &nodename ) )
00349                 {
00350                     tok.emsg("missing storage node hostname");
00351                     break;
00352                 }
00353                 // Mudanca para esperar pela inicializacao do servidor por uma
00354                 // quantidade maxima de vezes.
00355                 Attempts = 0;
00356                 do
00357                 {
00358                     Attempts++;
00359                         RioErr << "Trying to connect for " <<  Attempts + 1 << " time. Start" << endl;
00360                     rc2 = BuildNode( nodename, true );
00361                         RioErr << "Trying to connect for " <<  Attempts + 1 << " time. End" << endl;
00362                     if( ( Attempts < m_MaxAttempts ) && ( rc2 ) ) 
00363                     {
00364                        RioErr << "Error connecting to storage server \"" 
00365                               << nodename << "\" (attempt " << Attempts + 1 
00366                               << " of " << m_MaxAttempts << ")." << endl;
00367                            RioErr << "Waiting for " << m_TimeBetweenAttempts << " seconds." << endl;
00368                        sleep( m_TimeBetweenAttempts );
00369                     }
00370                 } while ( ( Attempts < m_MaxAttempts ) && ( rc2 ) );
00371                 // Verifica se precisamos criar a conexao com o servidor 
00372                 // inativo
00373                 if( rc2 )
00374                 {
00375                     if( m_IsFormatting )
00376                         RioErr << "Failed to connect to storage server \""
00377                                << nodename << "\" when formatting file system. "
00378                                << "Aborting. " << endl;
00379                     else
00380                     {
00381                         RioErr << "Failed to connect to storage server \""
00382                                << nodename << "\". Creating only the node for "
00383                                << "this server" << endl;
00384                         rc2 = BuildNode( nodename, false );
00385                     }
00386                 }
00387                 rc |= rc2;
00388                 m_log << "erro k_node. rc = " << rc << endl;
00389                 NumStorages++;
00390                 if( NumStorages > MAXNUMSTORAGES )
00391                 {
00392                     m_log << "Too many storage servers (max = "
00393                           <<  MAXNUMSTORAGES << endl;
00394                     return 1;      
00395                 } 
00396 
00397                 delete[] nodename;
00398                 break;
00399 
00400             default:
00401                 m_log << "erro invalid word." << endl;
00402                 tok.emsg("{default} invalid word");
00403                 continue;
00404         }
00405         tok.ckend();
00406     }
00407     tok.closefile();
00408 
00409     if( rc == 0 )
00410     {
00411         cout << " OK. " << endl;
00412     }
00413     else
00414         cout << " Error! " << endl; 
00415     return rc;
00416 }

int DiskMgr::Reset ( void   ) 

Definition at line 668 of file DiskMgr.cpp.

00669 {
00670     Disk *dp;
00671     int rc = 0;
00672     int rc2;
00673 
00674     for( dp = m_disklist; dp != 0; dp = dp->d_link )
00675     {
00676         rc2 = dp->d_BitMap.Reset();
00677         if( rc2 && !rc )
00678             rc = rc2;
00679     }
00680     return rc;
00681 }

void DiskMgr::SendStorageNode ( EventStorageRequest event,
u16  DiskId 
)

Definition at line 1179 of file DiskMgr.cpp.

01180 {
01181     if( DiskId > m_MaxDisks )
01182     {
01183         RioErr << "DiskMgr ERROR: StorageNode request to invalid disk: "
01184                << DiskId << endl;
01185         EventManager.Free((Event*) event);
01186         return;
01187     }
01188 
01189     if( m_disks[DiskId] == 0 )
01190     {
01191         RioErr << "DiskMgr ERROR: StorageNode request to inactive disk: "
01192                << DiskId << endl;
01193         EventManager.Free((Event*)event);
01194         return;
01195     }
01196     m_disks[DiskId]->SendStorageNode( event );
01197     return;
01198 }

int DiskMgr::SendStorageNodeByIP ( EventStorageRequest event,
u32  StorageIP 
)

Nova funcao, usada pelo gerenciamento de logs, para colocar um evento na fila de eventos (com mensagens a serem enviadas) ao servidor de armazenamento identificado pelo IP dado com parametro.

Obs: estamos supondo que o IP do servidor de armazenameno para a conexao TCP e o mesmo do que o da conexao UDP.

Returns:
S_OK se existe um servidor de armazenamento com este IP, ou o valor ERROR_UNEXPECTED se nao existir um servidor com o IP.

Definition at line 1391 of file DiskMgr.cpp.

01392 {
01393     SNode *np;
01394 
01395     // Procura pelo no com o IP dado como parametro
01396     np = m_nodelist;
01397     while( ( np != NULL ) && ( np->sn_IPaddress.Host != StorageIP ) )
01398     {
01399         np = np->sn_link;
01400     }
01401     
01402     // Se np nao for NULL, entao colocamos o evento na fila de np. 
01403     if( np != NULL )
01404     {
01405         np->sn_sendqueue.Put( ( Event* ) event );
01406         return ERROR_DISKMGR + S_OK;
01407     }
01408     else
01409     {
01410         // Libera o evento, pois nao achamos o IP do servidor de armazenamento.
01411         EventManager.Free( ( Event* )event );
01412         #ifdef RIO_DEBUG2
01413         struct in_addr ip;
01414         ip.s_addr = StorageIP;
01415         RioErr << "DiskMgr::SendStorageNodeByIP erro ao tentar enviar um "
01416                << "evento ao servidor de armazenamento com o IP " 
01417                << inet_ntoa( ip ) << endl;
01418         #endif       
01419         return ERROR_DISKMGR + ERROR_UNEXPECTED;       
01420     }
01421 }

int DiskMgr::Start ( void   ) 

Definition at line 643 of file DiskMgr.cpp.

00644 {
00645     Disk *dp;
00646     int rc = 0;
00647     int rc2;
00648 
00649     for( dp = m_disklist; dp != 0; dp = dp->d_link )
00650     {
00651         rc2 = dp->d_BitMap.Load();
00652         if( rc2 && !rc )
00653             rc = rc2;
00654     }
00655     // to test if an error happened before call BuildAlloc
00656     if( rc )
00657     {
00658         return rc;
00659     }
00660     // ------------------------------------------------------------------------
00661     BuildAlloc();
00662     return 0;
00663 }

int DiskMgr::Stop (  ) 

Friends And Related Function Documentation

friend class Disk [friend]

Definition at line 216 of file DiskMgr.h.

friend class SNode [friend]

Definition at line 217 of file DiskMgr.h.


Field Documentation

int DiskMgr::m_BlockSize [private]

Definition at line 127 of file DiskMgr.h.

int DiskMgr::m_cntAllocFail [private]

Definition at line 135 of file DiskMgr.h.

int DiskMgr::m_cntAllocMult [private]

Definition at line 133 of file DiskMgr.h.

int DiskMgr::m_cntAllocRetry [private]

Definition at line 134 of file DiskMgr.h.

char* DiskMgr::m_ConfigsDirectory [private]

Definition at line 165 of file DiskMgr.h.

Disk** DiskMgr::m_diska [private]

Definition at line 154 of file DiskMgr.h.

int DiskMgr::m_diskanum [private]

Definition at line 153 of file DiskMgr.h.

Definition at line 156 of file DiskMgr.h.

Disk** DiskMgr::m_disks [private]

Definition at line 146 of file DiskMgr.h.

bool DiskMgr::m_IsFormatting [private]

Definition at line 184 of file DiskMgr.h.

ofstream DiskMgr::m_log [private]

Definition at line 150 of file DiskMgr.h.

unsigned int DiskMgr::m_MaxAttempts [private]

Definition at line 169 of file DiskMgr.h.

int DiskMgr::m_MaxDisks [private]

Definition at line 128 of file DiskMgr.h.

int DiskMgr::m_MaxReps [private]

Definition at line 129 of file DiskMgr.h.

char* DiskMgr::m_MetaRoot [private]

Definition at line 130 of file DiskMgr.h.

pthread_mutex_t DiskMgr::m_mutex [private]

Definition at line 137 of file DiskMgr.h.

Definition at line 157 of file DiskMgr.h.

Definition at line 148 of file DiskMgr.h.

Definition at line 149 of file DiskMgr.h.

int DiskMgr::m_numDisks [private]

Definition at line 139 of file DiskMgr.h.

Definition at line 131 of file DiskMgr.h.

unsigned long long int DiskMgr::m_storagesnotfull [private]

Definition at line 178 of file DiskMgr.h.

Definition at line 132 of file DiskMgr.h.

int DiskMgr::m_termflag [private]

Definition at line 160 of file DiskMgr.h.

pthread_t DiskMgr::m_thread [private]

Definition at line 159 of file DiskMgr.h.

unsigned int DiskMgr::m_TimeBetweenAttempts [private]

Definition at line 170 of file DiskMgr.h.


The documentation for this class was generated from the following files:
Generated on Wed Jul 4 16:03:34 2012 for RIO by  doxygen 1.6.3