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