summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2007-06-12 21:33:11 +0000
committerphk <phk@FreeBSD.org>2007-06-12 21:33:11 +0000
commitc2d4f7354c477a216abac2d5d4da3021f1a9edaf (patch)
tree4f32eac2c639484c744762115ac01da8cedb04b7 /tools
parent103fd8415eccb2924f8f6932c0f3508e32499c89 (diff)
downloadFreeBSD-src-c2d4f7354c477a216abac2d5d4da3021f1a9edaf.zip
FreeBSD-src-c2d4f7354c477a216abac2d5d4da3021f1a9edaf.tar.gz
Recoverdisk is now part of the base system.
Diffstat (limited to 'tools')
-rw-r--r--tools/tools/recoverdisk/Makefile9
-rw-r--r--tools/tools/recoverdisk/recoverdisk.1133
-rw-r--r--tools/tools/recoverdisk/recoverdisk.c294
3 files changed, 0 insertions, 436 deletions
diff --git a/tools/tools/recoverdisk/Makefile b/tools/tools/recoverdisk/Makefile
deleted file mode 100644
index 6733a4f..0000000
--- a/tools/tools/recoverdisk/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# $FreeBSD$
-
-PROG= recoverdisk
-WARNS?= 6
-
-.include <bsd.prog.mk>
-
-test: ${PROG}
- ./${PROG} /dev/ad0
diff --git a/tools/tools/recoverdisk/recoverdisk.1 b/tools/tools/recoverdisk/recoverdisk.1
deleted file mode 100644
index c5526b3..0000000
--- a/tools/tools/recoverdisk/recoverdisk.1
+++ /dev/null
@@ -1,133 +0,0 @@
-.\" Copyright (c) 2006 Ulrich Spoerlein <uspoerlein@gmail.com>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd May 6, 2006
-.Dt RECOVERDISK 1
-.Os
-.Sh NAME
-.Nm recoverdisk
-.Nd recover data from hard disk or optical media
-.Sh SYNOPSIS
-.Nm
-.Op Fl r Ar rlist
-.Op Fl w Ar wlist
-.Ar special
-.Op Ar file
-.Sh DESCRIPTION
-The
-.Nm
-utility reads data from the
-.Ar special
-file until all blocks could be successfully read.
-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).
-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
-The options are as follows:
-.Bl -tag -width indent
-.It Fl r Ar rlist
-Read the list of blocks and block sizes to read from the specified file.
-.It Fl w Ar wlist
-Write the list of remaining blocks to read to the specified file if
-.Nm
-is aborted via
-.Dv SIGINT .
-.El
-.Pp
-The
-.Fl r
-and
-.Fl w
-options can be specified together.
-Especially, they can point to the same file, which will be updated on abort.
-.Sh OUTPUT
-The
-.Nm
-utility
-prints several columns, detailing the progress
-.Bl -tag -width remaining
-.It Va start
-Starting offset of the current block.
-.It Va size
-Read size of the current block.
-.It Va len
-Length of the current block.
-.It Va state
-Is increased for every failed read.
-.It Va done
-Number of bytes already read.
-.It Va remaining
-Number of bytes remaining.
-.It Va "% done"
-Percent complete.
-.El
-.Sh EXAMPLES
-.Bd -literal
-# recover data from failing hard drive ad3
-touch /data/lots_of_space
-recoverdisk /dev/ad3 /data/lots_of_space
-
-# clone a hard disk
-recoverdisk /dev/ad3 /dev/ad4
-
-# read an ISO image from a CD-ROM
-touch /data/cd.iso; recoverdisk /dev/acd0 /data/cd.iso
-
-# continue reading from a broken CD and update the existing worklist
-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
-.Ed
-.Sh SEE ALSO
-.Xr dd 1
-.Sh HISTORY
-The
-.Nm
-utility first appeared in
-.Fx 7.0 .
-.Sh AUTHORS
-.An -nosplit
-The original implementation was done by
-.An Poul-Henning Kamp Aq phk@FreeBSD.org
-with minor improvements from
-.An Ulrich Sp\(:orlein Aq uspoerlein@gmail.com .
-.Pp
-This manual page was written by
-.An Ulrich Sp\(:orlein .
-.Sh BUGS
-Reading from media where the sectorsize is not a power of 2 will make all
-1 MB reads fail.
-This is due to the DMA reads being split up into blocks of at most 128kB.
-These reads then fail if the sectorsize is not a divisor of 128kB.
-When reading a full raw audio CD, this leads to roughly 700 error messages
-flying by.
-This is harmless.
diff --git a/tools/tools/recoverdisk/recoverdisk.c b/tools/tools/recoverdisk/recoverdisk.c
deleted file mode 100644
index 0dc5d7c..0000000
--- a/tools/tools/recoverdisk/recoverdisk.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*-
- * ----------------------------------------------------------------------------
- * "THE BEER-WARE LICENSE" (Revision 42):
- * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
- * ----------------------------------------------------------------------------
- *
- * $FreeBSD$
- */
-#include <sys/param.h>
-#include <sys/queue.h>
-#include <sys/disk.h>
-#include <sys/stat.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-volatile sig_atomic_t aborting = 0;
-static size_t bigsize = 1024 * 1024;
-static size_t medsize = 64 * 1024;
-static size_t minsize = 512;
-
-struct lump {
- off_t start;
- off_t len;
- int state;
- TAILQ_ENTRY(lump) list;
-};
-
-static TAILQ_HEAD(, lump) lumps = TAILQ_HEAD_INITIALIZER(lumps);
-
-static void
-new_lump(off_t start, off_t len, int state)
-{
- struct lump *lp;
-
- lp = malloc(sizeof *lp);
- if (lp == NULL)
- err(1, "Malloc failed");
- lp->start = start;
- lp->len = len;
- lp->state = state;
- TAILQ_INSERT_TAIL(&lumps, lp, list);
-}
-
-static struct lump *lp;
-static char *wworklist = NULL;
-static char *rworklist = NULL;
-
-
-#define PRINT_HEADER \
- printf("%13s %7s %13s %5s %13s %13s %9s\n", \
- "start", "size", "block-len", "state", "done", "remaining", "% done")
-
-#define PRINT_STATUS(start, i, len, state, d, t) \
- printf("\r%13jd %7zu %13jd %5d %13jd %13jd %9.5f", \
- (intmax_t)start, \
- i, \
- (intmax_t)len, \
- state, \
- (intmax_t)d, \
- (intmax_t)(t - d), \
- 100*(double)d/(double)t)
-
-/* Save the worklist if -w was given */
-static void
-save_worklist(void)
-{
- FILE *file;
-
- if (wworklist != NULL) {
- (void)fprintf(stderr, "\nSaving worklist ...");
- fflush(stderr);
-
- file = fopen(wworklist, "w");
- if (file == NULL)
- err(1, "Error opening file %s", wworklist);
-
- for (;;) {
- lp = TAILQ_FIRST(&lumps);
- if (lp == NULL)
- break;
- fprintf(file, "%jd %jd %d\n",
- (intmax_t)lp->start, (intmax_t)lp->len, lp->state);
- TAILQ_REMOVE(&lumps, lp, list);
- }
- (void)fprintf(stderr, " done.\n");
- }
-}
-
-/* Read the worklist if -r was given */
-static off_t
-read_worklist(off_t t)
-{
- off_t s, l, d;
- int state, lines;
- FILE *file;
-
- (void)fprintf(stderr, "Reading worklist ...");
- fflush(stderr);
- file = fopen(rworklist, "r");
- if (file == NULL)
- err(1, "Error opening file %s", rworklist);
-
- lines = 0;
- d = t;
- for (;;) {
- ++lines;
- if (3 != fscanf(file, "%jd %jd %d\n", &s, &l, &state)) {
- if (!feof(file))
- err(1, "Error parsing file %s at line %d",
- rworklist, lines);
- else
- break;
- }
- new_lump(s, l, state);
- d -= l;
- }
- (void)fprintf(stderr, " done.\n");
- /*
- * Return the number of bytes already read
- * (at least not in worklist).
- */
- return (d);
-}
-
-static void
-usage(void)
-{
- (void)fprintf(stderr,
- "usage: recoverdisk [-r worklist] [-w worklist] source-drive [destination]\n");
- exit(1);
-}
-
-static void
-sighandler(__unused int sig)
-{
-
- aborting = 1;
-}
-
-int
-main(int argc, char * const argv[])
-{
- int ch;
- int fdr, fdw;
- off_t t, d, start, len;
- size_t i, j;
- int error, flags, state;
- u_char *buf;
- u_int sectorsize;
- time_t t1, t2;
- struct stat sb;
-
- while ((ch = getopt(argc, argv, "r:w:")) != -1) {
- switch (ch) {
- case 'r':
- rworklist = strdup(optarg);
- if (rworklist == NULL)
- err(1, "Cannot allocate enough memory");
- break;
- case 'w':
- wworklist = strdup(optarg);
- if (wworklist == NULL)
- err(1, "Cannot allocate enough memory");
- break;
- default:
- usage();
- /* NOTREACHED */
- }
- }
- argc -= optind;
- argv += optind;
-
- if (argc < 1 || argc > 2)
- usage();
-
- fdr = open(argv[0], O_RDONLY);
- if (fdr < 0)
- err(1, "Cannot open read descriptor %s", argv[0]);
-
- error = fstat(fdr, &sb);
- if (error < 0)
- err(1, "fstat failed");
- flags = O_WRONLY;
- if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
- error = ioctl(fdr, DIOCGSECTORSIZE, &sectorsize);
- 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;
-
- error = ioctl(fdr, DIOCGMEDIASIZE, &t);
- if (error < 0)
- err(1, "DIOCGMEDIASIZE failed");
- } else {
- t = sb.st_size;
- flags |= O_CREAT | O_TRUNC;
- }
-
- buf = malloc(bigsize);
- if (buf == NULL)
- err(1, "Cannot allocate %jd bytes buffer", (intmax_t)bigsize);
-
- if (argc > 1) {
- fdw = open(argv[1], flags, DEFFILEMODE);
- if (fdw < 0)
- err(1, "Cannot open write descriptor %s", argv[1]);
- } else
- fdw = -1;
-
- if (rworklist != NULL) {
- d = read_worklist(t);
- } else {
- new_lump(0, t, 0);
- d = 0;
- }
- if (wworklist != NULL)
- signal(SIGINT, sighandler);
-
- t1 = 0;
- start = len = i = state = 0;
- PRINT_HEADER;
- for (;;) {
- lp = TAILQ_FIRST(&lumps);
- if (lp == NULL)
- break;
- while (lp->len > 0 && !aborting) {
- /* These are only copied for printing stats */
- start = lp->start;
- len = lp->len;
- state = lp->state;
-
- i = MIN(lp->len, (off_t)bigsize);
- if (lp->state == 1)
- i = MIN(lp->len, (off_t)medsize);
- if (lp->state > 1)
- i = MIN(lp->len, (off_t)minsize);
- time(&t2);
- if (t1 != t2 || lp->len < (off_t)bigsize) {
- PRINT_STATUS(start, i, len, state, d, t);
- t1 = t2;
- }
- if (i == 0) {
- errx(1, "BOGUS i %10jd", (intmax_t)i);
- }
- fflush(stdout);
- j = pread(fdr, buf, i, lp->start);
- if (j == i) {
- d += i;
- if (fdw >= 0)
- j = pwrite(fdw, buf, i, lp->start);
- else
- j = i;
- if (j != i)
- printf("\nWrite error at %jd/%zu\n",
- lp->start, i);
- lp->start += i;
- lp->len -= i;
- continue;
- }
- printf("\n%jd %zu failed %d\n", lp->start, i, errno);
- new_lump(lp->start, i, lp->state + 1);
- lp->start += i;
- lp->len -= i;
- }
- if (aborting) {
- save_worklist();
- return (0);
- }
- TAILQ_REMOVE(&lumps, lp, list);
- free(lp);
- }
- PRINT_STATUS(start, i, len, state, d, t);
- printf("\nCompleted\n");
- return (0);
-}
OpenPOWER on IntegriCloud