qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

044 (3939B)


      1 #!/usr/bin/env python3
      2 # group: rw
      3 #
      4 # Tests growing a large refcount table.
      5 #
      6 # Copyright (C) 2012 Red Hat, Inc.
      7 #
      8 # This program is free software; you can redistribute it and/or modify
      9 # it under the terms of the GNU General Public License as published by
     10 # the Free Software Foundation; either version 2 of the License, or
     11 # (at your option) any later version.
     12 #
     13 # This program is distributed in the hope that it will be useful,
     14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 # GNU General Public License for more details.
     17 #
     18 # You should have received a copy of the GNU General Public License
     19 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     20 #
     21 
     22 import time
     23 import os
     24 import qcow2
     25 from qcow2 import QcowHeader
     26 import iotests
     27 from iotests import qemu_img, qemu_img_log, qemu_io
     28 import struct
     29 import subprocess
     30 import sys
     31 
     32 test_img = os.path.join(iotests.test_dir, 'test.img')
     33 
     34 class TestRefcountTableGrowth(iotests.QMPTestCase):
     35     '''Abstract base class for image mirroring test cases'''
     36 
     37     def preallocate(self, name):
     38         fd = open(name, "r+b")
     39         try:
     40             off_reftable = 512
     41             off_refblock = off_reftable + (512 * 512)
     42             off_l1       = off_refblock + (512 * 512 * 64)
     43             off_l2       = off_l1 + (512 * 512 * 4 * 8)
     44             off_data     = off_l2 + (512 * 512 * 4 * 512)
     45 
     46             # Write a new header
     47             h = QcowHeader(fd)
     48             h.refcount_table_offset = off_reftable
     49             h.refcount_table_clusters = 512
     50             h.l1_table_offset = off_l1
     51             h.l1_size = 512 * 512 * 4
     52             h.update(fd)
     53 
     54             # Write a refcount table
     55             fd.seek(off_reftable)
     56 
     57             for i in range(0, h.refcount_table_clusters):
     58                 sector = b''.join(struct.pack('>Q',
     59                     off_refblock + i * 64 * 512 + j * 512)
     60                     for j in range(0, 64))
     61                 fd.write(sector)
     62 
     63             # Write the refcount blocks
     64             assert(fd.tell() == off_refblock)
     65             sector = b''.join(struct.pack('>H', 1) for j in range(0, 64 * 256))
     66             for block in range(0, h.refcount_table_clusters):
     67                 fd.write(sector)
     68 
     69             # Write the L1 table
     70             assert(fd.tell() == off_l1)
     71             assert(off_l2 + 512 * h.l1_size == off_data)
     72             table = b''.join(struct.pack('>Q', (1 << 63) | off_l2 + 512 * j)
     73                 for j in range(0, h.l1_size))
     74             fd.write(table)
     75 
     76             # Write the L2 tables
     77             assert(fd.tell() == off_l2)
     78             img_file_size = h.refcount_table_clusters * 64 * 256 * 512
     79             remaining = img_file_size - off_data
     80 
     81             off = off_data
     82             while remaining > 1024 * 512:
     83                 pytable = list((1 << 63) | off + 512 * j
     84                     for j in range(0, 1024))
     85                 table = struct.pack('>1024Q', *pytable)
     86                 fd.write(table)
     87                 remaining = remaining - 1024 * 512
     88                 off = off + 1024 * 512
     89 
     90             table = b''.join(struct.pack('>Q', (1 << 63) | off + 512 * j)
     91                 for j in range(0, remaining // 512))
     92             fd.write(table)
     93 
     94 
     95             # Data
     96             fd.truncate(img_file_size)
     97 
     98 
     99         finally:
    100             fd.close()
    101 
    102 
    103     def setUp(self):
    104         qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=512', test_img, '16G')
    105         self.preallocate(test_img)
    106         pass
    107 
    108 
    109     def tearDown(self):
    110         os.remove(test_img)
    111         pass
    112 
    113     def test_grow_refcount_table(self):
    114         qemu_io('-c', 'write 3800M 1M', test_img)
    115         qemu_img_log('check' , test_img)
    116         pass
    117 
    118 if __name__ == '__main__':
    119     iotests.activate_logging()
    120     iotests.main(supported_fmts=['qcow2'],
    121                  supported_protocols=['file'],
    122                  unsupported_imgopts=['refcount_bits'])