lvmsync 3.2.0 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +2 -2
  3. data/bin/lvmsync +53 -35
  4. data/lib/vgcfgbackup.treetop +1 -1
  5. metadata +38 -70
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f78e30fa37ccf5150643fabe206713fe18750271
4
+ data.tar.gz: 0c0416476d7005349864889700f76541ad1eda45
5
+ SHA512:
6
+ metadata.gz: 8bdf6db2b0e37ce28af97557c0c3580b227379991b2abc0cdec656ca88333a51c48b75d2d68fd8cf826b4a0947791ea63ffebf25fb55efc11f94c641b3328741
7
+ data.tar.gz: 98f9474e839e61d8f6a17be2b9bd8976715cafa594c43ba066a1a9b5f6c18ae265b7da3577e415b476f6c7812fc521e02b9cfe4c43d17d2217c6333306080402
data/README.md CHANGED
@@ -107,7 +107,7 @@ Let's say you've got an LV, named `vmsrv1/somevm`, and you'd like to
107
107
  synchronise it to a new VM server, named `vmsrv2`. Assuming that `lvmsync` is
108
108
  installed on `vmsrv2` and `vmsrv2` has an LV named `vmsrv2/somevm` large
109
109
  enough to take the data, the following will do the trick rather nicely (all
110
- commands should be run on `vmsrv1`:
110
+ commands should be run on `vmsrv1`):
111
111
 
112
112
  # Take a snapshot before we do anything, so LVM will record all changes
113
113
  # made while we're doing the initial sync
@@ -168,7 +168,7 @@ each hour):
168
168
 
169
169
  This will produce files in /var/snapbacks named `somevm.<date-time>`. You
170
170
  need to create the `somevm-snapback-new` snapshot before you start
171
- `lvmsync`, so that you can guarantee no changes won't get noticed.
171
+ `lvmsync`, so that you can guarantee no changes will go unnoticed.
172
172
 
173
173
  There are some fairly large caveats to this method -- the LV will still be
174
174
  collecting writes while you're transferring the snapshots, so you won't get
data/bin/lvmsync CHANGED
@@ -43,10 +43,13 @@ def main()
43
43
  end
44
44
 
45
45
  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 }
47
50
 
48
51
  opts.on("-q", "--[no-]quiet",
49
- "Run quietly") { |v| options[:quiet] = v }
52
+ "Run quietly") { |v| $quiet = v }
50
53
 
51
54
  opts.on("-b <file>", "--snapback <file>",
52
55
  "Make a backup snapshot file on the destination") do |v|
@@ -75,49 +78,42 @@ def main()
75
78
  puts "lvmsync #{GVB.version}"
76
79
  exit 0
77
80
  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"
81
83
  end
82
84
  end
83
85
  end.parse!
84
86
 
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!"
88
89
  end
89
90
 
90
91
  if options[:apply]
91
92
  if ARGV[0].nil?
92
- $stderr.puts "No destination device specified."
93
- exit 1
93
+ fatal "No destination device specified."
94
94
  end
95
95
  options[:device] = ARGV[0]
96
96
  run_apply(options)
97
97
  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"
99
99
  if (ARGV[0].nil?)
100
- $stderr.puts "No destination block device specified. WTF?"
101
- exit 1
100
+ fatal "No destination block device specified. WTF?"
102
101
  end
103
102
  options[:apply] = '-'
104
103
  options[:device] = ARGV[0]
105
104
  run_apply(options)
106
105
  else
107
106
  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?"
110
108
  end
111
109
  options[:snapdev] = ARGV[0]
112
110
 
113
111
  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"
116
113
  end
117
114
 
118
115
  if (options[:stdout].nil? and ARGV[1].nil?)
119
- $stderr.puts "No destination specified."
120
- exit 1
116
+ fatal "No destination specified."
121
117
  end
122
118
  if options[:stdout].nil?
123
119
  dev, host = ARGV[1].split(':', 2).reverse
@@ -143,18 +139,19 @@ end
143
139
  def process_dumpdata(instream, destdev, snapback = nil, opts = {})
144
140
  handshake = instream.readline.chomp
145
141
  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}'"
148
143
  end
