mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-24 01:07:21 +01:00
Some improvements to recoverdisk
This commit is contained in:
parent
05dc172526
commit
584f5546ee
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=189691
@ -32,7 +32,9 @@
|
||||
.Nd recover data from hard disk or optical media
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl b Ar bigsize
|
||||
.Op Fl r Ar rlist
|
||||
.Op Fl s Ar snapshot
|
||||
.Op Fl w Ar wlist
|
||||
.Ar special
|
||||
.Op Ar file
|
||||
@ -46,15 +48,24 @@ It starts reading in multiples of the sector size.
|
||||
Whenever a block fails, it is put to the end of the working queue and will be
|
||||
read again, possibly with a smaller read size.
|
||||
.Pp
|
||||
It uses block sizes of roughly 1 MB, 64kB, and the native sector size (usually
|
||||
512 bytes).
|
||||
By default it uses block sizes of roughly 1 MB, 32kB, and the native
|
||||
sector size (usually 512 bytes).
|
||||
These figures are adjusted slightly, for devices whose sectorsize is not a
|
||||
power of 2, e.g., audio CDs with a sector size of 2352 bytes.
|
||||
.Pp
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width indent
|
||||
.It Fl b Ar bigsize
|
||||
The size of reads attempted first.
|
||||
The middle pass is roughly the logarithmic average of the bigsize and
|
||||
the sectorsize.
|
||||
.It Fl r Ar rlist
|
||||
Read the list of blocks and block sizes to read from the specified file.
|
||||
.It Fl s Ar snapshot
|
||||
How often we should update the worklist file while things go OK.
|
||||
The default is 60 and the units is "progress messages" so if things
|
||||
go well, this is the same as once per minute.
|
||||
.It Fl w Ar wlist
|
||||
Write the list of remaining blocks to read to the specified file if
|
||||
.Nm
|
||||
@ -106,6 +117,10 @@ recoverdisk -r worklist -w worklist /dev/acd0 /data/cd.iso
|
||||
|
||||
# recover a single file from the unreadable media
|
||||
touch file.avi; recoverdisk /cdrom/file.avi file.avi
|
||||
|
||||
# If the disk hangs the system on read-errors try:
|
||||
recoverdisk -b 0 /dev/ad3 /somewhere
|
||||
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr dd 1
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
volatile sig_atomic_t aborting = 0;
|
||||
static size_t bigsize = 1024 * 1024;
|
||||
static size_t medsize = 64 * 1024;
|
||||
static size_t medsize;
|
||||
static size_t minsize = 512;
|
||||
|
||||
struct lump {
|
||||
@ -76,6 +76,7 @@ static void
|
||||
save_worklist(void)
|
||||
{
|
||||
FILE *file;
|
||||
struct lump *llp;
|
||||
|
||||
if (wworklist != NULL) {
|
||||
(void)fprintf(stderr, "\nSaving worklist ...");
|
||||
@ -85,14 +86,11 @@ save_worklist(void)
|
||||
if (file == NULL)
|
||||
err(1, "Error opening file %s", wworklist);
|
||||
|
||||
for (;;) {
|
||||
lp = TAILQ_FIRST(&lumps);
|
||||
if (lp == NULL)
|
||||
break;
|
||||
TAILQ_FOREACH(llp, &lumps, list)
|
||||
fprintf(file, "%jd %jd %d\n",
|
||||
(intmax_t)lp->start, (intmax_t)lp->len, lp->state);
|
||||
TAILQ_REMOVE(&lumps, lp, list);
|
||||
}
|
||||
(intmax_t)llp->start, (intmax_t)llp->len,
|
||||
llp->state);
|
||||
fclose(file);
|
||||
(void)fprintf(stderr, " done.\n");
|
||||
}
|
||||
}
|
||||
@ -160,14 +158,21 @@ main(int argc, char * const argv[])
|
||||
u_int sectorsize;
|
||||
time_t t1, t2;
|
||||
struct stat sb;
|
||||
u_int n, snapshot = 60;
|
||||
|
||||
while ((ch = getopt(argc, argv, "r:w:")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "b:r:w:s:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'b':
|
||||
bigsize = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'r':
|
||||
rworklist = strdup(optarg);
|
||||
if (rworklist == NULL)
|
||||
err(1, "Cannot allocate enough memory");
|
||||
break;
|
||||
case 's':
|
||||
snapshot = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'w':
|
||||
wworklist = strdup(optarg);
|
||||
if (wworklist == NULL)
|
||||
@ -197,15 +202,8 @@ main(int argc, char * const argv[])
|
||||
if (error < 0)
|
||||
err(1, "DIOCGSECTORSIZE failed");
|
||||
|
||||
/*
|
||||
* Make medsize roughly 64kB, depending on native sector
|
||||
* size. bigsize has to be a multiple of medsize.
|
||||
* For media with 2352 sectors, this will
|
||||
* result in 2352, 63504, and 1016064 bytes.
|
||||
*/
|
||||
minsize = sectorsize;
|
||||
medsize = (medsize / sectorsize) * sectorsize;
|
||||
bigsize = medsize * 16;
|
||||
bigsize = (bigsize / sectorsize) * sectorsize;
|
||||
|
||||
error = ioctl(fdr, DIOCGMEDIASIZE, &t);
|
||||
if (error < 0)
|
||||
@ -215,6 +213,17 @@ main(int argc, char * const argv[])
|
||||
flags |= O_CREAT | O_TRUNC;
|
||||
}
|
||||
|
||||
if (bigsize < minsize)
|
||||
bigsize = minsize;
|
||||
|
||||
for (ch = 0; (bigsize >> ch) > minsize; ch++)
|
||||
continue;
|
||||
medsize = bigsize >> (ch / 2);
|
||||
medsize = (medsize / minsize) * minsize;
|
||||
|
||||
fprintf(stderr, "Bigsize = %u, medsize = %u, minsize = %u\n",
|
||||
bigsize, medsize, minsize);
|
||||
|
||||
buf = malloc(bigsize);
|
||||
if (buf == NULL)
|
||||
err(1, "Cannot allocate %jd bytes buffer", (intmax_t)bigsize);
|
||||
@ -238,6 +247,7 @@ main(int argc, char * const argv[])
|
||||
t1 = 0;
|
||||
start = len = i = state = 0;
|
||||
PRINT_HEADER;
|
||||
n = 0;
|
||||
for (;;) {
|
||||
lp = TAILQ_FIRST(&lumps);
|
||||
if (lp == NULL)
|
||||
@ -257,6 +267,10 @@ main(int argc, char * const argv[])
|
||||
if (t1 != t2 || lp->len < (off_t)bigsize) {
|
||||
PRINT_STATUS(start, i, len, state, d, t);
|
||||
t1 = t2;
|
||||
if (++n == snapshot) {
|
||||
save_worklist();
|
||||
n = 0;
|
||||
}
|
||||
}
|
||||
if (i == 0) {
|
||||
errx(1, "BOGUS i %10jd", (intmax_t)i);
|
||||
|
Loading…
Reference in New Issue
Block a user