Exemplo n.º 1
0
int read_hdr_file(char * root, int devices, int slice, rozofs_stor_bins_file_hdr_vall_t * hdr, uuid_t uuid, int *spare) {
  char             path[256];
  int              dev;
  int              Zdev=-1;
  struct stat      st;
  uint64_t         ts=0;
  int              fd;
  uint8_t          safe;
  uint8_t          fwd;
  uint8_t          inv;
  char            *pChar;
  uint32_t        *pCrc;
  uint32_t         crcLen;
  int              i;
  sid_t         * pDist;
  uint8_t val;
  
  for (*spare=0; *spare<2; *spare+=1) {
  
    for (dev=0; dev < devices; dev++) {
    
      pChar = storage_build_hdr_path(path,root,dev, *spare, slice);
      rozofs_uuid_unparse(uuid, pChar);
      
      // Check that the file exists
      if (stat(path, &st) == -1) {
        continue;
      }

      // 1rst header file found
      if (Zdev == -1) {
        Zdev = dev;
	ts   = st.st_mtime;
        continue;
      }
      
      // An other header file found
      if (st.st_mtime > ts) {
        // More recently modified
        Zdev = dev;
	ts   = st.st_mtime;
        continue;	
      }	     
    }
    
    //Header file has been found. Read it 
    if (Zdev != -1) {
      pChar = storage_build_hdr_path(path,root,Zdev, *spare, slice);
      rozofs_uuid_unparse(uuid, pChar);
      // Open hdr file
      fd = open(path, ROZOFS_ST_NO_CREATE_FILE_FLAG, ROZOFS_ST_BINS_FILE_MODE);
      if (fd < 0) {
	printf("open(%s) %s",path, strerror(errno));
	return -1;
      }
      int nb_read = pread(fd, hdr, sizeof (*hdr), 0);
      if (nb_read < 0) {
        printf("pread(%s) %s",path, strerror(errno));
	return -1; 
      } 
      
      close(fd);  
      printf("{ \"header file\" : {\n");
      printf("  \"path\"    : \"%s\",\n",path);
      printf("  \"version\" : %d,\n",hdr->v0.version);
      printf("  \"layout\"  : %d,\n",hdr->v0.layout);
      printf("  \"bsize\"   : %d,\n",hdr->v0.bsize);
      switch(hdr->v0.version) {
        case 0:
          rozofs_get_rozofs_invers_forward_safe(hdr->v0.layout, &inv, &fwd, &safe);
          pDist = hdr->v0.dist_set_current;
          break;
        case 1:  
          rozofs_get_rozofs_invers_forward_safe(hdr->v1.layout, &inv, &fwd, &safe);
          pDist = hdr->v1.dist_set_current;
          printf("  \"cid\"     : %d,\n", hdr->v1.cid);
          printf("  \"sid\"     : %d,\n", hdr->v1.sid);
          break;
        case 2:
          rozofs_get_rozofs_invers_forward_safe(hdr->v2.layout, &inv, &fwd, &safe);
          pDist = hdr->v2.distrib;
          printf("  \"cid\"     : %d,\n", hdr->v2.cid);
          printf("  \"sid\"     : %d,\n", hdr->v2.sid);
          memset(&hdr->v2.devFromChunk[hdr->v2.nbChunks], ROZOFS_EOF_CHUNK, ROZOFS_STORAGE_MAX_CHUNK_PER_FILE-hdr->v2.nbChunks);
          break;
        default:
          printf("Unknown header version\n");
          continue;
          break;     	 
      }    
      crcLen = rozofs_st_get_header_file_crc(hdr, &pCrc);
      
      printf("  \"distibution\" : {\n");      
      printf("      \"inverse\" : [");      
      printf(" %d", pDist[0]);
      for (i=1; i< inv; i++) {
        printf(", %d",pDist[i]);
      }
      printf("],\n      \"forward\" : [ %d",pDist[i]);      
      i++;
      for (  ; i< fwd; i++) {
        printf(", %d",pDist[i]);
      }
      printf("],\n      \"safe\"    : [ %d",pDist[i]);      
      i++;
      for (  ; i< safe; i++) {
        printf(", %d",pDist[i]);
      }          
      printf("]\n  },\n");
          

      i = 0;
      val = rozofs_st_header_get_chunk(hdr,i);
      printf("  \"devices\" : [ %d", val);
      i++;
      while(i<ROZOFS_STORAGE_MAX_CHUNK_PER_FILE) {
        val = rozofs_st_header_get_chunk(hdr,i);
        if (val == ROZOFS_EOF_CHUNK) break;
        if (val == ROZOFS_EMPTY_CHUNK) printf(", E");
        else printf(", %d",val);
        i++;
      }
      printf("],\n");
            
      uint32_t save_crc32 = *pCrc;;
      printf("  \"crc32\"   : ");
      if (save_crc32 == 0) {
        printf("\"None\"\n");
      }
      else { 
        *pCrc = 0;
        uint32_t crc32;
        crc32 = fid2crc32((uint32_t *)uuid);   
        crc32 = crc32c(crc32,(char *) hdr, crcLen);
        *pCrc = save_crc32;

	if (save_crc32 != crc32) {
          printf("BAD %x. Rxpecting %x\"\n",save_crc32,crc32);
          continue;
	}	
        printf("\"OK\"\n");
      }
      printf("}}\n");
      return 0;  	
    }            
    // Check for spare
  }
  return -1;
}
Exemplo n.º 2
0
int export_load_rmfentry(export_t * e) 
{
   int ret=0;
   int user_id;
   uint64_t count = 0;
   uint64_t file_id;
   rozofs_inode_t inode;
   int i;
   rmfentry_disk_t trash_entry;
   exp_trck_top_header_t *tracking_trash_p; 
   exp_trck_header_memory_t *slice_hdr_p;
   exp_trck_file_header_t tracking_buffer;
   rmfentry_t *rmfe;   
   time_t      when = time(NULL)+common_config.deletion_delay;   
   /*
   ** get the pointer to the tracking context associated with the 
   ** export
   */
   tracking_trash_p = e->trk_tb_p->tracking_table[ROZOFS_TRASH];   
   /*
   ** go through all the slices of the export check for all the file
   ** that are under deletion 
   ** The slices correspond to the case of the trash only
   */ 
   for (user_id = 0; user_id < EXP_TRCK_MAX_USER_ID; user_id++)
   {
     inode.s.usr_id = user_id;
     file_id = 0;
    
     /*
     ** read the main tracking file of each slices: the main tracking file contains the 
     ** first and list index of individual tracking file that contains the information
     ** relative to the file to delete. There are a maximum of 2044 files per tracking
     * file
     */
     slice_hdr_p = tracking_trash_p->entry_p[user_id];
     for (file_id = slice_hdr_p->entry.first_idx; file_id <= slice_hdr_p->entry.last_idx; file_id++)
     {
       ret = exp_metadata_get_tracking_file_header(tracking_trash_p,user_id,file_id,&tracking_buffer,NULL);
       if (ret < 0)
       {
	 if (errno != ENOENT)
	 {
            severe("error while main tracking file header of slice %d %s\n",user_id,strerror(errno));
	    continue;
	 }
	 ret = 0;
	 continue;
       }
       /*
       ** get the current count within the tracking file
       */
       {
          while(loop_fdl)
	  {
	     sleep(5);
	     severe("FDL bug wait for gdb");
	  }
       }
       count +=exp_metadata_get_tracking_file_count(&tracking_buffer);
       inode.s.file_id = file_id;

       for (i = 0; i < EXP_TRCK_MAX_INODE_PER_FILE; i++)
       {
          inode.s.idx = i;
	  if (tracking_buffer.inode_idx_table[i] == 0xffff) continue;
	  ret = exp_metadata_read_attributes(tracking_trash_p,&inode,&trash_entry,sizeof(trash_entry));
	  if (ret < 0)
	  {
	    severe("error while reading attributes at idx %d for trash slice %d in file %llu: %s\n",
	            inode.s.idx,inode.s.usr_id,
	            (long long unsigned int)inode.s.file_id,
		    strerror(errno));
		    continue;
	  }
	  /*
	  ** allocate memory for the file to delete
	  */
            for(;;)
	    {
              rmfe = xmalloc(sizeof (rmfentry_t));
	      if (rmfe == NULL)
	      {
		 /*
		 ** out of memory: just wait for a while and then retry
		 */
		 sleep(2);
	      }
	      break;
	    }
#if 0
	    {
	       char buf_fid[64];
	       rozofs_uuid_unparse(trash_entry.fid,buf_fid);
	       severe("FDL slice %u file %llu index %d  trash fid %s ",user_id,file_id,i, buf_fid);
	    }
#endif
            memcpy(rmfe->fid, trash_entry.fid, sizeof (fid_t));
            rmfe->cid = trash_entry.cid;
            memcpy(rmfe->initial_dist_set, trash_entry.initial_dist_set,
                    sizeof (sid_t) * ROZOFS_SAFE_MAX);
            memcpy(rmfe->current_dist_set, trash_entry.current_dist_set,
                    sizeof (sid_t) * ROZOFS_SAFE_MAX);
            memcpy(rmfe->trash_inode,trash_entry.trash_inode,sizeof(fid_t));
            list_init(&rmfe->list);
	    rmfe->time = when;
	    /*
	    **  Compute hash value for this fid
	    */
            uint32_t hash = rozofs_storage_fid_slice(trash_entry.fid);
	  
            /* Acquire lock on bucket trash list
	    */
            if ((errno = pthread_rwlock_wrlock
                    (&e->trash_buckets[hash].rm_lock)) != 0) {
                severe("pthread_rwlock_wrlock failed: %s", strerror(errno));
                // Best effort
            }
            /*
	    ** Check size of file : TODO: cannot be done here since the 
	    ** file size is not save on disk
	    */
            if (trash_entry.size >= RM_FILE_SIZE_TRESHOLD) {
                // Add to front of list
                list_push_front(&e->trash_buckets[hash].rmfiles, &rmfe->list);
            } else {
                // Add to back of list
                list_push_back(&e->trash_buckets[hash].rmfiles, &rmfe->list);
            }
            export_rm_bins_reload_count++;
            if ((errno = pthread_rwlock_unlock
                    (&e->trash_buckets[hash].rm_lock)) != 0) {
                severe("pthread_rwlock_unlock failed: %s", strerror(errno));
                // Best effort
            }
       }
       /*
       ** try the next
       */
     }   
   }
   return ret;
}