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

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

 



Thanks all for the feedback and nice catch regarding the rewind + stdin reading.

I'm currently working on a patch which should cover (following
Sandeen's suggestions) the items Darrick has brought.

I should send this soon.

Thanks,

On Thu, Feb 1, 2018 at 8:39 PM, Eric Sandeen <sandeen@xxxxxxxxxxx> wrote:
> 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



-- 
Marco Antonio Benatto
Linux user ID: #506236
--
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