diff options
author | Laurent Vivier <laurent@vivier.eu> | 2010-08-25 22:48:33 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2010-08-30 18:29:22 +0200 |
commit | 1d45f8b542f6b80b24c44533ef0dd9e1a3b17ea5 (patch) | |
tree | a94959416cdcfc3d9317d31e1026533563a59c79 /block | |
parent | 2aa326be0d2039f51192707bdb2fc935d0e87c21 (diff) |
nbd: Introduce NBD named exports.
This patch allows to connect Qemu using NBD protocol to an nbd-server
using named exports.
For instance, if on the host "isoserver", in /etc/nbd-server/config, you have:
[generic]
[debian-500-ppc-netinst]
exportname = /ISO/debian-500-powerpc-netinst.iso
[Fedora-10-ppc-netinst]
exportname = /ISO/Fedora-10-ppc-netinst.iso
You can connect to it, using:
qemu -cdrom nbd:isoserver:exportname=debian-500-ppc-netinst
qemu -cdrom nbd:isoserver:exportname=Fedora-10-ppc-netinst
NOTE: you need at least nbd-server 2.9.18
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/nbd.c | 68 |
1 files changed, 49 insertions, 19 deletions
diff --git a/block/nbd.c b/block/nbd.c index a1ec123a6..5e9d6cb8e 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -33,6 +33,8 @@ #include <sys/types.h> #include <unistd.h> +#define EN_OPTSTR ":exportname=" + typedef struct BDRVNBDState { int sock; off_t size; @@ -42,55 +44,83 @@ typedef struct BDRVNBDState { static int nbd_open(BlockDriverState *bs, const char* filename, int flags) { BDRVNBDState *s = bs->opaque; + uint32_t nbdflags; + + char *file; + char *name; const char *host; const char *unixpath; int sock; off_t size; size_t blocksize; int ret; + int err = -EINVAL; + + file = qemu_strdup(filename); - if (!strstart(filename, "nbd:", &host)) - return -EINVAL; + name = strstr(file, EN_OPTSTR); + if (name) { + if (name[strlen(EN_OPTSTR)] == 0) { + goto out; + } + name[0] = 0; + name += strlen(EN_OPTSTR); + } + + if (!strstart(file, "nbd:", &host)) { + goto out; + } if (strstart(host, "unix:", &unixpath)) { - if (unixpath[0] != '/') - return -EINVAL; + if (unixpath[0] != '/') { + goto out; + } sock = unix_socket_outgoing(unixpath); } else { - uint16_t port; + uint16_t port = NBD_DEFAULT_PORT; char *p, *r; char hostname[128]; pstrcpy(hostname, 128, host); p = strchr(hostname, ':'); - if (p == NULL) - return -EINVAL; + if (p != NULL) { + *p = '\0'; + p++; + + port = strtol(p, &r, 0); + if (r == p) { + goto out; + } + } else if (name == NULL) { + goto out; + } - *p = '\0'; - p++; - - port = strtol(p, &r, 0); - if (r == p) - return -EINVAL; sock = tcp_socket_outgoing(hostname, port); } - if (sock == -1) - return -errno; + if (sock == -1) { + err = -errno; + goto out; + } - ret = nbd_receive_negotiate(sock, &size, &blocksize); - if (ret == -1) - return -errno; + ret = nbd_receive_negotiate(sock, name, &nbdflags, &size, &blocksize); + if (ret == -1) { + err = -errno; + goto out; + } s->sock = sock; s->size = size; s->blocksize = blocksize; + err = 0; - return 0; +out: + qemu_free(file); + return err; } static int nbd_read(BlockDriverState *bs, int64_t sector_num, |