On 3/8/18 1:35 PM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > > Record the summary of an interactive session in the system log so that > future support requests can get a better picture of what happened. > > Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > --- > v2: only log beginning and results Reviewed-by: Eric Sandeen <sandeen@xxxxxxxxxx> > --- > scrub/common.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ > scrub/common.h | 10 ++++++++++ > scrub/phase1.c | 1 + > scrub/xfs_scrub.c | 18 +++++++++++++----- > scrub/xfs_scrub.h | 1 + > 5 files changed, 74 insertions(+), 5 deletions(-) > > diff --git a/scrub/common.c b/scrub/common.c > index 17c3699..4f26bf8 100644 > --- a/scrub/common.c > +++ b/scrub/common.c > @@ -21,6 +21,7 @@ > #include <pthread.h> > #include <stdbool.h> > #include <sys/statvfs.h> > +#include <syslog.h> > #include "platform_defs.h" > #include "xfs.h" > #include "xfs_fs.h" > @@ -29,6 +30,8 @@ > #include "common.h" > #include "progress.h" > > +extern char *progname; > + > /* > * Reporting Status to the Console > * > @@ -64,6 +67,12 @@ static const char *err_str[] = { > [S_PREEN] = "Optimized", > }; > > +static int log_level[] = { > + [S_ERROR] = LOG_ERR, > + [S_WARN] = LOG_WARNING, > + [S_INFO] = LOG_INFO, > +}; > + > /* If stream is a tty, clear to end of line to clean up progress bar. */ > static inline const char *stream_start(FILE *stream) > { > @@ -131,6 +140,46 @@ __str_out( > pthread_mutex_unlock(&ctx->lock); > } > > +/* Log a message to syslog. */ > +#define LOG_BUFSZ 4096 > +#define LOGNAME_BUFSZ 256 > +void > +__str_log( > + struct scrub_ctx *ctx, > + enum error_level level, > + const char *format, > + ...) > +{ > + va_list args; > + char logname[LOGNAME_BUFSZ]; > + char buf[LOG_BUFSZ]; > + int sz; > + > + /* We only want to hear about optimizing when in debug/verbose mode. */ > + if (level == S_PREEN && !debug && !verbose) > + return; > + > + /* > + * Skip logging if we're being run as a service (presumably the > + * service will log stdout/stderr); if we're being run in a non > + * interactive manner (assume we're a service); or if we're in > + * debug mode. > + */ > + if (is_service || !isatty(fileno(stdin)) || debug) > + return; > + > + snprintf(logname, LOGNAME_BUFSZ, "%s@%s", progname, ctx->mntpoint); > + openlog(logname, LOG_PID, LOG_DAEMON); > + > + sz = snprintf(buf, LOG_BUFSZ, "%s: ", _(err_str[level])); > + va_start(args, format); > + vsnprintf(buf + sz, LOG_BUFSZ - sz, format, args); > + va_end(args); > + syslog(log_level[level], "%s", buf); > + > + closelog(); > +} > + > double > timeval_subtract( > struct timeval *tv1, > diff --git a/scrub/common.h b/scrub/common.h > index 287bd4d..4f1f0cd 100644 > --- a/scrub/common.h > +++ b/scrub/common.h > @@ -56,6 +56,16 @@ void __str_out(struct scrub_ctx *ctx, const char *descr, enum error_level level, > #define dbg_printf(fmt, ...) \ > do {if (debug > 1) {printf(fmt, __VA_ARGS__);}} while (0) > > +void __str_log(struct scrub_ctx *ctx, enum error_level level, > + const char *format, ...); > + > +#define log_info(ctx, ...) \ > + __str_log(ctx, S_INFO, __VA_ARGS__) > +#define log_warn(ctx, ...) \ > + __str_log(ctx, S_WARN, __VA_ARGS__) > +#define log_err(ctx, ...) \ > + __str_log(ctx, S_ERROR, __VA_ARGS__) > + > /* Is this debug tweak enabled? */ > static inline bool > debug_tweak_on( > diff --git a/scrub/phase1.c b/scrub/phase1.c > index 6cd5442..b856a7f 100644 > --- a/scrub/phase1.c > +++ b/scrub/phase1.c > @@ -236,6 +236,7 @@ _("Unable to find realtime device path.")); > * this point are most probably corruption errors (as opposed to > * purely setup errors). > */ > + log_info(ctx, _("Invoking online scrub."), ctx); > ctx->need_repair = true; > return true; > } > diff --git a/scrub/xfs_scrub.c b/scrub/xfs_scrub.c > index ab26e63..7ab0c3e 100644 > --- a/scrub/xfs_scrub.c > +++ b/scrub/xfs_scrub.c > @@ -162,7 +162,7 @@ bool stdout_isatty; > * If we are running as a service, we need to be careful about what > * error codes we return to the calling process. > */ > -static bool is_service; > +bool is_service; > > #define SCRUB_RET_SUCCESS (0) /* no problems left behind */ > #define SCRUB_RET_CORRUPT (1) /* corruption remains on fs */ > @@ -501,19 +501,27 @@ report_outcome( > > total_errors = ctx->errors_found + ctx->runtime_errors; > > - if (total_errors == 0 && ctx->warnings_found == 0) > + if (total_errors == 0 && ctx->warnings_found == 0) { > + log_info(ctx, _("No errors found.")); > return; > + } > > - if (total_errors == 0) > + if (total_errors == 0) { > fprintf(stderr, _("%s: warnings found: %llu\n"), ctx->mntpoint, > ctx->warnings_found); > - else if (ctx->warnings_found == 0) > + log_warn(ctx, _("warnings found: %llu"), ctx->warnings_found); > + } else if (ctx->warnings_found == 0) { > fprintf(stderr, _("%s: errors found: %llu\n"), ctx->mntpoint, > total_errors); > - else > + log_err(ctx, _("errors found: %llu"), total_errors); > + } else { > fprintf(stderr, _("%s: errors found: %llu; warnings found: %llu\n"), > ctx->mntpoint, total_errors, > ctx->warnings_found); > + log_err(ctx, _("errors found: %llu; warnings found: %llu"), > + total_errors, ctx->warnings_found); > + } > + > if (ctx->need_repair) > fprintf(stderr, _("%s: Unmount and run xfs_repair.\n"), > ctx->mntpoint); > diff --git a/scrub/xfs_scrub.h b/scrub/xfs_scrub.h > index 89b46a4..b455747 100644 > --- a/scrub/xfs_scrub.h > +++ b/scrub/xfs_scrub.h > @@ -31,6 +31,7 @@ extern long page_size; > extern bool want_fstrim; > extern bool stderr_isatty; > extern bool stdout_isatty; > +extern bool is_service; > > enum scrub_mode { > SCRUB_MODE_DRY_RUN, > -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html