[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 6/9] sheepdog: accept URIs
From: |
Stefan Hajnoczi |
Subject: |
[Qemu-devel] [PATCH 6/9] sheepdog: accept URIs |
Date: |
Mon, 4 Mar 2013 10:15:28 +0100 |
From: MORITA Kazutaka <address@hidden>
The URI syntax is consistent with the NBD and Gluster syntax. The
syntax is
sheepdog[+tcp]://[host:port]/vdiname[#snapid|#tag]
Signed-off-by: MORITA Kazutaka <address@hidden>
Signed-off-by: Stefan Hajnoczi <address@hidden>
---
block/sheepdog.c | 139 +++++++++++++++++++++++++++++++++++++++++--------------
qemu-doc.texi | 16 +++----
qemu-options.hx | 18 ++-----
3 files changed, 117 insertions(+), 56 deletions(-)
diff --git a/block/sheepdog.c b/block/sheepdog.c
index 51e75ad..bfa8a00 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -13,6 +13,7 @@
*/
#include "qemu-common.h"
+#include "qemu/uri.h"
#include "qemu/error-report.h"
#include "qemu/sockets.h"
#include "block/block_int.h"
@@ -816,8 +817,52 @@ static int get_sheep_fd(BDRVSheepdogState *s)
return fd;
}
+static int sd_parse_uri(BDRVSheepdogState *s, const char *filename,
+ char *vdi, uint32_t *snapid, char *tag)
+{
+ URI *uri;
+ QueryParams *qp = NULL;
+ int ret = 0;
+
+ uri = uri_parse(filename);
+ if (!uri) {
+ return -EINVAL;
+ }
+
+ if (uri->path == NULL || !strcmp(uri->path, "/")) {
+ ret = -EINVAL;
+ goto out;
+ }
+ pstrcpy(vdi, SD_MAX_VDI_LEN, uri->path + 1);
+
+ /* sheepdog[+tcp]://[host:port]/vdiname */
+ s->addr = g_strdup(uri->server ?: SD_DEFAULT_ADDR);
+ if (uri->port) {
+ s->port = g_strdup_printf("%d", uri->port);
+ } else {
+ s->port = g_strdup(SD_DEFAULT_PORT);
+ }
+
+ /* snapshot tag */
+ if (uri->fragment) {
+ *snapid = strtoul(uri->fragment, NULL, 10);
+ if (*snapid == 0) {
+ pstrcpy(tag, SD_MAX_VDI_TAG_LEN, uri->fragment);
+ }
+ } else {
+ *snapid = CURRENT_VDI_ID; /* search current vdi */
+ }
+
+out:
+ if (qp) {
+ query_params_free(qp);
+ }
+ uri_free(uri);
+ return ret;
+}
+
/*
- * Parse a filename
+ * Parse a filename (old syntax)
*
* filename must be one of the following formats:
* 1. [vdiname]
@@ -836,9 +881,11 @@ static int get_sheep_fd(BDRVSheepdogState *s)
static int parse_vdiname(BDRVSheepdogState *s, const char *filename,
char *vdi, uint32_t *snapid, char *tag)
{
- char *p, *q;
- int nr_sep;
+ char *p, *q, *uri;
+ const char *host_spec, *vdi_spec;
+ int nr_sep, ret;
+ strstart(filename, "sheepdog:", (const char **)&filename);
p = q = g_strdup(filename);
/* count the number of separators */
@@ -851,38 +898,32 @@ static int parse_vdiname(BDRVSheepdogState *s, const char
*filename,
}
p = q;
- /* use the first two tokens as hostname and port number. */
+ /* use the first two tokens as host_spec. */
if (nr_sep >= 2) {
- s->addr = p;
+ host_spec = p;
p = strchr(p, ':');
- *p++ = '\0';
-
- s->port = p;
+ p++;
p = strchr(p, ':');
*p++ = '\0';
} else {
- s->addr = NULL;
- s->port = 0;
+ host_spec = "";
}
- pstrcpy(vdi, SD_MAX_VDI_LEN, p);
+ vdi_spec = p;
- p = strchr(vdi, ':');
+ p = strchr(vdi_spec, ':');
if (p) {
- *p++ = '\0';
- *snapid = strtoul(p, NULL, 10);
- if (*snapid == 0) {
- pstrcpy(tag, SD_MAX_VDI_TAG_LEN, p);
- }
- } else {
- *snapid = CURRENT_VDI_ID; /* search current vdi */
+ *p++ = '#';
}
- if (s->addr == NULL) {
- g_free(q);
- }
+ uri = g_strdup_printf("sheepdog://%s/%s", host_spec, vdi_spec);
- return 0;
+ ret = sd_parse_uri(s, uri, vdi, snapid, tag);
+
+ g_free(q);
+ g_free(uri);
+
+ return ret;
}
static int find_vdi_name(BDRVSheepdogState *s, char *filename, uint32_t snapid,
@@ -1097,16 +1138,19 @@ static int sd_open(BlockDriverState *bs, const char
*filename, int flags)
uint32_t snapid;
char *buf = NULL;
- strstart(filename, "sheepdog:", (const char **)&filename);
-
QLIST_INIT(&s->inflight_aio_head);
QLIST_INIT(&s->pending_aio_head);
s->fd = -1;
memset(vdi, 0, sizeof(vdi));
memset(tag, 0, sizeof(tag));
- if (parse_vdiname(s, filename, vdi, &snapid, tag) < 0) {
- ret = -EINVAL;
+
+ if (strstr(filename, "://")) {
+ ret = sd_parse_uri(s, filename, vdi, &snapid, tag);
+ } else {
+ ret = parse_vdiname(s, filename, vdi, &snapid, tag);
+ }
+ if (ret < 0) {
goto out;
}
s->fd = get_sheep_fd(s);
@@ -1275,17 +1319,17 @@ static int sd_create(const char *filename,
QEMUOptionParameter *options)
char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];
uint32_t snapid;
bool prealloc = false;
- const char *vdiname;
s = g_malloc0(sizeof(BDRVSheepdogState));
- strstart(filename, "sheepdog:", &vdiname);
-
memset(vdi, 0, sizeof(vdi));
memset(tag, 0, sizeof(tag));
- if (parse_vdiname(s, vdiname, vdi, &snapid, tag) < 0) {
- error_report("invalid filename");
- ret = -EINVAL;
+ if (strstr(filename, "://")) {
+ ret = sd_parse_uri(s, filename, vdi, &snapid, tag);
+ } else {
+ ret = parse_vdiname(s, filename, vdi, &snapid, tag);
+ }
+ if (ret < 0) {
goto out;
}
@@ -1392,6 +1436,7 @@ static void sd_close(BlockDriverState *bs)
qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL);
closesocket(s->fd);
g_free(s->addr);
+ g_free(s->port);
}
static int64_t sd_getlength(BlockDriverState *bs)
@@ -2054,7 +2099,7 @@ static QEMUOptionParameter sd_create_options[] = {
{ NULL }
};
-BlockDriver bdrv_sheepdog = {
+static BlockDriver bdrv_sheepdog = {
.format_name = "sheepdog",
.protocol_name = "sheepdog",
.instance_size = sizeof(BDRVSheepdogState),
@@ -2079,8 +2124,34 @@ BlockDriver bdrv_sheepdog = {
.create_options = sd_create_options,
};
+static BlockDriver bdrv_sheepdog_tcp = {
+ .format_name = "sheepdog",
+ .protocol_name = "sheepdog+tcp",
+ .instance_size = sizeof(BDRVSheepdogState),
+ .bdrv_file_open = sd_open,
+ .bdrv_close = sd_close,
+ .bdrv_create = sd_create,
+ .bdrv_getlength = sd_getlength,
+ .bdrv_truncate = sd_truncate,
+
+ .bdrv_co_readv = sd_co_readv,
+ .bdrv_co_writev = sd_co_writev,
+ .bdrv_co_flush_to_disk = sd_co_flush_to_disk,
+
+ .bdrv_snapshot_create = sd_snapshot_create,
+ .bdrv_snapshot_goto = sd_snapshot_goto,
+ .bdrv_snapshot_delete = sd_snapshot_delete,
+ .bdrv_snapshot_list = sd_snapshot_list,
+
+ .bdrv_save_vmstate = sd_save_vmstate,
+ .bdrv_load_vmstate = sd_load_vmstate,
+
+ .create_options = sd_create_options,
+};
+
static void bdrv_sheepdog_init(void)
{
bdrv_register(&bdrv_sheepdog);
+ bdrv_register(&bdrv_sheepdog_tcp);
}
block_init(bdrv_sheepdog_init);
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 747e052..2083e29 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -830,7 +830,7 @@ QEMU-based virtual machines.
You can create a Sheepdog disk image with the command:
@example
-qemu-img create sheepdog:@var{image} @var{size}
+qemu-img create sheepdog:///@var{image} @var{size}
@end example
where @var{image} is the Sheepdog image name and @var{size} is its
size.
@@ -838,29 +838,29 @@ size.
To import the existing @var{filename} to Sheepdog, you can use a
convert command.
@example
-qemu-img convert @var{filename} sheepdog:@var{image}
+qemu-img convert @var{filename} sheepdog:///@var{image}
@end example
You can boot from the Sheepdog disk image with the command:
@example
-qemu-system-i386 sheepdog:@var{image}
+qemu-system-i386 sheepdog:///@var{image}
@end example
You can also create a snapshot of the Sheepdog image like qcow2.
@example
-qemu-img snapshot -c @var{tag} sheepdog:@var{image}
+qemu-img snapshot -c @var{tag} sheepdog:///@var{image}
@end example
where @var{tag} is a tag name of the newly created snapshot.
To boot from the Sheepdog snapshot, specify the tag name of the
snapshot.
@example
-qemu-system-i386 sheepdog:@var{image}:@var{tag}
+qemu-system-i386 sheepdog:///@address@hidden
@end example
You can create a cloned image from the existing snapshot.
@example
-qemu-img create -b sheepdog:@var{base}:@var{tag} sheepdog:@var{image}
+qemu-img create -b sheepdog:///@address@hidden sheepdog:///@var{image}
@end example
where @var{base} is a image name of the source snapshot and @var{tag}
is its tag name.
@@ -868,8 +868,8 @@ is its tag name.
If the Sheepdog daemon doesn't run on the local host, you need to
specify one of the Sheepdog servers to connect to.
@example
-qemu-img create sheepdog:@var{hostname}:@var{port}:@var{image} @var{size}
-qemu-system-i386 sheepdog:@var{hostname}:@var{port}:@var{image}
+qemu-img create sheepdog://@var{hostname}:@var{port}/@var{image} @var{size}
+qemu-system-i386 sheepdog://@var{hostname}:@var{port}/@var{image}
@end example
@node disk_images_iscsi
diff --git a/qemu-options.hx b/qemu-options.hx
index 797d992..e8fb78c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2099,23 +2099,13 @@ QEMU supports using either local sheepdog devices or
remote networked
devices.
Syntax for specifying a sheepdog device
address@hidden @list
-``sheepdog:<vdiname>''
-
-``sheepdog:<vdiname>:<snapid>''
-
-``sheepdog:<vdiname>:<tag>''
-
-``sheepdog:<host>:<port>:<vdiname>''
-
-``sheepdog:<host>:<port>:<vdiname>:<snapid>''
-
-``sheepdog:<host>:<port>:<vdiname>:<tag>''
address@hidden table
address@hidden
+sheepdog[+tcp]://[host:port]/vdiname[#snapid|#tag]
address@hidden example
Example
@example
-qemu-system-i386 --drive file=sheepdog:192.0.2.1:30000:MyVirtualMachine
+qemu-system-i386 --drive file=sheepdog://192.0.2.1:30000/MyVirtualMachine
@end example
See also @url{http://http://www.osrg.net/sheepdog/}.
--
1.8.1.4
[Qemu-devel] [PATCH 1/9] ide/macio: Fix macio DMA initialisation., Stefan Hajnoczi, 2013/03/04
[Qemu-devel] [PATCH 2/9] virtio-blk: fix unplug + virsh reboot, Stefan Hajnoczi, 2013/03/04
[Qemu-devel] [PATCH 5/9] move socket_set_nodelay to osdep.c, Stefan Hajnoczi, 2013/03/04
[Qemu-devel] [PATCH 4/9] slirp/tcp_subr.c: fix coding style in tcp_connect, Stefan Hajnoczi, 2013/03/04
[Qemu-devel] [PATCH 6/9] sheepdog: accept URIs,
Stefan Hajnoczi <=
[Qemu-devel] [PATCH 7/9] sheepdog: use inet_connect to simplify connect code, Stefan Hajnoczi, 2013/03/04
[Qemu-devel] [PATCH 9/9] block: for HMP commit() operations on 'all', skip non-COW drives, Stefan Hajnoczi, 2013/03/04
[Qemu-devel] [PATCH 8/9] sheepdog: add support for connecting to unix domain socket, Stefan Hajnoczi, 2013/03/04