Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some updates for disaster recovery use #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 111 additions & 23 deletions zfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,20 @@ __FBSDID("$FreeBSD: stable/9/sys/boot/zfs/zfs.c 243243 2012-11-18 17:09:29Z ae $

#include "libzfs.h"

#define READ_BL_SIZE 32*1024
char *dirname(const char *);
char *fname = NULL;
const char *destfolder = NULL;
int opt_copy = 0;
int opt_recursive = 0;
int opt_ignore_errors = 0;
char **exclude_list = NULL;
int exclude_list_size = 0;
int exclude_list_count = 0;
char **device_list = NULL;
int device_list_size = 0;
int device_list_count = 0;

#include "zfsimpl.c"

#undef SOPEN_RASIZE
Expand Down Expand Up @@ -433,18 +447,19 @@ zfs_probe_partition(void *arg, const char *partname,
{
struct zfs_probe_args *ppa, pa;
struct ptable *table;
char devname[32];
char devname[64];
int ret;

/* Probe only freebsd-zfs and freebsd partitions */
if (part->type != PART_FREEBSD &&
part->type != PART_FREEBSD_ZFS)
return;
//if (part->type != PART_FREEBSD &&
// part->type != PART_FREEBSD_ZFS)
// return;

ppa = (struct zfs_probe_args *)arg;
strncpy(devname, ppa->devname, strlen(ppa->devname) - 1);
devname[strlen(ppa->devname) - 1] = '\0';
sprintf(devname, "%s%s:", devname, partname);
printf("dn: %s\n", devname);
pa.fd = open(devname, O_RDONLY);
if (pa.fd == -1)
return;
Expand All @@ -457,7 +472,7 @@ zfs_probe_partition(void *arg, const char *partname,
pa.pool_guid = ppa->pool_guid;
pa.secsz = ppa->secsz;
table = ptable_open(&pa, part->end - part->start + 1,
ppa->secsz, zfs_diskread);
ppa->secsz, zfs_diskread);
if (table != NULL) {
ptable_iterate(table, &pa, zfs_probe_partition);
ptable_close(table);
Expand All @@ -473,7 +488,7 @@ zfs_probe_dev(const char *devname, uint64_t *pool_guid)
struct zfs_probe_args pa;
off_t mediasz;
int ret;

printf("Probe Dev: %s\n", devname);
pa.fd = open(devname, O_RDONLY);
if (pa.fd == -1)
return (ENXIO);
Expand Down Expand Up @@ -714,9 +729,23 @@ zfs_list(const char *name)
static void
i386_zfs_probe(void)
{
char devname[32];
char devname[64];
int unit;

int part;

/* User specified devices to probe */
if (device_list_count) {
for (int di=0; di < device_list_count; di++) {
if (zfs_probe_dev(device_list[di], NULL) != 0) {
/* try with /dev prefix */
sprintf(devname, "/dev/%s", device_list[di]);
zfs_probe_dev(devname, NULL);
}
}
return;

}

/*
* Open all the disks we can find and see if we can reconstruct
* ZFS pools from them.
Expand All @@ -730,8 +759,12 @@ i386_zfs_probe(void)
sprintf(devname, "/dev/ada%d", unit);
if (zfs_probe_dev(devname, NULL) != 0)
break;
}
for (unit = 0; unit < MAXBDDEV; unit++) {
for (part = 1; part < 9; part++) {
sprintf(devname, "/dev/ada%dp%d", unit, part);
zfs_probe_dev(devname, NULL);
}
}
for (unit = 0; unit < MAXBDDEV; unit++) {
sprintf(devname, "/dev/da%d", unit);
if (zfs_probe_dev(devname, NULL) != 0)
break;
Expand Down Expand Up @@ -923,7 +956,7 @@ myread(struct open_file *f, void *dest, size_t bcount)
/* no more data, return what we had */
if (f->f_ralen == 0)
return(bcount - resid);
}
}
}

/*
Expand Down Expand Up @@ -1004,19 +1037,61 @@ build(char *path, mode_t omode)
return (retval);
}

#define READ_BL_SIZE 32*1024
char *dirname(const char *);
char *fname = NULL;
const char *destfolder = NULL;
int opt_copy = 0;
int opt_recursive = 0;
void
add_exclude(char *prefix)
{
int newsize;
printf("exclude: %s\n", prefix);

if (exclude_list_size == exclude_list_count) {
if (exclude_list_size) {
newsize = exclude_list_size << 1;
} else {
newsize = 8;
}
//printf("resize: %d -> %d\n", newsize, sizeof(char*) * newsize);
exclude_list = realloc(exclude_list, sizeof(char*) * newsize);
exclude_list_size = newsize;
}
exclude_list[exclude_list_count++] = prefix;
}


void
add_device(char *devname)
{
int newsize;
printf("Scan device: %s\n", devname);

if (device_list_size == device_list_count) {
if (device_list_size) {
newsize = device_list_size << 1;
} else {
newsize = 8;
}
//printf("resize: %d -> %d\n", newsize, sizeof(char*) * newsize);
device_list = realloc(device_list, sizeof(char*) * newsize);
device_list_size = newsize;
}
device_list[device_list_count++] = devname;
}


int
zfs_recover(const char *file, struct open_file *f)
{
int ret = 0;

//printf("zfs_recover file=%s\n", file);
printf("zfs_recover file=%s\n", file);
int flen=strlen(file); int xlen;
for (int xi=0; xi < exclude_list_count; xi++) {
xlen=strlen(exclude_list[xi]);
if (xlen > flen) continue;
if (!memcmp(file, exclude_list[xi], xlen)) {
printf("matches exclude rule %s\n", exclude_list[xi]);
return ret;
}
}
ret = zfs_open(file, f);
if (ret != 0) {
printf("zfs_open failed: %s\n", strerror(ret));
Expand Down Expand Up @@ -1117,7 +1192,8 @@ zfs_recover(const char *file, struct open_file *f)
ret = zfs_recover(d_name, f);
free(n1->file);
free(n1);
}
if (opt_recursive && ret != 0 && opt_ignore_errors == 0)
return ret; }
} else if (S_ISREG(sb.st_mode)) {
//printf("file size=%d\n", (int)sb.st_size);
if (!opt_copy) {
Expand Down Expand Up @@ -1196,15 +1272,18 @@ usage(void)
{

printf("%s\n%s\n%s\n\n",
"usage: zfs_read -d",
" zfs_read -l <pool_name>",
" zfs_read [-c <dest_folder>] [-r] -f <pool/dataset:folder>");
"usage: zfs_read [-n device] [-i] -d",
" zfs_read [-n device] [-i] -l <pool_name>",
" zfs_read [-n device] [-i [-i]] [-c <dest_folder>] [-x prefix ] [-r] -f <pool/dataset:folder>");
printf("OPTIONS\n");
printf("\t%-18s%s\n", "-d", "look for pool in device /dev/da* and /dev/ada*");
printf("\t%-18s%s\n", "-n device", "look for pool in device or file - repeat for multiple devices");
printf("\t%-18s%s\n", "-l pool_name", "list dataset for pool_name");
printf("\t%-18s%s\n", "-f dataset:folder", "working folder, example: mypool/Pictures:/");
printf("\t%-18s%s\n", "-c destfolder", "restore a copie of all files in destfolder");
printf("\t%-18s%s\n", "-r", "recursive list or copie");
printf("\t%-18s%s\n", "-i [-i]", "ignore errors (-i again to ignore more)");
printf("\t%-18s%s\n", "-x path_prefix", "exclude paths beginning with this prefix");

exit(EX_USAGE);
}
Expand All @@ -1215,7 +1294,7 @@ main(int argc, char **argv)
int ret, ch, opt_devprint = 0;
const char * opt_zfs_list = NULL;

while ((ch = getopt(argc, argv, "df:rc:l:")) != -1) {
while ((ch = getopt(argc, argv, "df:rc:l:x:in:")) != -1) {
switch (ch) {
case 'd':
opt_devprint = 1;
Expand All @@ -1235,6 +1314,15 @@ main(int argc, char **argv)
case 'l':
opt_zfs_list = optarg;
break;
case 'i':
opt_ignore_errors++;
break;
case 'x':
add_exclude(optarg);
break;
case 'n':
add_device(optarg);
break;
default:
usage();
}
Expand Down
13 changes: 10 additions & 3 deletions zfsimpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -930,8 +930,13 @@ vdev_probe(vdev_phys_read_t *read, void *read_priv, spa_t **spap)
if (nvlist_find(nvlist,
ZPOOL_CONFIG_FEATURES_FOR_READ,
DATA_TYPE_NVLIST, 0, &features) == 0
&& nvlist_check_features_for_read(features) != 0)
return (EIO);
&& nvlist_check_features_for_read(features) != 0) {

//unsupported flags are maybe not too bad
if (opt_ignore_errors == 0) {
return (EIO);
}
}

if (nvlist_find(nvlist,
ZPOOL_CONFIG_POOL_STATE,
Expand Down Expand Up @@ -1178,7 +1183,9 @@ zio_read(const spa_t *spa, const blkptr_t *bp, void *buf)
break;
}
if (error != 0)
printf("ZFS: i/o error - all block copies unavailable\n");
printf("ZFS: i/o error !!!- all block copies unavailable\n");
if (opt_ignore_errors > 1)
return 0;
return (error);
}

Expand Down