libafs: log server errors on hard mount retry
authorMichael Meffie <mmeffie@sinenomine.net>
Mon, 23 Apr 2012 18:42:24 +0000 (14:42 -0400)
committerDerrick Brashear <shadow@dementix.org>
Tue, 1 May 2012 07:14:33 +0000 (00:14 -0700)
Save the last errors seen during a request and log those
errors if a hard-mount retry is done.

Change-Id: I65e41207c5f667c41c7f9cf459243118e5baa074
Reviewed-on: http://gerrit.openafs.org/7275
Reviewed-by: Derrick Brashear <shadow@dementix.org>
Tested-by: BuildBot <buildbot@rampaginggeek.com>

src/afs/afs.h
src/afs/afs_analyze.c

index 95b4351..1f5996c 100644 (file)
@@ -244,6 +244,7 @@ struct vrequest {
     char tokenError;            /* a token error other than expired. */
     char idleError;             /* the server idled too long */
     char skipserver[AFS_MAXHOSTS];
+    afs_int32 lasterror[AFS_MAXHOSTS];
 };
 #define VOLMISSING 1
 #define VOLBUSY 2
index 6b9f496..0aa0c7d 100644 (file)
@@ -328,6 +328,55 @@ afs_ClearStatus(struct VenusFid *afid, int op, struct volume *avp)
 
 /*!
  * \brief
+ *      Print the last errors from the servers for the volume on
+ *      this request.
+ *
+ * \param[in] areq   The request record associated with this operation.
+ * \param[in] afid   The FID of the file involved in the action.  This argument
+ *                  may be null if none was involved.
+ *
+ * \return
+ *      None
+ *
+ * \note
+ *      This routine is called before a hard-mount retry, to display
+ *      the servers by primary address and the errors encountered.
+ */
+static void
+afs_PrintServerErrors(struct vrequest *areq, struct VenusFid *afid)
+{
+    int i;
+    struct volume *tvp;
+    struct srvAddr *sa;
+    afs_uint32 address;
+    char *sep = " (";
+    char *term = "";
+
+    if (afid) {
+       tvp = afs_FindVolume(afid, READ_LOCK);
+       if (tvp) {
+           for (i = 0; i < AFS_MAXHOSTS; i++) {
+               if (tvp->serverHost[i]) {
+                   sa = tvp->serverHost[i]->addr;
+                   if (sa) {
+                       address = ntohl(sa->sa_ip);
+                       afs_warnuser("%s%d.%d.%d.%d code=%d", sep,
+                                    (address >> 24), (address >> 16) & 0xff,
+                                    (address >> 8) & 0xff, (address) & 0xff,
+                                    areq->lasterror[i]);
+                       sep = ", ";
+                       term = ")";
+                   }
+               }
+           }
+           afs_PutVolume(tvp, READ_LOCK);
+       }
+    }
+    afs_warnuser("%s\n", term);
+}
+
+/*!
+ * \brief
  *     Analyze the outcome of an RPC operation, taking whatever support
  *     actions are necessary.
  *
@@ -487,8 +536,9 @@ afs_Analyze(struct afs_conn *aconn, struct rx_connection *rxconn,
                    if (shouldRetry) {
                        if (warn) {
                            afs_warnuser
-                               ("afs: hard-mount waiting for volume %u\n",
+                               ("afs: hard-mount waiting for volume %u",
                                 afid->Fid.Volume);
+                           afs_PrintServerErrors(areq, afid);
                        }
 
                        VSleep(hm_retry_int);
@@ -550,6 +600,17 @@ afs_Analyze(struct afs_conn *aconn, struct rx_connection *rxconn,
        return 0;
     }
 
+    /* Save the last code of this server on this request. */
+    tvp = afs_FindVolume(afid, READ_LOCK);
+    if (tvp) {
+       for (i = 0; i < AFS_MAXHOSTS; i++) {
+           if (tvp->serverHost[i] == tsp) {
+               areq->lasterror[i] = acode;
+           }
+       }
+       afs_PutVolume(tvp, READ_LOCK);
+    }
+
     /* If network troubles, mark server as having bogued out again. */
     /* VRESTARTING is < 0 because of backward compatibility issues
      * with 3.4 file servers and older cache managers */