File: mapbook.h

package info (click to toggle)
gddrescue 1.30-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,280 kB
  • sloc: cpp: 5,853; sh: 799; makefile: 159
file content (192 lines) | stat: -rw-r--r-- 6,907 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/* GNU ddrescue - Data recovery tool
   Copyright (C) 2004-2026 Antonio Diaz Diaz.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

struct Mb_options
  {
  int mapfile_save_interval;			// default -1 = auto
  int mapfile_sync_interval;			// default 300s (5m)

  Mb_options() : mapfile_save_interval( -1 ), mapfile_sync_interval( 300 ) {}
  };


class Mapbook : public Mapfile, public Mb_options
  {
  const long long offset_;		// outfile offset (opos - ipos);
  long long mapfile_insize_;
  Domain & domain_;			// rescue domain
  uint8_t *iobuf_base;			// alignment + iobuf + iobuf2
  uint8_t *iobuf_;			// buffer aligned to page and hardbs
  const int hardbs_, softbs_;
  const int iobuf_size_;
  std::string final_msg_;
  int final_errno_;
  long long um_t1, um_t1s;		// variables for update_mapfile
  bool um_prev_mf_sync;
  bool mapfile_exists_;

  bool save_mapfile( const char * const name );

  Mapbook( const Mapbook & );		// declared as private
  void operator=( const Mapbook & );	// declared as private

protected:
  bool emergency_save();

public:
  Mapbook( const long long offset, const long long insize,
           Domain & dom, const Mb_options & mb_opts,
           const char * const mapname, const int cluster,
           const int hardbs, const bool complete_only, const bool rescue );
  ~Mapbook() { delete[] iobuf_base; }

  bool update_mapfile( const int odes = -1, const bool force = false );

  const Domain & domain() const { return domain_; }
  uint8_t * iobuf() const { return iobuf_; }		// main I/O buffer
  // second buffer for compare_before_write and check_on_error
  uint8_t * iobuf2() const { return iobuf_ + iobuf_size_; }
  int iobuf_size() const { return iobuf_size_; }
  int hardbs() const { return hardbs_; }
  int softbs() const { return softbs_; }
  long long offset() const { return offset_; }
  const std::string & final_msg() const { return final_msg_; }
  int final_errno() const { return final_errno_; }
  bool mapfile_exists() const { return mapfile_exists_; }
  long long mapfile_insize() const { return mapfile_insize_; }

  void final_msg( const char * const filename, const char * const msg,
                  const int e = 0 )
    { final_msg_ = filename; final_msg_ += ": "; final_msg_ += msg;
      final_errno_ = e; }
  void final_msg( const char * const msg, const int e = 0 )
    { final_msg_ = msg; final_errno_ = e; }

  void truncate_domain( const long long end )
    { domain_.crop_by_file_size( end ); }
  };


struct Fb_options
  {
  std::string filltypes;
  bool ignore_write_errors;
  bool write_location_data;

  Fb_options() : ignore_write_errors( false ), write_location_data( false ) {}

  bool operator==( const Fb_options & o ) const
    { return ( filltypes == o.filltypes &&
               ignore_write_errors == o.ignore_write_errors &&
               write_location_data == o.write_location_data ); }
  bool operator!=( const Fb_options & o ) const
    { return !( *this == o ); }
  };


class Fillbook : public Mapbook, public Fb_options
  {
  long long filled_size;		// size already filled
  long long remaining_size;		// size to be filled
  const char * const oname_;
  unsigned long filled_areas;		// areas already filled
  unsigned long remaining_areas;	// areas to be filled
  int odes_;				// output file descriptor
  const bool synchronous_;
					// variables for show_status
  long long a_rate, c_rate, first_size, last_size;
  long long last_ipos;
  long long t0, t1;			// start, current times
  int oldlen;

  int fill_block( const Sblock & sb );
  int fill_areas();
  void show_status( const long long ipos, const char * const msg = 0,
                    bool force = false );

public:
  Fillbook( const long long offset, Domain & dom, const Fb_options & fb_opts,
            const Mb_options & mb_opts, const char * const oname,
            const char * const mapname, const int cluster, const int hardbs,
            const bool synchronous )
    : Mapbook( offset, 0, dom, mb_opts, mapname, cluster, hardbs, true, false ),
      Fb_options( fb_opts ),
      oname_( oname ), synchronous_( synchronous ),
      a_rate( 0 ), c_rate( 0 ), first_size( 0 ), last_size( 0 ),
      last_ipos( 0 ), t0( 0 ), t1( 0 ), oldlen( 0 )
      {}

  int do_fill( const int odes );
  bool read_buffer( const int ides );
  };


class Genbook : public Mapbook
  {
  long long finished_size, gensize;	// total recovered and generated sizes
  const char * const iname_;
  int odes_;				// output file descriptor
					// variables for show_status
  long long a_rate, c_rate, first_size, last_size;
  long long last_ipos;
  long long t0, t1;			// start, current times
  int oldlen;

  void check_block( const Block & b, int & copied_size, int & error_size );
  int check_all();
  void show_status( const long long ipos, const char * const msg = 0,
                    bool force = false );
public:
  Genbook( const long long offset, const long long insize,
           Domain & dom, const Mb_options & mb_opts, const char * const iname,
           const char * const mapname, const int cluster, const int hardbs )
    : Mapbook( offset, insize, dom, mb_opts, mapname, cluster, hardbs, false,
               false ),
      iname_( iname ), a_rate( 0 ), c_rate( 0 ), first_size( 0 ),
      last_size( 0 ), last_ipos( 0 ), t0( 0 ), t1( 0 ), oldlen( 0 )
      {}

  int do_generate( const int odes );
  };


inline bool block_is_zero( const uint8_t * const buf, const int size )
  {
  for( int i = 0; i < size; ++i ) if( buf[i] != 0 ) return false;
  return true;
  }


const char * const ctrlc_msg = "Press Ctrl-C to interrupt\n";
const char * const early_eof_msg = "EOF found below the size calculated from mapfile.";
const char * const initial_msg = "Initial status (read from mapfile)\n";
const char * const wr_err_msg = "Write error";

bool safe_fflush( FILE * const f );

// Defined in genbook.cc
const char * format_time( const long long t, const bool low_prec = false );

// Defined in io.cc
int readblock( const int fd, uint8_t * const buf, const int size );
int readblockp( const int fd, uint8_t * const buf, const int size,
                const long long pos );
int writeblockp( const int fd, const uint8_t * const buf, const int size,
                 const long long pos );
bool interrupted();
void set_signals();
int signaled_exit();