WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel][PATCH] add format of qcow2 to qcow-create

To: "keir.fraser@xxxxxxxxxxxxx" <keir.fraser@xxxxxxxxxxxxx>
Subject: [Xen-devel][PATCH] add format of qcow2 to qcow-create
From: "Zhang, Yang" <yang.zhang@xxxxxxxxx>
Date: Tue, 3 Mar 2009 20:36:37 +0800
Accept-language: en-US
Acceptlanguage: en-US
Cc: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Delivery-date: Tue, 03 Mar 2009 04:40:15 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: Acmb/LHN38LYt5VPRBmCbEivuaI/vg==
Thread-topic: [Xen-devel][PATCH] add format of qcow2 to qcow-create
Hi
        this patch enable the qcow-create to create qcow2 image by using the 
cmdline -f qcow2.
        please to review it.

Best Regards
--yang

Signed-off-by: Yang Zhang <yang.zhang@xxxxxxxxx>

diff -r 27e9687c5b3d tools/blktap/drivers/block-qcow2.c
--- a/tools/blktap/drivers/block-qcow2.c        Tue Jan 13 08:59:49 2009 +0000
+++ b/tools/blktap/drivers/block-qcow2.c        Tue Mar 03 04:32:12 2009 -0500
@@ -1980,6 +1980,91 @@ static int qcow_validate_parent(struct d
        return 0;
 }
 
