libafs: Rate-limit hard-mount waiting messages
authorAndrew Deason <adeason@sinenomine.net>
Wed, 20 Jul 2011 21:50:52 +0000 (16:50 -0500)
committerDerrick Brashear <shadow@dementia.org>
Fri, 29 Jul 2011 21:17:31 +0000 (14:17 -0700)
Limit how often we log "hard-mount waiting for XXX" messages. Without
this, it is possible for a client with hard-mounts enabled to spam the
kernel log rather excessively (in extreme cases this can even panic
the machine on at least some Linux).

To keep things simple, just log approximately one message per volume
per hard-mount interval.

Change-Id: Ie82f68c5eae76519fcf1491164133c1955ed9c08
Reviewed-on: http://gerrit.openafs.org/5060
Tested-by: Derrick Brashear <shadow@dementia.org>
Reviewed-by: Derrick Brashear <shadow@dementia.org>

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

index 413106c..6bf4f0e 100644 (file)
@@ -565,6 +565,7 @@ struct chservinfo {
 #define VBackup                        4       /* is this a backup volume? */
 #define VForeign               8       /* this is a non-afs volume */
 #define VPartVisible           16      /* Volume's partition is visible on the client */
+#define VHardMount             32      /* we are hard-mount waiting for the vol */
 
 enum repstate { not_busy, end_not_busy = 6, rd_busy, rdwr_busy, offline };
 
index fc65ca5..b6dbed8 100644 (file)
@@ -388,26 +388,72 @@ afs_Analyze(struct afs_conn *aconn, struct rx_connection *rxconn,
                ((afid && afs_IsPrimaryCellNum(afid->Cell))
                 || (cellp && afs_IsPrimaryCell(cellp)))) {
                if (!afid) {
-                   afs_warnuser
-                       ("afs: hard-mount waiting for a vlserver to return to service\n");
+                   static int afs_vl_hm = 0;
+                   int warn = 0;
+                   if (!afs_vl_hm) {
+                       afs_vl_hm = warn = 1;
+                   }
+                   if (warn) {
+                       afs_warnuser
+                           ("afs: hard-mount waiting for a vlserver to return to service\n");
+                   }
                    VSleep(hm_retry_int);
                    afs_CheckServers(1, cellp);
                    shouldRetry = 1;
+
+                   if (warn) {
+                       afs_vl_hm = 0;
+                   }
                } else {
+                   static int afs_unknown_vhm = 0;
+                   int warn = 0, vp_vhm = 0;
+
                    tvp = afs_FindVolume(afid, READ_LOCK);
                    if (!tvp || (tvp->states & VRO)) {
                        shouldRetry = hm_retry_RO;
                    } else {
                        shouldRetry = hm_retry_RW;
                    }
+
+                   /* Set 'warn' if we should afs_warnuser. Only let one
+                    * caller call afs_warnuser per hm_retry_int interval per
+                    * volume. */
+                   if (shouldRetry) {
+                       if (tvp) {
+                           if (!(tvp->states & VHardMount)) {
+                               tvp->states |= VHardMount;
+                               warn = vp_vhm = 1;
+                           }
+                       } else {
+                           if (!afs_unknown_vhm) {
+                               afs_unknown_vhm = 1;
+                               warn = 1;
+                           }
+                       }
+                   }
+
                    if (tvp)
                        afs_PutVolume(tvp, READ_LOCK);
+
                    if (shouldRetry) {
-                       afs_warnuser
-                           ("afs: hard-mount waiting for volume %u\n",
-                            afid->Fid.Volume);
+                       if (warn) {
+                           afs_warnuser
+                               ("afs: hard-mount waiting for volume %u\n",
+                                afid->Fid.Volume);
+                       }
+
                        VSleep(hm_retry_int);
                        afs_CheckServers(1, cellp);
+
+                       if (vp_vhm) {
+                           tvp = afs_FindVolume(afid, READ_LOCK);
+                           if (tvp) {
+                               tvp->states &= ~VHardMount;
+                               afs_PutVolume(tvp, READ_LOCK);
+                           }
+                       } else if (warn) {
+                           afs_unknown_vhm = 0;
+                       }
                    }
                }
            } /* if (hm_retry_int ... */