Merge branch 'alex'
[nbd.git] / nbd-server.c
index cd67e44..6d734b3 100644 (file)
@@ -133,17 +133,9 @@ int dontfork = 0;
 /* Debugging macros */
 //#define DODBG
 #ifdef DODBG
-#define DEBUG( a ) printf( a )
-#define DEBUG2( a,b ) printf( a,b )
-#define DEBUG3( a,b,c ) printf( a,b,c )
-#define DEBUG4( a,b,c,d ) printf( a,b,c,d )
-#define DEBUG5( a,b,c,d,e ) printf( a,b,c,d,e )
+#define DEBUG(...) printf(__VA_ARGS__)
 #else
-#define DEBUG( a )
-#define DEBUG2( a,b ) 
-#define DEBUG3( a,b,c ) 
-#define DEBUG4( a,b,c,d ) 
-#define DEBUG5( a,b,c,d,e ) 
+#define DEBUG(...)
 #endif
 #ifndef PACKAGE_VERSION
 #define PACKAGE_VERSION ""
@@ -269,6 +261,22 @@ typedef struct {
                                  is PARAM_BOOL. */
 } PARAM;
 
+static inline const char * getcommandname(uint64_t command) {
+       switch (command) {
+       case NBD_CMD_READ:
+               return "NBD_CMD_READ";
+       case NBD_CMD_WRITE:
+               return "NBD_CMD_WRITE";
+       case NBD_CMD_DISC:
+               return "NBD_CMD_DISC";
+       case NBD_CMD_FLUSH:
+               return "NBD_CMD_FLUSH";
+       default:
+               break;
+       }
+       return "UNKNOWN";
+}
+
 /**
  * Check whether a client is allowed to connect. Works with an authorization
  * file which contains one line per machine, no wildcards.
@@ -914,7 +922,7 @@ void sigchld_handler(int s) {
                if(!i) {
                        msg3(LOG_INFO, "SIGCHLD received for an unknown child with PID %ld", (long)pid);
                } else {
-                       DEBUG2("Removing %d from the list of children", pid);
+                       DEBUG("Removing %d from the list of children", pid);
                        g_hash_table_remove(children, &pid);
                }
        }
@@ -992,7 +1000,7 @@ off_t size_autodetect(int fhandle) {
        if (es > ((off_t)0)) {
                return es;
         } else {
-                DEBUG2("lseek failed: %d", errno==EBADF?1:(errno==ESPIPE?2:(errno==EINVAL?3:4)));
+                DEBUG("lseek failed: %d", errno==EBADF?1:(errno==ESPIPE?2:(errno==EINVAL?3:4)));
         }
 
        err("Could not find size of exported block device: %m");
@@ -1082,7 +1090,7 @@ ssize_t rawexpwrite(off_t a, char *buf, size_t len, CLIENT *client, int fua) {
        if(maxbytes && len > maxbytes)
                len = maxbytes;
 
-       DEBUG5("(WRITE to fd %d offset %llu len %u fua %d), ", fhandle, foffset, len, fua);
+       DEBUG("(WRITE to fd %d offset %llu len %u fua %d), ", fhandle, (long long unsigned)foffset, (unsigned int)len, fua);
 
        myseek(fhandle, foffset);
        retval = write(fhandle, buf, len);
@@ -1167,7 +1175,7 @@ ssize_t rawexpread(off_t a, char *buf, size_t len, CLIENT *client) {
        if(maxbytes && len > maxbytes)
                len = maxbytes;
 
-       DEBUG4("(READ from fd %d offset %llu len %u), ", fhandle, foffset, len);
+       DEBUG("(READ from fd %d offset %llu len %u), ", fhandle, (long long unsigned int)foffset, (unsigned int)len);
 
        myseek(fhandle, foffset);
        return read(fhandle, buf, len);
@@ -1204,7 +1212,7 @@ int expread(off_t a, char *buf, size_t len, CLIENT *client) {
 
        if (!(client->server->flags & F_COPYONWRITE))
                return(rawexpread_fully(a, buf, len, client));
-       DEBUG3("Asked to read %d bytes at %llu.\n", len, (unsigned long long)a);
+       DEBUG("Asked to read %u bytes at %llu.\n", (unsigned int)len, (unsigned long long)a);
 
        mapl=a/DIFFPAGESIZE; maph=(a+len-1)/DIFFPAGESIZE;
 
@@ -1214,12 +1222,12 @@ int expread(off_t a, char *buf, size_t len, CLIENT *client) {
                rdlen=(0<DIFFPAGESIZE-offset && len<(size_t)(DIFFPAGESIZE-offset)) ?
                        len : (size_t)DIFFPAGESIZE-offset;
                if (client->difmap[mapcnt]!=(u32)(-1)) { /* the block is already there */
