qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [4838] Allow QEMU to connect directly to an NBD server, by Laurent Vivier.
@ 2008-07-03 13:41 Thiemo Seufer
  2008-07-04  1:33 ` chenqing
  0 siblings, 1 reply; 31+ messages in thread
From: Thiemo Seufer @ 2008-07-03 13:41 UTC (permalink / raw)
  To: qemu-devel

Revision: 4838
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4838
Author:   ths
Date:     2008-07-03 13:41:03 +0000 (Thu, 03 Jul 2008)

Log Message:
-----------
Allow QEMU to connect directly to an NBD server, by Laurent Vivier.

Modified Paths:
--------------
    trunk/Makefile
    trunk/block.c
    trunk/block.h
    trunk/nbd.c
    trunk/nbd.h
    trunk/qemu-doc.texi
    trunk/qemu-nbd.c
    trunk/qemu-nbd.texi

Added Paths:
-----------
    trunk/block-nbd.c

Modified: trunk/Makefile
===================================================================
--- trunk/Makefile	2008-07-03 12:45:02 UTC (rev 4837)
+++ trunk/Makefile	2008-07-03 13:41:03 UTC (rev 4838)
@@ -42,7 +42,7 @@
 BLOCK_OBJS=cutils.o qemu-malloc.o
 BLOCK_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o
 BLOCK_OBJS+=block-dmg.o block-bochs.o block-vpc.o block-vvfat.o
-BLOCK_OBJS+=block-qcow2.o block-parallels.o
+BLOCK_OBJS+=block-qcow2.o block-parallels.o block-nbd.o
 
 ######################################################################
 # libqemu_common.a: Target independent part of system emulation. The
@@ -50,7 +50,7 @@
 # system emulation, i.e. a single QEMU executable should support all
 # CPUs and machines.
 
-OBJS=$(BLOCK_OBJS)
+OBJS=nbd.o $(BLOCK_OBJS)
 OBJS+=readline.o console.o
 OBJS+=block.o
 
@@ -159,7 +159,7 @@
 	rm -f $@ 
 	$(AR) rcs $@ $(USER_OBJS)
 
-QEMU_IMG_BLOCK_OBJS = $(BLOCK_OBJS)
+QEMU_IMG_BLOCK_OBJS = nbd.o $(BLOCK_OBJS)
 ifdef CONFIG_WIN32
 QEMU_IMG_BLOCK_OBJS += qemu-img-block-raw-win32.o
 else
@@ -180,7 +180,7 @@
 qemu-nbd-%.o: %.c
 	$(CC) $(CFLAGS) $(CPPFLAGS) -DQEMU_NBD -c -o $@ $<
 
-qemu-nbd$(EXESUF):  qemu-nbd.o nbd.o qemu-img-block.o \
+qemu-nbd$(EXESUF):  qemu-nbd.o qemu-nbd-nbd.o qemu-img-block.o \
 		    osdep.o qemu-nbd-block-raw-posix.o $(BLOCK_OBJS)
 	$(CC) $(LDFLAGS) -o $@ $^ -lz $(LIBS)
 

Added: trunk/block-nbd.c
===================================================================
--- trunk/block-nbd.c	                        (rev 0)
+++ trunk/block-nbd.c	2008-07-03 13:41:03 UTC (rev 4838)
@@ -0,0 +1,194 @@
+/*
+ * QEMU Block driver for  NBD
+ *
+ * Copyright (C) 2008 Bull S.A.S.
+ *     Author: Laurent Vivier <Laurent.Vivier@bull;net>
+ *
+ * Some parts:
+ *    Copyright (C) 2007 Anthony Liguori <anthony@codemonkey.ws>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu-common.h"
+#include "nbd.h"
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <pthread.h>
+
+typedef struct BDRVNBDState {
+    int sock;
+    off_t size;
+    size_t blocksize;
+} BDRVNBDState;
+
+static int nbd_open(BlockDriverState *bs, const char* filename, int flags)
+{
+    BDRVNBDState *s = bs->opaque;
+    const char *host;
+    const char *unixpath;
+    int sock;
+    off_t size;
+    size_t blocksize;
+    int ret;
+
+    if ((flags & BDRV_O_CREAT))
+        return -EINVAL;
+
+    if (!strstart(filename, "nbd:", &host))
+        return -EINVAL;
+
+    if (strstart(host, "unix:", &unixpath)) {
+
+        if (unixpath[0] != '/')
+            return -EINVAL;
+
+        sock = unix_socket_outgoing(unixpath);
+
+    } else {
+        uint16_t port;
+        char *p, *r;
+        char hostname[128];
+
+        pstrcpy(hostname, 128, host);
+
+        p = strchr(hostname, ':');
+        if (p == NULL)
+            return -EINVAL;
+
+        *p = '\0';
+        p++;
+
+        port = strtol(p, &r, 0);
+        if (r == p)
+            return -EINVAL;
+        sock = tcp_socket_outgoing(hostname, port);
+    }
+
+    if (sock == -1)
+        return -errno;
+
+    ret = nbd_receive_negotiate(sock, &size, &blocksize);
+    if (ret == -1)
+        return -errno;
+
+    s->sock = sock;
+    s->size = size;
+    s->blocksize = blocksize;
+
+    return 0;
+}
+
+static int nbd_read(BlockDriverState *bs, int64_t sector_num,
+                    uint8_t *buf, int nb_sectors)
+{
+    BDRVNBDState *s = bs->opaque;
+    struct nbd_request request;
+    struct nbd_reply reply;
+
+    request.type = NBD_CMD_READ;
+    request.handle = (uint64_t)(intptr_t)bs;
+    request.from = sector_num * 512;;
+    request.len = nb_sectors * 512;
+
+    if (nbd_send_request(s->sock, &request) == -1)
+        return -errno;
+
+    if (nbd_receive_reply(s->sock, &reply) == -1)
+        return -errno;
+
+    if (reply.error !=0)
+        return -reply.error;
+
+    if (reply.handle != request.handle)
+        return -EIO;
+
+    if (nbd_wr_sync(s->sock, buf, request.len, 1) != request.len)
+        return -EIO;
+
+    return 0;
+}
+
+static int nbd_write(BlockDriverState *bs, int64_t sector_num,
+                     const uint8_t *buf, int nb_sectors)
+{
+    BDRVNBDState *s = bs->opaque;
+    struct nbd_request request;
+    struct nbd_reply reply;
+
+    request.type = NBD_CMD_WRITE;
+    request.handle = (uint64_t)(intptr_t)bs;
+    request.from = sector_num * 512;;
+    request.len = nb_sectors * 512;
+
+    if (nbd_send_request(s->sock, &request) == -1)
+        return -errno;
+
+    if (nbd_wr_sync(s->sock, (uint8_t*)buf, request.len, 0) != request.len)
+        return -EIO;
+
+    if (nbd_receive_reply(s->sock, &reply) == -1)
+        return -errno;
+
+    if (reply.error !=0)
+        return -reply.error;
+
+    if (reply.handle != request.handle)
+        return -EIO;
+
+    return 0;
+}
+
+static void nbd_close(BlockDriverState *bs)
+{
+    BDRVNBDState *s = bs->opaque;
+    struct nbd_request request;
+
+    request.type = NBD_CMD_DISC;
+    request.handle = (uint64_t)(intptr_t)bs;
+    request.from = 0;
+    request.len = 0;
+    nbd_send_request(s->sock, &request);
+
+    close(s->sock);
+}
+
+static int64_t nbd_getlength(BlockDriverState *bs)
+{
+    BDRVNBDState *s = bs->opaque;
+
+    return s->size;
+}
+
+BlockDriver bdrv_nbd = {
+    "nbd",
+    sizeof(BDRVNBDState),
+    NULL, /* no probe for protocols */
+    nbd_open,
+    nbd_read,
+    nbd_write,
+    nbd_close,
+    .bdrv_getlength = nbd_getlength,
+    .protocol_name = "nbd",
+};

Modified: trunk/block.c
===================================================================
--- trunk/block.c	2008-07-03 12:45:02 UTC (rev 4837)
+++ trunk/block.c	2008-07-03 13:41:03 UTC (rev 4838)
@@ -1332,6 +1332,7 @@
     bdrv_register(&bdrv_vvfat);
     bdrv_register(&bdrv_qcow2);
     bdrv_register(&bdrv_parallels);
+    bdrv_register(&bdrv_nbd);
 }
 
 void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,

Modified: trunk/block.h
===================================================================
--- trunk/block.h	2008-07-03 12:45:02 UTC (rev 4837)
+++ trunk/block.h	2008-07-03 13:41:03 UTC (rev 4838)
@@ -16,6 +16,7 @@
 extern BlockDriver bdrv_vvfat;
 extern BlockDriver bdrv_qcow2;
 extern BlockDriver bdrv_parallels;
+extern BlockDriver bdrv_nbd;
 
 typedef struct BlockDriverInfo {
     /* in bytes, 0 if irrelevant */

Modified: trunk/nbd.c
===================================================================
--- trunk/nbd.c	2008-07-03 12:45:02 UTC (rev 4837)
+++ trunk/nbd.c	2008-07-03 13:41:03 UTC (rev 4838)
@@ -1,4 +1,4 @@
-/*\
+/*
  *  Copyright (C) 2005  Anthony Liguori <anthony@codemonkey.ws>
  *
  *  Network Block Device
@@ -15,7 +15,7 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-\*/
+ */
 
 #include "nbd.h"
 
@@ -31,17 +31,21 @@
 #include <arpa/inet.h>
 #include <netdb.h>
 
+#if defined(QEMU_NBD)
 extern int verbose;
+#else
+static int verbose = 0;
+#endif
 
+#define TRACE(msg, ...) do { \
+    if (verbose) LOG(msg, ## __VA_ARGS__); \
+} while(0)
+
 #define LOG(msg, ...) do { \
     fprintf(stderr, "%s:%s():L%d: " msg "\n", \
             __FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__); \
 } while(0)
 
-#define TRACE(msg, ...) do { \
-    if (verbose) LOG(msg, ## __VA_ARGS__); \
-} while(0)
-
 /* This is all part of the "official" NBD API */
 
 #define NBD_REQUEST_MAGIC       0x25609513
@@ -59,10 +63,10 @@
 
 /* That's all folks */
 
-#define read_sync(fd, buffer, size) wr_sync(fd, buffer, size, true)
-#define write_sync(fd, buffer, size) wr_sync(fd, buffer, size, false)
+#define read_sync(fd, buffer, size) nbd_wr_sync(fd, buffer, size, true)
+#define write_sync(fd, buffer, size) nbd_wr_sync(fd, buffer, size, false)
 
-static size_t wr_sync(int fd, void *buffer, size_t size, bool do_read)
+size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read)
 {
     size_t offset = 0;
 
@@ -76,7 +80,7 @@
         }
 
         /* recoverable error */
-        if (len == -1 && errno == EAGAIN) {
+        if (len == -1 && (errno == EAGAIN || errno == EINTR)) {
             continue;
         }
 
@@ -96,7 +100,7 @@
     return offset;
 }
 
-static int tcp_socket_outgoing(const char *address, uint16_t port)
+int tcp_socket_outgoing(const char *address, uint16_t port)
 {
     int s;
     struct in_addr in;
@@ -404,17 +408,32 @@
 	return ret;
 }
 
-int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
-             off_t *offset, bool readonly, uint8_t *data, int data_size)
+int nbd_send_request(int csock, struct nbd_request *request)
 {
 	uint8_t buf[4 + 4 + 8 + 8 + 4];
+
+	cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC);
+	cpu_to_be32w((uint32_t*)(buf + 4), request->type);
+	cpu_to_be64w((uint64_t*)(buf + 8), request->handle);
+	cpu_to_be64w((uint64_t*)(buf + 16), request->from);
+	cpu_to_be32w((uint32_t*)(buf + 24), request->len);
+
+	TRACE("Sending request to client");
+
+	if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
+		LOG("writing to socket failed");
+		errno = EINVAL;
+		return -1;
+	}
+	return 0;
+}
+
+
+static int nbd_receive_request(int csock, struct nbd_request *request)
+{
+	uint8_t buf[4 + 4 + 8 + 8 + 4];
 	uint32_t magic;
-	uint32_t type;
-	uint64_t from;
-	uint32_t len;
 
-	TRACE("Reading request.");
-
 	if (read_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
 		LOG("read failed");
 		errno = EINVAL;
@@ -422,97 +441,158 @@
 	}
 
 	/* Request
-	  [ 0 ..  3]   magic   (NBD_REQUEST_MAGIC)
-	  [ 4 ..  7]   type    (0 == READ, 1 == WRITE)
-	  [ 8 .. 15]   handle
-	  [16 .. 23]   from
-	  [24 .. 27]   len
+	   [ 0 ..  3]   magic   (NBD_REQUEST_MAGIC)
+	   [ 4 ..  7]   type    (0 == READ, 1 == WRITE)
+	   [ 8 .. 15]   handle
+	   [16 .. 23]   from
+	   [24 .. 27]   len
 	 */
 
 	magic = be32_to_cpup((uint32_t*)buf);
-	type  = be32_to_cpup((uint32_t*)(buf + 4));
-	from  = be64_to_cpup((uint64_t*)(buf + 16));
-	len   = be32_to_cpup((uint32_t*)(buf + 24));
+	request->type  = be32_to_cpup((uint32_t*)(buf + 4));
+	request->handle = be64_to_cpup((uint64_t*)(buf + 8));
+	request->from  = be64_to_cpup((uint64_t*)(buf + 16));
+	request->len   = be32_to_cpup((uint32_t*)(buf + 24));
 
 	TRACE("Got request: "
 	      "{ magic = 0x%x, .type = %d, from = %" PRIu64" , len = %u }",
-	      magic, type, from, len);
+	      magic, request->type, request->from, request->len);
 
-
 	if (magic != NBD_REQUEST_MAGIC) {
 		LOG("invalid magic (got 0x%x)", magic);
 		errno = EINVAL;
 		return -1;
 	}
+}
 
-	if (len > data_size) {
+int nbd_receive_reply(int csock, struct nbd_reply *reply)
+{
+	uint8_t buf[4 + 4 + 8];
+	uint32_t magic;
+
+	memset(buf, 0xAA, sizeof(buf));
+
+	if (read_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
+		LOG("read failed");
+		errno = EINVAL;
+		return -1;
+	}
+
+	/* Reply
+	   [ 0 ..  3]    magic   (NBD_REPLY_MAGIC)
+	   [ 4 ..  7]    error   (0 == no error)
+	   [ 7 .. 15]    handle
+	 */
+
+	magic = be32_to_cpup((uint32_t*)buf);
+	reply->error  = be32_to_cpup((uint32_t*)(buf + 4));
+	reply->handle = be64_to_cpup((uint64_t*)(buf + 8));
+
+	TRACE("Got reply: "
+	      "{ magic = 0x%x, .error = %d, handle = %" PRIu64" }",
+	      magic, reply->error, reply->handle);
+
+	if (magic != NBD_REPLY_MAGIC) {
+		LOG("invalid magic (got 0x%x)", magic);
+		errno = EINVAL;
+		return -1;
+	}
+	return 0;
+}
+
+static int nbd_send_reply(int csock, struct nbd_reply *reply)
+{
+	uint8_t buf[4 + 4 + 8];
+
+	/* Reply
+	   [ 0 ..  3]    magic   (NBD_REPLY_MAGIC)
+	   [ 4 ..  7]    error   (0 == no error)
+	   [ 7 .. 15]    handle
+	 */
+	cpu_to_be32w((uint32_t*)buf, NBD_REPLY_MAGIC);
+	cpu_to_be32w((uint32_t*)(buf + 4), reply->error);
+	cpu_to_be64w((uint64_t*)(buf + 8), reply->handle);
+
+	TRACE("Sending response to client");
+
+	if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
+		LOG("writing to socket failed");
+		errno = EINVAL;
+		return -1;
+	}
+	return 0;
+}
+
+int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
+             off_t *offset, bool readonly, uint8_t *data, int data_size)
+{
+	struct nbd_request request;
+	struct nbd_reply reply;
+
+	TRACE("Reading request.");
+
+	if (nbd_receive_request(csock, &request) == -1)
+		return -1;
+
+	if (request.len > data_size) {
 		LOG("len (%u) is larger than max len (%u)",
-		    len, data_size);
+		    request.len, data_size);
 		errno = EINVAL;
 		return -1;
 	}
 
-	if ((from + len) < from) {
+	if ((request.from + request.len) < request.from) {
 		LOG("integer overflow detected! "
 		    "you're probably being attacked");
 		errno = EINVAL;
 		return -1;
 	}
 
-	if ((from + len) > size) {
+	if ((request.from + request.len) > size) {
 	        LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64
 		    ", Offset: %" PRIu64 "\n",
-		     from, len, size, dev_offset);
+		     request.from, request.len, size, dev_offset);
 		LOG("requested operation past EOF--bad client?");
 		errno = EINVAL;
 		return -1;
 	}
 
-	/* Reply
-	 [ 0 ..  3]    magic   (NBD_REPLY_MAGIC)
-	 [ 4 ..  7]    error   (0 == no error)
-         [ 7 .. 15]    handle
-	 */
-	cpu_to_be32w((uint32_t*)buf, NBD_REPLY_MAGIC);
-	cpu_to_be32w((uint32_t*)(buf + 4), 0);
-
 	TRACE("Decoding type");
 
-	switch (type) {
-	case 0:
+	reply.handle = request.handle;
+	reply.error = 0;
+
+	switch (request.type) {
+	case NBD_CMD_READ:
 		TRACE("Request type is READ");
 
-		if (bdrv_read(bs, (from + dev_offset) / 512, data, len / 512) == -1) {
+		if (bdrv_read(bs, (request.from + dev_offset) / 512, data,
+			      request.len / 512) == -1) {
 			LOG("reading from file failed");
 			errno = EINVAL;
 			return -1;
 		}
-		*offset += len;
+		*offset += request.len;
 
-		TRACE("Read %u byte(s)", len);
+		TRACE("Read %u byte(s)", request.len);
 
-		TRACE("Sending OK response");
-
-		if (write_sync(csock, buf, 16) != 16) {
-			LOG("writing to socket failed");
-			errno = EINVAL;
+		if (nbd_send_reply(csock, &reply) == -1)
 			return -1;
-		}
 
 		TRACE("Sending data to client");
 
-		if (write_sync(csock, data, len) != len) {
+		if (write_sync(csock, data, request.len) != request.len) {
 			LOG("writing to socket failed");
 			errno = EINVAL;
 			return -1;
 		}
 		break;
-	case 1:
+	case NBD_CMD_WRITE:
 		TRACE("Request type is WRITE");
 
-		TRACE("Reading %u byte(s)", len);
+		TRACE("Reading %u byte(s)", request.len);
 
-		if (read_sync(csock, data, len) != len) {
+		if (read_sync(csock, data, request.len) != request.len) {
 			LOG("reading from socket failed");
 			errno = EINVAL;
 			return -1;
@@ -520,34 +600,29 @@
 
 		if (readonly) {
 			TRACE("Server is read-only, return error");
-
-			cpu_to_be32w((uint32_t*)(buf + 4), 1);
+			reply.error = 1;
 		} else {
 			TRACE("Writing to device");
 
-			if (bdrv_write(bs, (from + dev_offset) / 512, data, len / 512) == -1) {
+			if (bdrv_write(bs, (request.from + dev_offset) / 512,
+				       data, request.len / 512) == -1) {
 				LOG("writing to file failed");
 				errno = EINVAL;
 				return -1;
 			}
 
-			*offset += len;
+			*offset += request.len;
 		}
 
-		TRACE("Sending response to client");
-
-		if (write_sync(csock, buf, 16) != 16) {
-			LOG("writing to socket failed");
-			errno = EINVAL;
+		if (nbd_send_reply(csock, &reply) == -1)
 			return -1;
-		}
 		break;
-	case 2:
+	case NBD_CMD_DISC:
 		TRACE("Request type is DISCONNECT");
 		errno = 0;
 		return 1;
 	default:
-		LOG("invalid request type (%u) received", type);
+		LOG("invalid request type (%u) received", request.type);
 		errno = EINVAL;
 		return -1;
 	}

Modified: trunk/nbd.h
===================================================================
--- trunk/nbd.h	2008-07-03 12:45:02 UTC (rev 4837)
+++ trunk/nbd.h	2008-07-03 13:41:03 UTC (rev 4838)
@@ -1,4 +1,4 @@
-/*\
+/*
  *  Copyright (C) 2005  Anthony Liguori <anthony@codemonkey.ws>
  *
  *  Network Block Device
@@ -15,7 +15,7 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-\*/
+ */
 
 #ifndef NBD_H
 #define NBD_H
@@ -26,6 +26,26 @@
 #include <qemu-common.h>
 #include "block_int.h"
 
+struct nbd_request {
+    uint32_t type;
+    uint64_t handle;
+    uint64_t from;
+    uint32_t len;
+};
+
+struct nbd_reply {
+    uint32_t error;
+    uint64_t handle;
+};
+
+enum {
+    NBD_CMD_READ = 0,
+    NBD_CMD_WRITE = 1,
+    NBD_CMD_DISC = 2
+};
+
+size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read);
+int tcp_socket_outgoing(const char *address, uint16_t port);
 int tcp_socket_incoming(const char *address, uint16_t port);
 int unix_socket_outgoing(const char *path);
 int unix_socket_incoming(const char *path);
@@ -33,6 +53,8 @@
 int nbd_negotiate(BlockDriverState *bs, int csock, off_t size);
 int nbd_receive_negotiate(int csock, off_t *size, size_t *blocksize);
 int nbd_init(int fd, int csock, off_t size, size_t blocksize);
+int nbd_send_request(int csock, struct nbd_request *request);
+int nbd_receive_reply(int csock, struct nbd_reply *reply);
 int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
              off_t *offset, bool readonly, uint8_t *data, int data_size);
 int nbd_client(int fd, int csock);

Modified: trunk/qemu-doc.texi
===================================================================
--- trunk/qemu-doc.texi	2008-07-03 12:45:02 UTC (rev 4837)
+++ trunk/qemu-doc.texi	2008-07-03 13:41:03 UTC (rev 4838)
@@ -1321,6 +1321,7 @@
 * qemu_nbd_invocation::       qemu-nbd Invocation
 * host_drives::               Using host drives
 * disk_images_fat_images::    Virtual FAT disk images
+* disk_images_nbd::           NBD access
 @end menu
 
 @node disk_images_quickstart
@@ -1503,6 +1504,40 @@
 @item write to the FAT directory on the host system while accessing it with the guest system.
 @end itemize
 
+@node disk_images_nbd
+@subsection NBD access
+
+QEMU can access directly to block device exported using the Network Block Device
+protocol.
+
+@example
+qemu 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 linux.img -hdb nbd:unix:/tmp/my_socket
+@end example
+
+In this case, the block device must be exported using qemu-nbd:
+
+@example
+qemu-nbd --socket=/tmp/my_socket my_disk.qcow2
+@end example
+
+The use of qemu-nbd allows to share a disk between several guests:
+@example
+qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2
+@end example
+
+and then you can use it with two guests:
+@example
+qemu linux1.img -hdb nbd:unix:/tmp/my_socket
+qemu linux2.img -hdb nbd:unix:/tmp/my_socket
+@end example
+
 @node pcsys_network
 @section Network emulation
 

Modified: trunk/qemu-nbd.c
===================================================================
--- trunk/qemu-nbd.c	2008-07-03 12:45:02 UTC (rev 4837)
+++ trunk/qemu-nbd.c	2008-07-03 13:41:03 UTC (rev 4838)
@@ -56,6 +56,7 @@
 "  -c, --connect=DEV    connect FILE to the local NBD device DEV\n"
 "  -d, --disconnect     disconnect the specified device\n"
 "  -e, --shared=NUM     device can be shared by NUM clients (default '1')\n"
+"  -t, --persistent     don't exit on the last connection\n"
 "  -v, --verbose        display extra debugging information\n"
 "  -h, --help           display this help and exit\n"
 "  -V, --version        output version information and exit\n"
@@ -189,7 +190,7 @@
     char *device = NULL;
     char *socket = NULL;
     char sockpath[128];
-    const char *sopt = "hVbo:p:rsnP:c:dvk:e:";
+    const char *sopt = "hVbo:p:rsnP:c:dvk:e:t";
     struct option lopt[] = {
         { "help", 0, 0, 'h' },
         { "version", 0, 0, 'V' },
@@ -204,6 +205,7 @@
         { "snapshot", 0, 0, 's' },
         { "nocache", 0, 0, 'n' },
         { "shared", 1, 0, 'e' },
+        { "persistent", 0, 0, 't' },
         { "verbose", 0, 0, 'v' },
         { NULL, 0, 0, 0 }
     };
@@ -222,6 +224,7 @@
     int i;
     int nb_fds = 0;
     int max_fd;
+    int persistent = 0;
 
     while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
         switch (ch) {
@@ -283,6 +286,9 @@
                 errx(EINVAL, "Shared device number must be greater than 0\n");
             }
             break;
+	case 't':
+	    persistent = 1;
+	    break;
         case 'v':
             verbose = 1;
             break;
@@ -459,7 +465,7 @@
                 }
             }
         }
-    } while (nb_fds > 1);
+    } while (persistent || nb_fds > 1);
     qemu_free(data);
 
     close(sharing_fds[0]);

Modified: trunk/qemu-nbd.texi
===================================================================
--- trunk/qemu-nbd.texi	2008-07-03 12:45:02 UTC (rev 4837)
+++ trunk/qemu-nbd.texi	2008-07-03 13:41:03 UTC (rev 4838)
@@ -36,6 +36,8 @@
   disconnect the specified device
 @item -e, --shared=NUM
   device can be shared by NUM clients (default '1')
+@item -t, --persistent
+  don't exit on the last connection
 @item -v, --verbose
   display extra debugging information
 @item -h, --help

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [4838] Allow QEMU to connect directly to an NBD server, by Laurent Vivier.
  2008-07-03 13:41 [Qemu-devel] [4838] Allow QEMU to connect directly to an NBD server, by Laurent Vivier Thiemo Seufer
@ 2008-07-04  1:33 ` chenqing
  2008-07-04  2:34   ` Thiemo Seufer
  0 siblings, 1 reply; 31+ messages in thread
From: chenqing @ 2008-07-04  1:33 UTC (permalink / raw)
  To: qemu-devel

> +#include <sys/types.h>
> +#include <unistd.h>
> +#include <sys/socket.h>
> +#include <sys/un.h>
> +#include <netinet/in.h>
> +#include <arpa/inet.h>
> +#include <pthread.h>

Maybe you should wrap these with "#ifndef _WIN32", I get an error on windows:

nbd.c:24:23: warning: sys/ioctl.h: No such file or directory
nbd.c:27:24: warning: sys/socket.h: No such file or directory
nbd.c:28:20: warning: sys/un.h: No such file or directory
nbd.c:29:24: warning: netinet/in.h: No such file or directory
nbd.c:30:25: warning: netinet/tcp.h: No such file or directory
nbd.c:31:23: warning: arpa/inet.h: No such file or directory
nbd.c:32:19: warning: netdb.h: No such file or directory

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [4838] Allow QEMU to connect directly to an NBD server, by Laurent Vivier.
  2008-07-04  1:33 ` chenqing