149
144
 
150
145
  snapback.puts handshake if snapback
151
146
 
147
+ verbose "Writing changed data to #{destdev.inspect}"
152
148
  File.open(destdev, 'w+') do |dest|
153
149
  while header = instream.read(12)
154
150
  offset, chunksize = header.unpack("QN")
155
151
  offset = ntohq(offset)
156
152
 
157
153
  begin
154
+ debug "Seeking to #{offset}"
158
155
  dest.seek offset
159
156
  rescue Errno::EINVAL
160
157
  # In certain rare circumstances, we want to transfer a block
@@ -164,6 +161,8 @@ def process_dumpdata(instream, destdev, snapback = nil, opts = {})
164
161
  # if you didn't notice that your dd shit itself, it's unlikely
165
162
  # you're going to notice now.
166
163
 
164
+ info "Write occured past end of device"
165
+
167
166
  # Skip the chunk of data
168
167
  instream.read(chunksize)
169
168
  # Go to the next chunk
@@ -173,9 +172,12 @@ def process_dumpdata(instream, destdev, snapback = nil, opts = {})
173
172
  if snapback
174
173
  snapback.write(header)
175
174
  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`
176
177
  dest.seek offset
177
178
  end
178
179
  dest.write instream.read(chunksize)
180
+ debug "Wrote #{chunksize} bytes at #{offset}"
179
181
  end
180
182
  end
181
183
  end
@@ -189,13 +191,11 @@ def run_client(opts)
189
191
  lv = begin
190
192
  LVM::LogicalVolume.new(snapshot)
191
193
  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})"
194
195
  end
195
196
 
196
197
  unless lv.snapshot?
197
- $stderr.puts "#{snapshot}: Not a snapshot device"
198
- exit 1
198
+ fatal "#{snapshot}: Not a snapshot device"
199
199
  end
200
200
 
201
201
  # Since, in principle, we're not supposed to be reading from snapshot
@@ -208,14 +208,16 @@ def run_client(opts)
208
208
  snapback = opts[:snapback] ? "--snapback #{opts[:snapback]}" : ''
209
209
 
210
210
  source = opts[:source] || lv.origin.path
211
- $stderr.puts "Data source: #{source}" if opts[:verbose]
211
+ verbose "Data source: #{source}"
212
212
 
213
213
  if opts[:stdout]
214
214
  dump_changes(lv, source, $stdout, opts)
215
215
  else
216
- verbose = opts[:verbose] ? '-v' : ''
216
+ verbose = $verbose ? '-v' : ''
217
+ debug = $debug ? '-d' : ''
218
+
217
219
  server_cmd = if desthost
218
- "#{opts[:rsh]} #{desthost} lvmsync --apply - #{snapback} #{verbose} #{destdev}"
220
+ "#{opts[:rsh]} #{desthost} lvmsync --apply - #{snapback} #{verbose} #{debug} #{destdev}"
219
221
  else
220
222
  "#{$0} --apply - #{snapback} #{verbose} #{destdev}"
221
223
  end
@@ -232,7 +234,7 @@ def run_client(opts)
232
234
  until (active_fds = IO.select(fds, [], [], 0)).nil?
233
235
  active_fds[0].each do |fd|
234
236
  begin
235
- $stderr.puts "\e[2K\rremote:#{fd.readline}" unless opts[:quiet]
237
+ info "\e[2K\rremote:#{fd.readline}"
236
238
  rescue EOFError, Errno::EPIPE
237
239
  fd.close
238
240
  fds.delete(fd)
@@ -251,7 +253,7 @@ def run_client(opts)
251
253
  until (active_fds = IO.select(fds, [], [], 0.1)).nil?
252
254
  active_fds[0].each do |fd|
253
255
  begin
254
- $stderr.puts "\e[2K\rremote:#{fd.readline}" unless opts[:quiet]
256
+ info "\e[2K\rremote:#{fd.readline}"
255
257
  rescue EOFError, Errno::EPIPE
256
258
  fd.close
257
259
  fds.delete(fd)
@@ -262,7 +264,7 @@ def run_client(opts)
262
264
  end
263
265
 
264
266
  if (exit_status or $?).exitstatus != 0
265
- $stderr.puts "APPLY FAILED."
267
+ fatal "APPLY FAILED."
266
268
  end
267
269
  end
268
270
  end
@@ -282,8 +284,7 @@ def dump_changes(snapshot, source, outfd, opts)
282
284
  chunk_size = r.last - r.first + 1
283
285
  xfer_size += chunk_size
284
286
 
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}..."
287
288
 
288
289
  origindev.seek(r.first, IO::SEEK_SET)
289
290
 
@@ -297,7 +298,7 @@ def dump_changes(snapshot, source, outfd, opts)
297
298
  end
298
299
 
299
300
  # Progress bar!
300
- if xfer_count % 100 == 50 and !opts[:quiet]
301
+ if xfer_count % 100 == 50 and !$quiet
301
302
  $stderr.printf "\e[2K\rSending chunk %i of %i, %.2fMB/s",
302
303
  xfer_count,
303
304
  change_count,
@@ -311,7 +312,7 @@ def dump_changes(snapshot, source, outfd, opts)
311
312
  total_size = origindev.tell
312
313
  end
313
314
 
314
- unless opts[:quiet]
315
+ unless $quiet
315
316
  $stderr.printf "\rTransferred %i bytes in %.2f seconds\n",
316
317
  xfer_size, Time.now - start_time
317
318
 
@@ -336,4 +337,21 @@ def parse_snapshot_name(origname)
336
337
  end
337
338
  end
338
339
 
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
+
339
357
  main
@@ -24,7 +24,7 @@ grammar VgCfgBackup
24
24
  end
25
25
 
26
26
  rule list
27
- "[" space? ((string / integer) ", " / (string / integer))* space? "]" <List>
27
+ "[" space? ((string / integer) "," space? / (string / integer))* space? "]" <List>
28
28
  end
29
29
 
30
30
  rule space
metadata CHANGED
@@ -1,206 +1,181 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lvmsync
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
5
- prerelease:
4
+ version: 3.2.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Matt Palmer
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-10-14 00:00:00.000000000 Z
11
+ date: 2015-02-25 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: git-version-bump
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0.10'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0.10'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: treetop
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: bundler
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - ">="
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: github-release
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - ">="
68
60
  - !ruby/object:Gem::Version
69
61
  version: '0'
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ! '>='
66
+ - - ">="
76
67
  - !ruby/object:Gem::Version
77
68
  version: '0'
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: guard-spork
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ! '>='
73
+ - - ">="
84
74
  - !ruby/object:Gem::Version
85
75
  version: '0'
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ! '>='
80
+ - - ">="
92
81
  - !ruby/object:Gem::Version
93
82
  version: '0'
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: guard-rspec
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
- - - ! '>='
87
+ - - ">="
100
88
  - !ruby/object:Gem::Version
101
89
  version: '0'
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
- - - ! '>='
94
+ - - ">="
108
95
  - !ruby/object:Gem::Version
109
96
  version: '0'
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: plymouth
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
- - - ! '>='
101
+ - - ">="
116
102
  - !ruby/object:Gem::Version
117
103
  version: '0'
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
- - - ! '>='
108
+ - - ">="
124
109
  - !ruby/object:Gem::Version
125
110
  version: '0'
126
111
  - !ruby/object:Gem::Dependency
127
- name: pry-debugger
112
+ name: pry-byebug
128
113
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
114
  requirements:
131
- - - ! '>='
115
+ - - ">="
132
116
  - !ruby/object:Gem::Version
133
117
  version: '0'
134
118
  type: :development
135
119
  prerelease: false
136
120
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
121
  requirements:
139
- - - ! '>='
122
+ - - ">="
140
123
  - !ruby/object:Gem::Version
141
124
  version: '0'
142
125
  - !ruby/object:Gem::Dependency
143
126
  name: rake
144
127
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
128
  requirements:
147
- - - ! '>='
129
+ - - ">="
148
130
  - !ruby/object:Gem::Version
149
131
  version: '0'
150
132
  type: :development
151
133
  prerelease: false
152
134
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
135
  requirements:
155
- - - ! '>='
136
+ - - ">="
156
137
  - !ruby/object:Gem::Version
157
138
  version: '0'
158
139
  - !ruby/object:Gem::Dependency
159
140
  name: rb-inotify
160
141
  requirement: !ruby/object:Gem::Requirement
161
- none: false
162
142
  requirements:
163
- - - ~>
143
+ - - "~>"
164
144
  - !ruby/object:Gem::Version
165
145
  version: '0.9'
166
146
  type: :development
167
147
  prerelease: false
168
148
  version_requirements: !ruby/object:Gem::Requirement
169
- none: false
170
149
  requirements:
171
- - - ~>
150
+ - - "~>"
172
151
  - !ruby/object:Gem::Version
173
152
  version: '0.9'
174
153
  - !ruby/object:Gem::Dependency
175
154
  name: rdoc
176
155
  requirement: !ruby/object:Gem::Requirement
177
- none: false
178
156
  requirements:
179
- - - ! '>='
157
+ - - ">="
180
158
  - !ruby/object:Gem::Version
181
159
  version: '0'
182
160
  type: :development
183
161
  prerelease: false
184
162
  version_requirements: !ruby/object:Gem::Requirement
185
- none: false
186
163
  requirements:
187
- - - ! '>='
164
+ - - ">="
188
165
  - !ruby/object:Gem::Version
189
166
  version: '0'
190
167
  - !ruby/object:Gem::Dependency
191
168
  name: rspec
192
169
  requirement: !ruby/object:Gem::Requirement
193
- none: false
194
170
  requirements:
195
- - - ! '>='
171
+ - - ">="
196
172
  - !ruby/object:Gem::Version
197
173
  version: '0'
198
174
  type: :development
199
175
  prerelease: false
200
176
  version_requirements: !ruby/object:Gem::Requirement
201
- none: false
202
177
  requirements:
203
- - - ! '>='
178
+ - - ">="
204
179
  - !ruby/object:Gem::Version
205
180
  version: '0'
206
181
  description:
@@ -211,47 +186,40 @@ extensions: []
211
186
  extra_rdoc_files:
212
187
  - README.md
213
188
  files:
214
- - README.md
215
189
  - LICENCE
190
+ - README.md
216
191
  - bin/lvmsync
217
192
  - lib/lvm.rb
218
- - lib/lvm/lv_config.rb
193
+ - lib/lvm/helpers.rb
219
194
  - lib/lvm/logical_volume.rb
220
- - lib/lvm/thin_snapshot.rb
195
+ - lib/lvm/lv_config.rb
196
+ - lib/lvm/pv_config.rb
221
197
  - lib/lvm/snapshot.rb
198
+ - lib/lvm/thin_snapshot.rb
222
199
  - lib/lvm/vg_config.rb
223
- - lib/lvm/helpers.rb
224
- - lib/lvm/pv_config.rb
225
- - lib/vgcfgbackup.treetop
226
200
  - lib/vgcfgbackup.rb
201
+ - lib/vgcfgbackup.treetop
227
202
  homepage: http://theshed.hezmatt.org/lvmsync
228
203
  licenses: []
204
+ metadata: {}
229
205
  post_install_message:
230
206
  rdoc_options: []
231
207
  require_paths:
232
208
  - lib
233
209
  required_ruby_version: !ruby/object:Gem::Requirement
234
- none: false
235
210
  requirements:
236
- - - ! '>='
211
+ - - ">="
237
212
  - !ruby/object:Gem::Version
238
213
  version: '0'
239
- segments:
240
- - 0
241
- hash: -3943591993715626870
242
214
  required_rubygems_version: !ruby/object:Gem::Requirement
243
- none: false
244
215
  requirements:
245
- - - ! '>='
216
+ - - ">="
246
217
  - !ruby/object:Gem::Version
247
218
  version: '0'
248
- segments:
249
- - 0
250
- hash: -3943591993715626870
251
219
  requirements: []
252
220
  rubyforge_project:
253
- rubygems_version: 1.8.23
221
+ rubygems_version: 2.2.2
254
222
  signing_key:
255
- specification_version: 3
223
+ specification_version: 4
256
224
  summary: Efficiently transfer changes in LVM snapshots
257
225
  test_files: []