public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Brian Foster <bfoster@redhat.com>
To: Jan Tulak <jtulak@redhat.com>
Cc: linux-xfs@vger.kernel.org, sandeen@sandeen.net
Subject: Re: [PATCH 2/2] mdrestore: warn about corruption if log is dirty
Date: Tue, 11 Apr 2017 14:33:57 -0400	[thread overview]
Message-ID: <20170411183356.GB3865@bfoster.bfoster> (raw)
In-Reply-To: <20170411141237.9274-3-jtulak@redhat.com>

On Tue, Apr 11, 2017 at 04:12:37PM +0200, Jan Tulak wrote:
> A dirty log in an obfuscated dump means that a corruption can happen
> when replaying the log (which contains unobfuscated data). Warn the user
> about this possibility.
> 
> The xlog workaround is copy&paste solution from repair/phase2.c and
> other tools, because the function is not implemented in libxlog.
> 
> Signed-off-by: Jan Tulak <jtulak@redhat.com>
> ---
>  mdrestore/Makefile        |  4 +--
>  mdrestore/xfs_mdrestore.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 86 insertions(+), 2 deletions(-)
> 
> diff --git a/mdrestore/Makefile b/mdrestore/Makefile
> index 5171306..6355df9 100644
> --- a/mdrestore/Makefile
> +++ b/mdrestore/Makefile
> @@ -8,8 +8,8 @@ include $(TOPDIR)/include/builddefs
>  LTCOMMAND = xfs_mdrestore
>  CFILES = xfs_mdrestore.c
>  
> -LLDLIBS = $(LIBXFS) $(LIBRT) $(LIBPTHREAD) $(LIBUUID)
> -LTDEPENDENCIES = $(LIBXFS)
> +LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBRT) $(LIBPTHREAD) $(LIBUUID)
> +LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG)
>  LLDFLAGS = -static
>  

FYI, I get the following on a 'make -j 4':

...
Building mdrestore
gmake[3]: *** No rule to make target '../libxlog/libxlog.la', needed by 'xfs_mdrestore'.  Stop.
gmake[3]: *** Waiting for unfinished jobs....

It succeeds if I restart the build so I suspect something might be up
with the dependency tracking here.