@ 2008-07-04  2:34   ` Thiemo Seufer
  2008-07-04  3:51     ` chenqing
  2008-07-04  8:01     ` [Qemu-devel] [4838] Allow QEMU to connect directly to an NBD server, by Laurent Vivier Laurent Vivier
  0 siblings, 2 replies; 31+ messages in thread
From: Thiemo Seufer @ 2008-07-04  2:34 UTC (permalink / raw)
  To: chenqing, qemu-devel

chenqing wrote:
> > +#include <sys/types.h>
> > +#include <unistd.h>
> > +#include <sys/socket.h>
> > +#include <sys/un.h>
> > +#include <netinet/in.h>
> > +#include <arpa/inet.h>
> > +#include <pthread.h>
> 
> Maybe you should wrap these with "#ifndef _WIN32", I get an error on windows:
> 
> nbd.c:24:23: warning: sys/ioctl.h: No such file or directory
> nbd.c:27:24: warning: sys/socket.h: No such file or directory
> nbd.c:28:20: warning: sys/un.h: No such file or directory
> nbd.c:29:24: warning: netinet/in.h: No such file or directory
> nbd.c:30:25: warning: netinet/tcp.h: No such file or directory
> nbd.c:31:23: warning: arpa/inet.h: No such file or directory
> nbd.c:32:19: warning: netdb.h: No such file or directory

Hm, how much of nbd.c works on windows?


Thiemo

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [4838] Allow QEMU to connect directly to an NBD server, by Laurent Vivier.
  2008-07-04  2:34   ` Thiemo Seufer
