mirror of
https://github.com/kdave/btrfs-progs
synced 2024-12-27 08:32:20 +00:00
restore: Add regex matching of paths and files to be restored
The option -m is used to specify the regex string. -c is used to specify case insensitive matching. -i was already taken. In order to restore only a single folder somewhere in the btrfs tree, it is unfortunately neccessary to construct a slightly nontrivial regex, e.g.: restore -m '^/(|home(|/username(|/Desktop(|/.*))))$' /dev/sdb2 /output This is needed in order to match each directory along the way to the Desktop directory, as well as all contents below the Desktop directory. Signed-off-by: Peter Stuge <peter@stuge.se> Signed-off-by: Josef Bacik <josef@redhat.com> Signed-off-by: David Sterba <dsterba@suse.cz> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
This commit is contained in:
parent
3d86ac20b7
commit
e35450fa53
@ -27,9 +27,11 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <lzo/lzoconf.h>
|
#include <lzo/lzoconf.h>
|
||||||
#include <lzo/lzo1x.h>
|
#include <lzo/lzo1x.h>
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
#include <regex.h>
|
||||||
|
|
||||||
#include "ctree.h"
|
#include "ctree.h"
|
||||||
#include "disk-io.h"
|
#include "disk-io.h"
|
||||||
@ -539,7 +541,8 @@ set_size:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
|
static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
|
||||||
const char *output_rootdir, const char *dir)
|
const char *output_rootdir, const char *dir,
|
||||||
|
const regex_t *mreg)
|
||||||
{
|
{
|
||||||
struct btrfs_path *path;
|
struct btrfs_path *path;
|
||||||
struct extent_buffer *leaf;
|
struct extent_buffer *leaf;
|
||||||
@ -646,6 +649,9 @@ static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
|
|||||||
/* full path from root of btrfs being restored */
|
/* full path from root of btrfs being restored */
|
||||||
snprintf(fs_name, 4096, "%s/%s", dir, filename);
|
snprintf(fs_name, 4096, "%s/%s", dir, filename);
|
||||||
|
|
||||||
|
if (REG_NOMATCH == regexec(mreg, fs_name, 0, NULL, 0))
|
||||||
|
goto next;
|
||||||
|
|
||||||
/* full path from system root */
|
/* full path from system root */
|
||||||
snprintf(path_name, 4096, "%s%s", output_rootdir, fs_name);
|
snprintf(path_name, 4096, "%s%s", output_rootdir, fs_name);
|
||||||
|
|
||||||
@ -759,7 +765,7 @@ static int search_dir(struct btrfs_root *root, struct btrfs_key *key,
|
|||||||
}
|
}
|
||||||
loops = 0;
|
loops = 0;
|
||||||
ret = search_dir(search_root, &location,
|
ret = search_dir(search_root, &location,
|
||||||
output_rootdir, dir);
|
output_rootdir, dir, mreg);
|
||||||
free(dir);
|
free(dir);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (ignore_errors)
|
if (ignore_errors)
|
||||||
@ -990,8 +996,13 @@ int cmd_restore(int argc, char **argv)
|
|||||||
int super_mirror = 0;
|
int super_mirror = 0;
|
||||||
int find_dir = 0;
|
int find_dir = 0;
|
||||||
int list_roots = 0;
|
int list_roots = 0;
|
||||||
|
const char *match_regstr = NULL;
|
||||||
|
int match_cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
|
||||||
|
regex_t match_reg, *mreg = NULL;
|
||||||
|
char reg_err[256];
|
||||||
|
|
||||||
|
while ((opt = getopt(argc, argv, "sviot:u:df:r:lcm:")) != -1) {
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "sviot:u:df:r:l")) != -1) {
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 's':
|
case 's':
|
||||||
get_snaps = 1;
|
get_snaps = 1;
|
||||||
@ -1045,6 +1056,12 @@ int cmd_restore(int argc, char **argv)
|
|||||||
case 'l':
|
case 'l':
|
||||||
list_roots = 1;
|
list_roots = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'c':
|
||||||
|
match_cflags |= REG_ICASE;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
match_regstr = optarg;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage(cmd_restore_usage);
|
usage(cmd_restore_usage);
|
||||||
}
|
}
|
||||||
@ -1116,9 +1133,21 @@ int cmd_restore(int argc, char **argv)
|
|||||||
key.objectid = BTRFS_FIRST_FREE_OBJECTID;
|
key.objectid = BTRFS_FIRST_FREE_OBJECTID;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = search_dir(root, &key, dir_name, "");
|
if (match_regstr) {
|
||||||
|
ret = regcomp(&match_reg, match_regstr, match_cflags);
|
||||||
|
if (ret) {
|
||||||
|
regerror(ret, &match_reg, reg_err, sizeof(reg_err));
|
||||||
|
fprintf(stderr, "Regex compile failed: %s\n", reg_err);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
mreg = &match_reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = search_dir(root, &key, dir_name, "", mreg);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
if (mreg)
|
||||||
|
regfree(mreg);
|
||||||
close_ctree(root);
|
close_ctree(root);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user