From: Kevin Wolf <mail@kevin-wolf.de>
To: linuxram@us.ibm.com
Cc: Anthony Liguori <aliguori@us.ibm.com>,
qemu-devel@nongnu.org, kvm-devel <kvm@vger.kernel.org>
Subject: [Qemu-devel] Re: rev1 [PATCH] support colon in filenames
Date: Fri, 26 Jun 2009 09:45:17 +0200 [thread overview]
Message-ID: <4A447C8D.5000104@kevin-wolf.de> (raw)
In-Reply-To: <1245998284.6278.99.camel@localhost>
Ram Pai schrieb:
> 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:\::9999
> 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 <linuxram@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(-)
Okay, so some points beforehand: This is a change that should be made in
upstream qemu, not qemu-kvm. So you should base your patch on qemu, it
currently doesn't apply cleanly there.
Also, please take a look at the CODING_STYLE file. Whitespace and braces
are the points I noticed, maybe there are more.
> 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");
There is no reason to special-case "file:". You should just set
bdrv_raw.protocol_name = "file" and let the generic code handle it.
> +
> 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);
> + }
> +}
Passing ap to open doesn't look quite right to me...
> +
> +
> 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->filename, s->open_flags | O_NONBLOCK);
> if (fd >= 0) {
> if (ioctl(fd, FDEJECT, 0) < 0)
> perror("FDEJECT");
> @@ -1399,7 +1415,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;
I don't like this, honestly. Is there no chance to do the unescaping at
one central place instead of n - 1 place and forgetting the nth one?
> diff --git a/cutils.c b/cutils.c
> index 6ea0c49..f6d5bf5 100644
> --- a/cutils.c
> +++ b/cutils.c
> @@ -24,6 +24,32 @@
> #include "qemu-common.h"
> #include "host-utils.h"
>
> +/*
> + * fill buffer 'buff' with the contents of the string 'str' delimited by
> + * the character 'c'. If delimiter not found in 'len' bytes of the string
> + * assume '\0' as the default delimiter.
> + * Return pointer to the delimiting character
> + */
> +const char *fill_token(char *buf, int len, const char *str, char c)
> +{
> + const char *p=str;
> + char *q=buf;
> +
> + while (p < str+len) {
> + if (*p == c)
> + break;
> + if (*p == '\\' ) {
> + p++;
> + if (*p == '\0')
> + break;
> + }
> + *q++ = *p++;
> + }
> + *q='\0';
If we left the while loop because len is exhausted, this is a buffer
overflow.
In the other case, you will read beyond the end of str because you only
check for \0 after a backslash (actually, your code doesn't, but future
callers will as it is highly unusual for a string function to ignore \0).
> + return p;
> +}
> +
> +
> void pstrcpy(char *buf, int buf_size, const char *str)
> {
> int c;
> diff --git a/qemu-common.h b/qemu-common.h
> index 2dcb224..8916502 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 */
> +const char *fill_token(char *buf, int buf_size, const char *str, char);
> 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);
>
>
Kevin
next prev parent reply other threads:[~2009-06-26 7:46 UTC|newest]
Thread overview: 61+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1245862739.6278.7.camel@localhost>
2009-06-24 17:57 ` [Qemu-devel] Re: [PATCH] support colon in filenames Ram Pai
2009-06-25 9:14 ` Kevin Wolf
2009-06-25 17:52 ` Ram Pai
2009-06-26 6:53 ` Kevin Wolf
2009-06-26 6:38 ` [Qemu-devel] rev1 " Ram Pai
2009-06-26 7:45 ` Kevin Wolf [this message]
2009-06-27 0:41 ` [Qemu-devel] rev2 " Ram Pai
2009-07-02 5:08 ` [Qemu-devel] [PATCH] rev3: " Ram Pai
2009-07-02 8:52 ` Kevin Wolf
2009-07-02 12:52 ` Anthony Liguori
2009-07-02 13:18 ` Kevin Wolf
2009-07-08 8:30 ` [Qemu-devel] [PATCH] rev4: " Ram Pai
2009-07-08 15:05 ` [Qemu-devel] " Jan Kiszka
2009-07-10 13:31 ` Anthony Liguori
2009-07-15 7:51 ` [Qemu-devel] [PATCH] rev5: " Ram Pai
2009-07-15 9:30 ` [Qemu-devel] " Jan Kiszka
2009-07-15 17:03 ` Ram Pai
2009-07-15 18:20 ` Jamie Lokier
2009-07-15 18:44 ` Ram Pai
2009-07-15 21:04 ` [Qemu-devel] qcow2 relative paths (was: [PATCH] rev5: support colon in filenames) Jamie Lokier
2009-07-15 21:14 ` [Qemu-devel] Re: qcow2 relative paths Jan Kiszka
2009-07-16 2:28 ` [Qemu-devel] Re: qcow2 relative paths (was: [PATCH] rev5: support colon in filenames) Ram Pai
2009-07-16 7:38 ` [Qemu-devel] Re: qcow2 relative paths Kevin Wolf
2009-07-16 7:51 ` Ram Pai
2009-07-16 7:39 ` [Qemu-devel] [PATCH] rev6: support colon in filenames Ram Pai
2009-07-17 23:17 ` [Qemu-devel] [PATCH] rev7: " Ram Pai
2009-07-21 12:42 ` [Qemu-devel] " Kevin Wolf
2009-08-06 6:27 ` Ram Pai
2009-08-06 6:47 ` [Qemu-devel] [PATCH] rev8: " Ram Pai
2009-07-15 15:04 ` [Qemu-devel] [PATCH] rev5: " Blue Swirl
2009-07-15 15:14 ` Anthony Liguori
2009-07-15 15:29 ` Blue Swirl
2009-07-15 15:40 ` Anthony Liguori
2009-07-15 16:42 ` Kevin Wolf
2009-07-15 17:47 ` Michael S. Tsirkin
2009-07-16 10:57 ` Amit Shah
2009-07-16 13:43 ` Markus Armbruster
2009-07-16 14:10 ` Anthony Liguori
2009-07-16 15:13 ` Gerd Hoffmann
2009-07-16 15:12 ` Gerd Hoffmann
2009-07-15 15:34 ` Kevin Wolf
2009-07-15 15:41 ` Anthony Liguori
2009-07-15 15:52 ` Paul Brook
2009-07-15 16:03 ` Gerd Hoffmann
2009-07-15 16:08 ` Paul Brook
2009-07-16 7:39 ` Ram Pai
2009-07-16 7:43 ` Kevin Wolf
2009-07-15 18:14 ` [Qemu-devel] [PATCH] rev3: " Jamie Lokier
2009-07-15 20:54 ` Jan Kiszka
2009-07-15 21:36 ` Jamie Lokier
2009-07-15 21:42 ` Jan Kiszka
2009-07-15 22:00 ` Jamie Lokier
2009-07-15 22:16 ` Anthony Liguori
2009-07-15 22:39 ` Jamie Lokier
2009-07-15 22:41 ` Anthony Liguori
2009-07-15 22:51 ` Jamie Lokier
2009-07-16 0:03 ` Anthony Liguori
2009-07-16 7:20 ` Jan Kiszka
2009-07-16 7:16 ` Jan Kiszka
2009-07-16 8:01 ` Kevin Wolf
2009-07-16 23:53 ` Paul Brook
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4A447C8D.5000104@kevin-wolf.de \
--to=mail@kevin-wolf.de \
--cc=aliguori@us.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linuxram@us.ibm.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).