INTRO

BTRFS RESTORE: runs thru the specified filesystem and tries to restore files and folders. Useful if the filesystem is not mountable. Here we will explore using different regular expression to dump out specific part (folders or files) as sometimes we dont want to extract the full FS.

Here are the BTRFS RESTORE options that are going to be used: -v verbose (shows files & folders), -F to continously hit yes on looping thru large files (so that big files are extracted), -D for dry run / dry dumping, so you can just see what happens without any write operations happening, -i to ignore encountered errors (important as we might be dumping out a corrupt filesystem), -o to overwrite files that are there. -o and -F are useful because it removes user interaction with the “btrfs restore” and you can just leave it running until it finishes, which is alot more script friendly (script friends = less user interaction or better yet no user interaction whilst script runneth)

First lets look at a regular “btrfs restore” operation that dumps out all of the files inside the /dev/md127 filesystem to a /USB. First we run a dry run to see what is dumped out. Also in this example “btrfs restore” is more complex as we had to look at a none current tree location (notice -t 10669166821376) because the most recent one probably didnt return any files or folders in the dump (the most recent one is done with -t #)

Imagine we wanted a specific folder now. Imagine /dev/md127 is usually mounted to /data. And we wanted the /data/Backup folder. Backup can be a folder or a subvolume. Eitherway the commands would be identical, and the procedure would look like this (TIP: I would still start without a path-regex dry dump as seen above and then try a dry dump with a path regex):

Now if the FS is not too corrupt and the latest tree location works. Then try it without -t #. Ideally I should of put this at the top, as you should always try to get out the FS at the most current tree location – and then if that doesnt work try to get it at other tree locations (see this article: btrfs restore from other tree locations).

OTHER EXAMPLES WITH DIFFERENT REGULAR EXPRESSION TO GET DIFFERENT FOLDERS

NOTE: there is a couple of ways to restore a folder or a file. Also make sure to escape special characters:

 

NOTE: no need to escape dots, but need to escape (), also no need to escape spaces (its optional to escape dots and spaces). These would of also worked:

HOW TO BUILD PATH REGEX STEPS:

* get the folder or filepath path from the root of the filesystem (remove the mount point, and remove the left hand / and if its a folder remove the right hand /)… so /data/Backup/Files/ , would turn into Backup/Files , since /data is the mount point and we also dont want the first & last slash in /Backup/Files/ as the rest of the steps take care of those)
* At the beginning, left end, put ^/(| * Before each / slash put (| * Count up how many occurances of (| you have and call that number parcount
* At the right most end put ) parcount times
* At the right most end put $
* If its a folder that your extracting (so you want everything inside it recursively), locate the left most unescaped ), and to the left of it put either: (|.*)  or .* — so ))))))  becomes (|.*)))))))  <- prefered
— or ))))))  becomes .*)))))) — man page and examples online use (|.*) , to be more accurate I would (|.*)  because its more specific, and .*  is more general and might find more results than you need
* Or if its a folder that your extracting (you want everything inside it recursively), located the left most unescaped ), and right before it put
* which characters to escape with a backslash \? http://stackoverflow.com/questions/399078/what-special-characters-must-be-escaped-in-regular-expressions
* Surround whole thing with single quotes ‘whole path regex’

NOTE: the above would be easy to script out ‘./build-btrfs-path-regex.sh “/data/Backup/Files”‘

TIP:
* you dont need to escape spaces, but if you do it will not hurt the results
* first run a dry dump to see if your capturing what you want, as the dry dump operation is really quick

SO WHICH CHARACTERS TO ESCAPE?

From link above: For PCRE, and most other so-called Perl-compatible flavors, escape these outside character classes:
.^$*+?()[{\| 
and these inside character classes:
^-]\ 
Obivously in our cases we didnt need to escape . so thats probably the only exception from the list above.
Also if you accidentally escape }, thats fine, notice { is in the list but } is not
The point is, try doing a dry run first to see if you get what you want and then do a normal run. Or test every possible condition and let me know a better list to put here under the “SO WHICH CHARACTERS TO ESCAPE?”

WHY IS THE REGULAR EXPRESSION SO COMPLICATED?

So that BTRFS RESTORE doesnt only restore the files, but also the folders. So that you dont have to “mkdir” the full paths for everything before hand.
For example, using either of these:

You get these restoring messages:

Ignore The /dev/null (its showing up because im using a dry run and dumping to /dev/null – yes its a double nothing, a dry run that we are dumping to the nothingness which /dev/null)
Notice how it first restores the folders

As an example, lets look at this:

Which dumps

Now look at what happens if I remove the .*  or (|/.*) , they both become:

And now it only restores:

So the intericate regular expression of '^/(|Backup321(|/DRIVE.*))$'  or '^/(|Backup321(|/DRIVE(|/.*)))$' Evaluate true for /Backup321  so that Backup321 folder is created and for /Backup321/DRIVE  so that DRIVE folder is created in Backup321  and for /Backup321/DRIVE/*  so that all of the files and folders inside it are dumped.

Leave a Reply

Your email address will not be published. Required fields are marked *