17b94a
From 1bde083cbd1e06be66d00e4ca52075687cee0d60 Mon Sep 17 00:00:00 2001
17b94a
From: Csaba Henk <csaba@redhat.com>
17b94a
Date: Fri, 8 May 2020 23:01:04 +0200
17b94a
Subject: [PATCH 441/449] fuse: occasional logging for fuse device 'weird'
17b94a
 write errors
17b94a
17b94a
This change is a followup to
17b94a
I510158843e4b1d482bdc496c2e97b1860dc1ba93.
17b94a
17b94a
In referred change we pushed log messages about 'weird'
17b94a
write errors to fuse device out of sight, by reporting
17b94a
them at Debug loglevel instead of Error (where
17b94a
'weird' means errno is not POSIX compliant but having
17b94a
meaningful semantics for FUSE protocol).
17b94a
17b94a
This solved the issue of spurious error reporting.
17b94a
And so far so good: these messages don't indicate
17b94a
an error condition by themselves. However, when they
17b94a
come in high repetitions, that indicates a suboptimal
17b94a
condition which should be reported.[1]
17b94a
17b94a
Therefore now we shall emit a Warning if a certain
17b94a
errno occurs a certain number of times[2] as the
17b94a
outcome of a write to the fuse device.
17b94a
17b94a
___
17b94a
[1] typically ENOENTs and ENOTDIRs accumulate
17b94a
when glusterfs' inode invalidation lags behind
17b94a
the kernel's internal inode garbage collection
17b94a
(in this case above errnos mean that the inode
17b94a
which we requested to be invalidated is not found
17b94a
in kernel). This can be mitigated with the
17b94a
invalidate-limit command line / mount option,
17b94a
cf. bz#1732717.
17b94a
17b94a
[2] 256, as of the current implementation.
17b94a
17b94a
Upstream on https://review.gluster.org/24415
17b94a
> Change-Id: I8cc7fe104da43a88875f93b0db49d5677cc16045
17b94a
> Updates: #1000
17b94a
> Signed-off-by: Csaba Henk <csaba@redhat.com>
17b94a
17b94a
BUG: 1839137
17b94a
Change-Id: I8448d6d328d47cb01d560cd99a2f43cd8dab312d
17b94a
Signed-off-by: Csaba Henk <csaba@redhat.com>
17b94a
Reviewed-on: https://code.engineering.redhat.com/gerrit/202646
17b94a
Tested-by: RHGS Build Bot <nigelb@redhat.com>
17b94a
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
17b94a
---
17b94a
 xlators/mount/fuse/src/fuse-bridge.c | 36 +++++++++++++++++++++++++++++++++++-
17b94a
 xlators/mount/fuse/src/fuse-bridge.h | 18 ++++++++++++++++++
17b94a
 2 files changed, 53 insertions(+), 1 deletion(-)
