From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LCE3a-0007wL-9z for qemu-devel@nongnu.org; Mon, 15 Dec 2008 09:04:22 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LCE3Z-0007v3-5L for qemu-devel@nongnu.org; Mon, 15 Dec 2008 09:04:21 -0500 Received: from [199.232.76.173] (port=51312 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LCE3Z-0007um-00 for qemu-devel@nongnu.org; Mon, 15 Dec 2008 09:04:21 -0500 Received: from mx2.redhat.com ([66.187.237.31]:49212) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LCE3Y-0005mz-4b for qemu-devel@nongnu.org; Mon, 15 Dec 2008 09:04:20 -0500 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id mBFE4Gcv000798 for ; Mon, 15 Dec 2008 09:04:16 -0500 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id mBFE4FKZ004585 for ; Mon, 15 Dec 2008 09:04:15 -0500 Received: from [10.35.1.184] (dhcp-1-184.tlv.redhat.com [10.35.1.184]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id mBFE4DiQ022902 for ; Mon, 15 Dec 2008 09:04:14 -0500 Message-ID: <494663E4.3020409@redhat.com> Date: Mon, 15 Dec 2008 16:04:20 +0200 From: Shahar Frank MIME-Version: 1.0 Subject: [Qemu-devel][PATCH] Qemu image over raw devices Content-Type: multipart/mixed; boundary="------------040700020502050707030006" Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a multi-part message in MIME format. --------------040700020502050707030006 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi, The following patch enables QEMU to create and use images with any format on top of a raw device. Note that -f is not enough for bcking files support. The patch includes the following: 1. The check for block devices is weaken so you can override it by specifying a protocol 2. If a protocol exists but not found in the protocols list, the logic falls back to image type probing. This means use can write "probe:filename" or just ":filename" Note that if regular file/device path names are used, the previous behavior is kept. lvcreate -L 5G -n base store dd bs=32k if=win.qcow2 of=/dev/store/base ./qemu-img info :/dev/store/base lvcreate -L 2G -n l2 store ./qemu-img create -b :/dev/store/base -f qcow2 /dev/store/l2 ./x86_64-softmmu/qemu-system-x86_64 -hda :/dev/store/l2 -L pc-bios/ lvcreate -L 2G -n l3 store ./qemu-img create -b :/dev/store/l2 -f qcow2 /dev/store/l3 ./x86_64-softmmu/qemu-system-x86_64 -hda :/dev/store/l3 -L pc-bios/ Signed-off-by: Shahar Frank diff --git a/block.c b/block.c index 28d63d7..cbf9968 100644 --- a/block.c +++ b/block.c @@ -226,6 +226,17 @@ static int is_windows_drive(const char *filename) } #endif +static const char *raw_filename(const char *filename) +{ + char *_filename; + + _filename = strchr(filename, ':'); + if (_filename) + return _filename + 1; + else + return filename; +} + static BlockDriver *find_protocol(const char *filename) { BlockDriver *drv1; @@ -267,25 +278,28 @@ static BlockDriver *find_image_format(const char *filename) recognized as a host CDROM */ if (strstart(filename, "/dev/cdrom", NULL)) return &bdrv_host_device; + drv = find_protocol(filename); + + if (drv == &bdrv_raw) { #ifdef _WIN32 - if (is_windows_drive(filename)) - return &bdrv_host_device; + if (is_windows_drive(filename)) + return &bdrv_host_device; #else - { - struct stat st; - if (stat(filename, &st) >= 0 && - (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) { - return &bdrv_host_device; - } - } + { + struct stat st; + if (stat(filename, &st) >= 0 && + (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) { + return &bdrv_host_device; + } + } #endif + } - drv = find_protocol(filename); /* no need to test disk image formats for vvfat */ if (drv == &bdrv_vvfat) return drv; - ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY); + ret = bdrv_file_open(&bs, raw_filename(filename), BDRV_O_RDONLY); if (ret < 0) return NULL; ret = bdrv_pread(bs, 0, buf, sizeof(buf)); @@ -335,6 +349,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, int ret, open_flags; char tmp_filename[PATH_MAX]; char backing_filename[PATH_MAX]; + char const *_filename; bs->read_only = 0; bs->is_temporary = 0; @@ -403,9 +418,12 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, open_flags = BDRV_O_RDWR | (flags & BDRV_O_CACHE_MASK); else open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT); - ret = drv->bdrv_open(bs, filename, open_flags); + + _filename = raw_filename(filename); + + ret = drv->bdrv_open(bs, _filename, open_flags); if ((ret == -EACCES || ret == -EPERM) && !(flags & BDRV_O_FILE)) { - ret = drv->bdrv_open(bs, filename, open_flags & ~BDRV_O_RDWR); + ret = drv->bdrv_open(bs, _filename, open_flags & ~BDRV_O_RDWR); bs->read_only = 1; } if (ret < 0) { diff --git a/qemu-img.c b/qemu-img.c --------------040700020502050707030006 Content-Type: text/plain; name="qemu-image-over-raw.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="qemu-image-over-raw.patch" diff --git a/block.c b/block.c index 28d63d7..cbf9968 100644 --- a/block.c +++ b/block.c @@ -226,6 +226,17 @@ static int is_windows_drive(const char *filename) } #endif +static const char *raw_filename(const char *filename) +{ + char *_filename; + + _filename = strchr(filename, ':'); + if (_filename) + return _filename + 1; + else + return filename; +} + static BlockDriver *find_protocol(const char *filename) { BlockDriver *drv1; @@ -267,25 +278,28 @@ static BlockDriver *find_image_format(const char *filename) recognized as a host CDROM */ if (strstart(filename, "/dev/cdrom", NULL)) return &bdrv_host_device; + drv = find_protocol(filename); + + if (drv == &bdrv_raw) { #ifdef _WIN32 - if (is_windows_drive(filename)) - return &bdrv_host_device; + if (is_windows_drive(filename)) + return &bdrv_host_device; #else - { - struct stat st; - if (stat(filename, &st) >= 0 && - (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) { - return &bdrv_host_device; - } - } + { + struct stat st; + if (stat(filename, &st) >= 0 && + (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) { + return &bdrv_host_device; + } + } #endif + } - drv = find_protocol(filename); /* no need to test disk image formats for vvfat */ if (drv == &bdrv_vvfat) return drv; - ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY); + ret = bdrv_file_open(&bs, raw_filename(filename), BDRV_O_RDONLY); if (ret < 0) return NULL; ret = bdrv_pread(bs, 0, buf, sizeof(buf)); @@ -335,6 +349,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, int ret, open_flags; char tmp_filename[PATH_MAX]; char backing_filename[PATH_MAX]; + char const *_filename; bs->read_only = 0; bs->is_temporary = 0; @@ -403,9 +418,12 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, open_flags = BDRV_O_RDWR | (flags & BDRV_O_CACHE_MASK); else open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT); - ret = drv->bdrv_open(bs, filename, open_flags); + + _filename = raw_filename(filename); + + ret = drv->bdrv_open(bs, _filename, open_flags); if ((ret == -EACCES || ret == -EPERM) && !(flags & BDRV_O_FILE)) { - ret = drv->bdrv_open(bs, filename, open_flags & ~BDRV_O_RDWR); + ret = drv->bdrv_open(bs, _filename, open_flags & ~BDRV_O_RDWR); bs->read_only = 1; } if (ret < 0) { diff --git a/qemu-img.c b/qemu-img.c --------------040700020502050707030006--