@@ -43,10 +43,13 @@ def main()
4343 end
4444
4545 opts . on ( "-v" , "--[no-]verbose" ,
46- "Run verbosely" ) { |v | options [ :verbose ] = v }
46+ "Run verbosely" ) { |v | $verbose = v }
47+
48+ opts . on ( "-d" , "--[no-]debug" ,
49+ "Print debugging information" ) { |v | $debug = v }
4750
4851 opts . on ( "-q" , "--[no-]quiet" ,
49- "Run quietly" ) { |v | options [ : quiet] = v }
52+ "Run quietly" ) { |v | $ quiet = v }
5053
5154 opts . on ( "-b <file>" , "--snapback <file>" ,
5255 "Make a backup snapshot file on the destination" ) do |v |
@@ -75,49 +78,42 @@ def main()
7578 puts "lvmsync #{ GVB . version } "
7679 exit 0
7780 rescue GVB ::VersionUnobtainable
78- $stderr. puts "Unable to determine lvmsync version."
79- $stderr. puts "Install lvmsync as a gem, or run it from within a git checkout"
80- exit 1
81+ fatal "Unable to determine lvmsync version.\n " +
82+ "Install lvmsync as a gem, or run it from within a git checkout"
8183 end
8284 end
8385 end . parse!
8486
85- if options [ :quiet ] and options [ :verbose ]
86- $stderr. puts "I can't run quietly *and* verbosely at the same time!"
87- exit 1
87+ if $quiet and ( $verbose or $debug)
88+ fatal "I can't run quietly *and* verbosely at the same time!"
8889 end
8990
9091 if options [ :apply ]
9192 if ARGV [ 0 ] . nil?
92- $stderr. puts "No destination device specified."
93- exit 1
93+ fatal "No destination device specified."
9494 end
9595 options [ :device ] = ARGV [ 0 ]
9696 run_apply ( options )
9797 elsif options [ :server ]
98- $stderr . puts "--server is deprecated; please use '--apply -' instead" unless opts [ :quiet ]
98+ info "--server is deprecated; please use '--apply -' instead"
9999 if ( ARGV [ 0 ] . nil? )
100- $stderr. puts "No destination block device specified. WTF?"
101- exit 1
100+ fatal "No destination block device specified. WTF?"
102101 end
103102 options [ :apply ] = '-'
104103 options [ :device ] = ARGV [ 0 ]
105104 run_apply ( options )
106105 else
107106 if ARGV [ 0 ] . nil?
108- $stderr. puts "ERROR: No snapshot specified. Exiting."
109- exit 1
107+ fatal "No snapshot specified. Exiting. Do you need --help?"
110108 end
111109 options [ :snapdev ] = ARGV [ 0 ]
112110
113111 if options [ :stdout ] and options [ :snapback ]
114- $stderr. puts "--snapback cannot be used with --stdout"
115- exit 1
112+ fatal "--snapback cannot be used with --stdout"
116113 end
117114
118115 if ( options [ :stdout ] . nil? and ARGV [ 1 ] . nil? )
119- $stderr. puts "No destination specified."
120- exit 1
116+ fatal "No destination specified."
121117 end
122118 if options [ :stdout ] . nil?
123119 dev , host = ARGV [ 1 ] . split ( ':' , 2 ) . reverse
@@ -143,18 +139,19 @@ end
143139def process_dumpdata ( instream , destdev , snapback = nil , opts = { } )
144140 handshake = instream . readline . chomp
145141 unless handshake == PROTOCOL_VERSION
146- $stderr. puts "Handshake failed; protocol mismatch? (saw '#{ handshake } ' expected '#{ PROTOCOL_VERSION } '"
147- exit 1
142+ fatal "Handshake failed; protocol mismatch? (saw '#{ handshake } ' expected '#{ PROTOCOL_VERSION } '"
148143 end
149144
150145 snapback . puts handshake if snapback
151146
147+ verbose "Writing changed data to #{ destdev . inspect } "
152148 File . open ( destdev , 'w+' ) do |dest |
153149 while header = instream . read ( 12 )
154150 offset , chunksize = header . unpack ( "QN" )
155151 offset = ntohq ( offset )
156152
157153 begin
154+ debug "Seeking to #{ offset } "
158155 dest . seek offset
159156 rescue Errno ::EINVAL
160157 # In certain rare circumstances, we want to transfer a block
@@ -164,6 +161,8 @@ def process_dumpdata(instream, destdev, snapback = nil, opts = {})
164161 # if you didn't notice that your dd shit itself, it's unlikely
165162 # you're going to notice now.
166163
164+ info "Write occured past end of device"
165+
167166 # Skip the chunk of data
168167 instream . read ( chunksize )
169168 # Go to the next chunk
@@ -173,9 +172,12 @@ def process_dumpdata(instream, destdev, snapback = nil, opts = {})
173172 if snapback
174173 snapback . write ( header )
175174 snapback . write dest . read ( chunksize )
175+ # Got to back to where we were before, since the read from dest
176+ # has advanced the file pointer by `chunksize`
176177 dest . seek offset
177178 end
178179 dest . write instream . read ( chunksize )
180+ debug "Wrote #{ chunksize } bytes at #{ offset } "
179181 end
180182 end
181183end
@@ -189,13 +191,11 @@ def run_client(opts)
189191 lv = begin
190192 LVM ::LogicalVolume . new ( snapshot )
191193 rescue RuntimeError => e
192- $stderr. puts "#{ snapshot } : could not find logical volume (#{ e . message } )"
193- exit 1
194+ fatal "#{ snapshot } : could not find logical volume (#{ e . message } )"
194195 end
195196
196197 unless lv . snapshot?
197- $stderr. puts "#{ snapshot } : Not a snapshot device"
198- exit 1
198+ fatal "#{ snapshot } : Not a snapshot device"
199199 end
200200
201201 # Since, in principle, we're not supposed to be reading from snapshot
@@ -208,14 +208,16 @@ def run_client(opts)
208208 snapback = opts [ :snapback ] ? "--snapback #{ opts [ :snapback ] } " : ''
209209
210210 source = opts [ :source ] || lv . origin . path
211- $stderr . puts "Data source: #{ source } " if opts [ :verbose ]
211+ verbose "Data source: #{ source } "
212212
213213 if opts [ :stdout ]
214214 dump_changes ( lv , source , $stdout, opts )
215215 else
216- verbose = opts [ :verbose ] ? '-v' : ''
216+ verbose = $verbose ? '-v' : ''
217+ debug = $debug ? '-d' : ''
218+
217219 server_cmd = if desthost
218- "#{ opts [ :rsh ] } #{ desthost } lvmsync --apply - #{ snapback } #{ verbose } #{ destdev } "
220+ "#{ opts [ :rsh ] } #{ desthost } lvmsync --apply - #{ snapback } #{ verbose } #{ debug } #{ destdev } "
219221 else
220222 "#{ $0} --apply - #{ snapback } #{ verbose } #{ destdev } "
221223 end
@@ -232,7 +234,7 @@ def run_client(opts)
232234 until ( active_fds = IO . select ( fds , [ ] , [ ] , 0 ) ) . nil?
233235 active_fds [ 0 ] . each do |fd |
234236 begin
235- $stderr . puts "\e [2K\r remote:#{ fd . readline } " unless opts [ :quiet ]
237+ info "\e [2K\r remote:#{ fd . readline } "
236238 rescue EOFError , Errno ::EPIPE
237239 fd . close
238240 fds . delete ( fd )
@@ -251,7 +253,7 @@ def run_client(opts)
251253 until ( active_fds = IO . select ( fds , [ ] , [ ] , 0.1 ) ) . nil?
252254 active_fds [ 0 ] . each do |fd |
253255 begin
254- $stderr . puts "\e [2K\r remote:#{ fd . readline } " unless opts [ :quiet ]
256+ info "\e [2K\r remote:#{ fd . readline } "
255257 rescue EOFError , Errno ::EPIPE
256258 fd . close
257259 fds . delete ( fd )
@@ -262,7 +264,7 @@ def run_client(opts)
262264 end
263265
264266 if ( exit_status or $?) . exitstatus != 0
265- $stderr . puts "APPLY FAILED."
267+ fatal "APPLY FAILED."
266268 end
267269 end
268270end
@@ -282,8 +284,7 @@ def dump_changes(snapshot, source, outfd, opts)
282284 chunk_size = r . last - r . first + 1
283285 xfer_size += chunk_size
284286
285- $stderr. puts "Sending chunk #{ r . to_s } ..." if opts [ :verbose ]
286- $stderr. puts "Seeking to #{ r . first } in #{ source } " if opts [ :verbose ]
287+ debug "Sending chunk #{ r . to_s } ..."
287288
288289 origindev . seek ( r . first , IO ::SEEK_SET )
289290
@@ -297,7 +298,7 @@ def dump_changes(snapshot, source, outfd, opts)
297298 end
298299
299300 # Progress bar!
300- if xfer_count % 100 == 50 and !opts [ : quiet]
301+ if xfer_count % 100 == 50 and !$ quiet
301302 $stderr. printf "\e [2K\r Sending chunk %i of %i, %.2fMB/s" ,
302303 xfer_count ,
303304 change_count ,
@@ -311,7 +312,7 @@ def dump_changes(snapshot, source, outfd, opts)
311312 total_size = origindev . tell
312313 end
313314
314- unless opts [ : quiet]
315+ unless $ quiet
315316 $stderr. printf "\r Transferred %i bytes in %.2f seconds\n " ,
316317 xfer_size , Time . now - start_time
317318
@@ -336,4 +337,21 @@ def parse_snapshot_name(origname)
336337 end
337338end
338339
340+ def debug ( s )
341+ $stderr. puts s if $debug
342+ end
343+
344+ def verbose ( s )
345+ $stderr. puts s if $verbose or $debug
346+ end
347+
348+ def info ( s )
349+ $stderr. puts s unless $quiet
350+ end
351+
352+ def fatal ( s , status = 1 )
353+ $stderr. puts "FATAL ERROR: #{ s } "
354+ exit status
355+ end
356+
339357main
0 commit comments