17b94a
17b94a
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
17b94a
index 4264fad..2e7584c 100644
17b94a
--- a/xlators/mount/fuse/src/fuse-bridge.c
17b94a
+++ b/xlators/mount/fuse/src/fuse-bridge.c
17b94a
@@ -218,14 +218,30 @@ check_and_dump_fuse_W(fuse_private_t *priv, struct iovec *iov_out, int count,
17b94a
     if (res == -1) {
17b94a
         const char *errdesc = NULL;
17b94a
         gf_loglevel_t loglevel = GF_LOG_ERROR;
17b94a
+        gf_boolean_t errno_degraded = _gf_false;
17b94a
+        gf_boolean_t errno_promoted = _gf_false;
17b94a
+
17b94a
+#define ACCOUNT_ERRNO(eno)                                                     \
17b94a
+    do {                                                                       \
17b94a
+        if (errno_degraded) {                                                  \
17b94a
+            pthread_mutex_lock(&priv->fusedev_errno_cnt_mutex);                \
17b94a
+            {                                                                  \
17b94a
+                if (!++priv->fusedev_errno_cnt[FUSEDEV_##eno])                 \
17b94a
+                    errno_promoted = _gf_true;                                 \
17b94a
+            }                                                                  \
17b94a
+            pthread_mutex_unlock(&priv->fusedev_errno_cnt_mutex);              \
17b94a
+        }                                                                      \
17b94a
+    } while (0)
17b94a
 
17b94a
         /* If caller masked the errno, then it
17b94a
          * does not indicate an error at the application
17b94a
          * level, so we degrade the log severity to DEBUG.
17b94a
          */
17b94a
         if (errnomask && errno < ERRNOMASK_MAX &&
17b94a
-            GET_ERRNO_MASK(errnomask, errno))
17b94a
+            GET_ERRNO_MASK(errnomask, errno)) {
17b94a
             loglevel = GF_LOG_DEBUG;
17b94a
+            errno_degraded = _gf_true;
17b94a
+        }
17b94a
 
17b94a
         switch (errno) {
17b94a
             /* The listed errnos are FUSE status indicators,
17b94a
@@ -235,33 +251,43 @@ check_and_dump_fuse_W(fuse_private_t *priv, struct iovec *iov_out, int count,
17b94a
              */
17b94a
             case ENOENT:
17b94a
                 errdesc = "ENOENT";
17b94a
+                ACCOUNT_ERRNO(ENOENT);
17b94a
                 break;
17b94a
             case ENOTDIR:
17b94a
                 errdesc = "ENOTDIR";
17b94a
+                ACCOUNT_ERRNO(ENOTDIR);
17b94a
                 break;
17b94a
             case ENODEV:
17b94a
                 errdesc = "ENODEV";
17b94a
+                ACCOUNT_ERRNO(ENODEV);
17b94a
                 break;
17b94a
             case EPERM:
17b94a
                 errdesc = "EPERM";
17b94a
+                ACCOUNT_ERRNO(EPERM);
17b94a
                 break;
17b94a
             case ENOMEM:
17b94a
                 errdesc = "ENOMEM";
17b94a
+                ACCOUNT_ERRNO(ENOMEM);
17b94a
                 break;
17b94a
             case ENOTCONN:
17b94a
                 errdesc = "ENOTCONN";
17b94a
+                ACCOUNT_ERRNO(ENOTCONN);
17b94a
                 break;
17b94a
             case ECONNREFUSED:
17b94a
                 errdesc = "ECONNREFUSED";
17b94a
+                ACCOUNT_ERRNO(ECONNREFUSED);
17b94a
                 break;
17b94a
             case EOVERFLOW:
17b94a
                 errdesc = "EOVERFLOW";
17b94a
+                ACCOUNT_ERRNO(EOVERFLOW);
17b94a
                 break;
17b94a
             case EBUSY:
17b94a
                 errdesc = "EBUSY";
17b94a
+                ACCOUNT_ERRNO(EBUSY);
17b94a
                 break;
17b94a
             case ENOTEMPTY:
17b94a
                 errdesc = "ENOTEMPTY";
17b94a
+                ACCOUNT_ERRNO(ENOTEMPTY);
17b94a
                 break;
17b94a
             default:
17b94a
                 errdesc = strerror(errno);
17b94a
@@ -269,7 +295,13 @@ check_and_dump_fuse_W(fuse_private_t *priv, struct iovec *iov_out, int count,
17b94a
 
17b94a
         gf_log_callingfn("glusterfs-fuse", loglevel,
17b94a
                          "writing to fuse device failed: %s", errdesc);
17b94a
+        if (errno_promoted)
17b94a
+            gf_log("glusterfs-fuse", GF_LOG_WARNING,
17b94a
+                   "writing to fuse device yielded %s %d times", errdesc,
17b94a
+                   UINT8_MAX + 1);
17b94a
         return errno;
17b94a
+
17b94a
+#undef ACCOUNT_ERRNO
17b94a
     }
17b94a
 
17b94a
     fouh = iov_out[0].iov_base;
17b94a
@@ -6584,6 +6616,8 @@ init(xlator_t *this_xl)
17b94a
     INIT_LIST_HEAD(&priv->interrupt_list);
17b94a
     pthread_mutex_init(&priv->interrupt_mutex, NULL);
17b94a
 
17b94a
+    pthread_mutex_init(&priv->fusedev_errno_cnt_mutex, NULL);
17b94a
+
17b94a
     /* get options from option dictionary */
17b94a
     ret = dict_get_str(options, ZR_MOUNTPOINT_OPT, &value_string);
17b94a
     if (ret == -1 || value_string == NULL) {
17b94a
diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h
17b94a
index d2d462c..2fb15a6 100644
17b94a
--- a/xlators/mount/fuse/src/fuse-bridge.h
17b94a
+++ b/xlators/mount/fuse/src/fuse-bridge.h
17b94a
@@ -78,6 +78,20 @@ typedef struct fuse_in_header fuse_in_header_t;
17b94a
 typedef void(fuse_handler_t)(xlator_t *this, fuse_in_header_t *finh, void *msg,
17b94a
                              struct iobuf *iobuf);
17b94a
 
17b94a
+enum fusedev_errno {
17b94a
+    FUSEDEV_ENOENT,
17b94a
+    FUSEDEV_ENOTDIR,
17b94a
+    FUSEDEV_ENODEV,
17b94a
+    FUSEDEV_EPERM,
17b94a
+    FUSEDEV_ENOMEM,
17b94a
+    FUSEDEV_ENOTCONN,
17b94a
+    FUSEDEV_ECONNREFUSED,
17b94a
+    FUSEDEV_EOVERFLOW,
17b94a
+    FUSEDEV_EBUSY,
17b94a
+    FUSEDEV_ENOTEMPTY,
17b94a
+    FUSEDEV_EMAXPLUS
17b94a
+};
17b94a
+
17b94a
 struct fuse_private {
17b94a
     int fd;
17b94a
     uint32_t proto_minor;
17b94a
@@ -192,6 +206,10 @@ struct fuse_private {
17b94a
     /* LRU Limit, if not set, default is 64k for now */
17b94a
     uint32_t lru_limit;
17b94a
     uint32_t invalidate_limit;
17b94a
+
17b94a
+    /* counters for fusdev errnos */
17b94a
+    uint8_t fusedev_errno_cnt[FUSEDEV_EMAXPLUS];
17b94a
+    pthread_mutex_t fusedev_errno_cnt_mutex;
17b94a
 };
17b94a
 typedef struct fuse_private fuse_private_t;
17b94a
 
17b94a
-- 
17b94a
1.8.3.1
17b94a