-                       DEBUG3("Page %llu is at %lu\n", (unsigned long long)mapcnt,
+                       DEBUG("Page %llu is at %lu\n", (unsigned long long)mapcnt,
                               (unsigned long)(client->difmap[mapcnt]));
                        myseek(client->difffile, client->difmap[mapcnt]*DIFFPAGESIZE+offset);
                        if (read(client->difffile, buf, rdlen) != rdlen) return -1;
                } else { /* the block is not there */
-                       DEBUG2("Page %llu is not here, we read the original one\n",
+                       DEBUG("Page %llu is not here, we read the original one\n",
                               (unsigned long long)mapcnt);
                        if(rawexpread_fully(a, buf, rdlen, client)) return -1;
                }
@@ -1248,7 +1256,7 @@ int expwrite(off_t a, char *buf, size_t len, CLIENT *client, int fua) {
 
        if (!(client->server->flags & F_COPYONWRITE))
                return(rawexpwrite_fully(a, buf, len, client, fua)); 
-       DEBUG3("Asked to write %d bytes at %llu.\n", len, (unsigned long long)a);
+       DEBUG("Asked to write %u bytes at %llu.\n", (unsigned int)len, (unsigned long long)a);
 
        mapl=a/DIFFPAGESIZE ; maph=(a+len-1)/DIFFPAGESIZE ;
 
@@ -1259,7 +1267,7 @@ int expwrite(off_t a, char *buf, size_t len, CLIENT *client, int fua) {
                        len : (size_t)DIFFPAGESIZE-offset;
 
                if (client->difmap[mapcnt]!=(u32)(-1)) { /* the block is already there */
-                       DEBUG3("Page %llu is at %lu\n", (unsigned long long)mapcnt,
+                       DEBUG("Page %llu is at %lu\n", (unsigned long long)mapcnt,
                               (unsigned long)(client->difmap[mapcnt])) ;
                        myseek(client->difffile,
                                        client->difmap[mapcnt]*DIFFPAGESIZE+offset);
@@ -1267,7 +1275,7 @@ int expwrite(off_t a, char *buf, size_t len, CLIENT *client, int fua) {
                } else { /* the block is not there */
                        myseek(client->difffile,client->difffilelen*DIFFPAGESIZE) ;
                        client->difmap[mapcnt]=(client->server->flags&F_SPARSE)?mapcnt:client->difffilelen++;
-                       DEBUG3("Page %llu is not here, we put it at %lu\n",
+                       DEBUG("Page %llu is not here, we put it at %lu\n",
                               (unsigned long long)mapcnt,
                               (unsigned long)(client->difmap[mapcnt]));
                        rdlen=DIFFPAGESIZE ;
@@ -1292,9 +1300,6 @@ int expwrite(off_t a, char *buf, size_t len, CLIENT *client, int fua) {
 }
 
 int expflush(CLIENT *client) {
-       int fhandle;
-       off_t foffset;
-       size_t maxbytes;
        gint i;
 
         if (client->server->flags & F_COPYONWRITE) {
@@ -1469,34 +1474,15 @@ int mainloop(CLIENT *client) {
                request.from = ntohll(request.from);
                request.type = ntohl(request.type);
                command = request.type & NBD_CMD_MASK_COMMAND;
-
-               if (command==NBD_CMD_DISC) {
-                       msg2(LOG_INFO, "Disconnect request received.");
-                       if (client->server->flags & F_COPYONWRITE) { 
-                               if (client->difmap) g_free(client->difmap) ;
-                               close(client->difffile);
-                               unlink(client->difffilename);
-                               free(client->difffilename);
-                       }
-                       go_on=FALSE;
-                       continue;
-               }
-
                len = ntohl(request.len);
 
+               DEBUG("%s from %llu (%llu) len %d, ", getcommandname(command),
+                               (unsigned long long)request.from,
+                               (unsigned long long)request.from / 512, (unsigned int)len);
+
                if (request.magic != htonl(NBD_REQUEST_MAGIC))
                        err("Not enough magic.");
-               if (len > BUFSIZE - sizeof(struct nbd_reply)) {
-                       currlen = BUFSIZE - sizeof(struct nbd_reply);
-                       msg2(LOG_INFO, "oversized request (this is not a problem)");
-               } else {
-                       currlen = len;
-               }
-#ifdef DODBG
-               printf("%s from %llu (%llu) len %d, ", command ? "WRITE" :
-                               "READ", (unsigned long long)request.from,
-                               (unsigned long long)request.from / 512, len);
-#endif
+
                memcpy(reply.handle, request.handle, sizeof(reply.handle));
 
                if ((command==NBD_CMD_WRITE) || (command==NBD_CMD_READ)) {
@@ -1511,9 +1497,28 @@ int mainloop(CLIENT *client) {
                                ERROR(client, reply, EINVAL);
                                continue;
                        }
+
+                       currlen = len;
+                       if (currlen > BUFSIZE - sizeof(struct nbd_reply)) {
+                               currlen = BUFSIZE - sizeof(struct nbd_reply);
+                               msg2(LOG_INFO, "oversized request (this is not a problem)");
+                       }
                }
 
-               if (command==NBD_CMD_WRITE) {
+               switch (command) {
+
+               case NBD_CMD_DISC:
+                       msg2(LOG_INFO, "Disconnect request received.");
+                       if (client->server->flags & F_COPYONWRITE) { 
+                               if (client->difmap) g_free(client->difmap) ;
+                               close(client->difffile);
+                               unlink(client->difffilename);
+                               free(client->difffilename);
+                       }
+                       go_on=FALSE;
+                       continue;
+
+               case NBD_CMD_WRITE:
                        DEBUG("wr: net->buf, ");
                        while(len > 0) {
                                readit(client->net, buf, currlen);
@@ -1530,15 +1535,14 @@ int mainloop(CLIENT *client) {
                                        ERROR(client, reply, errno);
                                        continue;
                                }
-                               SEND(client->net, reply);
-                               DEBUG("OK!\n");
                                len -= currlen;
                                currlen = (len < BUFSIZE) ? len : BUFSIZE;
                        }
+                       SEND(client->net, reply);
+                       DEBUG("OK!\n");
                        continue;
-               }
 
-               if (command==NBD_CMD_FLUSH) {
+               case NBD_CMD_FLUSH:
                        DEBUG("fl: ");
                        if (expflush(client)) {
                                DEBUG("Flush failed: %m");
@@ -1548,9 +1552,8 @@ int mainloop(CLIENT *client) {
                        SEND(client->net, reply);
                        DEBUG("OK!\n");
                        continue;
-               }
 
-               if (command==NBD_CMD_READ) {
+               case NBD_CMD_READ:
                        DEBUG("exp->buf, ");
                        memcpy(buf, &reply, sizeof(struct nbd_reply));
                        if (client->transactionlogfd != -1)
@@ -1574,9 +1577,11 @@ int mainloop(CLIENT *client) {
                        }
                        DEBUG("OK!\n");
                        continue;
-               }
 
-               DEBUG ("Ignoring unknown command\n");
+               default:
+                       DEBUG ("Ignoring unknown command\n");
+                       continue;
+               }
        }
        return 0;
 }
@@ -1607,7 +1612,7 @@ void setupexport(CLIENT* client) {
                } else {
                        tmpname=g_strdup(client->exportname);
                }
-               DEBUG2( "Opening %s\n", tmpname );
+               DEBUG( "Opening %s\n", tmpname );
                fi.fhandle = open(tmpname, mode);
                if(fi.fhandle == -1 && mode == O_RDWR) {
                        /* Try again because maybe media was read-only */