qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] Add qcow2 documentation


From: Kevin Wolf
Subject: Re: [Qemu-devel] [PATCH] Add qcow2 documentation
Date: Thu, 10 Mar 2011 09:12:45 +0100
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.15) Gecko/20101027 Fedora/3.0.10-1.fc12 Thunderbird/3.0.10

Am 09.03.2011 19:08, schrieb Dushyant Bansal:
> On Tuesday 08 March 2011 05:17 PM, Kevin Wolf wrote:
>> This adds a description of the qcow2 file format to the docs/ directory.
>> Besides documenting what's there, which is never wrong, the document should
>> provide a good basis for the discussion of format extensions (called "qcow3"
>> in previous discussions)
>>
>> Signed-off-by: Kevin Wolf<address@hidden>
>> ---
>>   docs/specs/qcow2.txt |  228 
>> ++++++++++++++++++++++++++++++++++++++++++++++++++
>>   1 files changed, 228 insertions(+), 0 deletions(-)
>>   create mode 100644 docs/specs/qcow2.txt
>>
>> diff --git a/docs/specs/qcow2.txt b/docs/specs/qcow2.txt
>> new file mode 100644
>> index 0000000..0e7bcda
>> --- /dev/null
>> +++ b/docs/specs/qcow2.txt
>> @@ -0,0 +1,228 @@
>> +== Clusters ==
>> +
>> +A qcow2 image file is organized in units of constant size, which are called
>> +(host) clusters. A cluster is the unit in which all allocations are done,
>> +both for actual guest data and for image metadata.
>> +
>> +Likewise, the virtual disk as seen by the guest is divided into (guest)
>> +clusters of the same size.
>> +
>> +
>> +== Header ==
>> +
>> +The first cluster of a qcow2 image contains the file header:
>> +
>> +    Byte  0 -  3:   magic
>> +                    QCOW magic string ("QFI\xfb")
>> +
>> +          4 -  7:   version
>> +                    Version number (only valid value is 2)
>> +
>> +          8 - 15:   backing_file_offset
>> +                    Offset into the image file at which the backing file 
>> name
>> +                    is stored (NB: The string is not null terminated). 0 if 
>> the
>> +                    image doesn't have a backing file.
>> +
>> +         16 - 19:   backing_file_size
>> +                    Length of the backing file name in bytes. Must not be
>> +                    longer than 1023 bytes. Undefined if the image doesn't 
>> have
>> +                    a backing file.
>> +
>> +         20 - 23:   cluster_bits
>> +                    Number of bits that are used for addressing an offset
>> +                    within a cluster (1<<  cluster_bits is the cluster size)
>> +
>> +         24 - 31:   size
>> +                    Virtual disk size in bytes
>> +
>> +         32 - 35:   crypt_method
>> +                    0 for no encryption
>> +                    1 for AES encryption
>> +
>> +         36 - 39:   l1_size
>> +                    Number of entries in the active L1 table
>> +
>> +         40 - 47:   l1_table_offset
>> +                    Offset into the image file at which the active L1 table
>> +                    starts. Must be aligned to a cluster boundary.
>> +
>> +         48 - 55:   refcount_table_offset
>> +                    Offset into the image file at which the refcount table
>> +                    starts. Must be aligned to a cluster boundary.
>> +
>> +         56 - 59:   refcount_table_clusters
>> +                    Number of clusters that the refcount table occupies
>> +
>> +         60 - 63:   nb_snapshots
>> +                    Number of snapshots contained in the image
>> +
>> +         64 - 71:   snapshots_offset
>> +                    Offset into the image file at which the snapshot table
>> +                    starts. Must be aligned to a cluster boundary.
>> +
>> +All numbers in qcow2 are stored in Big Endian byte order.
>> +
>> +
>> +== Host cluster management ==
>> +
>> +qcow2 manages the allocation of host clusters by maintaining a reference 
>> count
>> +for each host cluster. A refcount of 0 means that the cluster is free, 1 
>> means
>> +that it is used, and>= 2 means that it is used and any write access must
>> +perform a COW (copy on write) operation.
>> +
>> +The refcounts are managed in a two-level table. The first level is called
>> +refcount table and has a variable size (which is stored in the header). The
>> +refcount table can cover multiple clusters, however it needs to be 
>> contiguous
>> +in the image file.
>> +
>> +It contains pointers to the second level structures which are called 
>> refcount
>> +blocks and are exactly one cluster in size.
>> +
>> +Given a offset into the image file, the refcount of its cluster can be 
>> obtained
>> +as follows:
>> +
>> +    refcount_block_entries = (cluster_size / sizeof(uint16_t))
>> +
>> +    refcount_block_index = (offset / cluster_size) % refcount_table_entries
>> +    refcount_table_index = (offset / cluster_size) / refcount_table_entries
>> +
>> +    refcount_block = load_cluster(refcount_table[refcount_table_index]);
>> +    return refcount_block[refcount_block_index];
>> +
>> +Refcount table entry:
>> +
>> +    Bit  0 -  8:    Reserved (set to 0)
>> +
>> +         9 - 63:    Bits 9-63 of the offset into the image file at which the
>> +                    refcount block starts. Must be aligned to a cluster
>> +                    boundary.
>> +
>> +                    If this is 0, the corresponding refcount block has not 
>> yet
>> +                    been allocated. All refcounts managed by this refcount 
>> block
>> +                    are 0.
>> +
>> +Refcount block entry:
>> +
>> +    Bit  0 - 15:    Reference count of the cluster
>> +
>> +
>> +== Cluster mapping ==
>> +
>> +Just as for refcounts, qcow2 uses a two-level structure for the mapping of
>> +guest clusters to host clusters. They are called L1 and L2 table.
>> +
>> +The L1 table has a variable size (stored in the header) and may use multiple
>> +clusters, however it must be contiguous in the image file. L2 tables are
>> +exactly one cluster in size.
>> +
>> +Given a offset into the virtual disk, the offset into the image file can be
>> +obtained as follows:
>> +
>> +    l2_entries = (cluster_size / sizeof(uint64_t))
>> +
>> +    l2_index = (offset / cluster_size) % l2_entries
>> +    l1_index = (offset / cluster_size) / l2_entries
>> +
>> +    l2_table = load_cluster(l1_table[l1_index]);
>> +    cluster_offset = refcount_block[l2_index];
>>    
> It should be cluster_offset = l2_table[l2_index];
> Right?

Correct. Thanks for catching this.

Kevin



reply via email to

[Prev in Thread] Current Thread [Next in Thread]