@ 2008-07-04  3:51     ` chenqing
  2008-07-04  8:42       ` Laurent Vivier
  2008-07-04  8:01     ` [Qemu-devel] [4838] Allow QEMU to connect directly to an NBD server, by Laurent Vivier Laurent Vivier
  1 sibling, 1 reply; 31+ messages in thread
From: chenqing @ 2008-07-04  3:51 UTC (permalink / raw)
  To: qemu-devel

> 
> Hm, how much of nbd.c works on windows?

We don't care nbd.c works on windows, we just want to compile qemu on
windows smoothly. In fact, I can did it successfully yestoday, but failed
today because these error.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [4838] Allow QEMU to connect directly to an NBD server, by Laurent Vivier.
  2008-07-04  2:34   ` Thiemo Seufer
  2008-07-04  3:51     ` chenqing
@ 2008-07-04  8:01     ` Laurent Vivier
  1 sibling, 0 replies; 31+ messages in thread
From: Laurent Vivier @ 2008-07-04  8:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: chenqing

Le vendredi 04 juillet 2008 à 03:34 +0100, Thiemo Seufer a écrit :
> chenqing wrote:
> > > +#include <sys/types.h>
> > > +#include <unistd.h>
> > > +#include <sys/socket.h>
> > > +#include <sys/un.h>
> > > +#include <netinet/in.h>
> > > +#include <arpa/inet.h>
> > > +#include <pthread.h>
> > 
> > Maybe you should wrap these with "#ifndef _WIN32", I get an error on windows:
> > 
> > nbd.c:24:23: warning: sys/ioctl.h: No such file or directory
> > nbd.c:27:24: warning: sys/socket.h: No such file or directory
> > nbd.c:28:20: warning: sys/un.h: No such file or directory
> > nbd.c:29:24: warning: netinet/in.h: No such file or directory
> > nbd.c:30:25: warning: netinet/tcp.h: No such file or directory
> > nbd.c:31:23: warning: arpa/inet.h: No such file or directory
> > nbd.c:32:19: warning: netdb.h: No such file or directory
> 
> Hm, how much of nbd.c works on windows?

