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 Signed-off-by: Ram Pai <linuxram@us.ibm.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
		
							parent
							
								
									ab4e5602a8
								
							
						
					
					
						commit
						707c0dbc97
					
				
							
								
								
									
										27
									
								
								block.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								block.c
									
									
									
									
									
								
							@ -225,7 +225,7 @@ static BlockDriver *find_protocol(const char *filename)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    BlockDriver *drv1;
 | 
					    BlockDriver *drv1;
 | 
				
			||||||
    char protocol[128];
 | 
					    char protocol[128];
 | 
				
			||||||
    int len;
 | 
					    int len = strnlen(filename, 127)+1;
 | 
				
			||||||
    const char *p;
 | 
					    const char *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
@ -233,14 +233,9 @@ static BlockDriver *find_protocol(const char *filename)
 | 
				
			|||||||
        is_windows_drive_prefix(filename))
 | 
					        is_windows_drive_prefix(filename))
 | 
				
			||||||
        return bdrv_find_format("raw");
 | 
					        return bdrv_find_format("raw");
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    p = strchr(filename, ':');
 | 
					    p = fill_token(protocol, len, filename, ':');
 | 
				
			||||||
    if (!p)
 | 
					    if (*p != ':')
 | 
				
			||||||
        return bdrv_find_format("raw");
 | 
					        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) {
 | 
					    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
 | 
				
			||||||
        if (drv1->protocol_name &&
 | 
					        if (drv1->protocol_name &&
 | 
				
			||||||
            !strcmp(drv1->protocol_name, protocol))
 | 
					            !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);
 | 
					        open_flags = BDRV_O_RDWR | (flags & BDRV_O_CACHE_MASK);
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
 | 
					        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)) {
 | 
					    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;
 | 
					        bs->read_only = 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (ret < 0) {
 | 
					    if (ret < 0) {
 | 
				
			||||||
@ -461,6 +456,18 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
 | 
				
			|||||||
    return 0;
 | 
					    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)
 | 
					void bdrv_close(BlockDriverState *bs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (bs->drv) {
 | 
					    if (bs->drv) {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								block.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								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_open(BlockDriverState *bs, const char *filename, int flags);
 | 
				
			||||||
int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
 | 
					int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
 | 
				
			||||||
               BlockDriver *drv);
 | 
					               BlockDriver *drv);
 | 
				
			||||||
 | 
					int bdrv_open3(BlockDriverState *bs, const char *filename, int flags,
 | 
				
			||||||
 | 
					               BlockDriver *drv);
 | 
				
			||||||
void bdrv_close(BlockDriverState *bs);
 | 
					void bdrv_close(BlockDriverState *bs);
 | 
				
			||||||
int bdrv_check(BlockDriverState *bs);
 | 
					int bdrv_check(BlockDriverState *bs);
 | 
				
			||||||
int bdrv_read(BlockDriverState *bs, int64_t sector_num,
 | 
					int bdrv_read(BlockDriverState *bs, int64_t sector_num,
 | 
				
			||||||
 | 
				
			|||||||
@ -94,7 +94,7 @@ dmg_close:
 | 
				
			|||||||
	close(s->fd);
 | 
						close(s->fd);
 | 
				
			||||||
	/* open raw instead */
 | 
						/* open raw instead */
 | 
				
			||||||
	bs->drv=bdrv_find_format("raw");
 | 
						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);
 | 
					    info_begin=read_off(s->fd);
 | 
				
			||||||
    if(info_begin==0)
 | 
					    if(info_begin==0)
 | 
				
			||||||
 | 
				
			|||||||
@ -892,6 +892,7 @@ static BlockDriver bdrv_raw = {
 | 
				
			|||||||
    .bdrv_getlength = raw_getlength,
 | 
					    .bdrv_getlength = raw_getlength,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .create_options = raw_create_options,
 | 
					    .create_options = raw_create_options,
 | 
				
			||||||
 | 
					    .protocol_name = "file",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/***********************************************/
 | 
					/***********************************************/
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										26
									
								
								cutils.c
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								cutils.c
									
									
									
									
									
								
							@ -24,6 +24,32 @@
 | 
				
			|||||||
#include "qemu-common.h"
 | 
					#include "qemu-common.h"
 | 
				
			||||||
#include "host-utils.h"
 | 
					#include "host-utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * fill first 'len' characters of 'buff' with pruned
 | 
				
			||||||
 | 
					 * contents of 'str' delimited by the character 'c'.
 | 
				
			||||||
 | 
					 * Escape character '\' is pruned off.
 | 
				
			||||||
 | 
					 * Return pointer to the delimiting character.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					const char *fill_token(char *buf, const int len, const char *str, const char c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    const char *p=str;
 | 
				
			||||||
 | 
					    char *q=buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (p < str+len-1) {
 | 
				
			||||||
 | 
					    if (*p == c)
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					        if (*p == '\\') {
 | 
				
			||||||
 | 
					            p++;
 | 
				
			||||||
 | 
					            if (*p == '\0')
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        *q++ = *p++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    *q='\0';
 | 
				
			||||||
 | 
					    return p;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pstrcpy(char *buf, int buf_size, const char *str)
 | 
					void pstrcpy(char *buf, int buf_size, const char *str)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int c;
 | 
					    int c;
 | 
				
			||||||
 | 
				
			|||||||
@ -104,6 +104,7 @@ void qemu_get_timedate(struct tm *tm, int offset);
 | 
				
			|||||||
int qemu_timedate_diff(struct tm *tm);
 | 
					int qemu_timedate_diff(struct tm *tm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* cutils.c */
 | 
					/* 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);
 | 
					void pstrcpy(char *buf, int buf_size, const char *str);
 | 
				
			||||||
char *pstrcat(char *buf, int buf_size, const char *s);
 | 
					char *pstrcat(char *buf, int buf_size, const char *s);
 | 
				
			||||||
int strstart(const char *str, const char *val, const char **ptr);
 | 
					int strstart(const char *str, const char *val, const char **ptr);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user