summaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorLaurent Vivier <laurent@vivier.eu>2010-08-25 22:48:33 +0200
committerKevin Wolf <kwolf@redhat.com>2010-08-30 18:29:22 +0200
commit1d45f8b542f6b80b24c44533ef0dd9e1a3b17ea5 (patch)
treea94959416cdcfc3d9317d31e1026533563a59c79 /block
parent2aa326be0d2039f51192707bdb2fc935d0e87c21 (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.c68
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,