Except the part of NBD client using kernel module, NBD should works
(it's only networking).

Regards,
Laurent
-- 
------------- Laurent.Vivier@bull.net ---------------
"The best way to predict the future is to invent it."
- Alan Kay

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [4838] Allow QEMU to connect directly to an NBD server, by Laurent Vivier.
  2008-07-04  3:51     ` chenqing
@ 2008-07-04  8:42       ` Laurent Vivier
  2008-07-04 20:32         ` Thiemo Seufer
  0 siblings, 1 reply; 31+ messages in thread
From: Laurent Vivier @ 2008-07-04  8:42 UTC (permalink / raw)
  To: chenqing; +Cc: qemu-devel@nongnu.org

[-- Attachment #1: Type: text/plain, Size: 499 bytes --]

Le vendredi 04 juillet 2008 à 11:51 +0800, chenqing a écrit :
> > 
> > Hm, how much of nbd.c works on windows?
> 
> We don't care nbd.c works on windows, we just want to compile qemu on
> windows smoothly. In fact, I can did it successfully yestoday, but failed
> today because these error.

The attached patch should disable NBD on win32.

Regards,
Laurent
-- 
------------- Laurent.Vivier@bull.net ---------------
"The best way to predict the future is to invent it."
- Alan Kay

[-- Attachment #2: nbd-win32.patch --]
[-- Type: text/x-vhdl, Size: 1533 bytes --]

---
 Makefile |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

Index: qemu/Makefile
===================================================================
--- qemu.orig/Makefile	2008-07-04 10:39:31.000000000 +0200
+++ qemu/Makefile	2008-07-04 10:39:35.000000000 +0200
@@ -42,7 +42,10 @@ recurse-all: $(SUBDIR_RULES)
 BLOCK_OBJS=cutils.o qemu-malloc.o
 BLOCK_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o
 BLOCK_OBJS+=block-dmg.o block-bochs.o block-vpc.o block-vvfat.o
-BLOCK_OBJS+=block-qcow2.o block-parallels.o block-nbd.o
+BLOCK_OBJS+=block-qcow2.o block-parallels.o 
+ifndef CONFIG_WIN32
+BLOCK_OBJS+=block-nbd.o
+endif
 
 ######################################################################
 # libqemu_common.a: Target independent part of system emulation. The
@@ -50,7 +53,10 @@ BLOCK_OBJS+=block-qcow2.o block-parallel
 # system emulation, i.e. a single QEMU executable should support all
 # CPUs and machines.
 
-OBJS=nbd.o $(BLOCK_OBJS)
+OBJS=$(BLOCK_OBJS)
+ifndef CONFIG_WIN32
+OBJS+=nbd.o
+endif
 OBJS+=readline.o console.o
 OBJS+=block.o
 
@@ -159,11 +165,11 @@ libqemu_user.a: $(USER_OBJS)
 	rm -f $@ 
 	$(AR) rcs $@ $(USER_OBJS)
 
-QEMU_IMG_BLOCK_OBJS = nbd.o $(BLOCK_OBJS)
+QEMU_IMG_BLOCK_OBJS = $(BLOCK_OBJS)
 ifdef CONFIG_WIN32
 QEMU_IMG_BLOCK_OBJS += qemu-img-block-raw-win32.o
 else
-QEMU_IMG_BLOCK_OBJS += qemu-img-block-raw-posix.o
+QEMU_IMG_BLOCK_OBJS += nbd.o qemu-img-block-raw-posix.o
 endif
 
 ######################################################################

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [4838] Allow QEMU to connect directly to an NBD server, by Laurent Vivier.
  2008-07-04  8:42       ` Laurent Vivier
@ 2008-07-04 20:32         ` Thiemo Seufer
  2008-07-04 20:52           ` Johannes Schindelin
  0 siblings, 1 reply; 31+ messages in thread
From: Thiemo Seufer @ 2008-07-04 20:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Laurent Vivier, chenqing

Laurent Vivier wrote:
> Le vendredi 04 juillet 2008 à 11:51 +0800, chenqing a écrit :
> > > 
> > > Hm, how much of nbd.c works on windows?
> > 
> > We don't care nbd.c works on windows, we just want to compile qemu on
> > windows smoothly. In fact, I can did it successfully yestoday, but failed
> > today because these error.
> 
> The attached patch should disable NBD on win32.

Anybody out there who thinks NBD could be useful on Win32, and is
inclined to write a patch?


Thiemo

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [4838] Allow QEMU to connect directly to an NBD server, by Laurent Vivier.
  2008-07-04 20:32         ` Thiemo Seufer
@ 2008-07-04 20:52           ` Johannes Schindelin
  2008-07-04 22:02             ` [Qemu-devel] [PATCH] Fix compilation of nbd on Windows Johannes Schindelin
  0 siblings, 1 reply; 31+ messages in thread
From: Johannes Schindelin @ 2008-07-04 20:52 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Laurent Vivier, qemu-devel, chenqing

[-- Attachment #1: Type: TEXT/PLAIN, Size: 744 bytes --]

Hi,

On Fri, 4 Jul 2008, Thiemo Seufer wrote:

> Laurent Vivier wrote:
> > Le vendredi 04 juillet 2008 à 11:51 +0800, chenqing a écrit :
> > > > 
> > > > Hm, how much of nbd.c works on windows?
> > > 
> > > We don't care nbd.c works on windows, we just want to compile qemu 
> > > on windows smoothly. In fact, I can did it successfully yestoday, 
> > > but failed today because these error.
> > 
> > The attached patch should disable NBD on win32.
> 
> Anybody out there who thinks NBD could be useful on Win32, and is 
> inclined to write a patch?

I think it would be useful, especially given the file system limitations 
Windows has.

Even if I am somewhat allergic to requests of Windows users, I will give 
a try at a patch.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH] Fix compilation of nbd on Windows
  2008-07-04 20:52           ` Johannes Schindelin
@ 2008-07-04 22:02             ` Johannes Schindelin
  2008-07-05 11:58               ` Filip Navara
                                 ` (2 more replies)
  0 siblings, 3 replies; 31+ messages in thread
From: Johannes Schindelin @ 2008-07-04 22:02 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Laurent Vivier, qemu-devel, chenqing


This still only supports the client side, and only the TCP version of
it, since Windows does not have Unix sockets.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---

	This is only compile-tested, since I can only work in an emulated
	environment.

	Oh, and feel free to reorder nbd.h so that it has only one 
	#ifndef..#endif.

	If I find some time next week, I might try to actually compile 
	qemu-nbd and get it to run on Windows.

 Makefile    |    1 +
 block-nbd.c |   11 ++++++++++-
 nbd.c       |   36 +++++++++++++++++++++++++++++++++++-
 nbd.h       |    6 ++++++
 4 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index adb36c6..ef55952 100644
--- a/Makefile
+++ b/Makefile
@@ -70,6 +70,7 @@ endif
 
 ifdef CONFIG_WIN32
 OBJS+=tap-win32.o
+LIBS+= -lws2_32
 endif
 
 AUDIO_OBJS = audio.o noaudio.o wavaudio.o mixeng.o
diff --git a/block-nbd.c b/block-nbd.c
index f350050..a2adbde 100644
--- a/block-nbd.c
+++ b/block-nbd.c
@@ -31,11 +31,17 @@
 
 #include <sys/types.h>
 #include <unistd.h>
+#ifdef _WIN32
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <pthread.h>
+#endif
 
 typedef struct BDRVNBDState {
     int sock;
@@ -61,11 +67,14 @@ static int nbd_open(BlockDriverState *bs, const char* filename, int flags)
 
     if (strstart(host, "unix:", &unixpath)) {
 
+#ifdef _WIN32
+	return -EINVAL;
+#else
         if (unixpath[0] != '/')
             return -EINVAL;
 
         sock = unix_socket_outgoing(unixpath);
-
+#endif
     } else {
         uint16_t port;
         char *p, *r;
diff --git a/nbd.c b/nbd.c
index e9308ee..d783cd0 100644
--- a/nbd.c
+++ b/nbd.c
@@ -21,15 +21,45 @@
 
 #include <errno.h>
 #include <string.h>
-#include <sys/ioctl.h>
 #include <ctype.h>
 #include <inttypes.h>
+#ifdef _WIN32
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+
+#define socket_error() WSAGetLastError()
+#undef EAGAIN
+#undef EINTR
+#undef EINVAL
+#define EAGAIN WSAEWOULDBLOCK
+#define EINTR WSAEINTR
+#define EINVAL WSAEINVAL
+
+static inline int inet_aton(const char *cp, struct in_addr *inp)
+{
+	unsigned long result = inet_addr(cp);
+	if (result == INADDR_NONE)
+		return 0;
+	inp->s_addr = result;
+	return 1;
+}
+
+static inline int mingw_setsockopt(int s, int level, int optname,
+		const void *optval, socklen_t optlen)
+{
+	return setsockopt(s, level, optname, (const char *)optval, optlen);
+}
+#define setsockopt mingw_setsockopt
+#else
+#include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <arpa/inet.h>
 #include <netdb.h>
+#endif
 
 #if defined(QEMU_NBD)
 extern int verbose;
@@ -188,6 +218,7 @@ error:
     return -1;
 }
 
+#ifndef _WIN32
 int unix_socket_incoming(const char *path)
 {
     int s;
@@ -245,6 +276,7 @@ error:
     errno = serrno;
     return -1;
 }
+#endif
 
 
 /* Basic flow
@@ -334,6 +366,7 @@ int nbd_receive_negotiate(int csock, off_t *size, size_t *blocksize)
         return 0;
 }
 
+#ifndef _WIN32
 int nbd_init(int fd, int csock, off_t size, size_t blocksize)
 {
 	TRACE("Setting block size to %lu", (unsigned long)blocksize);
@@ -407,6 +440,7 @@ int nbd_client(int fd, int csock)
 	errno = serrno;
 	return ret;
 }
+#endif
 
 int nbd_send_request(int csock, struct nbd_request *request)
 {
diff --git a/nbd.h b/nbd.h
index 55ba1ba..387246d 100644
--- a/nbd.h
+++ b/nbd.h
@@ -47,17 +47,23 @@ enum {
 size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read);
 int tcp_socket_outgoing(const char *address, uint16_t port);
 int tcp_socket_incoming(const char *address, uint16_t port);
+#ifndef _WIN32
 int unix_socket_outgoing(const char *path);
 int unix_socket_incoming(const char *path);
+#endif
 
 int nbd_negotiate(BlockDriverState *bs, int csock, off_t size);
 int nbd_receive_negotiate(int csock, off_t *size, size_t *blocksize);
+#ifndef _WIN32
 int nbd_init(int fd, int csock, off_t size, size_t blocksize);
+#endif
 int nbd_send_request(int csock, struct nbd_request *request);
 int nbd_receive_reply(int csock, struct nbd_reply *reply);
 int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
              off_t *offset, bool readonly, uint8_t *data, int data_size);
+#ifndef _WIN32
 int nbd_client(int fd, int csock);
 int nbd_disconnect(int fd);
+#endif
 
 #endif
-- 
1.5.6.1.376.g6b0fd

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH] Fix compilation of nbd on Windows
  2008-07-04 22:02             ` [Qemu-devel] [PATCH] Fix compilation of nbd on Windows Johannes Schindelin
@ 2008-07-05 11:58               ` Filip Navara
  2008-07-05 22:41                 ` Jamie Lokier
  2008-07-08 19:22               ` Anthony Liguori
  2008-08-02 19:21               ` [Qemu-devel] [PATCH v2] " Johannes Schindelin
  2 siblings, 1 reply; 31+ messages in thread
From: Filip Navara @ 2008-07-05 11:58 UTC (permalink / raw)
  To: qemu-devel; +Cc: Laurent Vivier, chenqing

Closing sockets with "close" doesn't work on WinSock. Add "#define
close closesocket" to the top of file to fix it. Otherwise, good job!

Best regards,
Filip Navara

On Sat, Jul 5, 2008 at 12:02 AM, Johannes Schindelin
<Johannes.Schindelin@gmx.de> wrote:
>
> This still only supports the client side, and only the TCP version of
> it, since Windows does not have Unix sockets.
>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>
>        This is only compile-tested, since I can only work in an emulated
>        environment.
>
>        Oh, and feel free to reorder nbd.h so that it has only one
>        #ifndef..#endif.
>
>        If I find some time next week, I might try to actually compile
>        qemu-nbd and get it to run on Windows.
>
>  Makefile    |    1 +
>  block-nbd.c |   11 ++++++++++-
>  nbd.c       |   36 +++++++++++++++++++++++++++++++++++-
>  nbd.h       |    6 ++++++
>  4 files changed, 52 insertions(+), 2 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index adb36c6..ef55952 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -70,6 +70,7 @@ endif
>
>  ifdef CONFIG_WIN32
>  OBJS+=tap-win32.o
> +LIBS+= -lws2_32
>  endif
>
>  AUDIO_OBJS = audio.o noaudio.o wavaudio.o mixeng.o
> diff --git a/block-nbd.c b/block-nbd.c
> index f350050..a2adbde 100644
> --- a/block-nbd.c
> +++ b/block-nbd.c
> @@ -31,11 +31,17 @@
>
>  #include <sys/types.h>
>  #include <unistd.h>
> +#ifdef _WIN32
> +#include <windows.h>
> +#include <winsock2.h>
> +#include <ws2tcpip.h>
> +#else
>  #include <sys/socket.h>
>  #include <sys/un.h>
>  #include <netinet/in.h>
>  #include <arpa/inet.h>
>  #include <pthread.h>
> +#endif
>
>  typedef struct BDRVNBDState {
>     int sock;
> @@ -61,11 +67,14 @@ static int nbd_open(BlockDriverState *bs, const char* filename, int flags)
>
>     if (strstart(host, "unix:", &unixpath)) {
>
> +#ifdef _WIN32
> +       return -EINVAL;
> +#else
>         if (unixpath[0] != '/')
>             return -EINVAL;
>
>         sock = unix_socket_outgoing(unixpath);
> -
> +#endif
>     } else {
>         uint16_t port;
>         char *p, *r;
> diff --git a/nbd.c b/nbd.c
> index e9308ee..d783cd0 100644
> --- a/nbd.c
> +++ b/nbd.c
> @@ -21,15 +21,45 @@
>
>  #include <errno.h>
>  #include <string.h>
> -#include <sys/ioctl.h>
>  #include <ctype.h>
>  #include <inttypes.h>
> +#ifdef _WIN32
> +#include <windows.h>
> +#include <winsock2.h>
> +#include <ws2tcpip.h>
> +
> +#define socket_error() WSAGetLastError()
> +#undef EAGAIN
> +#undef EINTR
> +#undef EINVAL
> +#define EAGAIN WSAEWOULDBLOCK
> +#define EINTR WSAEINTR
> +#define EINVAL WSAEINVAL
> +
> +static inline int inet_aton(const char *cp, struct in_addr *inp)
> +{
> +       unsigned long result = inet_addr(cp);
> +       if (result == INADDR_NONE)
> +               return 0;
> +       inp->s_addr = result;
> +       return 1;
> +}
> +
> +static inline int mingw_setsockopt(int s, int level, int optname,
> +               const void *optval, socklen_t optlen)
> +{
> +       return setsockopt(s, level, optname, (const char *)optval, optlen);
> +}
> +#define setsockopt mingw_setsockopt
> +#else
> +#include <sys/ioctl.h>
>  #include <sys/socket.h>
>  #include <sys/un.h>
>  #include <netinet/in.h>
>  #include <netinet/tcp.h>
>  #include <arpa/inet.h>
>  #include <netdb.h>
> +#endif
>
>  #if defined(QEMU_NBD)
>  extern int verbose;
> @@ -188,6 +218,7 @@ error:
>     return -1;
>  }
>
> +#ifndef _WIN32
>  int unix_socket_incoming(const char *path)
>  {
>     int s;
> @@ -245,6 +276,7 @@ error:
>     errno = serrno;
>     return -1;
>  }
> +#endif
>
>
>  /* Basic flow
> @@ -334,6 +366,7 @@ int nbd_receive_negotiate(int csock, off_t *size, size_t *blocksize)
>         return 0;
>  }
>
> +#ifndef _WIN32
>  int nbd_init(int fd, int csock, off_t size, size_t blocksize)
>  {
>        TRACE("Setting block size to %lu", (unsigned long)blocksize);
> @@ -407,6 +440,7 @@ int nbd_client(int fd, int csock)
>        errno = serrno;
>        return ret;
>  }
> +#endif
>
>  int nbd_send_request(int csock, struct nbd_request *request)
>  {
> diff --git a/nbd.h b/nbd.h
> index 55ba1ba..387246d 100644
> --- a/nbd.h
> +++ b/nbd.h
> @@ -47,17 +47,23 @@ enum {
>  size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read);
>  int tcp_socket_outgoing(const char *address, uint16_t port);
>  int tcp_socket_incoming(const char *address, uint16_t port);
> +#ifndef _WIN32
>  int unix_socket_outgoing(const char *path);
>  int unix_socket_incoming(const char *path);
> +#endif
>
>  int nbd_negotiate(BlockDriverState *bs, int csock, off_t size);
>  int nbd_receive_negotiate(int csock, off_t *size, size_t *blocksize);
> +#ifndef _WIN32
>  int nbd_init(int fd, int csock, off_t size, size_t blocksize);
> +#endif
>  int nbd_send_request(int csock, struct nbd_request *request);
>  int nbd_receive_reply(int csock, struct nbd_reply *reply);
>  int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
>              off_t *offset, bool readonly, uint8_t *data, int data_size);
> +#ifndef _WIN32
>  int nbd_client(int fd, int csock);
>  int nbd_disconnect(int fd);
> +#endif
>
>  #endif
> --
> 1.5.6.1.376.g6b0fd
>
>
>
>
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH] Fix compilation of nbd on Windows
  2008-07-05 11:58               ` Filip Navara
@ 2008-07-05 22:41                 ` Jamie Lokier
  2008-07-06  1:51                   ` Johannes Schindelin
  0 siblings, 1 reply; 31+ messages in thread
From: Jamie Lokier @ 2008-07-05 22:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Laurent Vivier, chenqing

Filip Navara wrote:
> Closing sockets with "close" doesn't work on WinSock. Add "#define
> close closesocket" to the top of file to fix it. Otherwise, good job!

Socket error handling is different too, you might want to check any
places errno is used in the socket code.  Also ioctl -> ioctlsocket
(but you probably don't use it).

Or look at the rest of QEMU, which surely does some Windows networking.

-- Jamie

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH] Fix compilation of nbd on Windows
  2008-07-05 22:41                 ` Jamie Lokier
@ 2008-07-06  1:51                   ` Johannes Schindelin
  2008-07-06 16:49                     ` Jamie Lokier
  0 siblings, 1 reply; 31+ messages in thread
From: Johannes Schindelin @ 2008-07-06  1:51 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Laurent Vivier, qemu-devel, chenqing

Hi,

On Sat, 5 Jul 2008, Jamie Lokier wrote:

> Filip Navara wrote:
> > Closing sockets with "close" doesn't work on WinSock. Add "#define
> > close closesocket" to the top of file to fix it.

Yep, seems like I missed that, in spite of having looked at some sample 
code of mine.

> Socket error handling is different too, you might want to check any 
> places errno is used in the socket code.

Now, that is funny, as ...

> Or look at the rest of QEMU, which surely does some Windows networking.

... I did exactly that, and copied the GetLastError() part from there.

Puzzled,
Dscho

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH] Fix compilation of nbd on Windows
  2008-07-06  1:51                   ` Johannes Schindelin
@ 2008-07-06 16:49                     ` Jamie Lokier
  2008-07-06 17:23                       ` Johannes Schindelin
  0 siblings, 1 reply; 31+ messages in thread
From: Jamie Lokier @ 2008-07-06 16:49 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Laurent Vivier, qemu-devel, chenqing

Johannes Schindelin wrote:
> > Socket error handling is different too, you might want to check any 
> > places errno is used in the socket code.
> 
> Now, that is funny, as ...
> 
> > Or look at the rest of QEMU, which surely does some Windows networking.
> 
> ... I did exactly that, and copied the GetLastError() part from there.

NP, I didn't look at your code, just following on from the parent
comment, the few key differences with Winsock. :-)

-- Jamie

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH] Fix compilation of nbd on Windows
  2008-07-06 16:49                     ` Jamie Lokier
@ 2008-07-06 17:23                       ` Johannes Schindelin
  0 siblings, 0 replies; 31+ messages in thread
From: Johannes Schindelin @ 2008-07-06 17:23 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Laurent Vivier, qemu-devel, chenqing

Hi,

On Sun, 6 Jul 2008, Jamie Lokier wrote:

> Johannes Schindelin wrote:
> > > Socket error handling is different too, you might want to check any 
> > > places errno is used in the socket code.
> > 
> > Now, that is funny, as ...
> > 
> > > Or look at the rest of QEMU, which surely does some Windows 
> > > networking.
> > 
> > ... I did exactly that, and copied the GetLastError() part from there.
> 
> NP, I didn't look at your code, just following on from the parent 
> comment, the few key differences with Winsock. :-)

NP, I just thought you had something to say to me.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH] Fix compilation of nbd on Windows
  2008-07-04 22:02             ` [Qemu-devel] [PATCH] Fix compilation of nbd on Windows Johannes Schindelin
  2008-07-05 11:58               ` Filip Navara
@ 2008-07-08 19:22               ` Anthony Liguori
  2008-07-09  0:14                 ` Johannes Schindelin
  2008-08-02 19:21               ` [Qemu-devel] [PATCH v2] " Johannes Schindelin
  2 siblings, 1 reply; 31+ messages in thread
From: Anthony Liguori @ 2008-07-08 19:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: Laurent Vivier, chenqing

Johannes Schindelin wrote:
> This still only supports the client side, and only the TCP version of
> it, since Windows does not have Unix sockets.
>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>
> 	This is only compile-tested, since I can only work in an emulated
> 	environment.
>
> 	Oh, and feel free to reorder nbd.h so that it has only one 
> 	#ifndef..#endif.
>
> 	If I find some time next week, I might try to actually compile 
> 	qemu-nbd and get it to run on Windows.
>
>  Makefile    |    1 +
>  block-nbd.c |   11 ++++++++++-
>  nbd.c       |   36 +++++++++++++++++++++++++++++++++++-
>  nbd.h       |    6 ++++++
>  4 files changed, 52 insertions(+), 2 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index adb36c6..ef55952 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -70,6 +70,7 @@ endif
>  
>  ifdef CONFIG_WIN32
>  OBJS+=tap-win32.o
> +LIBS+= -lws2_32
>  endif
>  
>  AUDIO_OBJS = audio.o noaudio.o wavaudio.o mixeng.o
> diff --git a/block-nbd.c b/block-nbd.c
> index f350050..a2adbde 100644
> --- a/block-nbd.c
> +++ b/block-nbd.c
> @@ -31,11 +31,17 @@
>  
>  #include <sys/types.h>
>  #include <unistd.h>
> +#ifdef _WIN32
> +#include <windows.h>
> +#include <winsock2.h>
> +#include <ws2tcpip.h>
> +#else
>  #include <sys/socket.h>
>  #include <sys/un.h>
>  #include <netinet/in.h>
>  #include <arpa/inet.h>
>  #include <pthread.h>
> +#endif
>   

qemu_socket.h already does this for you.


>  typedef struct BDRVNBDState {
>      int sock;
> @@ -61,11 +67,14 @@ static int nbd_open(BlockDriverState *bs, const char* filename, int flags)
>  
>      if (strstart(host, "unix:", &unixpath)) {
>  
> +#ifdef _WIN32
> +	return -EINVAL;
> +#else
>          if (unixpath[0] != '/')
>              return -EINVAL;
>  
>          sock = unix_socket_outgoing(unixpath);
> -
> +#endif
>      } else {
>          uint16_t port;
>          char *p, *r;
> diff --git a/nbd.c b/nbd.c
> index e9308ee..d783cd0 100644
> --- a/nbd.c
> +++ b/nbd.c
> @@ -21,15 +21,45 @@
>  
>  #include <errno.h>
>  #include <string.h>
> -#include <sys/ioctl.h>
>  #include <ctype.h>
>  #include <inttypes.h>
> +#ifdef _WIN32
> +#include <windows.h>
> +#include <winsock2.h>
> +#include <ws2tcpip.h>
> +
> +#define socket_error() WSAGetLastError()
> +#undef EAGAIN
> +#undef EINTR
> +#undef EINVAL
> +#define EAGAIN WSAEWOULDBLOCK
> +#define EINTR WSAEINTR
> +#define EINVAL WSAEINVAL
> +
> +static inline int inet_aton(const char *cp, struct in_addr *inp)
> +{
> +	unsigned long result = inet_addr(cp);
> +	if (result == INADDR_NONE)
> +		return 0;
> +	inp->s_addr = result;
> +	return 1;
> +}
> +
> +static inline int mingw_setsockopt(int s, int level, int optname,
> +		const void *optval, socklen_t optlen)
> +{
> +	return setsockopt(s, level, optname, (const char *)optval, optlen);
> +}
> +#define setsockopt mingw_setsockopt
> +#else
>   

Any more compat stuff should go in qemu_socket.h

Regards,

Anthony Liguori

> +#include <sys/ioctl.h>
>  #include <sys/socket.h>
>  #include <sys/un.h>
>  #include <netinet/in.h>
>  #include <netinet/tcp.h>
>  #include <arpa/inet.h>
>  #include <netdb.h>
> +#endif
>  
>  #if defined(QEMU_NBD)
>  extern int verbose;
> @@ -188,6 +218,7 @@ error:
>      return -1;
>  }
>  
> +#ifndef _WIN32
>  int unix_socket_incoming(const char *path)
>  {
>      int s;
> @@ -245,6 +276,7 @@ error:
>      errno = serrno;
>      return -1;
>  }
> +#endif
>  
>  
>  /* Basic flow
> @@ -334,6 +366,7 @@ int nbd_receive_negotiate(int csock, off_t *size, size_t *blocksize)
>          return 0;
>  }
>  
> +#ifndef _WIN32
>  int nbd_init(int fd, int csock, off_t size, size_t blocksize)
>  {
>  	TRACE("Setting block size to %lu", (unsigned long)blocksize);
> @@ -407,6 +440,7 @@ int nbd_client(int fd, int csock)
>  	errno = serrno;
>  	return ret;
>  }
> +#endif
>  
>  int nbd_send_request(int csock, struct nbd_request *request)
>  {
> diff --git a/nbd.h b/nbd.h
> index 55ba1ba..387246d 100644
> --- a/nbd.h
> +++ b/nbd.h
> @@ -47,17 +47,23 @@ enum {
>  size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read);
>  int tcp_socket_outgoing(const char *address, uint16_t port);
>  int tcp_socket_incoming(const char *address, uint16_t port);
> +#ifndef _WIN32
>  int unix_socket_outgoing(const char *path);
>  int unix_socket_incoming(const char *path);
> +#endif
>  
>  int nbd_negotiate(BlockDriverState *bs, int csock, off_t size);
>  int nbd_receive_negotiate(int csock, off_t *size, size_t *blocksize);
> +#ifndef _WIN32
>  int nbd_init(int fd, int csock, off_t size, size_t blocksize);
> +#endif
>  int nbd_send_request(int csock, struct nbd_request *request);
>  int nbd_receive_reply(int csock, struct nbd_reply *reply);
>  int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
>               off_t *offset, bool readonly, uint8_t *data, int data_size);
> +#ifndef _WIN32
>  int nbd_client(int fd, int csock);
>  int nbd_disconnect(int fd);
> +#endif
>  
>  #endif
>   

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH] Fix compilation of nbd on Windows
  2008-07-08 19:22               ` Anthony Liguori
@ 2008-07-09  0:14                 ` Johannes Schindelin
  2008-07-18 14:24                   ` [Qemu-devel] " Sebastian Herbszt
  0 siblings, 1 reply; 31+ messages in thread
From: Johannes Schindelin @ 2008-07-09  0:14 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Laurent Vivier, qemu-devel, chenqing

Hi,

On Tue, 8 Jul 2008, Anthony Liguori wrote:

> Johannes Schindelin wrote:
> > This still only supports the client side, and only the TCP version of
> > it, since Windows does not have Unix sockets.
> >
> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> > ---
> >
> >  This is only compile-tested, since I can only work in an emulated
> >  environment.
> >
> >  Oh, and feel free to reorder nbd.h so that it has only one #ifndef..#endif.
> >
> >  If I find some time next week, I might try to actually compile qemu-nbd and
> >  get it to run on Windows.
> >
> >  Makefile    |    1 +
> >  block-nbd.c |   11 ++++++++++-
> >  nbd.c       |   36 +++++++++++++++++++++++++++++++++++-
> >  nbd.h       |    6 ++++++
> >  4 files changed, 52 insertions(+), 2 deletions(-)
> >
> > diff --git a/Makefile b/Makefile
> > index adb36c6..ef55952 100644
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -70,6 +70,7 @@ endif
> >  
> >  ifdef CONFIG_WIN32
> >  OBJS+=tap-win32.o
> > +LIBS+= -lws2_32
> >  endif
> >  
> >  AUDIO_OBJS = audio.o noaudio.o wavaudio.o mixeng.o
> > diff --git a/block-nbd.c b/block-nbd.c
> > index f350050..a2adbde 100644
> > --- a/block-nbd.c
> > +++ b/block-nbd.c
> > @@ -31,11 +31,17 @@
> >  
> >  #include <sys/types.h>
> >  #include <unistd.h>
> > +#ifdef _WIN32
> > +#include <windows.h>
> > +#include <winsock2.h>
> > +#include <ws2tcpip.h>
> > +#else
> >  #include <sys/socket.h>
> >  #include <sys/un.h>
> >  #include <netinet/in.h>
> >  #include <arpa/inet.h>
> >  #include <pthread.h>
> > +#endif
> >   
> 
> qemu_socket.h already does this for you.

Thanks!  That was actually very useful advice!

Note that I will likely have to do different things until later this 
week, but then I will definitely take this advice into account, and try to 
get qemu-nbd going (tcp-only) on Windows.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] Re: [PATCH] Fix compilation of nbd on Windows
  2008-07-09  0:14                 ` Johannes Schindelin
@ 2008-07-18 14:24                   ` Sebastian Herbszt
  2008-07-18 15:26                     ` Johannes Schindelin
  0 siblings, 1 reply; 31+ messages in thread
From: Sebastian Herbszt @ 2008-07-18 14:24 UTC (permalink / raw)
  To: qemu-devel

Johannes Schindelin wrote:

> Note that I will likely have to do different things until later this 
> week, but then I will definitely take this advice into account, and try to 
> get qemu-nbd going (tcp-only) on Windows.

Did you find some time to take a look at it again?

- Sebastian

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] Re: [PATCH] Fix compilation of nbd on Windows
  2008-07-18 14:24                   ` [Qemu-devel] " Sebastian Herbszt
@ 2008-07-18 15:26                     ` Johannes Schindelin
  0 siblings, 0 replies; 31+ messages in thread
From: Johannes Schindelin @ 2008-07-18 15:26 UTC (permalink / raw)
  To: Sebastian Herbszt; +Cc: qemu-devel

Hi,

On Fri, 18 Jul 2008, Sebastian Herbszt wrote:

> Johannes Schindelin wrote:
> 
> > Note that I will likely have to do different things until later this 
> > week, but then I will definitely take this advice into account, and 
> > try to get qemu-nbd going (tcp-only) on Windows.
> 
> Did you find some time to take a look at it again?

Unfortunately, not yet.  Otherwise I would have posted a new version of 
the patch already.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH v2] Fix compilation of nbd on Windows
  2008-07-04 22:02             ` [Qemu-devel] [PATCH] Fix compilation of nbd on Windows Johannes Schindelin
  2008-07-05 11:58               ` Filip Navara
  2008-07-08 19:22               ` Anthony Liguori
@ 2008-08-02 19:21               ` Johannes Schindelin
  2008-08-03 17:11                 ` Anthony Liguori
  2 siblings, 1 reply; 31+ messages in thread
From: Johannes Schindelin @ 2008-08-02 19:21 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Laurent Vivier, qemu-devel, chenqing


This still only supports the client side, and only the TCP version of
it, since Windows does not have Unix sockets.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---

	This is still untested; that is the job of Windows users.
	At least it compiles.

 Makefile      |    1 +
 block-nbd.c   |   10 +++++++---
 nbd.c         |   31 +++++++++++++++++++------------
 nbd.h         |    6 ++++++
 qemu_socket.h |   18 ++++++++++++++++++
 5 files changed, 51 insertions(+), 15 deletions(-)

diff --git a/Makefile b/Makefile
index 0472e16..cf5501f 100644
--- a/Makefile
+++ b/Makefile
@@ -75,6 +75,7 @@ endif
 
 ifdef CONFIG_WIN32
 OBJS+=tap-win32.o
+LIBS+= -lws2_32
 endif
 
 AUDIO_OBJS = audio.o noaudio.o wavaudio.o mixeng.o
diff --git a/block-nbd.c b/block-nbd.c
index 88b6199..7cdbb7c 100644
--- a/block-nbd.c
+++ b/block-nbd.c
@@ -31,11 +31,12 @@
 
 #include <sys/types.h>
 #include <unistd.h>
-#include <sys/socket.h>
+#include "qemu_socket.h"
+#ifndef WIN32
 #include <sys/un.h>
-#include <netinet/in.h>
 #include <arpa/inet.h>
 #include <pthread.h>
+#endif
 
 typedef struct BDRVNBDState {
     int sock;
@@ -61,11 +62,14 @@ static int nbd_open(BlockDriverState *bs, const char* filename, int flags)
 
     if (strstart(host, "unix:", &unixpath)) {
 
+#ifdef _WIN32
+	return -EINVAL;
+#else
         if (unixpath[0] != '/')
             return -EINVAL;
 
         sock = unix_socket_outgoing(unixpath);
-
+#endif
     } else {
         uint16_t port;
         char *p, *r;
diff --git a/nbd.c b/nbd.c
index 9bebe4a..b334f15 100644
--- a/nbd.c
+++ b/nbd.c
@@ -21,18 +21,18 @@
 
 #include <errno.h>
 #include <string.h>
+#include <ctype.h>
+#include <inttypes.h>
+#include "qemu_socket.h"
+#ifndef _WIN32
 #include <sys/ioctl.h>
 #ifdef __sun__
 #include <sys/ioccom.h>
 #endif
-#include <ctype.h>
-#include <inttypes.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <arpa/inet.h>
 #include <netdb.h>
+#endif
 
 #if defined(QEMU_NBD)
 extern int verbose;
@@ -83,7 +83,8 @@ size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read)
         }
 
         /* recoverable error */
-        if (len == -1 && (errno == EAGAIN || errno == EINTR)) {
+        if (len == -1 && (socket_error() == EAGAIN ||
+				socket_error() == EINTR)) {
             continue;
         }
 
@@ -112,6 +113,7 @@ int tcp_socket_outgoing(const char *address, uint16_t port)
 
     s = socket(PF_INET, SOCK_STREAM, 0);
     if (s == -1) {
+        errno = socket_error();
         return -1;
     }
 
@@ -136,8 +138,8 @@ int tcp_socket_outgoing(const char *address, uint16_t port)
 
     return s;
 error:
-    serrno = errno;
-    close(s);
+    serrno = socket_error();
+    closesocket(s);
     errno = serrno;
     return -1;
 }
@@ -152,6 +154,7 @@ int tcp_socket_incoming(const char *address, uint16_t port)
 
     s = socket(PF_INET, SOCK_STREAM, 0);
     if (s == -1) {
+        errno = socket_error();
         return -1;
     }
 
@@ -185,12 +188,13 @@ int tcp_socket_incoming(const char *address, uint16_t port)
 
     return s;
 error:
-    serrno = errno;
-    close(s);
+    serrno = socket_error();
+    closesocket(s);
     errno = serrno;
     return -1;
 }
 
+#ifndef _WIN32
 int unix_socket_incoming(const char *path)
 {
     int s;
@@ -217,7 +221,7 @@ int unix_socket_incoming(const char *path)
     return s;
 error:
     serrno = errno;
-    close(s);
+    closesocket(s);
     errno = serrno;
     return -1;
 }
@@ -244,10 +248,11 @@ int unix_socket_outgoing(const char *path)
     return s;
 error:
     serrno = errno;
-    close(s);
+    closesocket(s);
     errno = serrno;
     return -1;
 }