>  default: depend $(LTCOMMAND)
> diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
> index 0d399f1..3797955 100644
> --- a/mdrestore/xfs_mdrestore.c
> +++ b/mdrestore/xfs_mdrestore.c
> @@ -17,6 +17,7 @@
>   */
>  
>  #include "libxfs.h"
> +#include "libxlog.h"
>  #include "xfs_metadump.h"
>  
>  char 		*progname;
> @@ -190,6 +191,87 @@ perform_restore(
>  	free(metablock);
>  }
>  
> +/* workaround craziness in the xlog routines */
> +int xlog_recover_do_trans(struct xlog *log, xlog_recover_t *t, int p)
> +{
> +	return 0;
> +}
> +
> +/*
> + * Warn if we just wrote a dump with a dirty log.
> + */
> +void
> +test_dirty_log(
> +	bool	is_target_file,
> +	char*	target_name)
> +{
> +	struct xfs_sb	*sbp;
> +	struct xfs_buf	*bp;
> +	struct xfs_mount	xmount;
> +	struct xfs_mount	*mp;
> +	struct xlog		xlog;
> +	libxfs_init_t		x;
> +
> +	x.isreadonly = LIBXFS_ISREADONLY;
> +	if (is_target_file) {
> +		x.dname = target_name;
> +		x.disfile = true;
> +	} else {
> +		x.disfile = false;
> +		x.volname = target_name;
> +	}
> +
> +	if (!libxfs_init(&x)) {
> +		fatal(_("\nfatal error -- couldn't initialize XFS library\n"),
> +		      strerror(errno));
> +	}
> +
> +	memset(&xmount, 0, sizeof(struct xfs_mount));
> +	libxfs_buftarg_init(&xmount, x.ddev, x.logdev, x.rtdev);
> +	bp = libxfs_readbuf(xmount.m_ddev_targp, XFS_SB_DADDR,
> +			    1 << (XFS_MAX_SECTORSIZE_LOG - BBSHIFT), 0, NULL);
> +
> +	if (!bp || bp->b_error) {
> +		fprintf(stderr, _("%s: %s is invalid (cannot read first 512 "
> +			"bytes)\n"), progname, target_name);
> +		exit(1);
> +	}
> +
> +	/* copy SB from buffer to in-core, converting architecture as we go */
> +	libxfs_sb_from_disk(&xmount.m_sb, XFS_BUF_TO_SBP(bp));
> +	libxfs_putbuf(bp);
> +	libxfs_purgebuf(bp);
> +
> +	sbp = &xmount.m_sb;
> +	mp = libxfs_mount(&xmount, sbp, x.ddev, x.logdev, x.rtdev,
> +			  LIBXFS_MOUNT_DEBUGGER);
> +	if (!mp) {
> +		fprintf(stderr,
> +			_("%s: restored device %s unusable (not an XFS filesystem?)\n"),
> +			progname, target_name);
> +		exit(1);
> +	}

It might be cleaner to bury all of this init stuff in a separate init
function to be called before the log check. We also may not want to exit
the program if parsing the log or something happens to fail, given that
this is a debug tool.

> +
> +	switch (xlog_is_dirty(mp, &xlog, &x,0)) {
> +		case -1:
> +			/* An error occured and we can't read the log. */
> +			fprintf(stderr,
> +			_("Warning: can't discern a log.\n"));
> +			break;
> +		case 1:
> +			/* The log is dirty, warn. */
> +			fprintf(stderr,
> +			_("Warning: The log is dirty. If the image was obfuscated, "
> +			  "an attempt to replay the log may lead to corruption.\n"));
> +			break;

Then the above can remain in the test_log_dirty() helper or just be
open-coded at the end of main(), provided the mount was initialized
successfully (or we could still warn if we can't make sense of the log).

BTW, this is going to warn on every xfs_mdrestore of an image with a
dirty log, right? That is slightly unfortunate, if so. Do we have any
method to track or determine whether an image is obfuscated (I'm
guessing not easily...)?

Brian

> +		case 0:
> +			 /* Everything is ok. */
> +			break;
> +	}
> +
> +}
> +
> +
>  static void
>  usage(void)
>  {
> @@ -271,5 +353,7 @@ main(
>  	if (src_f != stdin)
>  		fclose(src_f);
>  
> +	test_dirty_log(is_target_file, argv[optind]);
> +
>  	return 0;
>  }
> -- 
> 2.1.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2017-04-11 18:33 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-11 14:12 [PATCH 0/2] xfsprogs: metadump/mdrestore warns about dirty journal Jan Tulak
2017-04-11 14:12 ` [PATCH 1/2] metadump: warn about corruption if log is dirty Jan Tulak
2017-04-11 18:30   ` Brian Foster
2017-04-11 18:34     ` Eric Sandeen
2017-04-11 18:43       ` Brian Foster
2017-04-11 19:01         ` Eric Sandeen
2017-04-11 23:44           ` Darrick J. Wong
2017-04-12 11:03             ` Brian Foster
2017-04-12 11:24               ` Jan Tulak
2017-04-11 14:12 ` [PATCH 2/2] mdrestore: " Jan Tulak
2017-04-11 18:33   ` Brian Foster [this message]
2017-04-11 18:39     ` Eric Sandeen
2017-04-11 18:49       ` Brian Foster
2017-04-11 18:59         ` Eric Sandeen
2017-04-11 22:34   ` Dave Chinner
2017-04-11 23:43     ` Darrick J. Wong
2017-04-12  1:48       ` Eric Sandeen
2017-04-12 11:26         ` Brian Foster
2017-04-12 11:06       ` Brian Foster
2017-04-12 17:45         ` Darrick J. Wong
2017-04-13  8:12           ` Jan Tulak
2017-04-12 11:04     ` Brian Foster
2017-04-13  2:51       ` Dave Chinner
2017-04-13 13:10         ` Brian Foster
2017-04-14  0:29           ` Dave Chinner
2017-04-14  2:54             ` Brian Foster
2017-05-25 17:29 ` [PATCH 0/2] xfsprogs: metadump/mdrestore warns about dirty journal Eric Sandeen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170411183356.GB3865@bfoster.bfoster \
    --to=bfoster@redhat.com \
    --cc=jtulak@redhat.com \
    --cc=linux-xfs@vger.kernel.org \
    --cc=sandeen@sandeen.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox