예제 #1
0
 def __getitem__(self, item):
     if item < 0:
         return None
     if self._levels == 1:
         return self._root if item == 0 else None
     indices = self._get_level_indices(item)
     bpa = self._root
     for (l, i) in enumerate(indices[:-1]):
         level_cache = self._cache.get(l)
         if level_cache is None:
             level_cache = {}
             self._cache[l] = level_cache
         if i in level_cache:
             next_bpa = level_cache[i]
         else:
             b = bpa[i]
             bpa_data = None
             for dva in range(3):
                 bpa_data = self._vdev.read_block(b, dva=dva)
                 if bpa_data:
                     break
             next_bpa = None
             if bpa_data is not None:
                 next_bpa = BlockPtrArray(bpa_data)
             else:
                 print("[-] Block tree is broken at", b)
             level_cache[i] = next_bpa
         bpa = next_bpa
         if bpa is None:
             return None
     return bpa[indices[-1]]
예제 #2
0
def _indirect_zap_factory(vdev, bptr, dbsize, nblocks):
    data,c = vdev.read_block(bptr)
    if data is None:
        return None
    # Data contains first indirection block
    bpa = BlockPtrArray(data)
    return _blockptrar_zap_factory(vdev, bpa, dbsize, nblocks)
예제 #3
0
 def __getitem__(self, item):
     if item < 0:
         return None
     if self._levels == 1:
         return self._root if item == 0 else None
     indices = self._get_level_indices(item)
     bpa = self._root
     _cache = self._cache
     for (l, i) in enumerate(indices[:-1]):
         if not i in _cache:
             _cache[i] = {'b': None, 'n': {}}  # generate a graph
         if not _cache[i]['b'] is None:
             next_bpa = _cache[i]['b']
         else:
             b = bpa[i]
             bpa_data = None
             for dva in range(3):
                 bpa_data, c = self._vdev.read_block(b, dva=dva)
                 if bpa_data and c:
                     break
             next_bpa = None
             if bpa_data is not None:
                 next_bpa = BlockPtrArray(bpa_data)
             else:
                 print("[-] Block tree is broken at", b)
             _cache[i]['b'] = next_bpa
         bpa = next_bpa
         self.printidx(indices, l, str(bpa))
         if bpa is None:
             return None
         _cache = _cache[i]['n']
     b = bpa[indices[-1]]
     print(("[t-%d] " % (item)) + color.GREEN + str(indices) + color.END +
           " : " + str(b) + " : " + str(bpa))
     return b
예제 #4
0
 def _load_from_bptr(self, bptr):
     block_data = None
     for dva in range(3):
         block_data = self._vdev.read_block(bptr, dva=dva)
         if block_data:
             break
     if block_data is None:
         return None
     return BlockPtrArray(block_data)
예제 #5
0
def zap_factory(vdev, dnode):
    bptr = dnode.blkptrs[0]
    dbsize = dnode.datablksize
    if dnode.levels == 1:
        nblocks = dnode._nblkptr
        bpa = BlockPtrArray(dnode._data[BLKPTR_OFFSET:BLKPTR_OFFSET+nblocks*128])
        return _blockptrar_zap_factory(vdev, bpa, dbsize, nblocks)
    elif dnode.levels == 2:
        return _indirect_zap_factory(vdev, bptr, dbsize, dnode.maxblkid+1)
    # TODO: Implement Fat Zap with BlockTree
    raise NotImplementedError("Deeper ZAPs not supported yet")
예제 #6
0
파일: zap.py 프로젝트: zecke/py-zfs-rescue
def _indirect_zap_factory(vdev, bptr, dbsize, nblocks):
    data = vdev.read_block(bptr)
    if data is None:
        return None
    # Data contains first indirection block
    bpa = BlockPtrArray(data)
    data = bytearray()
    for i in range(nblocks):
        data += vdev.read_block(bpa[i])
    (block_type, ) = struct.unpack("=Q", data[:8])
    if block_type == ZBT_MICRO:
        zap = MicroZap()
    elif block_type == ZBT_HEADER:
        zap = FatZap(dbsize)
    else:
        print("[-]  Data is not a ZAP object: type={}".format(hex(block_type)))
        return None
    zap.parse(data)
    return zap