Exemple #1
0
/// calculate offset of logical volume
static uint32_t logical_volume_offset(vmfs_fs_t *fs)
{
    /* reference vmfs-tools/libvmfs/vmfs_volume.c 
       pos += vol->vmfs_base + 0x1000000;
     */
    return (VMFS_VOLINFO_BASE + 0x1000000) / vmfs_fs_get_blocksize(fs);
}
Exemple #2
0
void read_super_blocks(char* device, file_system_info* fs_info)
{
    uint32_t offset, total, alloc;

    fs_open(device);
    strncpy(fs_info->fs, vmfs_MAGIC, FS_MAGIC_SIZE);
    offset = logical_volume_offset(fs);
    total = fs->fbb->bmh.total_items + offset;
    alloc = vmfs_bitmap_allocated_items(fs->fbb) + offset;

    fs_info->block_size  = vmfs_fs_get_blocksize(fs);
    fs_info->totalblock  = total;
    fs_info->usedblocks  = alloc;
    fs_info->device_size = vmfs_fs_get_blocksize(fs) * total;
    fs_close();
}
Exemple #3
0
/// read super block and write to image head
extern void initial_image_hdr(char* device, image_head* image_hdr)
{

    uint32_t alloc,total;

    fs_open(device);
    strncpy(image_hdr->magic, IMAGE_MAGIC, IMAGE_MAGIC_SIZE);
    strncpy(image_hdr->fs, vmfs_MAGIC, FS_MAGIC_SIZE);
    total = fs->fbb->bmh.total_items;
    alloc = vmfs_bitmap_allocated_items(fs->fbb);

    image_hdr->block_size  = vmfs_fs_get_blocksize(fs);
    image_hdr->totalblock  = total;
    image_hdr->usedblocks  = alloc;
    image_hdr->device_size = (vmfs_fs_get_blocksize(fs)*total);
    fs_close();
}
Exemple #4
0
static int cmd_remove(vmfs_fs_t *fs,int argc,char *argv[])
{
   /* Dangerous */
   vmfs_lvm_t *lvm = (vmfs_lvm_t *)fs->dev;
   vmfs_volume_t *extent;
   DECL_ALIGNED_BUFFER(buf,512);
   vmfs_bitmap_entry_t entry;
   uint32_t i, blocks_per_segment, items_per_area,
            items_in_last_entry, old_area_count;

   fprintf(stderr, "Extents removal is experimental ! Use at your own risk !\n");
   while (1) {
      char *answer = local_readline("Are you sure you want to go further? [y/N] ");
      char a = answer[0];
      char null = answer[1];
      free(answer);
      if ((a == 0) || ((tolower(a) == 'n') && (null == 0)))
         return(2);
      if ((tolower(a) == 'y') && (null == 0))
         break;
   }
   if (lvm->lvm_info.num_extents == 1) {
      fprintf(stderr, "Can't remove an extent when there is only one\n");
      return(1);
   }

   /* Get last extent */
   extent = lvm->extents[lvm->loaded_extents - 1];

   /* Check whether data blocks are used on the last extents */
   blocks_per_segment = VMFS_LVM_SEGMENT_SIZE / vmfs_fs_get_blocksize(fs);
   for (i = extent->vol_info.first_segment * blocks_per_segment;
        i < extent->vol_info.last_segment * blocks_per_segment;
        i++)
      if (vmfs_block_get_status(fs, VMFS_BLK_FB_BUILD(i, 0))) {
         fprintf(stderr, "There is data on the last extent ; can't remove it\n");
         return(1);
      }

   /* At filesystem level, only the FBB needs to be downsized */
   fs->fbb->bmh.total_items -= extent->vol_info.num_segments * blocks_per_segment;
   items_per_area = fs->fbb->bmh.items_per_bitmap_entry *
                    fs->fbb->bmh.bmp_entries_per_area;
   old_area_count = fs->fbb->bmh.area_count;
   fs->fbb->bmh.area_count = (fs->fbb->bmh.total_items + items_per_area - 1) /
                             items_per_area;

   memset(buf, 0, buf_len);
   vmfs_bmh_write(&fs->fbb->bmh, buf);
   /* TODO: Error handling */
   vmfs_file_pwrite(fs->fbb->f, buf, buf_len, 0);

   /* Adjust new last entry */
   if ((items_in_last_entry =
        fs->fbb->bmh.total_items % fs->fbb->bmh.items_per_bitmap_entry)) {
      vmfs_bitmap_get_entry(fs->fbb, 0, fs->fbb->bmh.total_items, &entry);
      entry.free -= entry.total - items_in_last_entry;
      entry.total = items_in_last_entry;
      if (entry.ffree > entry.total)
         entry.ffree = 0;
      /* Adjust bitmap in last entry */
      if (items_in_last_entry % 8)
         entry.bitmap[items_in_last_entry / 8] &=
            0xff << (8 - (items_in_last_entry % 8));
      memset(&entry.bitmap[(items_in_last_entry + 7) / 8], 0,
         (fs->fbb->bmh.items_per_bitmap_entry - items_in_last_entry - 7) / 8);
      vmfs_bme_update(fs, &entry);
   }
   /* Truncate the fbb file depending on the new area count */
   if (old_area_count != fs->fbb->bmh.area_count)
      vmfs_file_truncate(fs->fbb->f, fs->fbb->bmh.hdr_size +
                            fs->fbb->bmh.area_count * fs->fbb->bmh.area_size);
   /* Adjust entries after the new last one */
   for (i = fs->fbb->bmh.total_items + (items_in_last_entry ?
           (fs->fbb->bmh.items_per_bitmap_entry - items_in_last_entry) : 0);
        i < fs->fbb->bmh.area_count * items_per_area;
        i += fs->fbb->bmh.items_per_bitmap_entry) {
      uint64_t pos;
      vmfs_bitmap_get_entry(fs->fbb, 0, i, &entry);
      pos = entry.mdh.pos;
      memset(&entry, 0, sizeof(entry));
      vmfs_device_write(fs->dev, pos, (u_char *)&entry, sizeof(entry));
   }

   /* At LVM level, all extents need to have the LVM information updated */
   for (i = 0; i < lvm->loaded_extents - 1; i++) {
      lvm->extents[i]->vol_info.blocks -= extent->vol_info.num_segments + 1;
      lvm->extents[i]->vol_info.num_extents--;
      lvm->extents[i]->vol_info.lvm_size =
         (lvm->extents[i]->vol_info.blocks -
            lvm->extents[i]->vol_info.num_extents) * VMFS_LVM_SEGMENT_SIZE;

      /* Until there is an API for that, do it by hand */
      m_pread(lvm->extents[i]->fd,buf,buf_len,
              lvm->extents[i]->vmfs_base + VMFS_LVMINFO_OFFSET);
      write_le64(buf, VMFS_LVMINFO_OFS_SIZE - VMFS_LVMINFO_OFFSET,
         lvm->extents[i]->vol_info.lvm_size);
      write_le64(buf, VMFS_LVMINFO_OFS_BLKS - VMFS_LVMINFO_OFFSET,
         lvm->extents[i]->vol_info.blocks);
      write_le32(buf, VMFS_LVMINFO_OFS_NUM_EXTENTS - VMFS_LVMINFO_OFFSET,
         lvm->extents[i]->vol_info.num_extents);
      m_pwrite(lvm->extents[i]->fd,buf,buf_len,
               lvm->extents[i]->vmfs_base + VMFS_LVMINFO_OFFSET);
   }
   return(0);
}