vol: Log more info on wrong SYNC response length
[openafs.git] / src / vol / daemon_com.c
index 28bcf52..4256a20 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2006-2008, Sine Nomine Associates and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
 #include <afsconfig.h>
 #include <afs/param.h>
 
-
-#include <sys/types.h>
-#include <stdio.h>
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
-#include <time.h>
-#else
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <sys/time.h>
-#endif
-#include <errno.h>
-#include <assert.h>
-#include <signal.h>
-#include <string.h>
-
+#include <roken.h>
+#include <afs/opr.h>
 
 #include <rx/xdr.h>
 #include <afs/afsint.h>
-#include "nfs.h"
 #include <afs/errors.h>
+#include <rx/rx_queue.h>
+
+#include "nfs.h"
 #include "daemon_com.h"
 #include "lwp.h"
 #include "lock.h"
@@ -52,6 +38,7 @@
 #include "vnode.h"
 #include "volume.h"
 #include "partition.h"
+#include "common.h"
 #include <rx/rx_queue.h>
 
 #ifdef USE_UNIX_SOCKETS
@@ -59,8 +46,6 @@
 #include <sys/un.h>
 #endif
 
-/*@printflike@*/ extern void Log(const char *format, ...);
-
 int (*V_BreakVolumeCallbacks) (VolumeId);
 
 #define MAXHANDLERS    4       /* Up to 4 clients; must be at least 2, so that