+int qcow2_create(const char *filename, uint64_t total_size,
+                      const char *backing_file, int flags)
+{
+    int fd, header_size, backing_filename_len, l1_size, i, shift, l2_bits;
+    QCowHeader header;
+    uint64_t tmp, offset;
+    QCowCreateState s1, *s = &s1;
+
+    memset(s, 0, sizeof(*s));
+
+    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 
0644);X_NAME_LEN
+    if (fd < 0)
+        return -1;
+    memset(&header, 0, sizeof(header));
+    header.magic = cpu_to_be32(QCOW_MAGIC);
+    header.version = cpu_to_be32(QCOW_VERSION);
+    header.size = cpu_to_be64(total_size * 512);
+    header_size = sizeof(header);
+    backing_filename_len = 0;
+    if (backing_file) {
+        header.backing_file_offset = cpu_to_be64(header_size);
+        backing_filename_len = strlen(backing_file);
+        header.backing_file_size = cpu_to_be32(backing_filename_len);
+        header_size += backing_filename_len;
+    }
+    s->cluster_bits = 12;  /* 4 KB clusters */
+    s->cluster_size = 1 << s->cluster_bits;
+    header.cluster_bits = cpu_to_be32(s->cluster_bits);
+    header_size = (header_size + 7) & ~7;
+    if (flags & BLOCK_FLAG_ENCRYPT) {
+        header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
+    } else {
+        header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
+    }
+    l2_bits = s->cluster_bits - 3;
+    shift = s->cluster_bits + l2_bits;
+    l1_size = (((total_size * 512) + (1LL << shift) - 1) >> shift);
+    offset = align_offset(header_size, s->cluster_size);
+    s->l1_table_offset = offset;
+    header.l1_table_offset = cpu_to_be64(s->l1_table_offset);
+    header.l1_size = cpu_to_be32(l1_size);
+    offset += align_offset(l1_size * sizeof(uint64_t), s->cluster_size);
+
+    s->refcount_table = qemu_mallocz(s->cluster_size);
+    s->refcount_block = qemu_mallocz(s->cluster_size);
+
+    s->refcount_table_offset = offset;
+    header.refcount_table_offset = cpu_to_be64(offset);
+    header.refcount_table_clusters = cpu_to_be32(1);
+    offset += s->cluster_size;
+
+    s->refcount_table[0] = cpu_to_be64(offset);
+    s->refcount_block_offset = offset;
+    offset += s->cluster_size;
+
+    /* update refcounts */
+    create_refcount_update(s, 0, header_size);
+    create_refcount_update(s, s->l1_table_offset, l1_size * sizeof(uint64_t));
+    create_refcount_update(s, s->refcount_table_offset, s->cluster_size);
+    create_refcount_update(s, s->refcount_block_offset, s->cluster_size);
+
+    /* write all the data */
+    write(fd, &header, sizeof(header));
+    if (backing_file) {
+        write(fd, backing_file, backing_filename_len);
+    }
+    lseek(fd, s->l1_table_offset, SEEK_SET);
+    tmp = 0;
+    for(i = 0;i < l1_size; i++) {
+        write(fd, &tmp, sizeof(tmp));
+    }
+    lseek(fd, s->refcount_table_offset, SEEK_SET);
+    write(fd, s->refcount_table, s->cluster_size);
+
+    lseek(fd, s->refcount_block_offset, SEEK_SET);
+    write(fd, s->refcount_block, s->cluster_size);
+
+    qemu_free(s->refcount_table);
+    qemu_free(s->refcount_block);
+    close(fd);
+    return 0;
+}
+
+
+
 struct tap_disk tapdisk_qcow2 = {
        "qcow2",
        sizeof(BDRVQcowState),
diff -r 27e9687c5b3d tools/blktap/drivers/qcow-create.c
--- a/tools/blktap/drivers/qcow-create.c        Tue Jan 13 08:59:49 2009 +0000
+++ b/tools/blktap/drivers/qcow-create.c        Tue Mar 03 06:55:40 2009 -0500
@@ -52,7 +52,7 @@ static void help(void)
 {
        fprintf(stderr, "Qcow-utils: v1.0.0\n");
        fprintf(stderr, 
-               "usage: qcow-create [-h help] [-r reserve] <SIZE(MB)> 
<FILENAME> "
+               "usage: qcow-create [-h help] [-r reserve] [-f format] 
<SIZE(MB)> <FILENAME> "
                "[<BACKING_FILENAME>]\n"); 
        exit(-1);
 }
@@ -61,17 +61,22 @@ int main(int argc, char *argv[])
 {
        int ret = -1, c, backed = 0;
        int sparse =  1;
+       char *fmt = "qcow";
        uint64_t size;
        char filename[MAX_NAME_LEN], bfilename[MAX_NAME_LEN];
+       char *tmpfile;
 
         for(;;) {
-                c = getopt(argc, argv, "hr");
+                c = getopt(argc, argv, "hrf");
                 if (c == -1)
                         break;
                 switch(c) {
                 case 'h':
                         help();
                         exit(0);
+                        break;
+                case 'f':
+                        fmt = argv[optind++];
                         break;
                 case 'r':
                        sparse = 0;
@@ -105,11 +110,16 @@ int main(int argc, char *argv[])
                }
        }
 
-       DFPRINTF("Creating file size %llu, name %s\n",(long long unsigned)size, 
filename);
-       if (!backed)
-               ret = qcow_create(filename,size,NULL,sparse);
-       else
-               ret = qcow_create(filename,size,bfilename,sparse);
+    tmpfile = backed ? bfilename: NULL; 
+    if (!strcmp(fmt, "qcow")) {
+        ret = qcow_create(filename, size, tmpfile, sparse);
+    } else if(!strcmp(fmt, "qcow2")) {
+        ret = qcow2_create(filename, size, tmpfile, sparse);
+    } else {
+        fprintf(stderr,"Unsupport format:%s\n", fmt);
+        exit(-1);
+    } 
+    DFPRINTF("Creating file size %llu, name %s\n",(long long unsigned)size, 
filename);
 
        if (ret < 0)
                DPRINTF("Unable to create QCOW file\n");
diff -r 27e9687c5b3d tools/blktap/drivers/tapdisk.h
--- a/tools/blktap/drivers/tapdisk.h    Tue Jan 13 08:59:49 2009 +0000
+++ b/tools/blktap/drivers/tapdisk.h    Tue Mar 03 04:32:12 2009 -0500
@@ -266,4 +266,7 @@ typedef struct fd_list_entry {
 
 int qcow_create(const char *filename, uint64_t total_size,
                const char *backing_file, int flags);
+
+int qcow2_create(const char *filename, uint64_t total_size,
+               const char *backing_file, int flags);
 #endif /*TAPDISK_H_*/

Attachment: add_format_of_qcow2_to_qcow-create.patch
Description: add_format_of_qcow2_to_qcow-create.patch

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>