]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_scrub: common error handling
authorDarrick J. Wong <darrick.wong@oracle.com>
Fri, 2 Feb 2018 15:32:45 +0000 (09:32 -0600)
committerEric Sandeen <sandeen@redhat.com>
Fri, 2 Feb 2018 15:32:45 +0000 (09:32 -0600)
Standardize how we record and report errors.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
scrub/common.c
scrub/common.h
scrub/xfs_scrub.c
scrub/xfs_scrub.h

index 0a58c1679c96d8f91231afa9af6883d8447b4606..8137881fbf46dd048a6b8063c06aa5b1e28cfb38 100644 (file)
  * along with this program; if not, write the Free Software Foundation,
  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
  */
+#include <stdio.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include "platform_defs.h"
+#include "xfs.h"
+#include "xfs_scrub.h"
 #include "common.h"
+
+/*
+ * Reporting Status to the Console
+ *
+ * We aim for a roughly standard reporting format -- the severity of the
+ * status being reported, a textual description of the object being
+ * reported, and whatever the status happens to be.
+ *
+ * Errors are the most severe and reflect filesystem corruption.
+ * Warnings indicate that something is amiss and needs the attention of
+ * the administrator, but does not constitute a corruption.  Information
+ * is merely advisory.
+ */
+
+/* Too many errors? Bail out. */
+bool
+xfs_scrub_excessive_errors(
+       struct scrub_ctx        *ctx)
+{
+       bool                    ret;
+
+       pthread_mutex_lock(&ctx->lock);
+       ret = ctx->max_errors > 0 && ctx->errors_found >= ctx->max_errors;
+       pthread_mutex_unlock(&ctx->lock);
+
+       return ret;
+}
+
+static const char *err_str[] = {
+       [S_ERROR]       = "Error",
+       [S_WARN]        = "Warning",
+       [S_INFO]        = "Info",
+};
+
+/* Print a warning string and some warning text. */
+void
+__str_out(
+       struct scrub_ctx        *ctx,
+       const char              *descr,
+       enum error_level        level,
+       int                     error,
+       const char              *file,
+       int                     line,
+       const char              *format,
+       ...)
+{
+       FILE                    *stream = stderr;
+       va_list                 args;
+       char                    buf[DESCR_BUFSZ];
+
+       /* print strerror or format of choice but not both */
+       assert(!(error && format));
+
+       if (level >= S_INFO)
+               stream = stdout;
+
+       pthread_mutex_lock(&ctx->lock);
+       fprintf(stream, "%s: %s: ", _(err_str[level]), descr);
+       if (error) {
+               fprintf(stream, _("%s."), strerror_r(error, buf, DESCR_BUFSZ));
+       } else {
+               va_start(args, format);
+               vfprintf(stream, format, args);
+               va_end(args);
+       }
+
+       if (debug)
+               fprintf(stream, _(" (%s line %d)"), file, line);
+       fprintf(stream, "\n");
+       if (stream == stdout)
+               fflush(stream);
+
+       if (error)      /* A syscall failed */
+               ctx->runtime_errors++;
+       else if (level == S_ERROR)
+               ctx->errors_found++;
+       else if (level == S_WARN)
+               ctx->warnings_found++;
+
+       pthread_mutex_unlock(&ctx->lock);
+}
index 1082296b11c4c215600bd1df96639273d5f5c88e..b383767bb10fd26e5983d6f816655789ea371f88 100644 (file)
 #ifndef XFS_SCRUB_COMMON_H_
 #define XFS_SCRUB_COMMON_H_
 
+/*
+ * When reporting a defective metadata object to the console, this
+ * is the size of the buffer to use to store the description of that
+ * item.
+ */
+#define DESCR_BUFSZ    256
+
+bool xfs_scrub_excessive_errors(struct scrub_ctx *ctx);
+
+enum error_level {
+       S_ERROR = 0,
+       S_WARN,
+       S_INFO,
+};
+
+void __str_out(struct scrub_ctx *ctx, const char *descr, enum error_level level,
+              int error, const char *file, int line, const char *format, ...);
+
+#define str_errno(ctx, str) \
+       __str_out(ctx, str, S_ERROR,    errno,  __FILE__, __LINE__, NULL)
+#define str_error(ctx, str, ...) \
+       __str_out(ctx, str, S_ERROR,    0,      __FILE__, __LINE__, __VA_ARGS__)
+#define str_warn(ctx, str, ...) \
+       __str_out(ctx, str, S_WARN,     0,      __FILE__, __LINE__, __VA_ARGS__)
+#define str_info(ctx, str, ...) \
+       __str_out(ctx, str, S_INFO,     0,      __FILE__, __LINE__, __VA_ARGS__)
+
+#define dbg_printf(fmt, ...) \
+       do {if (debug > 1) {printf(fmt, __VA_ARGS__);}} while (0)
+
 #endif /* XFS_SCRUB_COMMON_H_ */
index a4b9c710ba602e6df70c9a9000777924d1d9db2f..6ed7bf66a1ca48e86ff01c46e7030a374803d950 100644 (file)
@@ -18,6 +18,8 @@
  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 #include <stdio.h>
+#include <pthread.h>
+#include <stdbool.h>
 #include "xfs_scrub.h"
 
 /*
 /* Program name; needed for libfrog error reports. */
 char                           *progname = "xfs_scrub";
 
+/* Debug level; higher values mean more verbosity. */
+unsigned int                   debug;
+
 int
 main(
        int                     argc,
index ff9c24dcdb4bc57ec2ef6fd6814026b887be57eb..811bc2de5e6dbdafb9bffd183c5d82510ba595ba 100644 (file)
 #ifndef XFS_SCRUB_XFS_SCRUB_H_
 #define XFS_SCRUB_XFS_SCRUB_H_
 
+extern unsigned int            debug;
+
+struct scrub_ctx {
+       /* Mutable scrub state; use lock. */
+       pthread_mutex_t         lock;
+       unsigned long long      max_errors;
+       unsigned long long      runtime_errors;
+       unsigned long long      errors_found;
+       unsigned long long      warnings_found;
+};
+
 #endif /* XFS_SCRUB_XFS_SCRUB_H_ */