+#endif
 
 
 /* Basic flow
@@ -337,6 +342,7 @@ int nbd_receive_negotiate(int csock, off_t *size, size_t *blocksize)
         return 0;
 }
 
+#ifndef _WIN32
 int nbd_init(int fd, int csock, off_t size, size_t blocksize)
 {
 	TRACE("Setting block size to %lu", (unsigned long)blocksize);
@@ -410,6 +416,7 @@ int nbd_client(int fd, int csock)
 	errno = serrno;
 	return ret;
 }
+#endif
 
 int nbd_send_request(int csock, struct nbd_request *request)
 {
diff --git a/nbd.h b/nbd.h
index 55ba1ba..387246d 100644
--- a/nbd.h
+++ b/nbd.h
@@ -47,17 +47,23 @@ enum {
 size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read);
 int tcp_socket_outgoing(const char *address, uint16_t port);
 int tcp_socket_incoming(const char *address, uint16_t port);
+#ifndef _WIN32
 int unix_socket_outgoing(const char *path);
 int unix_socket_incoming(const char *path);
+#endif
 
 int nbd_negotiate(BlockDriverState *bs, int csock, off_t size);
 int nbd_receive_negotiate(int csock, off_t *size, size_t *blocksize);
+#ifndef _WIN32
 int nbd_init(int fd, int csock, off_t size, size_t blocksize);
+#endif
 int nbd_send_request(int csock, struct nbd_request *request);
 int nbd_receive_reply(int csock, struct nbd_reply *reply);
 int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
              off_t *offset, bool readonly, uint8_t *data, int data_size);
+#ifndef _WIN32
 int nbd_client(int fd, int csock);
 int nbd_disconnect(int fd);
+#endif
 
 #endif
diff --git a/qemu_socket.h b/qemu_socket.h
index 5229c24..73e05d8 100644
--- a/qemu_socket.h
+++ b/qemu_socket.h
@@ -10,9 +10,27 @@
 
 #define socket_error() WSAGetLastError()
 #undef EINTR
+#undef EINVAL
 #define EWOULDBLOCK WSAEWOULDBLOCK
 #define EINTR       WSAEINTR
 #define EINPROGRESS WSAEINPROGRESS
+#define EINVAL      WSAEINVAL
+
+static inline int inet_aton(const char *cp, struct in_addr *inp)
+{
+	unsigned long result = inet_addr(cp);
+	if (result == INADDR_NONE)
+		return 0;
+	inp->s_addr = result;
+	return 1;
+}
+
+static inline int mingw_setsockopt(int s, int level, int optname,
+		const void *optval, socklen_t optlen)
+{
+	return setsockopt(s, level, optname, (const char *)optval, optlen);
+}
+#define setsockopt mingw_setsockopt
 
 #else
 
-- 
1.6.0.rc1.70.g91e1d

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH v2] Fix compilation of nbd on Windows
  2008-08-02 19:21               ` [Qemu-devel] [PATCH v2] " Johannes Schindelin
@ 2008-08-03 17:11                 ` Anthony Liguori
  2008-08-03 17:32                   ` Johannes Schindelin
  0 siblings, 1 reply; 31+ messages in thread
From: Anthony Liguori @ 2008-08-03 17:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Laurent Vivier, chenqing

Johannes Schindelin wrote:
> This still only supports the client side, and only the TCP version of
> it, since Windows does not have Unix sockets.
>   

This patch fixes the build of qemu-nbd but breaks the build of qemu for 
win32.

> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>
> diff --git a/qemu_socket.h b/qemu_socket.h
> index 5229c24..73e05d8 100644
> --- a/qemu_socket.h
> +++ b/qemu_socket.h
> @@ -10,9 +10,27 @@
>  
>  #define socket_error() WSAGetLastError()
>  #undef EINTR
> +#undef EINVAL
>  #define EWOULDBLOCK WSAEWOULDBLOCK
>  #define EINTR       WSAEINTR
>  #define EINPROGRESS WSAEINPROGRESS
> +#define EINVAL      WSAEINVAL
> +
> +static inline int inet_aton(const char *cp, struct in_addr *inp)
> +{
> +	unsigned long result = inet_addr(cp);
> +	if (result == INADDR_NONE)
> +		return 0;
> +	inp->s_addr = result;
> +	return 1;
> +}
>   

This bit conflicts with:

> #include <winsock2.h>
> int inet_aton(const char *cp, struct in_addr *ia);
> #endif

This definition in vl.c

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH v2] Fix compilation of nbd on Windows
  2008-08-03 17:11                 ` Anthony Liguori
@ 2008-08-03 17:32                   ` Johannes Schindelin
  2008-08-03 20:42                     ` Anthony Liguori
                                       ` (2 more replies)
  0 siblings, 3 replies; 31+ messages in thread
From: Johannes Schindelin @ 2008-08-03 17:32 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Laurent Vivier, qemu-devel, chenqing

Hi,

[was it intentional that you culled me, and me alone, from the Cc: list? 
 I know that you like to be rude against me, but I'd like to know if it 
 was really meant this way this time.]

On Sun, 3 Aug 2008, Anthony Liguori wrote:

> Johannes Schindelin wrote:
> > This still only supports the client side, and only the TCP version of
> > it, since Windows does not have Unix sockets.
> >   
> 
> This patch fixes the build of qemu-nbd but breaks the build of qemu for 
> win32.

The build did not break here.

But then, I do not have a Windows computer myself, so I could not really 
test QEmu itself.

> > +static inline int inet_aton(const char *cp, struct in_addr *inp)
> > +{
> > +	unsigned long result = inet_addr(cp);
> > +	if (result == INADDR_NONE)
> > +		return 0;
> > +	inp->s_addr = result;
> > +	return 1;
> > +}
> >   
> 
> This bit conflicts with:
> 
> > #include <winsock2.h>
> > int inet_aton(const char *cp, struct in_addr *ia);
> > #endif
> 
> This definition in vl.c

It is not the definition, but just the declaration.  And by your own 
reasoning, it should not be in vl.c but in qemu_socket.h, where I would 
have picked up on it and spared myself writing my own implementation of 
inet_aton().

Indeed, it seems that inet_aton() is defined in slirp/misc.c.  So 
qemu_socket.h is not even the right place for the definition, but better 
than nothing.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH v2] Fix compilation of nbd on Windows
  2008-08-03 17:32                   ` Johannes Schindelin
@ 2008-08-03 20:42                     ` Anthony Liguori
  2008-08-03 20:58                       ` Johannes Schindelin
  2008-08-04 13:29                       ` Jamie Lokier
  2008-08-03 21:21                     ` Anthony Liguori
  2008-08-03 21:57                     ` Andreas Färber
  2 siblings, 2 replies; 31+ messages in thread
From: Anthony Liguori @ 2008-08-03 20:42 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Laurent Vivier, qemu-devel, chenqing

Johannes Schindelin wrote:
> Hi,
>
> [was it intentional that you culled me, and me alone, from the Cc: list? 
>  I know that you like to be rude against me, but I'd like to know if it 
>  was really meant this way this time.]
>   

No, it's the annoying way that the mailing list is configured.   The 
mailing list sets a Reply-To header and reply to all in thunderbird 
ignores the original From line (because Reply-To has been set).

> It is not the definition, but just the declaration.

The problem is mixing a static and non-static declaration of a function.

>   And by your own 
> reasoning, it should not be in vl.c but in qemu_socket.h,

Yup.

>  where I would 
> have picked up on it and spared myself writing my own implementation of 
> inet_aton().
>
> Indeed, it seems that inet_aton() is defined in slirp/misc.c.  So 
> qemu_socket.h is not even the right place for the definition, but better 
> than nothing.
>   

Ugh, I wonder what happens when you do --disable-slirp :-(  Do you want 
to work up a patch to sanitize all of this or should I?

Regards,

Anthony Liguori

> Ciao,
> Dscho
>
>   

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH v2] Fix compilation of nbd on Windows
  2008-08-03 20:42                     ` Anthony Liguori
@ 2008-08-03 20:58                       ` Johannes Schindelin
  2008-08-03 21:09                         ` Anthony Liguori
  2008-08-04 13:29                       ` Jamie Lokier
  1 sibling, 1 reply; 31+ messages in thread
From: Johannes Schindelin @ 2008-08-03 20:58 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Laurent Vivier, qemu-devel, chenqing

Hi,

On Sun, 3 Aug 2008, Anthony Liguori wrote:

> Johannes Schindelin wrote:
>
> > Indeed, it seems that inet_aton() is defined in slirp/misc.c.  So 
> > qemu_socket.h is not even the right place for the definition, but 
> > better than nothing.
> 
> Ugh, I wonder what happens when you do --disable-slirp :-( Do you want 
> to work up a patch to sanitize all of this or should I?

You mean to keep my static implementation, but put it in an #ifndef 
CONFIG_SLIRP, with the #else branch declaring the function?

Sure, I can do it, just tell me if that is what you meant.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH v2] Fix compilation of nbd on Windows
  2008-08-03 20:58                       ` Johannes Schindelin
@ 2008-08-03 21:09                         ` Anthony Liguori
  2008-08-03 21:30                           ` Johannes Schindelin
  0 siblings, 1 reply; 31+ messages in thread
From: Anthony Liguori @ 2008-08-03 21:09 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Laurent Vivier, qemu-devel, chenqing

Johannes Schindelin wrote:
> Hi,
>
> On Sun, 3 Aug 2008, Anthony Liguori wrote:
>
>   
>> Johannes Schindelin wrote:
>>
>>     
>>> Indeed, it seems that inet_aton() is defined in slirp/misc.c.  So 
>>> qemu_socket.h is not even the right place for the definition, but 
>>> better than nothing.
>>>       
>> Ugh, I wonder what happens when you do --disable-slirp :-( Do you want 
>> to work up a patch to sanitize all of this or should I?
>>     
>
> You mean to keep my static implementation, but put it in an #ifndef 
> CONFIG_SLIRP, with the #else branch declaring the function?
>
> Sure, I can do it, just tell me if that is what you meant.
>   

It's all pretty messy right now.  I tried to wrap your static 
implementation in a #ifdef QEMU_IMG but then nbd.o gets linked into both 
qemu and qemu-nbd which makes things a pain.  I actually ended up just 
removing the declaration in vl.c and that seemed to work.

Whatever you can do that will make it so we're only using a single 
implementation of inet_aton() will make me happy.

Regards,

Anthony Liguori

> Ciao,
> Dscho
>
>   

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH v2] Fix compilation of nbd on Windows
  2008-08-03 17:32                   ` Johannes Schindelin
  2008-08-03 20:42                     ` Anthony Liguori
@ 2008-08-03 21:21                     ` Anthony Liguori
  2008-08-03 21:37                       ` Johannes Schindelin
  2008-08-03 21:57                     ` Andreas Färber
  2 siblings, 1 reply; 31+ messages in thread
From: Anthony Liguori @ 2008-08-03 21:21 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Laurent Vivier, qemu-devel, chenqing

Johannes Schindelin wrote:
> Hi,
>
> [was it intentional that you culled me, and me alone, from the Cc: list? 
>  I know that you like to be rude against me, but I'd like to know if it 
>  was really meant this way this time.]
>
> On Sun, 3 Aug 2008, Anthony Liguori wrote:
>
>   
>> Johannes Schindelin wrote:
>>     
>>> This still only supports the client side, and only the TCP version of
>>> it, since Windows does not have Unix sockets.
>>>   
>>>       
>> This patch fixes the build of qemu-nbd but breaks the build of qemu for 
>> win32.
>>     
>
> The build did not break here.
>
> But then, I do not have a Windows computer myself, so I could not really 
> test QEmu itself.
>   

BTW, QEMU seems to run just fine under wine.  Right now I'm building 
with mingw and testing with wine.  That seems to be working pretty well.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH v2] Fix compilation of nbd on Windows
  2008-08-03 21:09                         ` Anthony Liguori
@ 2008-08-03 21:30                           ` Johannes Schindelin
  0 siblings, 0 replies; 31+ messages in thread
From: Johannes Schindelin @ 2008-08-03 21:30 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Laurent Vivier, qemu-devel, chenqing

Hi Anthony,

On Sun, 3 Aug 2008, Anthony Liguori wrote:

> Johannes Schindelin wrote:
>
> > On Sun, 3 Aug 2008, Anthony Liguori wrote:
> >
> > > Johannes Schindelin wrote:
> > >     
> > > > Indeed, it seems that inet_aton() is defined in slirp/misc.c.  So 
> > > > qemu_socket.h is not even the right place for the definition, but 
> > > > better than nothing.
> > >
> > > Ugh, I wonder what happens when you do --disable-slirp :-( Do you 
> > > want to work up a patch to sanitize all of this or should I?
> >
> > You mean to keep my static implementation, but put it in an #ifndef 
> > CONFIG_SLIRP, with the #else branch declaring the function?
> >
> > Sure, I can do it, just tell me if that is what you meant.
> 
> It's all pretty messy right now.  I tried to wrap your static 
> implementation in a #ifdef QEMU_IMG but then nbd.o gets linked into both 
> qemu and qemu-nbd which makes things a pain.  I actually ended up just 
> removing the declaration in vl.c and that seemed to work.

Yes, I just realized that it gets messy.

> Whatever you can do that will make it so we're only using a single 
> implementation of inet_aton() will make me happy.

Well, we cannot cleanly include qemu_socket.h from slirp, can we?  And we 
cannot link qemu_common.a to qemu-img because of the missing 
implementations for *_input().

So I think that unfortunately, we have no clean way to have a single 
implementation, short of having a separate "inet_aton.h" in slirp/ with a 
static implementation...

The whole issue only arises because Win32 misses inet_aton(), sigh.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH v2] Fix compilation of nbd on Windows
  2008-08-03 21:21                     ` Anthony Liguori
@ 2008-08-03 21:37                       ` Johannes Schindelin
  2008-08-04 13:23                         ` Jamie Lokier
  0 siblings, 1 reply; 31+ messages in thread
From: Johannes Schindelin @ 2008-08-03 21:37 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Laurent Vivier, qemu-devel, chenqing

Hi,

On Sun, 3 Aug 2008, Anthony Liguori wrote:

> Johannes Schindelin wrote:
>
> > On Sun, 3 Aug 2008, Anthony Liguori wrote:
> >   
> > > Johannes Schindelin wrote:
> > >     
> > > > This still only supports the client side, and only the TCP version 
> > > > of it, since Windows does not have Unix sockets.
> > >
> > > This patch fixes the build of qemu-nbd but breaks the build of qemu 
> > > for win32.
> >
> > The build did not break here.
> >
> > But then, I do not have a Windows computer myself, so I could not 
> > really test QEmu itself.
> 
> BTW, QEMU seems to run just fine under wine.  Right now I'm building 
> with mingw and testing with wine.  That seems to be working pretty well.

In my experience, Wine only shows you so far what works on Windows and 
what does not.  For example, MingW itself does not run properly in Wine.  
At least last time I needed it.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH v2] Fix compilation of nbd on Windows
  2008-08-03 17:32                   ` Johannes Schindelin
  2008-08-03 20:42                     ` Anthony Liguori
  2008-08-03 21:21                     ` Anthony Liguori
@ 2008-08-03 21:57                     ` Andreas Färber
  2 siblings, 0 replies; 31+ messages in thread
From: Andreas Färber @ 2008-08-03 21:57 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Laurent Vivier, qemu-devel

Hi Dscho,

Am 03.08.2008 um 19:32 schrieb Johannes Schindelin:

> [was it intentional that you culled me, and me alone, from the Cc:  
> list?

I have seen it happening myself multiple times on this list that a CC  
was somehow dropped. That is, it's still there in my sent message but  
doesn't show up in the received list message.

My recent nbd patch for instance was cc'ed to Laurent Vivier but the  
list message shows no CC at all.

Anyway, don't take it personal.

Andreas

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH v2] Fix compilation of nbd on Windows
  2008-08-03 21:37                       ` Johannes Schindelin
@ 2008-08-04 13:23                         ` Jamie Lokier
  0 siblings, 0 replies; 31+ messages in thread
From: Jamie Lokier @ 2008-08-04 13:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: Laurent Vivier, chenqing

Johannes Schindelin wrote:
> > > But then, I do not have a Windows computer myself, so I could not 
> > > really test QEmu itself.
> > 
> > BTW, QEMU seems to run just fine under wine.  Right now I'm building 
> > with mingw and testing with wine.  That seems to be working pretty well.
> 
> In my experience, Wine only shows you so far what works on Windows and 
> what does not.  For example, MingW itself does not run properly in Wine.  
> At least last time I needed it.


Unfortunately, for testing, Wine is also _able_ to run some programs
that _don't_ run under Windows.

I cross-compiled my unix application using Mingw (GCC for native
Windows), and after a few fixes, it was working in Wine.

Unfortunately when I came to deliver the program to a real user, it
totally failed under Windows XP.

In that instance, it was because Wine allocates file descriptors with
small numbers (like unix) and Windows allocates large HANDLE values,
so my unix-friendly code ran ok under Wine but not under real Windows.

The only real test is running it under Windows - I use a virtual
machine (KVM) for that.

-- Jamie

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH v2] Fix compilation of nbd on Windows
  2008-08-03 20:42                     ` Anthony Liguori
  2008-08-03 20:58                       ` Johannes Schindelin
@ 2008-08-04 13:29                       ` Jamie Lokier
  2008-08-04 16:49                         ` Thiemo Seufer
  1 sibling, 1 reply; 31+ messages in thread
From: Jamie Lokier @ 2008-08-04 13:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Laurent Vivier, chenqing

Anthony Liguori wrote:
> Johannes Schindelin wrote:
> >Hi,
> >
> >[was it intentional that you culled me, and me alone, from the Cc: list? 
> > I know that you like to be rude against me, but I'd like to know if it 
> > was really meant this way this time.]
> >  
> 
> No, it's the annoying way that the mailing list is configured.   The 
> mailing list sets a Reply-To header and reply to all in thunderbird 
> ignores the original From line (because Reply-To has been set).

Mutt's group-reply function is the same.  It sends to everyone in the
To and Cc, but not the person in From!  Very annoying on a list like this.
It has an option to ignore list's Reply-To entirely, but not an option
to make group-reply send to everyone.

-- Jamie

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH v2] Fix compilation of nbd on Windows
  2008-08-04 13:29                       ` Jamie Lokier
@ 2008-08-04 16:49                         ` Thiemo Seufer
  0 siblings, 0 replies; 31+ messages in thread
From: Thiemo Seufer @ 2008-08-04 16:49 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Laurent Vivier, qemu-devel, chenqing

Jamie Lokier wrote:
> Anthony Liguori wrote:
> > Johannes Schindelin wrote:
> > >Hi,
> > >
> > >[was it intentional that you culled me, and me alone, from the Cc: list? 
> > > I know that you like to be rude against me, but I'd like to know if it 
> > > was really meant this way this time.]
> > >  
> > 
> > No, it's the annoying way that the mailing list is configured.   The 
> > mailing list sets a Reply-To header and reply to all in thunderbird 
> > ignores the original From line (because Reply-To has been set).
> 
> Mutt's group-reply function is the same.  It sends to everyone in the
> To and Cc, but not the person in From!  Very annoying on a list like this.
> It has an option to ignore list's Reply-To entirely, but not an option
> to make group-reply send to everyone.

Maybe

  unset reply_to

helps in this case.


Thiemo

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2008-08-04 16:49 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-03 13:41 [Qemu-devel] [4838] Allow QEMU to connect directly to an NBD server, by Laurent Vivier Thiemo Seufer
2008-07-04  1:33 ` chenqing
2008-07-04  2:34   ` Thiemo Seufer
2008-07-04  3:51     ` chenqing
2008-07-04  8:42       ` Laurent Vivier
2008-07-04 20:32         ` Thiemo Seufer
2008-07-04 20:52           ` Johannes Schindelin
2008-07-04 22:02             ` [Qemu-devel] [PATCH] Fix compilation of nbd on Windows Johannes Schindelin
2008-07-05 11:58               ` Filip Navara
2008-07-05 22:41                 ` Jamie Lokier
2008-07-06  1:51                   ` Johannes Schindelin
2008-07-06 16:49                     ` Jamie Lokier
2008-07-06 17:23                       ` Johannes Schindelin
2008-07-08 19:22               ` Anthony Liguori
2008-07-09  0:14                 ` Johannes Schindelin
2008-07-18 14:24                   ` [Qemu-devel] " Sebastian Herbszt
2008-07-18 15:26                     ` Johannes Schindelin
2008-08-02 19:21               ` [Qemu-devel] [PATCH v2] " Johannes Schindelin
2008-08-03 17:11                 ` Anthony Liguori
2008-08-03 17:32                   ` Johannes Schindelin
2008-08-03 20:42                     ` Anthony Liguori
2008-08-03 20:58                       ` Johannes Schindelin
2008-08-03 21:09                         ` Anthony Liguori
2008-08-03 21:30                           ` Johannes Schindelin
2008-08-04 13:29                       ` Jamie Lokier
2008-08-04 16:49                         ` Thiemo Seufer
2008-08-03 21:21                     ` Anthony Liguori
2008-08-03 21:37                       ` Johannes Schindelin
2008-08-04 13:23                         ` Jamie Lokier
2008-08-03 21:57                     ` Andreas Färber
2008-07-04  8:01     ` [Qemu-devel] [4838] Allow QEMU to connect directly to an NBD server, by Laurent Vivier Laurent Vivier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).