nbd: accept URIs
The URI syntax is consistent with the Gluster syntax. Export names are specified in the path, preceded by one or more (otherwise unused) slashes. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
d04b0bbbc9
commit
1d7d2a9d21
98
block/nbd.c
98
block/nbd.c
@ -28,6 +28,7 @@
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "nbd.h"
|
||||
#include "uri.h"
|
||||
#include "block_int.h"
|
||||
#include "module.h"
|
||||
#include "qemu_socket.h"
|
||||
@ -69,6 +70,69 @@ typedef struct BDRVNBDState {
|
||||
char *export_name; /* An NBD server may export several devices */
|
||||
} BDRVNBDState;
|
||||
|
||||
static int nbd_parse_uri(BDRVNBDState *s, const char *filename)
|
||||
{
|
||||
URI *uri;
|
||||
const char *p;
|
||||
QueryParams *qp = NULL;
|
||||
int ret = 0;
|
||||
|
||||
uri = uri_parse(filename);
|
||||
if (!uri) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* transport */
|
||||
if (!strcmp(uri->scheme, "nbd")) {
|
||||
s->is_unix = false;
|
||||
} else if (!strcmp(uri->scheme, "nbd+tcp")) {
|
||||
s->is_unix = false;
|
||||
} else if (!strcmp(uri->scheme, "nbd+unix")) {
|
||||
s->is_unix = true;
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
p = uri->path ? uri->path : "/";
|
||||
p += strspn(p, "/");
|
||||
if (p[0]) {
|
||||
s->export_name = g_strdup(p);
|
||||
}
|
||||
|
||||
qp = query_params_parse(uri->query);
|
||||
if (qp->n > 1 || (s->is_unix && !qp->n) || (!s->is_unix && qp->n)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (s->is_unix) {
|
||||
/* nbd+unix:///export?socket=path */
|
||||
if (uri->server || uri->port || strcmp(qp->p[0].name, "socket")) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
s->host_spec = g_strdup(qp->p[0].value);
|
||||
} else {
|
||||
/* nbd[+tcp]://host:port/export */
|
||||
if (!uri->server) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (!uri->port) {
|
||||
uri->port = NBD_DEFAULT_PORT;
|
||||
}
|
||||
s->host_spec = g_strdup_printf("%s:%d", uri->server, uri->port);
|
||||
}
|
||||
|
||||
out:
|
||||
if (qp) {
|
||||
query_params_free(qp);
|
||||
}
|
||||
uri_free(uri);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nbd_config(BDRVNBDState *s, const char *filename)
|
||||
{
|
||||
char *file;
|
||||
@ -77,6 +141,10 @@ static int nbd_config(BDRVNBDState *s, const char *filename)
|
||||
const char *unixpath;
|
||||
int err = -EINVAL;
|
||||
|
||||
if (strstr(filename, "://")) {
|
||||
return nbd_parse_uri(s, filename);
|
||||
}
|
||||
|
||||
file = g_strdup(filename);
|
||||
|
||||
export_name = strstr(file, EN_OPTSTR);
|
||||
@ -495,6 +563,33 @@ static int64_t nbd_getlength(BlockDriverState *bs)
|
||||
|
||||
static BlockDriver bdrv_nbd = {
|
||||
.format_name = "nbd",
|
||||
.protocol_name = "nbd",
|
||||
.instance_size = sizeof(BDRVNBDState),
|
||||
.bdrv_file_open = nbd_open,
|
||||
.bdrv_co_readv = nbd_co_readv,
|
||||
.bdrv_co_writev = nbd_co_writev,
|
||||
.bdrv_close = nbd_close,
|
||||
.bdrv_co_flush_to_os = nbd_co_flush,
|
||||
.bdrv_co_discard = nbd_co_discard,
|
||||
.bdrv_getlength = nbd_getlength,
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_nbd_tcp = {
|
||||
.format_name = "nbd",
|
||||
.protocol_name = "nbd+tcp",
|
||||
.instance_size = sizeof(BDRVNBDState),
|
||||
.bdrv_file_open = nbd_open,
|
||||
.bdrv_co_readv = nbd_co_readv,
|
||||
.bdrv_co_writev = nbd_co_writev,
|
||||
.bdrv_close = nbd_close,
|
||||
.bdrv_co_flush_to_os = nbd_co_flush,
|
||||
.bdrv_co_discard = nbd_co_discard,
|
||||
.bdrv_getlength = nbd_getlength,
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_nbd_unix = {
|
||||
.format_name = "nbd",
|
||||
.protocol_name = "nbd+unix",
|
||||
.instance_size = sizeof(BDRVNBDState),
|
||||
.bdrv_file_open = nbd_open,
|
||||
.bdrv_co_readv = nbd_co_readv,
|
||||
@ -503,12 +598,13 @@ static BlockDriver bdrv_nbd = {
|
||||
.bdrv_co_flush_to_os = nbd_co_flush,
|
||||
.bdrv_co_discard = nbd_co_discard,
|
||||
.bdrv_getlength = nbd_getlength,
|
||||
.protocol_name = "nbd",
|
||||
};
|
||||
|
||||
static void bdrv_nbd_init(void)
|
||||
{
|
||||
bdrv_register(&bdrv_nbd);
|
||||
bdrv_register(&bdrv_nbd_tcp);
|
||||
bdrv_register(&bdrv_nbd_unix);
|
||||
}
|
||||
|
||||
block_init(bdrv_nbd_init);
|
||||
|
@ -610,14 +610,14 @@ QEMU can access directly to block device exported using the Network Block Device
|
||||
protocol.
|
||||
|
||||
@example
|
||||
qemu-system-i386 linux.img -hdb nbd:my_nbd_server.mydomain.org:1024
|
||||
qemu-system-i386 linux.img -hdb nbd://my_nbd_server.mydomain.org:1024/
|
||||
@end example
|
||||
|
||||
If the NBD server is located on the same host, you can use an unix socket instead
|
||||
of an inet socket:
|
||||
|
||||
@example
|
||||
qemu-system-i386 linux.img -hdb nbd:unix:/tmp/my_socket
|
||||
qemu-system-i386 linux.img -hdb nbd+unix://?socket=/tmp/my_socket
|
||||
@end example
|
||||
|
||||
In this case, the block device must be exported using qemu-nbd:
|
||||
@ -631,17 +631,26 @@ The use of qemu-nbd allows to share a disk between several guests:
|
||||
qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
and then you can use it with two guests:
|
||||
@example
|
||||
qemu-system-i386 linux1.img -hdb nbd:unix:/tmp/my_socket
|
||||
qemu-system-i386 linux2.img -hdb nbd:unix:/tmp/my_socket
|
||||
qemu-system-i386 linux1.img -hdb nbd+unix://?socket=/tmp/my_socket
|
||||
qemu-system-i386 linux2.img -hdb nbd+unix://?socket=/tmp/my_socket
|
||||
@end example
|
||||
|
||||
If the nbd-server uses named exports (since NBD 2.9.18), you must use the
|
||||
"exportname" option:
|
||||
If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's
|
||||
own embedded NBD server), you must specify an export name in the URI:
|
||||
@example
|
||||
qemu-system-i386 -cdrom nbd:localhost:exportname=debian-500-ppc-netinst
|
||||
qemu-system-i386 -cdrom nbd:localhost:exportname=openSUSE-11.1-ppc-netinst
|
||||
qemu-system-i386 -cdrom nbd://localhost/debian-500-ppc-netinst
|
||||
qemu-system-i386 -cdrom nbd://localhost/openSUSE-11.1-ppc-netinst
|
||||
@end example
|
||||
|
||||
The URI syntax for NBD is supported since QEMU 1.3. An alternative syntax is
|
||||
also available. Here are some example of the older syntax:
|
||||
@example
|
||||
qemu-system-i386 linux.img -hdb nbd:my_nbd_server.mydomain.org:1024
|
||||
qemu-system-i386 linux2.img -hdb nbd:unix:/tmp/my_socket
|
||||
qemu-system-i386 -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst
|
||||
@end example
|
||||
|
||||
@node disk_images_sheepdog
|
||||
|
Loading…
Reference in New Issue
Block a user