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; }
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; }