Re: [PATCH v5 2/4] block: add the block queue support
On Tue, Aug 09, 2011 at 12:17:50PM +0800, Zhi Yong Wu wrote: The patch introduce one block queue for QEMU block layer. Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com --- block/blk-queue.c | 141 + block/blk-queue.h | 73 +++ 2 files changed, 214 insertions(+), 0 deletions(-) create mode 100644 block/blk-queue.c create mode 100644 block/blk-queue.h diff --git a/block/blk-queue.c b/block/blk-queue.c new file mode 100644 index 000..f36f3e2 --- /dev/null +++ b/block/blk-queue.c @@ -0,0 +1,141 @@ +/* + * QEMU System Emulator queue definition for block layer + * + * Copyright (c) 2011 Zhi Yong Wu zwu.ker...@gmail.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include block_int.h +#include qemu-queue.h +#include block/blk-queue.h + +/* The APIs for block request queue on qemu block layer. + */ + +static void qemu_block_queue_cancel(BlockDriverAIOCB *acb) +{ +qemu_aio_release(acb); +} + +static AIOPool block_queue_pool = { +.aiocb_size = sizeof(struct BlockDriverAIOCB), +.cancel = qemu_block_queue_cancel, +}; + +static void qemu_block_queue_callback(void *opaque, int ret) +{ +BlockDriverAIOCB *acb = opaque; + +qemu_aio_release(acb); +} + +BlockQueue *qemu_new_block_queue(void) +{ +BlockQueue *queue; + +queue = qemu_mallocz(sizeof(BlockQueue)); + +QTAILQ_INIT(queue-requests); + +return queue; +} + +void qemu_del_block_queue(BlockQueue *queue) +{ +BlockIORequest *request, *next; + +QTAILQ_FOREACH_SAFE(request, queue-requests, entry, next) { +QTAILQ_REMOVE(queue-requests, request, entry); +qemu_free(request); +} + +qemu_free(queue); +} + +BlockDriverAIOCB *qemu_block_queue_enqueue(BlockQueue *queue, +BlockDriverState *bs, +BlockRequestHandler *handler, +int64_t sector_num, +QEMUIOVector *qiov, +int nb_sectors, +BlockDriverCompletionFunc *cb, +void *opaque) +{ +BlockIORequest *request; +BlockDriverAIOCB *acb; + +request = qemu_malloc(sizeof(BlockIORequest)); +request-bs = bs; +request-handler = handler; +request-sector_num = sector_num; +request-qiov = qiov; +request-nb_sectors = nb_sectors; +request-cb = cb; +request-opaque = opaque; + +QTAILQ_INSERT_TAIL(queue-requests, request, entry); + +acb = qemu_aio_get(block_queue_pool, bs, + qemu_block_queue_callback, opaque); + +request-acb = acb; + +return acb; +} + +int qemu_block_queue_handler(BlockIORequest *request) +{ +int ret; +BlockDriverAIOCB *res; + +/* indicate this req is from block queue */ +request-bs-req_from_queue = true; + +res = request-handler(request-bs, request-sector_num, + request-qiov, request-nb_sectors, + request-cb, request-opaque); should'nt you return with a failure here if res == NULL? Otherwise qemu_block_queue_callback() gets called which will release the acb. + +if (request-acb) { +qemu_block_queue_callback(request-acb, 0); +} + +ret = (res == NULL) ? 0 : 1; + +return ret; +} RP -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 3/4] block: add block timer and block throttling algorithm
On Tue, Aug 09, 2011 at 12:17:51PM +0800, Zhi Yong Wu wrote: Note: 1.) When bps/iops limits are specified to a small value such as 511 bytes/s, this VM will hang up. We are considering how to handle this senario. 2.) When dd command is issued in guest, if its option bs is set to a large value such as bs=1024K, the result speed will slightly bigger than the limits. For these problems, if you have nice thought, pls let us know.:) Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com --- block.c | 347 +-- block.h |6 +- block_int.h | 30 + 3 files changed, 372 insertions(+), 11 deletions(-) diff --git a/block.c b/block.c index 24a25d5..8fd6643 100644 --- a/block.c +++ b/block.c @@ -29,6 +29,9 @@ #include module.h #include qemu-objects.h +#include qemu-timer.h +#include block/blk-queue.h + #ifdef CONFIG_BSD #include sys/types.h #include sys/stat.h @@ -58,6 +61,13 @@ static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num, static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors); +static bool bdrv_exceed_bps_limits(BlockDriverState *bs, int nb_sectors, +bool is_write, double elapsed_time, uint64_t *wait); +static bool bdrv_exceed_iops_limits(BlockDriverState *bs, bool is_write, +double elapsed_time, uint64_t *wait); +static bool bdrv_exceed_io_limits(BlockDriverState *bs, int nb_sectors, +bool is_write, uint64_t *wait); + static QTAILQ_HEAD(, BlockDriverState) bdrv_states = QTAILQ_HEAD_INITIALIZER(bdrv_states); @@ -90,6 +100,68 @@ int is_windows_drive(const char *filename) } #endif +/* throttling disk I/O limits */ +void bdrv_io_limits_disable(BlockDriverState *bs) +{ +bs-io_limits_enabled = false; +bs-req_from_queue= false; + +if (bs-block_queue) { +qemu_block_queue_flush(bs-block_queue); +qemu_del_block_queue(bs-block_queue); +} + +if (bs-block_timer) { +qemu_del_timer(bs-block_timer); +qemu_free_timer(bs-block_timer); +} + +bs-slice_start[0] = 0; +bs-slice_start[1] = 0; + +bs-slice_end[0] = 0; +bs-slice_end[1] = 0; +} + +static void bdrv_block_timer(void *opaque) +{ +BlockDriverState *bs = opaque; +BlockQueue *queue = bs-block_queue; + +qemu_block_queue_flush(queue); +} + +void bdrv_io_limits_enable(BlockDriverState *bs) +{ +bs-req_from_queue = false; + +bs-block_queue= qemu_new_block_queue(); +bs-block_timer= qemu_new_timer_ns(vm_clock, bdrv_block_timer, bs); + +bs-slice_start[BLOCK_IO_LIMIT_READ] = qemu_get_clock_ns(vm_clock); +bs-slice_start[BLOCK_IO_LIMIT_WRITE] = qemu_get_clock_ns(vm_clock); a minor comment. better to keep the slice_start of the both the READ and WRITE side the same. bs-slice_start[BLOCK_IO_LIMIT_WRITE] = bs-slice_start[BLOCK_IO_LIMIT_READ]; saves a call to qemu_get_clock_ns(). + +bs-slice_end[BLOCK_IO_LIMIT_READ]= + qemu_get_clock_ns(vm_clock) + BLOCK_IO_SLICE_TIME; bs-slice_end[BLOCK_IO_LIMIT_READ] = bs-slice_start[BLOCK_IO_LIMIT_READ] + BLOCK_IO_SLICE_TIME; saves one more call to qemu_get_clock_ns() +bs-slice_end[BLOCK_IO_LIMIT_WRITE] = + qemu_get_clock_ns(vm_clock) + BLOCK_IO_SLICE_TIME; bs-slice_end[BLOCK_IO_LIMIT_WRITE] = bs-slice_start[BLOCK_IO_LIMIT_WRITE] + BLOCK_IO_SLICE_TIME; yet another call saving. +} + +bool bdrv_io_limits_enabled(BlockDriverState *bs) +{ +BlockIOLimit *io_limits = bs-io_limits; +if ((io_limits-bps[BLOCK_IO_LIMIT_READ] == 0) + (io_limits-bps[BLOCK_IO_LIMIT_WRITE] == 0) + (io_limits-bps[BLOCK_IO_LIMIT_TOTAL] == 0) + (io_limits-iops[BLOCK_IO_LIMIT_READ] == 0) + (io_limits-iops[BLOCK_IO_LIMIT_WRITE] == 0) + (io_limits-iops[BLOCK_IO_LIMIT_TOTAL] == 0)) { +return false; +} + +return true; +} can be optimized to: return (io_limits-bps[BLOCK_IO_LIMIT_READ] || io_limits-bps[BLOCK_IO_LIMIT_WRITE] || io_limits-bps[BLOCK_IO_LIMIT_TOTAL] || io_limits-iops[BLOCK_IO_LIMIT_READ] || io_limits-iops[BLOCK_IO_LIMIT_WRITE] || io_limits-iops[BLOCK_IO_LIMIT_TOTAL]); + /* check if the path starts with protocol: */ static int path_has_protocol(const char *path) { @@ -642,6 +714,11 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, bs-change_cb(bs-change_opaque, CHANGE_MEDIA); } +/* throttling disk I/O limits */ +if (bs-io_limits_enabled) { +bdrv_io_limits_enable(bs); +} + return 0; unlink_and_fail: @@ -680,6 +757,16 @@ void bdrv_close(BlockDriverState
Re: KVM: VMX: flush TLB with INVEPT on cpu migration
On Thu, 2009-10-01 at 19:16 -0300, Marcelo Tosatti wrote: It is possible that stale EPTP-tagged mappings are used, if a vcpu migrates to a different pcpu. Set KVM_REQ_TLB_FLUSH in vmx_vcpu_load, when switching pcpus, which will invalidate both VPID and EPT mappings on the next vm-entry. Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index e86f1a6..97f4265 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -708,7 +708,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) if (vcpu-cpu != cpu) { vcpu_clear(vmx); kvm_migrate_timers(vcpu); - vpid_sync_vcpu_all(vmx); + set_bit(KVM_REQ_TLB_FLUSH, vcpu-requests); local_irq_disable(); list_add(vmx-local_vcpus_link, per_cpu(vcpus_on_cpu, cpu)); -- This patch fixes my ept misconfig problem seen very so often while installing sles11 guest. thanks, RP -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] rev7: support colon in filenames
On Tue, 2009-07-21 at 14:42 +0200, Kevin Wolf wrote: Ram Pai schrieb: Problem: It is impossible to feed filenames with the character colon because qemu interprets such names as a protocol. For example filename scsi:0, is interpreted as a protocol by name scsi. This patch allows user to espace colon characters. For example the above filename can now be expressed either as 'scsi\:0' or as file:scsi:0 anything following the file: tag is interpreted verbatin. However if file: tag is omitted then any colon characters in the string must be escaped using backslash. Here are couple of examples: scsi\:0\:abc is a local file scsi:0:abc http\://myweb is a local file by name http://myweb file:scsi:0:abc is a local file scsi:0:abc file:http://myweb is a local file by name http://myweb fat:c:\path\to\dir\:floppy\: is a fat file by name \path\to\dir:floppy: NOTE:The above example cannot be expressed using the file: protocol. Changelog w.r.t to iteration 0: 1) removes flexibility added to nbd semantics eg -- nbd:\:: 2) introduce the file: protocol to indicate local file Changelog w.r.t to iteration 1: 1) generically handles 'file:' protocol in find_protocol 2) centralizes 'filename' pruning before the call to open(). 3) fixes buffer overflow seen in fill_token() 4) adheres to codying style 5) patch against upstream qemu tree Changelog w.r.t to iteration 2: 1) really really fixes buffer overflow seen in fill_token() (if not, beat me :) 2) the centralized 'filename' pruning had a side effect with qcow2 files and other files. Fixed it. _open() is back. Changelog w.r.t to iteration 3: 1) support added to raw-win32.c (i do not have the setup to test this change. Request help with testing) 2) ability to espace option-values containing commas using backslashes eg file=file:abc,, can also be expressed as file=file:abc\, where 'abc,' is a filename 3) fixes a bug (reported by Jan Kiszka) w.r.t support for -snapshot 4) renamed _open() to qemu_open() and removed dependency on PATH_MAX Changelog w.r.t to iteration 4: 1) applies to upstream qemu tree Changelog w.r.t to iteration 5: 1) fixed a issue with backing_filename for qcow2 files, reported by Jamie Lokier. 2) fixed a compile issue with win32-raw.c reported by Blue Swirl. (I do not have the setup to test win32 changes. Request help with testing) Changelog w.r.t to iteration 6: 1) fixed all the issues found with win32. a) changed the call to strnlen() to qemu_strlen() in cutils.c b) fixed the call to CreateFile() in qemu_CreateFile() Signed-off-by: Ram Pai linux...@us.ibm.com block.c | 38 - block/raw-posix.c | 15 block/raw-win32.c | 26 -- block/vvfat.c | 97 +++- cutils.c | 46 + qemu-common.h |2 + qemu-option.c |8 - 7 files changed, 195 insertions(+), 37 deletions(-) diff --git a/block.c b/block.c index 39f726c..da6eaf7 100644 --- a/block.c +++ b/block.c @@ -225,7 +225,6 @@ static BlockDriver *find_protocol(const char *filename) { BlockDriver *drv1; char protocol[128]; -int len; const char *p; #ifdef _WIN32 @@ -233,14 +232,9 @@ static BlockDriver *find_protocol(const char *filename) is_windows_drive_prefix(filename)) return bdrv_find_format(raw); #endif -p = strchr(filename, ':'); -if (!p) +p = prune_strcpy(protocol, sizeof(protocol), filename, ':'); +if (*p != ':') return bdrv_find_format(raw); -len = p - filename; -if (len sizeof(protocol) - 1) -len = sizeof(protocol) - 1; -memcpy(protocol, filename, len); -protocol[len] = '\0'; for(drv1 = first_drv; drv1 != NULL; drv1 = drv1-next) { if (drv1-protocol_name !strcmp(drv1-protocol_name, protocol)) @@ -331,7 +325,6 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, { int ret, open_flags; char tmp_filename[PATH_MAX]; -char backing_filename[PATH_MAX]; bs-read_only = 0; bs-is_temporary = 0; @@ -343,7 +336,6 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, if (flags BDRV_O_SNAPSHOT) { BlockDriverState *bs1; int64_t total_size; -int is_protocol = 0; BlockDriver *bdrv_qcow2; QEMUOptionParameter *options; @@ -359,25 +351,15 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, } total_size = bdrv_getlength(bs1) SECTOR_BITS; -if (bs1
[PATCH] rev8: support colon in filenames
Problem: It is impossible to feed filenames with the character colon because qemu interprets such names as a protocol. For example filename scsi:0, is interpreted as a protocol by name scsi. This patch allows user to espace colon characters. For example the above filename can now be expressed either as 'scsi\:0' or as file:scsi:0 anything following the file: tag is interpreted verbatin. However if file: tag is omitted then any colon characters in the string must be escaped using backslash. Here are couple of examples: scsi\:0\:abc is a local file scsi:0:abc http\://myweb is a local file by name http://myweb file:scsi:0:abc is a local file scsi:0:abc file:http://myweb is a local file by name http://myweb fat:c:\path\to\dir\:floppy\: is a fat file by name \path\to\dir:floppy: NOTE:The above example cannot be expressed using the file: protocol. Changelog w.r.t to iteration 0: 1) removes flexibility added to nbd semantics eg -- nbd:\:: 2) introduce the file: protocol to indicate local file Changelog w.r.t to iteration 1: 1) generically handles 'file:' protocol in find_protocol 2) centralizes 'filename' pruning before the call to open(). 3) fixes buffer overflow seen in fill_token() 4) adheres to codying style 5) patch against upstream qemu tree Changelog w.r.t to iteration 2: 1) really really fixes buffer overflow seen in fill_token() (if not, beat me :) 2) the centralized 'filename' pruning had a side effect with qcow2 files and other files. Fixed it. _open() is back. Changelog w.r.t to iteration 3: 1) support added to raw-win32.c (i do not have the setup to test this change. Request help with testing) 4) ability to espace option-values containing commas using backslashes eg file=file:abc,, can also be expressed as file=file:abc\, where 'abc,' is a filename 3) fixes a bug (reported by Jan Kiszka) w.r.t support for -snapshot 4) renamed _open() to qemu_open() and removed dependency on PATH_MAX Changelog w.r.t to iteration 4: 1) applies to upstream qemu tree Changelog w.r.t to iteration 5: 1) fixed a issue with backing_filename for qcow2 files, reported by Jamie Lokier. 2) fixed a compile issue with win32-raw.c reported by Blue Swirl. (I do not have the setup to test win32 changes. Request help with testing) Changelog w.r.t to iteration 6: 1) fixed all the issues found with win32. a) changed the call to strnlen() to qemu_strlen() in cutils.c b) fixed the call to CreateFile() in qemu_CreateFile() Changelog w.r.t to iteration 7: 1) fixed buffer overflow issues introduced in get_opt_value() to support escaping comma using \ 2) added ability in get_opt_value() to express a backslash character using a backslash character 3) moved qemu_open() into raw driver code and renamed the function as raw_open2() Signed-off-by: Ram Pai linux...@us.ibm.com block.c | 38 - block/raw-posix.c | 34 +++ block/raw-win32.c | 26 -- block/vvfat.c | 97 +++- cutils.c | 26 ++ qemu-common.h |1 + qemu-option.c |6 +++- 7 files changed, 191 insertions(+), 37 deletions(-) diff --git a/block.c b/block.c index 82ffea8..7761dd0 100644 --- a/block.c +++ b/block.c @@ -225,7 +225,6 @@ static BlockDriver *find_protocol(const char *filename) { BlockDriver *drv1; char protocol[128]; -int len; const char *p; #ifdef _WIN32 @@ -233,14 +232,9 @@ static BlockDriver *find_protocol(const char *filename) is_windows_drive_prefix(filename)) return bdrv_find_format(raw); #endif -p = strchr(filename, ':'); -if (!p) +p = prune_strcpy(protocol, sizeof(protocol), filename, ':'); +if (*p != ':') return bdrv_find_format(raw); -len = p - filename; -if (len sizeof(protocol) - 1) -len = sizeof(protocol) - 1; -memcpy(protocol, filename, len); -protocol[len] = '\0'; for(drv1 = first_drv; drv1 != NULL; drv1 = drv1-next) { if (drv1-protocol_name !strcmp(drv1-protocol_name, protocol)) @@ -331,7 +325,6 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, { int ret, open_flags; char tmp_filename[PATH_MAX]; -char backing_filename[PATH_MAX]; bs-read_only = 0; bs-is_temporary = 0; @@ -343,7 +336,6 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, if (flags BDRV_O_SNAPSHOT) { BlockDriverState *bs1; int64_t total_size; -int is_protocol = 0; BlockDriver *bdrv_qcow2; QEMUOptionParameter *options; @@ -359,25 +351,15 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, } total_size = bdrv_getlength(bs1
[PATCH] rev7: support colon in filenames
Problem: It is impossible to feed filenames with the character colon because qemu interprets such names as a protocol. For example filename scsi:0, is interpreted as a protocol by name scsi. This patch allows user to espace colon characters. For example the above filename can now be expressed either as 'scsi\:0' or as file:scsi:0 anything following the file: tag is interpreted verbatin. However if file: tag is omitted then any colon characters in the string must be escaped using backslash. Here are couple of examples: scsi\:0\:abc is a local file scsi:0:abc http\://myweb is a local file by name http://myweb file:scsi:0:abc is a local file scsi:0:abc file:http://myweb is a local file by name http://myweb fat:c:\path\to\dir\:floppy\: is a fat file by name \path\to\dir:floppy: NOTE:The above example cannot be expressed using the file: protocol. Changelog w.r.t to iteration 0: 1) removes flexibility added to nbd semantics eg -- nbd:\:: 2) introduce the file: protocol to indicate local file Changelog w.r.t to iteration 1: 1) generically handles 'file:' protocol in find_protocol 2) centralizes 'filename' pruning before the call to open(). 3) fixes buffer overflow seen in fill_token() 4) adheres to codying style 5) patch against upstream qemu tree Changelog w.r.t to iteration 2: 1) really really fixes buffer overflow seen in fill_token() (if not, beat me :) 2) the centralized 'filename' pruning had a side effect with qcow2 files and other files. Fixed it. _open() is back. Changelog w.r.t to iteration 3: 1) support added to raw-win32.c (i do not have the setup to test this change. Request help with testing) 2) ability to espace option-values containing commas using backslashes eg file=file:abc,, can also be expressed as file=file:abc\, where 'abc,' is a filename 3) fixes a bug (reported by Jan Kiszka) w.r.t support for -snapshot 4) renamed _open() to qemu_open() and removed dependency on PATH_MAX Changelog w.r.t to iteration 4: 1) applies to upstream qemu tree Changelog w.r.t to iteration 5: 1) fixed a issue with backing_filename for qcow2 files, reported by Jamie Lokier. 2) fixed a compile issue with win32-raw.c reported by Blue Swirl. (I do not have the setup to test win32 changes. Request help with testing) Changelog w.r.t to iteration 6: 1) fixed all the issues found with win32. a) changed the call to strnlen() to qemu_strlen() in cutils.c b) fixed the call to CreateFile() in qemu_CreateFile() Signed-off-by: Ram Pai linux...@us.ibm.com block.c | 38 - block/raw-posix.c | 15 block/raw-win32.c | 26 -- block/vvfat.c | 97 +++- cutils.c | 46 + qemu-common.h |2 + qemu-option.c |8 - 7 files changed, 195 insertions(+), 37 deletions(-) diff --git a/block.c b/block.c index 39f726c..da6eaf7 100644 --- a/block.c +++ b/block.c @@ -225,7 +225,6 @@ static BlockDriver *find_protocol(const char *filename) { BlockDriver *drv1; char protocol[128]; -int len; const char *p; #ifdef _WIN32 @@ -233,14 +232,9 @@ static BlockDriver *find_protocol(const char *filename) is_windows_drive_prefix(filename)) return bdrv_find_format(raw); #endif -p = strchr(filename, ':'); -if (!p) +p = prune_strcpy(protocol, sizeof(protocol), filename, ':'); +if (*p != ':') return bdrv_find_format(raw); -len = p - filename; -if (len sizeof(protocol) - 1) -len = sizeof(protocol) - 1; -memcpy(protocol, filename, len); -protocol[len] = '\0'; for(drv1 = first_drv; drv1 != NULL; drv1 = drv1-next) { if (drv1-protocol_name !strcmp(drv1-protocol_name, protocol)) @@ -331,7 +325,6 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, { int ret, open_flags; char tmp_filename[PATH_MAX]; -char backing_filename[PATH_MAX]; bs-read_only = 0; bs-is_temporary = 0; @@ -343,7 +336,6 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, if (flags BDRV_O_SNAPSHOT) { BlockDriverState *bs1; int64_t total_size; -int is_protocol = 0; BlockDriver *bdrv_qcow2; QEMUOptionParameter *options; @@ -359,25 +351,15 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, } total_size = bdrv_getlength(bs1) SECTOR_BITS; -if (bs1-drv bs1-drv-protocol_name) -is_protocol = 1; - bdrv_delete(bs1); get_tmp_filename(tmp_filename, sizeof(tmp_filename)); -/* Real path is meaningless for protocols */ -if (is_protocol) -snprintf(backing_filename, sizeof(backing_filename
Re: [Qemu-devel] [PATCH] rev5: support colon in filenames
On Wed, 2009-07-15 at 18:04 +0300, Blue Swirl wrote: On 7/15/09, Ram Pai linux...@us.ibm.com wrote: Problem: It is impossible to feed filenames with the character colon because qemu interprets such names as a protocol. For example filename scsi:0, is interpreted as a protocol by name scsi. --- a/block/raw-posix.c +++ b/block/raw-posix.c +static int qemu_open(const char *filename, int flags, ...) --- a/block/raw-win32.c +++ b/block/raw-win32.c +fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, I bet this won't compile on win32. yes. good catch. fix is in the next revision(rev 6). However I do not have a setup to compile and test changes in win32-raw.c . I will have to rely on somebody to do the testing. RP -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] rev6: support colon in filenames
Problem: It is impossible to feed filenames with the character colon because qemu interprets such names as a protocol. For example filename scsi:0, is interpreted as a protocol by name scsi. This patch allows user to espace colon characters. For example the above filename can now be expressed either as 'scsi\:0' or as file:scsi:0 anything following the file: tag is interpreted verbatin. However if file: tag is omitted then any colon characters in the string must be escaped using backslash. Here are couple of examples: scsi\:0\:abc is a local file scsi:0:abc http\://myweb is a local file by name http://myweb file:scsi:0:abc is a local file scsi:0:abc file:http://myweb is a local file by name http://myweb fat:c:\path\to\dir\:floppy\: is a fat file by name \path\to\dir:floppy: NOTE:The above example cannot be expressed using the file: protocol. Changelog w.r.t to iteration 0: 1) removes flexibility added to nbd semantics eg -- nbd:\:: 2) introduce the file: protocol to indicate local file Changelog w.r.t to iteration 1: 1) generically handles 'file:' protocol in find_protocol 2) centralizes 'filename' pruning before the call to open(). 3) fixes buffer overflow seen in fill_token() 4) adheres to codying style 5) patch against upstream qemu tree Changelog w.r.t to iteration 2: 1) really really fixes buffer overflow seen in fill_token() (if not, beat me :) 2) the centralized 'filename' pruning had a side effect with qcow2 files and other files. Fixed it. _open() is back. Changelog w.r.t to iteration 3: 1) support added to raw-win32.c (i do not have the setup to test this change. Request help with testing) 2) ability to espace option-values containing commas using backslashes eg file=file:abc,, can also be expressed as file=file:abc\, where 'abc,' is a filename 3) fixes a bug (reported by Jan Kiszka) w.r.t support for -snapshot 4) renamed _open() to qemu_open() and removed dependency on PATH_MAX Changelog w.r.t to iteration 4: 1) applies to upstream qemu tree Changelog w.r.t to iteration 5: 1) fixed a issue with backing_filename for qcow2 files, reported by Jamie Lokier. 2) fixed a compile issue with win32-raw.c reported by Blue Swirl. (I do not have the setup to test win32 changes. Request help with testing) Signed-off-by: Ram Pai linux...@us.ibm.com block.c | 39 block/raw-posix.c | 15 block/raw-win32.c | 26 -- block/vvfat.c | 97 - cutils.c | 46 +++ qemu-common.h |2 + qemu-option.c |8 - 8 files changed, 196 insertions(+), 37 deletions(-) diff --git a/block.c b/block.c index cefbe77..4423c72 100644 --- a/block.c +++ b/block.c @@ -225,7 +225,6 @@ static BlockDriver *find_protocol(const char *filename) { BlockDriver *drv1; char protocol[128]; -int len; const char *p; #ifdef _WIN32 @@ -233,14 +232,9 @@ static BlockDriver *find_protocol(const char *filename) is_windows_drive_prefix(filename)) return bdrv_find_format(raw); #endif -p = strchr(filename, ':'); -if (!p) +p = prune_strcpy(protocol, sizeof(protocol), filename, ':'); +if (*p != ':') return bdrv_find_format(raw); -len = p - filename; -if (len sizeof(protocol) - 1) -len = sizeof(protocol) - 1; -memcpy(protocol, filename, len); -protocol[len] = '\0'; for(drv1 = first_drv; drv1 != NULL; drv1 = drv1-next) { if (drv1-protocol_name !strcmp(drv1-protocol_name, protocol)) @@ -331,7 +325,6 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, { int ret, open_flags; char tmp_filename[PATH_MAX]; -char backing_filename[PATH_MAX]; bs-read_only = 0; bs-is_temporary = 0; @@ -343,7 +336,6 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, if (flags BDRV_O_SNAPSHOT) { BlockDriverState *bs1; int64_t total_size; -int is_protocol = 0; BlockDriver *bdrv_qcow2; QEMUOptionParameter *options; @@ -359,25 +351,15 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, } total_size = bdrv_getlength(bs1) SECTOR_BITS; -if (bs1-drv bs1-drv-protocol_name) -is_protocol = 1; - bdrv_delete(bs1); get_tmp_filename(tmp_filename, sizeof(tmp_filename)); -/* Real path is meaningless for protocols */ -if (is_protocol) -snprintf(backing_filename, sizeof(backing_filename), - %s, filename); -else -realpath(filename, backing_filename); - bdrv_qcow2 = bdrv_find_format(qcow2); options = parse_option_parameters
[PATCH] rev5: support colon in filenames
Problem: It is impossible to feed filenames with the character colon because qemu interprets such names as a protocol. For example filename scsi:0, is interpreted as a protocol by name scsi. This patch allows user to espace colon characters. For example the above filename can now be expressed either as 'scsi\:0' or as file:scsi:0 anything following the file: tag is interpreted verbatin. However if file: tag is omitted then any colon characters in the string must be escaped using backslash. Here are couple of examples: scsi\:0\:abc is a local file scsi:0:abc http\://myweb is a local file by name http://myweb file:scsi:0:abc is a local file scsi:0:abc file:http://myweb is a local file by name http://myweb fat:c:\path\to\dir\:floppy\: is a fat file by name \path\to\dir:floppy: NOTE:The above example cannot be expressed using the file: protocol. Changelog w.r.t to iteration 0: 1) removes flexibility added to nbd semantics eg -- nbd:\:: 2) introduce the file: protocol to indicate local file Changelog w.r.t to iteration 1: 1) generically handles 'file:' protocol in find_protocol 2) centralizes 'filename' pruning before the call to open(). 3) fixes buffer overflow seen in fill_token() 4) adheres to codying style 5) patch against upstream qemu tree Changelog w.r.t to iteration 2: 1) really really fixes buffer overflow seen in fill_token() (if not, beat me :) 2) the centralized 'filename' pruning had a side effect with qcow2 files and other files. Fixed it. _open() is back. Changelog w.r.t to iteration 3: 1) support added to raw-win32.c (i do not have the setup to test this change. Request help with testing) 2) ability to espace option-values containing commas using backslashes eg file=file:abc,, can also be expressed as file=file:abc\, where 'abc,' is a filename 3) fixes a bug (reported by Jan Kiszka) w.r.t support for -snapshot 4) renamed _open() to qemu_open() and removed dependency on PATH_MAX Changelog w.r.t to iteration 4: 1) applies to upstream qemu and qemu-kvm tree Signed-off-by: Ram Pai linux...@us.ibm.com block.c | 30 +++- block/raw-posix.c | 35 ++ block/raw-win32.c | 26 -- block/vvfat.c | 97 - cutils.c | 26 + qemu-common.h |1 + qemu-option.c |8 - 8 files changed, 185 insertions(+), 38 deletions(-) diff --git a/block.c b/block.c index cefbe77..178edcc 100644 --- a/block.c +++ b/block.c @@ -225,7 +225,6 @@ static BlockDriver *find_protocol(const char *filename) { BlockDriver *drv1; char protocol[128]; -int len; const char *p; #ifdef _WIN32 @@ -233,14 +232,9 @@ static BlockDriver *find_protocol(const char *filename) is_windows_drive_prefix(filename)) return bdrv_find_format(raw); #endif -p = strchr(filename, ':'); -if (!p) +p = prune_strcpy(protocol, sizeof(protocol), filename, ':'); +if (*p != ':') return bdrv_find_format(raw); -len = p - filename; -if (len sizeof(protocol) - 1) -len = sizeof(protocol) - 1; -memcpy(protocol, filename, len); -protocol[len] = '\0'; for(drv1 = first_drv; drv1 != NULL; drv1 = drv1-next) { if (drv1-protocol_name !strcmp(drv1-protocol_name, protocol)) @@ -330,8 +324,6 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, BlockDriver *drv) { int ret, open_flags; -char tmp_filename[PATH_MAX]; -char backing_filename[PATH_MAX]; bs-read_only = 0; bs-is_temporary = 0; @@ -343,9 +335,9 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, if (flags BDRV_O_SNAPSHOT) { BlockDriverState *bs1; int64_t total_size; -int is_protocol = 0; BlockDriver *bdrv_qcow2; QEMUOptionParameter *options; +char tmp_filename[PATH_MAX]; /* if snapshot, we create a temporary backing file and open it instead of opening 'filename' directly */ @@ -359,25 +351,15 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, } total_size = bdrv_getlength(bs1) SECTOR_BITS; -if (bs1-drv bs1-drv-protocol_name) -is_protocol = 1; - bdrv_delete(bs1); get_tmp_filename(tmp_filename, sizeof(tmp_filename)); -/* Real path is meaningless for protocols */ -if (is_protocol) -snprintf(backing_filename, sizeof(backing_filename), - %s, filename); -else -realpath(filename, backing_filename); - bdrv_qcow2 = bdrv_find_format(qcow2); options = parse_option_parameters(, bdrv_qcow2-create_options, NULL); set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size
Re: [PATCH] rev5: support colon in filenames
On Wed, 2009-07-15 at 11:30 +0200, Jan Kiszka wrote: Ram Pai wrote: Problem: It is impossible to feed filenames with the character colon because qemu interprets such names as a protocol. For example filename scsi:0, is interpreted as a protocol by name scsi. This patch allows user to espace colon characters. For example the above filename can now be expressed either as 'scsi\:0' or as file:scsi:0 anything following the file: tag is interpreted verbatin. However if file: tag is omitted then any colon characters in the string must be escaped using backslash. Here are couple of examples: scsi\:0\:abc is a local file scsi:0:abc http\://myweb is a local file by name http://myweb file:scsi:0:abc is a local file scsi:0:abc file:http://myweb is a local file by name http://myweb fat:c:\path\to\dir\:floppy\: is a fat file by name \path\to\dir:floppy: NOTE:The above example cannot be expressed using the file: protocol. Changelog w.r.t to iteration 0: 1) removes flexibility added to nbd semantics eg -- nbd:\:: 2) introduce the file: protocol to indicate local file Changelog w.r.t to iteration 1: 1) generically handles 'file:' protocol in find_protocol 2) centralizes 'filename' pruning before the call to open(). 3) fixes buffer overflow seen in fill_token() 4) adheres to codying style 5) patch against upstream qemu tree Changelog w.r.t to iteration 2: 1) really really fixes buffer overflow seen in fill_token() (if not, beat me :) 2) the centralized 'filename' pruning had a side effect with qcow2 files and other files. Fixed it. _open() is back. Changelog w.r.t to iteration 3: 1) support added to raw-win32.c (i do not have the setup to test this change. Request help with testing) 2) ability to espace option-values containing commas using backslashes eg file=file:abc,, can also be expressed as file=file:abc\, where 'abc,' is a filename 3) fixes a bug (reported by Jan Kiszka) w.r.t support for -snapshot Yep, that's fixed in this version. 4) renamed _open() to qemu_open() and removed dependency on PATH_MAX Changelog w.r.t to iteration 4: 1) applies to upstream qemu and qemu-kvm tree Signed-off-by: Ram Pai linux...@us.ibm.com block.c | 30 +++- block/raw-posix.c | 35 ++ block/raw-win32.c | 26 -- block/vvfat.c | 97 - cutils.c | 26 + qemu-common.h |1 + qemu-option.c |8 - 8 files changed, 185 insertions(+), 38 deletions(-) diff --git a/block.c b/block.c ... @@ -359,25 +351,15 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, } total_size = bdrv_getlength(bs1) SECTOR_BITS; -if (bs1-drv bs1-drv-protocol_name) -is_protocol = 1; - bdrv_delete(bs1); get_tmp_filename(tmp_filename, sizeof(tmp_filename)); -/* Real path is meaningless for protocols */ -if (is_protocol) -snprintf(backing_filename, sizeof(backing_filename), - %s, filename); -else -realpath(filename, backing_filename); - This removes realpath without any replacement, right? Did you verify that this doesn't break anything, namely snapshots with relative paths for the backing image? Please check commit a817d93 and provide a reasoning why it's safe to drop it. I have verified with relative paths and it works. After analyzing the code, i came to the conclusion that call to realpath() adds no real value. The logic in bdrv_open2() is something like this bdrv_open2() { if (snapshot) { backup = realpath(filename); filename=generate_a_temp_file(); } drv=parse_and_get_bdrv(filename); drv-bdrv_open(filename); if (backup) { bdrv_open2(backup); } } in the above function, the call to realpath() would have been useful had it changed the current working directory before calling bdrv_open2(backup). It does not. If in case any function within drv-bdrv_open change the cwd, then I expect them to restore before returning. Also drv-bdrv_open() can anyway handle relative paths. Hence I conclude that the call to realpath() adds no value. Do you see a flaw in this logic? RP Jan -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Qemu-devel] Re: [PATCH] rev5: support colon in filenames
On Wed, 2009-07-15 at 19:20 +0100, Jamie Lokier wrote: Ram Pai wrote: I have verified with relative paths and it works. After analyzing the code, i came to the conclusion that call to realpath() adds no real value. The logic in bdrv_open2() is something like this bdrv_open2() { if (snapshot) { backup = realpath(filename); filename=generate_a_temp_file(); } drv=parse_and_get_bdrv(filename); drv-bdrv_open(filename); if (backup) { bdrv_open2(backup); } } in the above function, the call to realpath() would have been useful had it changed the current working directory before calling bdrv_open2(backup). It does not. If in case any function within drv-bdrv_open change the cwd, then I expect them to restore before returning. Also drv-bdrv_open() can anyway handle relative paths. Hence I conclude that the call to realpath() adds no value. Do you see a flaw in this logic? I don't know about snapshot, but when a qcow2 file contains a relative path to it's backing file, QEMU cannot simply open using that relative path, because it's relative to the directory containing the qcow2 file, not QEMU's current directory. I have successfully verified qcow2 files. But then I may not be trying out the exact thing that you are talking about. Can you give me a test case that I can verify. I am pretty sure that the patch would work. However i have not accumulated enough flight time on qemu; so i can be wrong :( And one other thing. Let me know if there a test-suite that I can try for regressions. RP (That said, I find it quite annoying when renaming qcow2 files that there's no easy way to rename their backing files, and it's even worse when moving qcow2 files which refer to backing files in another directory, and _especially_ when the qcow2 file contains an absolute path to the backing file and you're asked to move it to another system which doesn't have those directories.) -- Jamie -- Ram Pai System X Device-Driver Enablement Lead Linux Technology Center Beaverton OR-97006 503-5783752 t/l 7753752 linux...@us.ibm.com -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: qcow2 relative paths (was: [PATCH] rev5: support colon in filenames)
On Wed, 2009-07-15 at 22:04 +0100, Jamie Lokier wrote: Ram Pai wrote: I have successfully verified qcow2 files. But then I may not be trying out the exact thing that you are talking about. Can you give me a test case that I can verify. Commands tried with qemu-0.10.0-1ubuntu1: $ mkdir unlikely_subdir $ cd unlikely_subdir $ qemu-img create -f qcow2 backing.img 10 Formatting 'backing.img', fmt=qcow2, size=10 kB $ qemu-img create -f qcow2 -b ../unlikely_subdir/backing.img main.img 10 Formatting 'main.img', fmt=qcow2, backing_file=../unlikely_subdir/backing.img, size=10 kB $ cd .. $ qemu-img info unlikely_subdir/main.img image: unlikely_subdir/main.img file format: qcow2 virtual size: 10K (10240 bytes) disk size: 16K cluster_size: 4096 highest_alloc: 16384 backing file: ../unlikely_subdir/backing.img (actual path: unlikely_subdir/../unlikely_subdir/backing.img) See especially the actual path line. $ mv unlikely_subdir other_subdir $ ls -l other_subdir total 32 -rw-r--r-- 1 jamie jamie 16384 2009-07-15 21:59 backing.img -rw-r--r-- 1 jamie jamie 16384 2009-07-15 21:59 main.img $ qemu-img info other_subdir/main.img qemu-img: Could not open 'other_subdir/main.img' Turns out that I did introduce a bug by deleting the call to path_combine() before calling bdrv_open() on the backing filename. However the call to realpath() is still not needed. It feels like a kludge introduced to stop path_combine() from munging backing_filename. I will send out yet another revision with the fix. I just dont' know what else I will be breaking without having a regression test harness. :( What an unhelpful error message... There isn't even a way to find out the backing file path which the tool is looking for. Ok. i have introduced a message towards the effect, in the next revision of the patch. Hope that will make things a little easier. I have to go through the all the other mails to understand what has been proposed, and what I need to incorporate. Looks like a tall order. For now i will send out revision 6 in the next few hours. RP And one other thing. Let me know if there a test-suite that I can try for regressions. Sorry, I don't know anything about any QEMU test suites. -- Jamie RP -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] rev4: support colon in filenames
Problem: It is impossible to feed filenames with the character colon because qemu interprets such names as a protocol. For example filename scsi:0, is interpreted as a protocol by name scsi. This patch allows user to espace colon characters. For example the above filename can now be expressed either as 'scsi\:0' or as file:scsi:0 anything following the file: tag is interpreted verbatin. However if file: tag is omitted then any colon characters in the string must be escaped using backslash. Here are couple of examples: scsi\:0\:abc is a local file scsi:0:abc http\://myweb is a local file by name http://myweb file:scsi:0:abc is a local file scsi:0:abc file:http://myweb is a local file by name http://myweb fat:c:\path\to\dir\:floppy\: is a fat file by name \path\to\dir:floppy: NOTE:The above example cannot be expressed using the file: protocol. Changelog w.r.t to iteration 0: 1) removes flexibility added to nbd semantics eg -- nbd:\:: 2) introduce the file: protocol to indicate local file Changelog w.r.t to iteration 1: 1) generically handles 'file:' protocol in find_protocol 2) centralizes 'filename' pruning before the call to open(). 3) fixes buffer overflow seen in fill_token() 4) adheres to codying style 5) patch against upstream qemu tree Changelog w.r.t to iteration 2: 1) really really fixes buffer overflow seen in fill_token() (if not, beat me :) 2) the centralized 'filename' pruning had a side effect with qcow2 files and other files. Fixed it. _open() is back. Changelog w.r.t to iteration 3: 1) support added to raw-win32.c (i do not have the setup to test this change. Request help with testing) 2) ability to espace option values containing commas using backslashes eg file=file:abc,, can also be expressed as file=file:abc\, where 'abc,' is a filename 3) fixes a bug (reported by Jan Kiszka) w.r.t support for -snapshot 4) renamed _open() to qemu_open() and removed dependency on PATH_MAX the patch applies to qemu-kvm tree only. Will port the patch to qemu tree after successful test results. Signed-off-by: Ram Pai linux...@us.ibm.com block.c | 30 +++-- block/raw-posix.c | 35 +++ block/raw-win32.c | 26 -- block/vvfat.c | 97 +++- cutils.c | 26 ++ qemu-common.h |1 + qemu-option.c |8 - 7 files changed, 185 insertions(+), 38 deletions(-) diff --git a/block.c b/block.c index aca5a6d..be10bf9 100644 --- a/block.c +++ b/block.c @@ -225,7 +225,6 @@ static BlockDriver *find_protocol(const char *filename) { BlockDriver *drv1; char protocol[128]; -int len; const char *p; #ifdef _WIN32 @@ -233,14 +232,9 @@ static BlockDriver *find_protocol(const char *filename) is_windows_drive_prefix(filename)) return bdrv_find_format(raw); #endif -p = strchr(filename, ':'); -if (!p) +p = prune_strcpy(protocol, sizeof(protocol), filename, ':'); +if (*p != ':') return bdrv_find_format(raw); -len = p - filename; -if (len sizeof(protocol) - 1) -len = sizeof(protocol) - 1; -memcpy(protocol, filename, len); -protocol[len] = '\0'; for(drv1 = first_drv; drv1 != NULL; drv1 = drv1-next) { if (drv1-protocol_name !strcmp(drv1-protocol_name, protocol)) @@ -330,8 +324,6 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, BlockDriver *drv) { int ret, open_flags; -char tmp_filename[PATH_MAX]; -char backing_filename[PATH_MAX]; bs-read_only = 0; bs-is_temporary = 0; @@ -343,9 +335,9 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, if (flags BDRV_O_SNAPSHOT) { BlockDriverState *bs1; int64_t total_size; -int is_protocol = 0; BlockDriver *bdrv_qcow2; QEMUOptionParameter *options; +char tmp_filename[PATH_MAX]; /* if snapshot, we create a temporary backing file and open it instead of opening 'filename' directly */ @@ -359,25 +351,15 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, } total_size = bdrv_getlength(bs1) SECTOR_BITS; -if (bs1-drv bs1-drv-protocol_name) -is_protocol = 1; - bdrv_delete(bs1); get_tmp_filename(tmp_filename, sizeof(tmp_filename)); -/* Real path is meaningless for protocols */ -if (is_protocol) -snprintf(backing_filename, sizeof(backing_filename), - %s, filename); -else -realpath(filename, backing_filename); - bdrv_qcow2 = bdrv_find_format(qcow2); options = parse_option_parameters(, bdrv_qcow2-create_options, NULL); set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size
[PATCH] rev3: support colon in filenames
Problem: It is impossible to feed filenames with the character colon because qemu interprets such names as a protocol. For example filename scsi:0, is interpreted as a protocol by name scsi. This patch allows user to escape colon characters. For example the above filename can now be expressed either as 'scsi\:0' or as file:scsi:0 anything following the file: tag is interpreted verbatim. However if file: tag is omitted then any colon characters in the string must be escaped using backslash. Here are couple of examples: scsi\:0\:abc is a local file scsi:0:abc http\://myweb is a local file by name http://myweb file:scsi:0:abc is a local file scsi:0:abc file:http://myweb is a local file by name http://myweb fat:c:\path\to\dir\:floppy\: is a fat file by name \path\to\dir:floppy: NOTE:The above example cannot be expressed using the file: protocol. Changelog w.r.t to iteration 0: 1) removes flexibility added to nbd semantics eg -- nbd:\:: 2) introduce the file: protocol to indicate local file Changelog w.r.t to iteration 1: 1) generically handles 'file:' protocol in find_protocol 2) centralizes 'filename' pruning before the call to open(). 3) fixes buffer overflow seen in fill_token() 4) adheres to coding style 5) patch against upstream qemu tree Changelog w.r.t to iteration 2: 1) really really fixes buffer overflow seen in fill_token() 2) the centralized 'filename' pruning had a side effect with qcow2 files and other files. Fixed it. _open() is back. Signed-off-by: Ram Pai linux...@us.ibm.com block.c | 10 + block/raw-posix.c | 15 block/vvfat.c | 100 ++-- cutils.c | 40 + qemu-common.h |2 + 5 files changed, 148 insertions(+), 19 deletions(-) diff --git a/block.c b/block.c index aca5a6d..7ad4dd9 100644 --- a/block.c +++ b/block.c @@ -225,7 +225,6 @@ static BlockDriver *find_protocol(const char *filename) { BlockDriver *drv1; char protocol[128]; -int len; const char *p; #ifdef _WIN32 @@ -233,14 +232,9 @@ static BlockDriver *find_protocol(const char *filename) is_windows_drive_prefix(filename)) return bdrv_find_format(raw); #endif -p = strchr(filename, ':'); -if (!p) +p = prune_strcpy(protocol, 128, filename, ':'); +if (*p != ':') return bdrv_find_format(raw); -len = p - filename; -if (len sizeof(protocol) - 1) -len = sizeof(protocol) - 1; -memcpy(protocol, filename, len); -protocol[len] = '\0'; for(drv1 = first_drv; drv1 != NULL; drv1 = drv1-next) { if (drv1-protocol_name !strcmp(drv1-protocol_name, protocol)) diff --git a/block/raw-posix.c b/block/raw-posix.c index 41bfa37..8a0c0df 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -151,7 +151,7 @@ static int raw_open_common(BlockDriverState *bs, const char *filename, s-open_flags |= O_DSYNC; s-fd = -1; -fd = open(filename, s-open_flags, 0644); +fd = _open(filename, s-open_flags, 0644); if (fd 0) { ret = -errno; if (ret == -EROFS) @@ -844,7 +844,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options) options++; } -fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, +fd = _open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); if (fd 0) return -EIO; @@ -889,6 +889,7 @@ static BlockDriver bdrv_raw = { .bdrv_getlength = raw_getlength, .create_options = raw_create_options, +.protocol_name = file, }; /***/ @@ -985,7 +986,7 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) if ( bsdPath[ 0 ] != '\0' ) { strcat(bsdPath,s0); /* some CDs don't have a partition 0 */ -fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); +fd = _open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); if (fd 0) { bsdPath[strlen(bsdPath)-1] = '1'; } else { @@ -1037,7 +1038,7 @@ static int fd_open(BlockDriverState *bs) #endif return -EIO; } -s-fd = open(bs-filename, s-open_flags ~O_NONBLOCK); +s-fd = _open(bs-filename, s-open_flags ~O_NONBLOCK); if (s-fd 0) { s-fd_error_time = qemu_get_clock(rt_clock); s-fd_got_error = 1; @@ -1133,7 +1134,7 @@ static int hdev_create(const char *filename, QEMUOptionParameter *options) options++; } -fd = open(filename, O_WRONLY | O_BINARY); +fd = _open(filename, O_WRONLY | O_BINARY); if (fd 0) return -EIO; @@ -1239,7 +1240,7 @@ static int floppy_eject(BlockDriverState *bs, int eject_flag) close(s-fd); s-fd = -1; } -fd = open(bs-filename, s-open_flags | O_NONBLOCK); +fd = _open(bs-filename
rev1 [PATCH] support colon in filenames
Problem: It is impossible to feed filenames with the character colon because qemu interprets such names as a protocol. For example a filename scsi:0, is interpreted as a protocol by name scsi. This patch allows user to espace colon characters. For example the above filename can now be expressed either as 'scsi\:0' or as file:scsi:0 anything following the file: tag is interpreted verbatim. However if file: tag is omitted then any colon characters in the string must be escaped using backslash. Here are couple of examples: scsi\:0\:abc is a local file scsi:0:abc http\://myweb is a local file by name http://myweb file:scsi:0:abc is a local file scsi:0:abc file:http://myweb is a local file by name http://myweb Changelog w.r.t to iteration 1: 1) removes flexibility added to nbd semantics eg -- nbd:\:: 2) introduce the file: protocol to indicate local file NOTE: no code changes are needed to handle commas in a filename. As always a comma has to be escaped by a preceding comma. Signed-off-by: Ram Pai linux...@us.ibm.com --- block.c | 16 ++-- block/raw-posix.c | 30 +++--- cutils.c | 26 ++ qemu-common.h |1 + 4 files changed, 56 insertions(+), 17 deletions(-) diff --git a/block.c b/block.c index aca5a6d..0064e22 100644 --- a/block.c +++ b/block.c @@ -225,22 +225,18 @@ static BlockDriver *find_protocol(const char *filename) { BlockDriver *drv1; char protocol[128]; -int len; -const char *p; +const char *f; +int len = strnlen(filename, 128); #ifdef _WIN32 if (is_windows_drive(filename) || is_windows_drive_prefix(filename)) return bdrv_find_format(raw); #endif -p = strchr(filename, ':'); -if (!p) -return bdrv_find_format(raw); -len = p - filename; -if (len sizeof(protocol) - 1) -len = sizeof(protocol) - 1; -memcpy(protocol, filename, len); -protocol[len] = '\0'; +f = fill_token(protocol, len, filename, ':'); +if (*f != ':' || !strcmp(protocol, file)) + return bdrv_find_format(raw); + for(drv1 = first_drv; drv1 != NULL; drv1 = drv1-next) { if (drv1-protocol_name !strcmp(drv1-protocol_name, protocol)) diff --git a/block/raw-posix.c b/block/raw-posix.c index 41bfa37..03d6581 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -124,6 +124,22 @@ static int fd_open(BlockDriverState *bs); static int cdrom_reopen(BlockDriverState *bs); #endif +static int _open(const char *filename, int flags, ...) +{ + char myfile[PATH_MAX]; + const char *f; + va_list ap; + va_start(ap, flags); + + if (!strstart(filename, file:, f)) { + fill_token(myfile, PATH_MAX, filename, '\0'); + return open(myfile, flags, ap); + } else { + return open(f, flags, ap); + } +} + + static int raw_open_common(BlockDriverState *bs, const char *filename, int flags) { @@ -151,7 +167,7 @@ static int raw_open_common(BlockDriverState *bs, const char *filename, s-open_flags |= O_DSYNC; s-fd = -1; -fd = open(filename, s-open_flags, 0644); +fd = _open(filename, s-open_flags, 0644); if (fd 0) { ret = -errno; if (ret == -EROFS) @@ -844,7 +860,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options) options++; } -fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, +fd = _open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); if (fd 0) return -EIO; @@ -985,7 +1001,7 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) if ( bsdPath[ 0 ] != '\0' ) { strcat(bsdPath,s0); /* some CDs don't have a partition 0 */ -fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); +fd = _open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); if (fd 0) { bsdPath[strlen(bsdPath)-1] = '1'; } else { @@ -1037,7 +1053,7 @@ static int fd_open(BlockDriverState *bs) #endif return -EIO; } -s-fd = open(bs-filename, s-open_flags ~O_NONBLOCK); +s-fd = _open(bs-filename, s-open_flags ~O_NONBLOCK); if (s-fd 0) { s-fd_error_time = qemu_get_clock(rt_clock); s-fd_got_error = 1; @@ -1133,7 +1149,7 @@ static int hdev_create(const char *filename, QEMUOptionParameter *options) options++; } -fd = open(filename, O_WRONLY | O_BINARY); +fd = _open(filename, O_WRONLY | O_BINARY); if (fd 0) return -EIO; @@ -1239,7 +1255,7 @@ static int floppy_eject(BlockDriverState *bs, int eject_flag) close(s-fd); s-fd = -1; } -fd = open(bs-filename, s-open_flags | O_NONBLOCK); +fd = _open(bs
rev2 [PATCH] support colon in filenames
Problem: It is impossible to feed filenames with the character colon because qemu interprets such names as a protocol. For example filename scsi:0, is interpreted as a protocol by name scsi. This patch allows user to espace colon characters. For example the above filename can now be expressed either as 'scsi\:0' or as file:scsi:0 anything following the file: tag is interpreted verbatin. However if file: tag is omitted then any colon characters in the string must be escaped using backslash. Here are couple of examples: scsi\:0\:abc is a local file scsi:0:abc http\://myweb is a local file by name http://myweb file:scsi:0:abc is a local file scsi:0:abc file:http://myweb is a local file by name http://myweb Changelog w.r.t to iteration 0: 1) removes flexibility added to nbd semantics eg -- nbd:\:: 2) introduce the file: protocol to indicate local file Changelog w.r.t to iteration 1: 1) generically handles 'file:' protocol in find_protocol 2) centralizes 'filename' pruning before the call to open(). 3) fixes buffer overflow seen in fill_token() 4) adheres to codying style 5) patch against upstream qemu tree Signed-off-by: Ram Pai linux...@us.ibm.com --- block.c | 27 +-- block.h |2 ++ block/dmg.c |2 +- block/raw-posix.c |1 + cutils.c | 26 ++ qemu-common.h |1 + 6 files changed, 48 insertions(+), 11 deletions(-) diff --git a/block.c b/block.c index aca5a6d..3fe9317 100644 --- a/block.c +++ b/block.c @@ -225,7 +225,7 @@ static BlockDriver *find_protocol(const char *filename) { BlockDriver *drv1; char protocol[128]; -int len; +int len = strnlen(filename, 127)+1; const char *p; #ifdef _WIN32 @@ -233,14 +233,9 @@ static BlockDriver *find_protocol(const char *filename) is_windows_drive_prefix(filename)) return bdrv_find_format(raw); #endif -p = strchr(filename, ':'); -if (!p) +p = fill_token(protocol, len, filename, ':'); +if (*p != ':') return bdrv_find_format(raw); -len = p - filename; -if (len sizeof(protocol) - 1) -len = sizeof(protocol) - 1; -memcpy(protocol, filename, len); -protocol[len] = '\0'; for(drv1 = first_drv; drv1 != NULL; drv1 = drv1-next) { if (drv1-protocol_name !strcmp(drv1-protocol_name, protocol)) @@ -414,9 +409,9 @@ 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); +ret = bdrv_open3(bs, filename, open_flags, drv); if ((ret == -EACCES || ret == -EPERM) !(flags BDRV_O_FILE)) { -ret = drv-bdrv_open(bs, filename, open_flags ~BDRV_O_RDWR); +ret = bdrv_open3(bs, filename, open_flags ~BDRV_O_RDWR, drv); bs-read_only = 1; } if (ret 0) { @@ -461,6 +456,18 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, return 0; } +int bdrv_open3(BlockDriverState *bs, const char *filename, int flags, BlockDriver *drv) +{ +char myfile[PATH_MAX]; +const char *f; + +if (!strstart(filename, file:, f)) { +fill_token(myfile, PATH_MAX, filename, '\0'); +return drv-bdrv_open(bs,myfile,flags); +} +return drv-bdrv_open(bs,f,flags); +} + void bdrv_close(BlockDriverState *bs) { if (bs-drv) { diff --git a/block.h b/block.h index 71e87fc..b595772 100644 --- a/block.h +++ b/block.h @@ -58,6 +58,8 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags); int bdrv_open(BlockDriverState *bs, const char *filename, int flags); int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, BlockDriver *drv); +int bdrv_open3(BlockDriverState *bs, const char *filename, int flags, + BlockDriver *drv); void bdrv_close(BlockDriverState *bs); int bdrv_check(BlockDriverState *bs); int bdrv_read(BlockDriverState *bs, int64_t sector_num, diff --git a/block/dmg.c b/block/dmg.c index 262560f..dd98af4 100644 --- a/block/dmg.c +++ b/block/dmg.c @@ -94,7 +94,7 @@ dmg_close: close(s-fd); /* open raw instead */ bs-drv=bdrv_find_format(raw); - return bs-drv-bdrv_open(bs, filename, flags); + return bdrv_open3(bs, filename, flags, bs-drv); } info_begin=read_off(s-fd); if(info_begin==0) diff --git a/block/raw-posix.c b/block/raw-posix.c index fa1a394..31b68ff 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -892,6 +892,7 @@ static BlockDriver bdrv_raw = { .bdrv_getlength = raw_getlength, .create_options = raw_create_options, +.protocol_name = file, }; /***/ diff --git a/cutils.c b/cutils.c index 0623cf7
Re: [PATCH] support colon in filenames
On Thu, 2009-06-25 at 11:14 +0200, Kevin Wolf wrote: Ram Pai schrieb: Copying the qemu-devel mailing list too. On Wed, 2009-06-24 at 09:58 -0700, Ram Pai wrote: Problem: It is impossible to feed filenames with the character colon because qemu interprets such names as a protocol. For example a filename scsi:0, is interpreted as a protocol by name scsi. This patch allows users to espace colon characters. For example the above filename can now be expressed as 'scsi\:0' Here are couple of examples: ndb:\:: is treated as a ndb protocol with a hostname ':' on port scsi\:0\:abc is a local file scsi:0:abc http\://myweb is a local file by name http://myweb nbd\::localhost:2558 is a protocol by name nbd: Is there any use in having a host named : or protocol nbd:? I don't think so. I do not see the utility either. However if one does find a novel use, the syntax is expressive enough. The other examples could be achieved much easier by assigning the file: protocol to raw, so we would have: file:scsi:0:abc file:http://myweb yes. This is something if implemented; would help. But then its another mechanism for expression. It has to be a separate patch built on top of this patch, because you will still need escaping characters like space, comma, etc This solution wasn't accepted last time because it wouldn't solve the problems with other characters like commas (they need to be escaped as double comma on the command line) and that won't be solved by this patch either. This patch does handle commas and any other character as long as it is escaped using backslashes. I just checked the man page and it says that commas in the filename can be escaped by commas :( . Ok i will add that feature to my patch and resend it. Will that be acceptable after that? Thanks, RP Kevin -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] support colon in filenames
Problem: It is impossible to feed filenames with the character colon because qemu interprets such names as a protocol. For example a filename scsi:0, is interpreted as a protocol by name scsi. This patch allows users to espace colon characters. For example the above filename can now be expressed as 'scsi\:0' Here are couple of examples: ndb:\:: is treated as a ndb protocol with a hostname ':' on port scsi\:0\:abc is a local file scsi:0:abc http\://myweb is a local file by name http://myweb nbd\::localhost:2558 is a protocol by name nbd: Signed-off-by: Ram Pai linux...@us.ibm.com --- block.c | 26 +- block/nbd.c | 19 ++- block/raw-posix.c | 24 +--- cutils.c | 22 ++ qemu-common.h |1 + vl.c |3 +-- 6 files changed, 72 insertions(+), 23 deletions(-) diff --git a/block.c b/block.c index aca5a6d..80bded9 100644 --- a/block.c +++ b/block.c @@ -225,22 +225,30 @@ static BlockDriver *find_protocol(const char *filename) { BlockDriver *drv1; char protocol[128]; -int len; -const char *p; +char *p = protocol; +const char *f=filename; +int len = strnlen(filename, 128); #ifdef _WIN32 if (is_windows_drive(filename) || is_windows_drive_prefix(filename)) return bdrv_find_format(raw); #endif -p = strchr(filename, ':'); -if (!p) +while ( f filename+len ) { + if ( *f == ':' ) + break; + if ( *f == '\\') { + f++; + if ( *f == '\0') + break; + } + *p++ = *f++; +} +*p='\0'; + +if (*f != ':') return bdrv_find_format(raw); -len = p - filename; -if (len sizeof(protocol) - 1) -len = sizeof(protocol) - 1; -memcpy(protocol, filename, len); -protocol[len] = '\0'; + for(drv1 = first_drv; drv1 != NULL; drv1 = drv1-next) { if (drv1-protocol_name !strcmp(drv1-protocol_name, protocol)) diff --git a/block/nbd.c b/block/nbd.c index 47d4778..a011cc7 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -64,18 +64,27 @@ static int nbd_open(BlockDriverState *bs, const char* filename, int flags) } else { uint16_t port; -char *p, *r; +char *q, *p, *r; char hostname[128]; pstrcpy(hostname, 128, host); -p = strchr(hostname, ':'); -if (p == NULL) + q=p=hostname; + while ( p hostname+128 ) { + if (*p == ':') + break; + if ( *p == '\\' ) { + p++; + if (*p =='\0') + break; + } + *q++=*p++; + } +if (*p != ':') return -EINVAL; -*p = '\0'; + *q='\0'; p++; - port = strtol(p, r, 0); if (r == p) return -EINVAL; diff --git a/block/raw-posix.c b/block/raw-posix.c index 41bfa37..98ede17 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -124,6 +124,16 @@ static int fd_open(BlockDriverState *bs); static int cdrom_reopen(BlockDriverState *bs); #endif +static int _open(const char *filename, int flags, ...) +{ + char myfile[PATH_MAX]; + va_list ap; + va_start(ap, flags); + return open(esc_string(myfile, PATH_MAX, filename), + flags, ap); +} + + static int raw_open_common(BlockDriverState *bs, const char *filename, int flags) { @@ -151,7 +161,7 @@ static int raw_open_common(BlockDriverState *bs, const char *filename, s-open_flags |= O_DSYNC; s-fd = -1; -fd = open(filename, s-open_flags, 0644); +fd = _open(filename, s-open_flags, 0644); if (fd 0) { ret = -errno; if (ret == -EROFS) @@ -844,7 +854,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options) options++; } -fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, +fd = _open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); if (fd 0) return -EIO; @@ -985,7 +995,7 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) if ( bsdPath[ 0 ] != '\0' ) { strcat(bsdPath,s0); /* some CDs don't have a partition 0 */ -fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); +fd = _open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); if (fd 0) { bsdPath[strlen(bsdPath)-1] = '1'; } else { @@ -1037,7 +1047,7 @@ static int fd_open(BlockDriverState *bs) #endif return -EIO; } -s-fd = open(bs-filename, s-open_flags ~O_NONBLOCK); +s-fd = _open(bs-filename, s-open_flags ~O_NONBLOCK
Re: [PATCH] support colon in filenames
On Wed, 2009-06-24 at 22:38 +0530, Balbir Singh wrote: * Ram Pai linux...@us.ibm.com [2009-06-24 09:58:59]: Problem: It is impossible to feed filenames with the character colon because qemu interprets such names as a protocol. For example a filename scsi:0, is interpreted as a protocol by name scsi. This patch allows users to espace colon characters. For example the above filename can now be expressed as 'scsi\:0' Here are couple of examples: ndb:\:: is treated as a ndb protocol with a hostname ':' on port scsi\:0\:abc is a local file scsi:0:abc http\://myweb is a local file by name http://myweb nbd\::localhost:2558 is a protocol by name nbd: Signed-off-by: Ram Pai linux...@us.ibm.com Are colons useful for filenames? Is there a common use case for this? Yes. files like /dev/disk/by-path/pci-:0b:00.0-sas-phy0:1-0x5000c5000c14b41d:0-lun0-part3 RP -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] support colon in filenames
Copying the qemu-devel mailing list too. On Wed, 2009-06-24 at 09:58 -0700, Ram Pai wrote: Problem: It is impossible to feed filenames with the character colon because qemu interprets such names as a protocol. For example a filename scsi:0, is interpreted as a protocol by name scsi. This patch allows users to espace colon characters. For example the above filename can now be expressed as 'scsi\:0' Here are couple of examples: ndb:\:: is treated as a ndb protocol with a hostname ':' on port scsi\:0\:abc is a local file scsi:0:abc http\://myweb is a local file by name http://myweb nbd\::localhost:2558 is a protocol by name nbd: Signed-off-by: Ram Pai linux...@us.ibm.com --- block.c | 26 +- block/nbd.c | 19 ++- block/raw-posix.c | 24 +--- cutils.c | 22 ++ qemu-common.h |1 + vl.c |3 +-- 6 files changed, 72 insertions(+), 23 deletions(-) diff --git a/block.c b/block.c index aca5a6d..80bded9 100644 --- a/block.c +++ b/block.c @@ -225,22 +225,30 @@ static BlockDriver *find_protocol(const char *filename) { BlockDriver *drv1; char protocol[128]; -int len; -const char *p; +char *p = protocol; +const char *f=filename; +int len = strnlen(filename, 128); #ifdef _WIN32 if (is_windows_drive(filename) || is_windows_drive_prefix(filename)) return bdrv_find_format(raw); #endif -p = strchr(filename, ':'); -if (!p) +while ( f filename+len ) { + if ( *f == ':' ) + break; + if ( *f == '\\') { + f++; + if ( *f == '\0') + break; + } + *p++ = *f++; +} +*p='\0'; + +if (*f != ':') return bdrv_find_format(raw); -len = p - filename; -if (len sizeof(protocol) - 1) -len = sizeof(protocol) - 1; -memcpy(protocol, filename, len); -protocol[len] = '\0'; + for(drv1 = first_drv; drv1 != NULL; drv1 = drv1-next) { if (drv1-protocol_name !strcmp(drv1-protocol_name, protocol)) diff --git a/block/nbd.c b/block/nbd.c index 47d4778..a011cc7 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -64,18 +64,27 @@ static int nbd_open(BlockDriverState *bs, const char* filename, int flags) } else { uint16_t port; -char *p, *r; +char *q, *p, *r; char hostname[128]; pstrcpy(hostname, 128, host); -p = strchr(hostname, ':'); -if (p == NULL) + q=p=hostname; + while ( p hostname+128 ) { + if (*p == ':') + break; + if ( *p == '\\' ) { + p++; + if (*p =='\0') + break; + } + *q++=*p++; + } +if (*p != ':') return -EINVAL; -*p = '\0'; + *q='\0'; p++; - port = strtol(p, r, 0); if (r == p) return -EINVAL; diff --git a/block/raw-posix.c b/block/raw-posix.c index 41bfa37..98ede17 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -124,6 +124,16 @@ static int fd_open(BlockDriverState *bs); static int cdrom_reopen(BlockDriverState *bs); #endif +static int _open(const char *filename, int flags, ...) +{ + char myfile[PATH_MAX]; + va_list ap; + va_start(ap, flags); + return open(esc_string(myfile, PATH_MAX, filename), + flags, ap); +} + + static int raw_open_common(BlockDriverState *bs, const char *filename, int flags) { @@ -151,7 +161,7 @@ static int raw_open_common(BlockDriverState *bs, const char *filename, s-open_flags |= O_DSYNC; s-fd = -1; -fd = open(filename, s-open_flags, 0644); +fd = _open(filename, s-open_flags, 0644); if (fd 0) { ret = -errno; if (ret == -EROFS) @@ -844,7 +854,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options) options++; } -fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, +fd = _open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); if (fd 0) return -EIO; @@ -985,7 +995,7 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) if ( bsdPath[ 0 ] != '\0' ) { strcat(bsdPath,s0); /* some CDs don't have a partition 0 */ -fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); +fd = _open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); if (fd 0) { bsdPath[strlen(bsdPath)-1] = '1'; } else { @@ -1037,7 +1047,7 @@ static int fd_open
Re: kvm: emulation failure
On Mon, 2009-06-22 at 13:12 +0800, Sheng Yang wrote: On Saturday 20 June 2009 03:23:40 Ram Pai wrote: I see this problem with a x86 sles10 guest running on x86_64 intel host. If the guest is reset abruptly and rebooted, some where before grub sequence it hangs and the following message is seen in the logs emulation failed (pagetable) rip 7ed5 66 60 ac 20. I located this instruction sequence in isolinux.bin on the iso ;if that is relevant. I did some analysis and find that there is an ept violation, which is handled and then the next instruction '66 60' is attempted to decode and emulate. But decode fails. kvm continues loops in the kernel in __vcpu_run(). the code path is kvm_run() - __vcpu_run() - vcpu_enter_guest() - kvm_handle_exit() - handle_ept_violation() - kvm_mmu_page_fault() - emulate_instruction() - x86_decode_insn() Hi Ram Seems KVM failed to emulate a unknown instruction. 6660 pushad 0002 AClodsb And PUSHAD have not implemented in x86_emulate.c. Thanks Sheng for your response, Good. that was the conclusion i had reached reading the code. However was not sure whether the (a) the code path should have never reached there or (b) the code must have learnt to emulate pushad. Sounds like (b) is the case. But I am a little curious about why this code path was only triggered when reset. Maybe other issue exists. What do you want me to check? I have seen ept violation code getting triggered a few number of times at various stages. But the one reported above is the only case where the instruction being emulated is 66 60. one more observation: seen only if the /boot partition is reiserfs. I have been unable to reproduce this with /boot being ext3. thanks and let me know, RP -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: kvm: emulation failure
On Mon, 2009-06-22 at 11:26 +0300, Avi Kivity wrote: On 06/22/2009 09:55 AM, Ram Pai wrote: On Mon, 2009-06-22 at 13:12 +0800, Sheng Yang wrote: On Saturday 20 June 2009 03:23:40 Ram Pai wrote: I see this problem with a x86 sles10 guest running on x86_64 intel host. If the guest is reset abruptly and rebooted, some where before grub sequence it hangs and the following message is seen in the logs emulation failed (pagetable) rip 7ed5 66 60 ac 20. I located this instruction sequence in isolinux.bin on the iso ;if that is relevant. I did some analysis and find that there is an ept violation, which is handled and then the next instruction '66 60' is attempted to decode and emulate. But decode fails. kvm continues loops in the kernel in __vcpu_run(). the code path is kvm_run() - __vcpu_run() - vcpu_enter_guest() - kvm_handle_exit() - handle_ept_violation() - kvm_mmu_page_fault() - emulate_instruction() - x86_decode_insn() Hi Ram Seems KVM failed to emulate a unknown instruction. 6660 pushad 0002 AClodsb And PUSHAD have not implemented in x86_emulate.c. Thanks Sheng for your response, Good. that was the conclusion i had reached reading the code. However was not sure whether the (a) the code path should have never reached there or (b) the code must have learnt to emulate pushad. Sounds like (b) is the case. With ept, the only reason to emulate is mmio. It's very unlikely that the guest is using the pusha instruction for mmio, so the guest is probably confused here. Current kvm.git will return an error here, and current qemu-kvm.git will stop the guest on error so we can debug. But the real problem likely started much earlier, I'm not sure we'll get much useful information. Is this problem reproducible? I can reproduce this at will. the latest qem-kvm.git hangs looping in the kernel, spewing out regularly the following message emulation failed (pagetable) rip 7ed5 66 60 ac 20 the way to reproduce it -- install sles10sp2 i386; I suppose one could probably reproduce using a opensuse guest too(though I have not tried myself). After installation, reset the guest through the monitor, and the guest will hang just before grub takes control. Key is to have the --cdrom iso on the command line. But I am a little curious about why this code path was only triggered when reset. Maybe other issue exists. What do you want me to check? I have seen ept violation code getting triggered a few number of times at various stages. But the one reported above is the only case where the instruction being emulated is 66 60. one more observation: seen only if the /boot partition is reiserfs. I have been unable to reproduce this with /boot being ext3. Please try it with current sources and post the output of 'info registers' in the monitor. EAX=0080 EBX= ECX= EDX= ESI=aa1a EDI=0004cd0c EBP= ESP=d562 EIP=9e67 EFL=00033282 [--S] CPL=3 II=0 A20=1 SMM=0 HLT=0 ES = f300 CS = f300 SS =99e9 00099e90 f300 DS = f300 FS = f300 GS = f300 LDT= 8200 TR =0080 fffbd000 2088 8b00 GDT= 00040620 000f IDT= 03ff CR0=0010 CR2= CR3= CR4= DR0= DR1= DR2= DR3= DR6=0ff0 DR7=0400 FCW=037f FSW= [ST=0] FTW=00 MXCSR= FPR0= FPR1= FPR2= FPR3= FPR4= FPR5= FPR6= FPR7= XMM00= XMM01= XMM02= XMM03= XMM04= XMM05= XMM06= XMM07= RP -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
kvm: emulation failure
I see this problem with a x86 sles10 guest running on x86_64 intel host. If the guest is reset abruptly and rebooted, some where before grub sequence it hangs and the following message is seen in the logs emulation failed (pagetable) rip 7ed5 66 60 ac 20. I located this instruction sequence in isolinux.bin on the iso ;if that is relevant. I did some analysis and find that there is an ept violation, which is handled and then the next instruction '66 60' is attempted to decode and emulate. But decode fails. kvm continues loops in the kernel in __vcpu_run(). the code path is kvm_run() - __vcpu_run() - vcpu_enter_guest() - kvm_handle_exit() - handle_ept_violation() - kvm_mmu_page_fault() - emulate_instruction() - x86_decode_insn() Any insights here on how to fix the problem is appreciated. And if a fix already exists even better :) thanks, RP -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html