aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2018-02-02 09:32:45 -0600
committerEric Sandeen <sandeen@redhat.com>2018-02-02 09:32:45 -0600
commitf0585fce2320152445ac7896e0b8545a50bb9d18 (patch)
treed37643e4b69db2cbf529f3097b27ea9387648eb7
parent95b1e5059176245137406e14e4cd2ecca3c493d1 (diff)
downloadxfsprogs-dev-f0585fce2320152445ac7896e0b8545a50bb9d18.tar.gz
xfs_scrub: common error handling
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>
-rw-r--r--scrub/common.c87
-rw-r--r--scrub/common.h30
-rw-r--r--scrub/xfs_scrub.c5
-rw-r--r--scrub/xfs_scrub.h11
4 files changed, 133 insertions, 0 deletions
diff --git a/scrub/common.c b/scrub/common.c
index 0a58c1679c..8137881fbf 100644
--- a/scrub/common.c
+++ b/scrub/common.c
@@ -17,4 +17,91 @@
* 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);
+}
diff --git a/scrub/common.h b/scrub/common.h
index 1082296b11..b383767bb1 100644
--- a/scrub/common.h
+++ b/scrub/common.h
@@ -20,4 +20,34 @@
#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_ */
diff --git a/scrub/xfs_scrub.c b/scrub/xfs_scrub.c
index a4b9c710ba..6ed7bf66a1 100644
--- a/scrub/xfs_scrub.c
+++ b/scrub/xfs_scrub.c
@@ -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"
/*
@@ -99,6 +101,9 @@
/* 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,
diff --git a/scrub/xfs_scrub.h b/scrub/xfs_scrub.h
index ff9c24dcdb..811bc2de5e 100644
--- a/scrub/xfs_scrub.h
+++ b/scrub/xfs_scrub.h
@@ -20,4 +20,15 @@
#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_ */