@@ -96,17 +81,13 @@ static int SYNC_ask_internal(SYNC_client_state * state, SYNC_command * com, SYNC
 void
 SYNC_getAddr(SYNC_endpoint_t * endpoint, SYNC_sockaddr_t * addr)
 {
-#ifdef USE_UNIX_SOCKETS
-    char tbuffer[AFSDIR_PATH_MAX];
-#endif /* USE_UNIX_SOCKETS */
-
     memset(addr, 0, sizeof(*addr));
 
 #ifdef USE_UNIX_SOCKETS
-    strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/",
-               endpoint->un, NULL);
     addr->sun_family = AF_UNIX;
-    strncpy(addr->sun_path, tbuffer, (sizeof(struct sockaddr_un) - sizeof(short)));
+    snprintf(addr->sun_path, sizeof(addr->sun_path), "%s/%s",
+            AFSDIR_SERVER_LOCAL_DIRPATH, endpoint->un);
+    addr->sun_path[sizeof(addr->sun_path) - 1] = '\0';
 #else  /* !USE_UNIX_SOCKETS */
 #ifdef STRUCT_SOCKADDR_HAS_SA_LEN
     addr->sin_len = sizeof(struct sockaddr_in);
@@ -131,7 +112,7 @@ osi_socket
 SYNC_getSock(SYNC_endpoint_t * endpoint)
 {
     osi_socket sd;
-    assert((sd = socket(endpoint->domain, SOCK_STREAM, 0)) >= 0);
+    opr_Verify((sd = socket(endpoint->domain, SOCK_STREAM, 0)) >= 0);
     return sd;
 }
 
@@ -156,7 +137,7 @@ SYNC_connect(SYNC_client_state * state)
        { 3, 3, 3, 5, 5, 5, 7, 15, 16, 24, 32, 40, 48, 0 };
     time_t *timeout = &backoff[0];
 
-    if (state->fd >= 0) {
+    if (state->fd != OSI_NULLSOCKET) {
        return 1;
     }
 
@@ -189,12 +170,8 @@ SYNC_connect(SYNC_client_state * state)
 int
 SYNC_disconnect(SYNC_client_state * state)
 {
-#ifdef AFS_NT40_ENV
-    closesocket(state->fd);
-#else
-    close(state->fd);
-#endif
-    state->fd = -1;
+    rk_closesocket(state->fd);
+    state->fd = OSI_NULLSOCKET;
     return 0;
 }
 
@@ -213,7 +190,7 @@ SYNC_closeChannel(SYNC_client_state * state)
     SYNC_response res;
     SYNC_PROTO_BUF_DECL(ores);
 
-    if (state->fd == -1)
+    if (state->fd == OSI_NULLSOCKET)
        return SYNC_OK;
 
     memset(&com, 0, sizeof(com));
@@ -275,16 +252,11 @@ SYNC_ask(SYNC_client_state * state, SYNC_command * com, SYNC_response * res)
     int tries;
     afs_uint32 now, timeout, code=SYNC_OK;
 
-    if (state->fatal_error) {
-       return SYNC_COM_ERROR;
-    }
-
-    if (state->fd == -1) {
+    if (state->fd == OSI_NULLSOCKET) {
        SYNC_connect(state);
     }
 
-    if (state->fd == -1) {
-       state->fatal_error = 1;
+    if (state->fd == OSI_NULLSOCKET) {
        return SYNC_COM_ERROR;
     }
 
@@ -294,7 +266,7 @@ SYNC_ask(SYNC_client_state * state, SYNC_command * com, SYNC_response * res)
 
     now = FT_ApproxTime();
     timeout = now + state->hard_timeout;
-    for (tries = 0; 
+    for (tries = 0;
         (tries <= state->retry_limit) && (now <= timeout);
         tries++, now = FT_ApproxTime()) {
        code = SYNC_ask_internal(state, com, res);
@@ -311,19 +283,18 @@ SYNC_ask(SYNC_client_state * state, SYNC_command * com, SYNC_response * res)
            SYNC_reconnect(state);
            /* try again */
        } else {
-           /* 
-            * unknown (probably protocol-specific) response code, pass it up to 
-            * the caller, and let them deal with it 
+           /*
+            * unknown (probably protocol-specific) response code, pass it up to
+            * the caller, and let them deal with it
             */
            break;
        }
     }
 
     if (code == SYNC_COM_ERROR) {
-       Log("SYNC_ask: fatal protocol error on circuit '%s'; disabling sync "
-           "protocol until next server restart\n", 
-           state->proto_name);
-       state->fatal_error = 1;
+       Log("SYNC_ask: too many / too latent fatal protocol errors on circuit "
+           "'%s'; giving up (tries %d timeout %d)\n",
+           state->proto_name, tries, timeout);
     }
 
     return code;
@@ -352,7 +323,7 @@ SYNC_ask_internal(SYNC_client_state * state, SYNC_command * com, SYNC_response *
     struct iovec iov[2];
 #endif
 
-    if (state->fd == -1) {
+    if (state->fd == OSI_NULLSOCKET) {
        Log("SYNC_ask:  invalid sync file descriptor on circuit '%s'\n",
            state->proto_name);
        res->hdr.response = SYNC_COM_ERROR;
@@ -378,7 +349,7 @@ SYNC_ask_internal(SYNC_client_state * state, SYNC_command * com, SYNC_response *
 #else
     com->hdr.pid = getpid();
 #ifdef AFS_PTHREAD_ENV
-    com->hdr.tid = (afs_int32)pthread_self();
+    com->hdr.tid = afs_pointer_to_int(pthread_self());
 #else
     {
        PROCESS handle = LWP_ThreadId();
@@ -389,7 +360,7 @@ SYNC_ask_internal(SYNC_client_state * state, SYNC_command * com, SYNC_response *
 
     memcpy(buf, &com->hdr, sizeof(com->hdr));
     if (com->payload.len) {
-       memcpy(buf + sizeof(com->hdr), com->payload.buf, 
+       memcpy(buf + sizeof(com->hdr), com->payload.buf,
               com->hdr.command_len - sizeof(com->hdr));
     }
 
@@ -448,7 +419,7 @@ SYNC_ask_internal(SYNC_client_state * state, SYNC_command * com, SYNC_response *
     res->recv_len = n;
 
     if (n < sizeof(res->hdr)) {
-       Log("SYNC_ask:  response too short on circuit '%s'\n", 
+       Log("SYNC_ask:  response too short on circuit '%s'\n",
            state->proto_name);
        res->hdr.response = SYNC_COM_ERROR;
        goto done;
@@ -458,7 +429,7 @@ SYNC_ask_internal(SYNC_client_state * state, SYNC_command * com, SYNC_response *
 #endif
 
     if ((n - sizeof(res->hdr)) > res->payload.len) {
-       Log("SYNC_ask:  response too long on circuit '%s'\n", 
+       Log("SYNC_ask:  response too long on circuit '%s'\n",
            state->proto_name);
        res->hdr.response = SYNC_COM_ERROR;
        goto done;
@@ -469,7 +440,10 @@ SYNC_ask_internal(SYNC_client_state * state, SYNC_command * com, SYNC_response *
 
     if (res->hdr.response_len != n) {
        Log("SYNC_ask:  length field in response inconsistent "
-           "on circuit '%s'\n", state->proto_name);
+           "on circuit '%s' command %ld, %d != %lu\n", state->proto_name,
+           afs_printable_int32_ld(com->hdr.command),
+           n,
+           afs_printable_uint32_lu(res->hdr.response_len));
        res->hdr.response = SYNC_COM_ERROR;
        goto done;
     }
@@ -482,8 +456,8 @@ SYNC_ask_internal(SYNC_client_state * state, SYNC_command * com, SYNC_response *
 }
 
 
-/* 
- * daemon com SYNC server-side interfaces 
+/*
+ * daemon com SYNC server-side interfaces
  */
 
 /**
@@ -574,7 +548,7 @@ SYNC_getCom(SYNC_server_state_t * state,
  *    @retval SYNC_COM_ERROR
  */
 afs_int32
-SYNC_putRes(SYNC_server_state_t * state, 
+SYNC_putRes(SYNC_server_state_t * state,
            osi_socket fd,
            SYNC_response * res)
 {
@@ -603,7 +577,7 @@ SYNC_putRes(SYNC_server_state_t * state,
 
     memcpy(buf, &res->hdr, sizeof(res->hdr));
     if (res->payload.len) {
-       memcpy(buf + sizeof(res->hdr), res->payload.buf, 
+       memcpy(buf + sizeof(res->hdr), res->payload.buf,
               res->hdr.response_len - sizeof(res->hdr));
     }
 
@@ -630,7 +604,7 @@ SYNC_verifyProtocolString(char * buf, size_t len)
 {
     size_t s_len;
 
-    s_len = afs_strnlen(buf, len);
+    s_len = strnlen(buf, len);
 
     return (s_len == len) ? 1 : 0;
 }
@@ -676,8 +650,8 @@ SYNC_bindSock(SYNC_server_state_t * state)
        Log("SYNC_bindSock: setsockopt failed with (%d)\n", errno);
 
     for (numTries = 0; numTries < state->bind_retry_limit; numTries++) {
-       code = bind(state->fd, 
-                   (struct sockaddr *)&state->addr, 
+       code = bind(state->fd,
+                   (struct sockaddr *)&state->addr,
                    AFS_SOCKADDR_LEN(&state->addr));
        if (code == 0)
            break;