Merge branch 'master' of /home/nchip/public_html/qemu into garage-push
[qemu] / nbd.c
diff --git a/nbd.c b/nbd.c
index 9bebe4a..b397a5f 100644 (file)
--- a/nbd.c
+++ b/nbd.c
  *
  *  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
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
  */
 
 #include "nbd.h"
 
 #include <errno.h>
 #include <string.h>
+#ifndef _WIN32
 #include <sys/ioctl.h>
+#endif
 #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>
-
-#if defined(QEMU_NBD)
-extern int verbose;
-#else
-static int verbose = 0;
-#endif
 
+#include "qemu_socket.h"
+
+//#define DEBUG_NBD
+
+#ifdef DEBUG_NBD
 #define TRACE(msg, ...) do { \
-    if (verbose) LOG(msg, ## __VA_ARGS__); \
+    LOG(msg, ## __VA_ARGS__); \
 } while(0)
+#else
+#define TRACE(msg, ...) \
+    do { } while (0)
+#endif
 
 #define LOG(msg, ...) do { \
     fprintf(stderr, "%s:%s():L%d: " msg "\n", \
@@ -77,11 +76,14 @@ size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read)
         ssize_t len;
 
         if (do_read) {
-            len = read(fd, buffer + offset, size - offset);
+            len = recv(fd, buffer + offset, size - offset, 0);
         } else {
-            len = write(fd, buffer + offset, size - offset);
+            len = send(fd, buffer + offset, size - offset, 0);
         }
 
+        if (len == -1)
+            errno = socket_error();
+
         /* recoverable error */
         if (len == -1 && (errno == EAGAIN || errno == EINTR)) {
             continue;
@@ -108,7 +110,6 @@ int tcp_socket_outgoing(const char *address, uint16_t port)
     int s;
     struct in_addr in;
     struct sockaddr_in addr;
-    int serrno;
 
     s = socket(PF_INET, SOCK_STREAM, 0);
     if (s == -1) {
@@ -136,9 +137,7 @@ int tcp_socket_outgoing(const char *address, uint16_t port)
 
     return s;
 error:
-    serrno = errno;
-    close(s);
-    errno = serrno;
+    closesocket(s);
     return -1;
 }
 
@@ -147,7 +146,6 @@ int tcp_socket_incoming(const char *address, uint16_t port)
     int s;
     struct in_addr in;
     struct sockaddr_in addr;
-    int serrno;
     int opt;
 
     s = socket(PF_INET, SOCK_STREAM, 0);
@@ -171,7 +169,8 @@ int tcp_socket_incoming(const char *address, uint16_t port)
     memcpy(&addr.sin_addr.s_addr, &in, sizeof(in));
 
     opt = 1;
-    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {
+    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+                   (const void *) &opt, sizeof(opt)) == -1) {
         goto error;
     }
 
@@ -185,17 +184,15 @@ int tcp_socket_incoming(const char *address, uint16_t port)
 
     return s;
 error:
-    serrno = errno;
-    close(s);
-    errno = serrno;
+    closesocket(s);
     return -1;
 }
 
+#ifndef _WIN32
 int unix_socket_incoming(const char *path)
 {
     int s;
     struct sockaddr_un addr;
-    int serrno;
 
     s = socket(PF_UNIX, SOCK_STREAM, 0);
     if (s == -1) {
@@ -216,9 +213,7 @@ int unix_socket_incoming(const char *path)
 
     return s;
 error:
-    serrno = errno;
-    close(s);
-    errno = serrno;
+    closesocket(s);
     return -1;
 }
 
@@ -226,7 +221,6 @@ int unix_socket_outgoing(const char *path)
 {
     int s;
     struct sockaddr_un addr;
-    int serrno;
 
     s = socket(PF_UNIX, SOCK_STREAM, 0);
     if (s == -1) {
@@ -243,12 +237,23 @@ int unix_socket_outgoing(const char *path)
 
     return s;
 error:
-    serrno = errno;
-    close(s);
-    errno = serrno;
+    closesocket(s);
+    return -1;
+}
+#else
+int unix_socket_incoming(const char *path)
+{
+    errno = ENOTSUP;
     return -1;
 }
 
+int unix_socket_outgoing(const char *path)
+{
+    errno = ENOTSUP;
+    return -1;
+}
+#endif
+
 
 /* Basic flow
 
@@ -264,7 +269,7 @@ error:
                   Request (type == 2)
 */
 
-int nbd_negotiate(BlockDriverState *bs, int csock, off_t size)
+int nbd_negotiate(int csock, off_t size)
 {
        char buf[8 + 8 + 8 + 128];
 
@@ -310,14 +315,14 @@ int nbd_receive_negotiate(int csock, off_t *size, size_t *blocksize)
        *blocksize = 1024;
 
        TRACE("Magic is %c%c%c%c%c%c%c%c",
-             isprint(buf[0]) ? buf[0] : '.',
-             isprint(buf[1]) ? buf[1] : '.',
-             isprint(buf[2]) ? buf[2] : '.',
-             isprint(buf[3]) ? buf[3] : '.',
-             isprint(buf[4]) ? buf[4] : '.',
-             isprint(buf[5]) ? buf[5] : '.',
-             isprint(buf[6]) ? buf[6] : '.',
-             isprint(buf[7]) ? buf[7] : '.');
+             qemu_isprint(buf[0]) ? buf[0] : '.',
+             qemu_isprint(buf[1]) ? buf[1] : '.',
+             qemu_isprint(buf[2]) ? buf[2] : '.',
+             qemu_isprint(buf[3]) ? buf[3] : '.',
+             qemu_isprint(buf[4]) ? buf[4] : '.',
+             qemu_isprint(buf[5]) ? buf[5] : '.',
+             qemu_isprint(buf[6]) ? buf[6] : '.',
+             qemu_isprint(buf[7]) ? buf[7] : '.');
        TRACE("Magic is 0x%" PRIx64, magic);
        TRACE("Size is %" PRIu64, *size);
 
@@ -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,25 @@ int nbd_client(int fd, int csock)
        errno = serrno;
        return ret;
 }
+#else
+int nbd_init(int fd, int csock, off_t size, size_t blocksize)
+{
+    errno = ENOTSUP;
+    return -1;
+}
+
+int nbd_disconnect(int fd)
+{
+    errno = ENOTSUP;
+    return -1;
+}
+
+int nbd_client(int fd, int csock)
+{
+    errno = ENOTSUP;
+    return -1;
+}
+#endif
 
 int nbd_send_request(int csock, struct nbd_request *request)
 {
@@ -555,7 +580,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset,
        if ((request.from + request.len) > size) {
                LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64
                    ", Offset: %" PRIu64 "\n",
-                    request.from, request.len, size, dev_offset);
+                    request.from, request.len, (uint64_t)size, dev_offset);
                LOG("requested operation past EOF--bad client?");
                errno = EINVAL;
                return -1;