Re: [PATCH] xfs_mdrestore: Don't restore over a dump file

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2/1/18 4:28 PM, Darrick J. Wong wrote:
> On Thu, Feb 01, 2018 at 02:50:19PM -0600, Eric Sandeen wrote:
>> On 2/1/18 2:37 PM, Marco A Benatto wrote:
>>> Currently, if the user switch source and target parameters
>>> position, xfs_mdrestore truncates the dumpfile before abort
>>> the execution.
>>>
>>> This patch checks the target parameter and if XFS_MD_MAGIC is
>>> found, it aborts execution and leave dump file intact.
>>
>> Yeah, I think this is a good idea.  It's pretty unforgiving
>> to get it wrong and destroy your metadump in the process.
>>
>> (though tbh I usually get a compressed dump, and
>> # bzcat dumpfile.bz2 | xfs_mdrestore - target
>> works quite well and is more foolproof)
>>
>> So, despite the fact that I already talked with you about
>> this a bit online, I think my subconscious was working on
>> it in the meantime.  What you've got is generally ok, but
>> I wonder if the goal is to detect switched arguments, if
>> it might be simpler to first validate the given source, and
>> stop if it's not a metadump file.  We've already got that in
>> place, and it'd just be a question of checking the header
>> unconditionally, something like this, which just moves some
>> of the existing stuff work of the conditional:
>>
>>         xfs_metablock_t         mb;
>>
>>
>>         /* validate that our source file is really a metadump */
>>         if (fread(&mb, sizeof(mb), 1, src_f) != 1)
>>                 fatal("error reading from source file: %s\n", strerror(errno));
>>
>>         if (be32_to_cpu(mb.mb_magic) != XFS_MD_MAGIC)
>>                 fatal("specified source file is not a metadata dump\n");
>>
>>         if (show_info) {
>>                 if (mb.mb_info & XFS_METADUMP_INFO_FLAGS) {
>>                         printf("%s: %sobfuscated, %s log, %s metadata blocks\n",
>>                         argv[optind],
>>                         mb.mb_info & XFS_METADUMP_OBFUSCATED ? "":"not ",
>>                         mb.mb_info & XFS_METADUMP_DIRTYLOG ? "dirty":"clean",
>>                         mb.mb_info & XFS_METADUMP_FULLBLOCKS ? "full":"zeroed");
>>                 } else {
>>                         printf("%s: no informational flags present\n",
>>                                 argv[optind]);
>>                 }
>>
>>                 if (argc - optind == 1)
>>                         exit(0);
>>         }
>>
>>         /* Go back to the beginning for the restore function */
>>         fseek(src_f, 0L, SEEK_SET);
> 
> So now you got /me/ looking at mdrestore and wondering, if the metadump
> source is a pipe (as in your example above), won't this seek fail?  We
> already read the metadump super from the stream, so we can't seek
> backwards and read it again:
> 
> # cat foo.md | xfs_mdrestore -i - /dev/sda
> -: not obfuscated, clean log, full metadata blocks
> xfs_mdrestore: specified file is not a metadata dump
> 
> Not to mention xfs_mdrestore --help doesn't tell you there's an -i
> option.

<there is no --help> ;)

Neato!

> Also, we already /do/ check that the source actually has a metadump
> header, the problem is that we open the destination O_TRUNC before we
> read the header and so if the target was a file, *poof* it's empty.

hhmm yeah.

> I think we'll need to fix both of those problems.  Maybe we solve it by
> opening src_f, checking the magic, optionally printing the metadump
> info, and then passing both src_f and the header into perform_restore?
> 
> Separate patch, though.

right, and make perform_restore know that we're already past the first
header block, right.  Simply moving the first fread out of perform_restore
would do the trick.  Would need to pass the read metablock into the
restore function.

yeah that makes sense.

>> It's not explicitly checking the target, but it would probably serve
>> the same purpose with fewer lines of new code.  Either is ok with me,
>> really.  Any thoughts?
>>
>> Thanks,
>> -Eric
>>
>>
>>>
>>> Signed-off-by: Marco A Benatto <marco.antonio.780@xxxxxxxxx>
>>> ---
>>>  mdrestore/xfs_mdrestore.c | 16 +++++++++++++++-
>>>  1 file changed, 15 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
>>> index c49c13a..b4bf7b4 100644
>>> --- a/mdrestore/xfs_mdrestore.c
>>> +++ b/mdrestore/xfs_mdrestore.c
>>> @@ -205,7 +205,7 @@ main(
>>>  	int 		argc,
>>>  	char 		**argv)
>>>  {
>>> -	FILE		*src_f;
>>> +	FILE		*src_f, *dst_f;
>>>  	int		dst_fd;
>>>  	int		c;
>>>  	int		open_flags;
>>> @@ -277,6 +277,7 @@ main(
>>>  
>>>  	optind++;
>>>  
>>> +
>>>  	/* check and open target */
>>>  	open_flags = O_RDWR;
>>>  	is_target_file = 0;
>>> @@ -285,6 +286,19 @@ main(
>>>  		open_flags |= O_CREAT;
>>>  		is_target_file = 1;
>>>  	} else if (S_ISREG(statbuf.st_mode))  {
>>> +		xfs_metablock_t mb;
> 
> dst_f could be declared here, right?
> 
>>> +
>>> +		dst_f = fopen(argv[optind], "rb");
>>> +		if (dst_f == NULL)
>>> +			fatal("cannot open target\n");
>>> +
>>> +		if (fread(&mb, sizeof(mb), 1, dst_f) == 1) {
>>> +			if (be32_to_cpu(mb.mb_magic) == XFS_MD_MAGIC)
>>> +				fatal("target file is a xfs_metadump. switched arguments?\n");
>>> +		}
> 
> if (fread(&mb, sizeof(mb), 1, dst_f) == 1 &&
>     mb.mb_magic == cpu_to_be32(XFS_MD_MAGIC))
> 	fatal("...");

*nod*

-Eric
--
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



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux