All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] add format of qcow2 to qcow-create
@ 2009-03-03 12:36 Zhang, Yang
  2009-03-03 12:48 ` Daniel P. Berrange
  0 siblings, 1 reply; 3+ messages in thread
From: Zhang, Yang @ 2009-03-03 12:36 UTC (permalink / raw)
  To: keir.fraser@eu.citrix.com; +Cc: xen-devel@lists.xensource.com

[-- Attachment #1: Type: text/plain, Size: 6245 bytes --]

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@intel.com>

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 #2: add_format_of_qcow2_to_qcow-create.patch --]
[-- Type: application/octet-stream, Size: 6067 bytes --]

add the qcow2 to qcow-create

add new cmdline -f format for qcow-create. Only support format:
qcow, qcow2. Using qcow default.

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

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 #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] add format of qcow2 to qcow-create
  2009-03-03 12:36 [PATCH] add format of qcow2 to qcow-create Zhang, Yang
@ 2009-03-03 12:48 ` Daniel P. Berrange
  2009-03-04  1:23   ` Zhang, Yang
  0 siblings, 1 reply; 3+ messages in thread
From: Daniel P. Berrange @ 2009-03-03 12:48 UTC (permalink / raw)
  To: Zhang, Yang; +Cc: xen-devel@lists.xensource.com, keir.fraser@eu.citrix.com

On Tue, Mar 03, 2009 at 08:36:37PM +0800, Zhang, Yang wrote:
> Hi
> 	this patch enable the qcow-create to create qcow2 image by using the cmdline -f qcow2.
> 	please to review it.

Why do we need a 'qcow-create' command at all, when 'qemu-img' can create
all the formats supported by both the IOEMU and this qcow-create tool ?

Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: [PATCH] add format of qcow2 to qcow-create
  2009-03-03 12:48 ` Daniel P. Berrange
@ 2009-03-04  1:23   ` Zhang, Yang
  0 siblings, 0 replies; 3+ messages in thread
From: Zhang, Yang @ 2009-03-04  1:23 UTC (permalink / raw)
  To: Daniel P. Berrange
  Cc: xen-devel@lists.xensource.com, keir.fraser@eu.citrix.com

Hi
	We use the 'qcow-create' in our test script .And now we want it to support the qcow2 format.
And I don't kown why using the 'qcow-create' tools instead of 'qemu-img'.

Best Regards
--yang

Daniel P. Berrange wrote:
> On Tue, Mar 03, 2009 at 08:36:37PM +0800, Zhang, Yang wrote:
>> Hi
>> 	this patch enable the qcow-create to create qcow2 image by using
>> 	the cmdline -f qcow2. please to review it.
> 
> Why do we need a 'qcow-create' command at all, when 'qemu-img' can
> create all the formats supported by both the IOEMU and this
> qcow-create tool ? 
> 
> Daniel
>>> Red Hat, Engineering, London   -o-  
>>> http://people.redhat.com/berrange/ :| http://libvirt.org  -o- 
>>> http://virt-manager.org  -o-  http://ovirt.org :|
>>> http://autobuild.org       -o-        
>>> http://search.cpan.org/~danberr/ :| GnuPG: 7D3B9505  -o-  F3C9 553F
>>> A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|  

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-03-04  1:23 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-03 12:36 [PATCH] add format of qcow2 to qcow-create Zhang, Yang
2009-03-03 12:48 ` Daniel P. Berrange
2009-03-04  1:23   ` Zhang, Yang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.