>From 450aaeda98a3e37c50d2a8e3b12330bbea2a86ac Mon Sep 17 00:00:00 2001 From: Andreas Oberritter Date: Mon, 11 Oct 2010 03:54:08 +0200 Subject: [PATCH 3/4] Add new command-line option -E to specifiy maximum amount of new errors --- ddrescue.h | 8 ++++---- doc/ddrescue.1 | 7 +++++-- main.cc | 22 ++++++++++++++-------- rescuebook.cc | 5 +++-- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/ddrescue.h b/ddrescue.h index 6fb3cd7..13793e2 100644 --- a/ddrescue.h +++ b/ddrescue.h @@ -125,9 +125,9 @@ class Rescuebook : public Logbook long long sparse_size; // end position of pending writes long long recsize, errsize; // total recovered and error sizes const char * const iname_; - int errors; // error areas found so far + int errors, old_errors; // error areas found so far int ides_, odes_; // input and output file descriptors - const int max_errors_, max_retries_, skipbs_; + const int max_errors_, max_new_errors_, max_retries_, skipbs_; const bool nosplit_, sparse_, synchronous_; // variables for show_status long long a_rate, c_rate, first_size, last_size; @@ -142,7 +142,7 @@ class Rescuebook : public Logbook int check_all(); void count_errors() throw(); bool too_many_errors() const throw() - { return ( max_errors_ >= 0 && errors > max_errors_ ); } + { return ( max_errors_ >= 0 && errors > max_errors_ ) || ( max_new_errors_ >= 0 && errors - old_errors >= max_new_errors_ ); } int copy_and_update( const Block & b, const Sblock::Status st, int & copied_size, int & error_size, const char * const msg, bool & first_post ); @@ -156,7 +156,7 @@ public: Rescuebook( const long long ipos, const long long opos, Domain & dom, const long long isize, const char * const iname, const char * const logname, const int cluster, const int hardbs, - const int max_errors = -1, const int max_retries = 0, + const int max_errors = -1, const int max_new_errors = -1, const int max_retries = 0, const bool complete_only = false, const bool nosplit = false, const bool retrim = false, const bool sparse = false, const bool synchronous = false, const bool try_again = false ); diff --git a/doc/ddrescue.1 b/doc/ddrescue.1 index f74e6f0..f87642c 100644 --- a/doc/ddrescue.1 +++ b/doc/ddrescue.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1. -.TH DDRESCUE "1" "August 2010" "ddrescue 1.13" "User Commands" +.TH DDRESCUE "1" "October 2010" "ddrescue 1.13" "User Commands" .SH NAME ddrescue \- data recovery tool .SH SYNOPSIS @@ -38,7 +38,10 @@ use direct disc access for input file use synchronous writes for output file .TP \fB\-e\fR, \fB\-\-max\-errors=\fR -maximum number of error areas allowed +maximum number of total error areas allowed +.TP +\fB\-E\fR, \fB\-\-max\-new\-errors=\fR +maximum number of additional error areas allowed .TP \fB\-f\fR, \fB\-\-force\fR overwrite output device or partition diff --git a/main.cc b/main.cc index 9129e6f..845bdc8 100644 --- a/main.cc +++ b/main.cc @@ -73,7 +73,8 @@ void show_help( const int cluster, const int hardbs ) throw() std::printf( " -C, --complete-only do not read new data beyond logfile limits\n" ); std::printf( " -d, --direct use direct disc access for input file\n" ); std::printf( " -D, --synchronous use synchronous writes for output file\n" ); - std::printf( " -e, --max-errors= maximum number of error areas allowed\n" ); + std::printf( " -e, --max-errors= maximum number of total error areas allowed\n" ); + std::printf( " -E, --max-new-errors= maximum number of additional error areas allowed\n" ); std::printf( " -f, --force overwrite output device or partition\n" ); std::printf( " -F, --fill= fill given type blocks with infile data (?*/-+)\n" ); std::printf( " -g, --generate-logfile generate approximate logfile from partial copy\n" ); @@ -318,7 +319,7 @@ int do_generate( const long long ipos, const long long opos, Domain & domain, int do_rescue( const long long ipos, const long long opos, Domain & domain, const char *iname, const char *oname, const char *logname, const int cluster, const int hardbs, - const int max_errors, const int max_retries, + const int max_errors, const int max_new_errors, const int max_retries, const int o_direct, const int o_trunc, const bool complete_only, const bool nosplit, const bool preallocate, const bool retrim, const bool sparse, @@ -332,7 +333,7 @@ int do_rescue( const long long ipos, const long long opos, Domain & domain, { show_error( "Input file is not seekable." ); return 1; } Rescuebook rescuebook( ipos, opos, domain, isize, iname, logname, cluster, - hardbs, max_errors, max_retries, complete_only, + hardbs, max_errors, max_new_errors, max_retries, complete_only, nosplit, retrim, sparse, synchronous, try_again ); if( rescuebook.domain().in_size() == 0 ) { show_error( "Nothing to do." ); return 0; } @@ -375,6 +376,8 @@ int do_rescue( const long long ipos, const long long opos, Domain & domain, bool nl = false; if( max_errors >= 0 ) { nl = true; std::printf( "Max_errors: %d ", max_errors ); } + if( max_new_errors >= 0 ) + { nl = true; std::printf( "Max_new_errors: %d ", max_new_errors ); } if( max_retries >= 0 ) { nl = true; std::printf( "Max_retries: %d ", max_retries ); } if( nl ) std::printf( "\n" ); @@ -438,6 +441,7 @@ int main( const int argc, const char * const argv[] ) int cluster = 0; int hardbs = 512; int max_errors = -1; + int max_new_errors = -1; int max_retries = 0; int o_direct = 0; int o_trunc = 0; @@ -465,6 +469,7 @@ int main( const int argc, const char * const argv[] ) { 'd', "direct", Arg_parser::no }, { 'D', "synchronous", Arg_parser::no }, { 'e', "max-errors", Arg_parser::yes }, + { 'E', "max-new-errors", Arg_parser::yes }, { 'f', "force", Arg_parser::no }, { 'F', "fill", Arg_parser::yes }, { 'g', "generate-logfile", Arg_parser::no }, @@ -510,6 +515,7 @@ int main( const int argc, const char * const argv[] ) break; case 'D': synchronous = true; break; case 'e': max_errors = getnum( arg, 0, -1, INT_MAX ); break; + case 'E': max_new_errors = getnum( arg, 0, -1, INT_MAX ); break; case 'f': force = true; break; case 'F': filltypes = arg; check_fill_types( filltypes ); break; case 'g': generate = true; break; @@ -554,11 +560,11 @@ int main( const int argc, const char * const argv[] ) if( filltypes.size() ) { - if( max_errors >= 0 || max_retries || o_direct || o_trunc || + if( max_errors >= 0 || max_new_errors >= 0 || max_retries || o_direct || o_trunc || complete_only || generate || nosplit || preallocate || retrim || sparse || synchronous || try_again ) { - show_error( "warning: Options -C -d -D -e -g -n -p -r -R -S -t and -T" ); + show_error( "warning: Options -C -d -D -e -E -g -n -p -r -R -S -t and -T" ); show_error( "are ignored in fill mode." ); } @@ -567,11 +573,11 @@ int main( const int argc, const char * const argv[] ) } if( generate ) { - if( max_errors >= 0 || max_retries || o_direct || o_trunc || + if( max_errors >= 0 || max_new_errors >= 0 || max_retries || o_direct || o_trunc || complete_only || nosplit || preallocate || retrim || sparse || synchronous || try_again ) { - show_error( "warning: Options -C -d -D -e -n -p -r -R -S -t and -T" ); + show_error( "warning: Options -C -d -D -e -E -n -p -r -R -S -t and -T" ); show_error( "are ignored in generate-logfile mode." ); } @@ -579,7 +585,7 @@ int main( const int argc, const char * const argv[] ) cluster, hardbs ); } return do_rescue( ipos, opos, domain, iname, oname, logname, cluster, - hardbs, max_errors, max_retries, o_direct, o_trunc, + hardbs, max_errors, max_new_errors, max_retries, o_direct, o_trunc, complete_only, nosplit, preallocate, retrim, sparse, synchronous, try_again ); } diff --git a/rescuebook.cc b/rescuebook.cc index bdd8d43..b54fa40 100644 --- a/rescuebook.cc +++ b/rescuebook.cc @@ -289,14 +289,14 @@ int Rescuebook::copy_errors() Rescuebook::Rescuebook( const long long ipos, const long long opos, Domain & dom, const long long isize, const char * const iname, const char * const logname, const int cluster, const int hardbs, - const int max_errors, const int max_retries, + const int max_errors, const int max_new_errors, const int max_retries, const bool complete_only, const bool nosplit, const bool retrim, const bool sparse, const bool synchronous, const bool try_again ) : Logbook( ipos, opos, dom, isize, logname, cluster, hardbs, complete_only ), sparse_size( 0 ), iname_( ( iname && access( iname, F_OK ) == 0 ) ? iname : 0 ), - max_errors_( max_errors ), max_retries_( max_retries ), + max_errors_( max_errors ), max_new_errors_( max_new_errors ), max_retries_( max_retries ), skipbs_( std::max( 65536, hardbs ) ), nosplit_( nosplit ), sparse_( sparse ), synchronous_( synchronous ), a_rate( 0 ), c_rate( 0 ), first_size( 0 ), last_size( 0 ), @@ -404,6 +404,7 @@ int Rescuebook::do_rescue( const int ides, const int odes ) } count_errors(); set_signals(); + old_errors = errors; if( verbosity >= 0 ) { std::printf( "Press Ctrl-C to interrupt\n" ); -- 1.7.0.4