diff mbox

support colon in filenames

Message ID 1245862739.6278.7.camel@localhost (mailing list archive)
State New, archived
Headers show

Commit Message

Ram Pai June 24, 2009, 4:58 p.m. UTC
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:\::9999  is treated as a ndb protocol with a hostname ':' on port 9999
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 <linuxram@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(-)


 

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Balbir Singh June 24, 2009, 5:08 p.m. UTC | #1
* Ram Pai <linuxram@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:\::9999  is treated as a ndb protocol with a hostname ':' on port 9999
> 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 <linuxram@us.ibm.com>

Are colons useful for filenames? Is there a common use case for this?
Amit Shah June 24, 2009, 5:26 p.m. UTC | #2
On (Wed) Jun 24 2009 [09:58:59], 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'

Eduardo (CC'ed) had a patch as well:

http://thread.gmane.org/gmane.comp.emulators.qemu/39229/focus=39229

		Amit
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Amit Shah June 24, 2009, 5:27 p.m. UTC | #3
(Actually add Eduardo to CC)

On (Wed) Jun 24 2009 [22:56:59], Amit Shah wrote:
> On (Wed) Jun 24 2009 [09:58:59], 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'
> 
> Eduardo (CC'ed) had a patch as well:
> 
> http://thread.gmane.org/gmane.comp.emulators.qemu/39229/focus=39229

		Amit
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ram Pai June 24, 2009, 5:30 p.m. UTC | #4
On Wed, 2009-06-24 at 22:38 +0530, Balbir Singh wrote:
> * Ram Pai <linuxram@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:\::9999  is treated as a ndb protocol with a hostname ':' on port 9999
> > 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 <linuxram@us.ibm.com>
> 
> Are colons useful for filenames? Is there a common use case for this?

Yes. files like
 
/dev/disk/by-path/pci-0000: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 majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ram Pai June 24, 2009, 5:57 p.m. UTC | #5
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:\::9999  is treated as a ndb protocol with a hostname ':' on port 9999
> 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 <linuxram@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);
>          if (s->fd < 0) {
>              s->fd_error_time = qemu_get_clock(rt_clock);
>              s->fd_got_error = 1;
> @@ -1133,7 +1143,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 +1249,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, s->open_flags | O_NONBLOCK);
>      if (fd >= 0) {
>          if (ioctl(fd, FDEJECT, 0) < 0)
>              perror("FDEJECT");
> @@ -1399,7 +1409,7 @@ static int cdrom_reopen(BlockDriverState *bs)
>       */
>      if (s->fd >= 0)
>          close(s->fd);
> -    fd = open(bs->filename, s->open_flags, 0644);
> +    fd = _open(bs->filename, s->open_flags, 0644);
>      if (fd < 0) {
>          s->fd = -1;
>          return -EIO;
> diff --git a/cutils.c b/cutils.c
> index 6ea0c49..63c196d 100644
> --- a/cutils.c
> +++ b/cutils.c
> @@ -24,6 +24,28 @@
>  #include "qemu-common.h"
>  #include "host-utils.h"
> 
> +/*
> + * prune escape character '\'
> + */
> +char *esc_string(char *buf, int buf_size, const char *str)
> +{
> +        const char *p=str;
> +        int len = strlen(str);
> +        char *q=buf;
> +
> +	len = (buf_size < len) ? buf_size: len;
> +        while (p < str+len) {
> +                if (*p == '\\') {
> +                        p++;
> +			if (*p == '\0')
> +				break;
> +		}
> +                *q++ = *p++;
> +        }
> +        *q='\0';
> +	return buf;
> +}
> +
>  void pstrcpy(char *buf, int buf_size, const char *str)
>  {
>      int c;
> diff --git a/qemu-common.h b/qemu-common.h
> index 2dcb224..1e510dc 100644
> --- a/qemu-common.h
> +++ b/qemu-common.h
> @@ -104,6 +104,7 @@ void qemu_get_timedate(struct tm *tm, int offset);
>  int qemu_timedate_diff(struct tm *tm);
> 
>  /* cutils.c */
> +char *esc_string(char *buf, int buf_size, const char *str);
>  void pstrcpy(char *buf, int buf_size, const char *str);
>  char *pstrcat(char *buf, int buf_size, const char *s);
>  int strstart(const char *str, const char *val, const char **ptr);
> diff --git a/vl.c b/vl.c
> index 7278999..5d7b024 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -2583,8 +2583,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
>      else if (cache == 3) /* not specified */
>          bdrv_flags |= BDRV_O_CACHE_DEF;
>      if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
> -        fprintf(stderr, "qemu: could not open disk image %s\n",
> -                        file);
> +        fprintf(stderr, "qemu: could not open disk image %s\n", file);
>          return -1;
>      }
>      if (bdrv_key_required(bdrv))
> 
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Balbir Singh June 24, 2009, 6:31 p.m. UTC | #6
* Ram Pai <linuxram@us.ibm.com> [2009-06-24 10:30:00]:

> On Wed, 2009-06-24 at 22:38 +0530, Balbir Singh wrote:
> > * Ram Pai <linuxram@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:\::9999  is treated as a ndb protocol with a hostname ':' on port 9999
> > > 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 <linuxram@us.ibm.com>
> > 
> > Are colons useful for filenames? Is there a common use case for this?
> 
> Yes. files like
> 
> /dev/disk/by-path/pci-0000:0b:00.0-sas-phy0:1-0x5000c5000c14b41d:0-lun0-part3
>

Yes, that does make sense. Thanks!
Kevin Wolf June 25, 2009, 9:14 a.m. UTC | #7
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:\::9999  is treated as a ndb protocol with a hostname ':' on port 9999
>> 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. 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

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.

Kevin
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ram Pai June 25, 2009, 5:52 p.m. UTC | #8
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:\::9999  is treated as a ndb protocol with a hostname ':' on port 9999
> >> 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 majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kevin Wolf June 26, 2009, 6:53 a.m. UTC | #9
Ram Pai schrieb:
> 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:\::9999  is treated as a ndb protocol with a hostname ':' on port 9999
>>>> 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

The problem with the handling of colon, comma and space is that there
isn't one central place where they are used in some other way and could
be escaped.

As you know, colons are interpreted when extracting the protocol from
the file name, so somewhere in block.c. Commas are interpreted when
separating options, somewhere in vl.c. Spaces, I think, aren't a problem
in qemu itself but must be properly escaped in the shell. I think you
see why it's difficult to handle all cases uniformly.

>> 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. 

Try it, it works with no change on your side. Commas are handled
elsewhere. It's just that you still need to say "file=foo,,bar" instead
of "file=foo\,bar" because otherwise it would be split up into two
options "file=foo\" and "bar".

Kevin
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

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);
         if (s->fd < 0) {
             s->fd_error_time = qemu_get_clock(rt_clock);
             s->fd_got_error = 1;
@@ -1133,7 +1143,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 +1249,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, s->open_flags | O_NONBLOCK);
     if (fd >= 0) {
         if (ioctl(fd, FDEJECT, 0) < 0)
             perror("FDEJECT");
@@ -1399,7 +1409,7 @@  static int cdrom_reopen(BlockDriverState *bs)
      */
     if (s->fd >= 0)
         close(s->fd);
-    fd = open(bs->filename, s->open_flags, 0644);
+    fd = _open(bs->filename, s->open_flags, 0644);
     if (fd < 0) {
         s->fd = -1;
         return -EIO;
diff --git a/cutils.c b/cutils.c
index 6ea0c49..63c196d 100644
--- a/cutils.c
+++ b/cutils.c
@@ -24,6 +24,28 @@ 
 #include "qemu-common.h"
 #include "host-utils.h"
 
+/*
+ * prune escape character '\'
+ */
+char *esc_string(char *buf, int buf_size, const char *str)
+{
+        const char *p=str;
+        int len = strlen(str);
+        char *q=buf;
+
+	len = (buf_size < len) ? buf_size: len;
+        while (p < str+len) {
+                if (*p == '\\') {
+                        p++;
+			if (*p == '\0')
+				break;
+		}
+                *q++ = *p++;
+        }
+        *q='\0';
+	return buf;
+}
+
 void pstrcpy(char *buf, int buf_size, const char *str)
 {
     int c;
diff --git a/qemu-common.h b/qemu-common.h
index 2dcb224..1e510dc 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -104,6 +104,7 @@  void qemu_get_timedate(struct tm *tm, int offset);
 int qemu_timedate_diff(struct tm *tm);
 
 /* cutils.c */
+char *esc_string(char *buf, int buf_size, const char *str);
 void pstrcpy(char *buf, int buf_size, const char *str);
 char *pstrcat(char *buf, int buf_size, const char *s);
 int strstart(const char *str, const char *val, const char **ptr);
diff --git a/vl.c b/vl.c
index 7278999..5d7b024 100644
--- a/vl.c
+++ b/vl.c
@@ -2583,8 +2583,7 @@  int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
     else if (cache == 3) /* not specified */
         bdrv_flags |= BDRV_O_CACHE_DEF;
     if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
-        fprintf(stderr, "qemu: could not open disk image %s\n",
-                        file);
+        fprintf(stderr, "qemu: could not open disk image %s\n", file);
         return -1;
     }
     if (bdrv_key_required(bdrv))