From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=46444 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PxNpn-0005pI-Go for qemu-devel@nongnu.org; Wed, 09 Mar 2011 13:10:08 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PxNpl-0002zp-SH for qemu-devel@nongnu.org; Wed, 09 Mar 2011 13:10:07 -0500 Received: from smtp1.iitd.ernet.in ([202.141.68.45]:47473) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PxNpk-0002lF-QH for qemu-devel@nongnu.org; Wed, 09 Mar 2011 13:10:05 -0500 Message-ID: <4D77C236.3020309@cse.iitd.ac.in> Date: Wed, 09 Mar 2011 23:38:54 +0530 From: Dushyant Bansal MIME-Version: 1.0 Subject: Re: [Qemu-devel] [PATCH] Add qcow2 documentation References: <1299584839-5688-1-git-send-email-kwolf@redhat.com> In-Reply-To: <1299584839-5688-1-git-send-email-kwolf@redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Kevin Wolf Cc: qemu-devel@nongnu.org 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 > --- > 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? -- Dushyant