qdumpfs 0.7.0 → 1.1.0
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile.lock +3 -3
- data/README.md +22 -16
- data/lib/qdumpfs.rb +77 -125
- data/lib/qdumpfs/option.rb +9 -1
- data/lib/qdumpfs/util.rb +10 -11
- data/lib/qdumpfs/version.rb +4 -3
- data/run_list.sh +5 -0
- data/run_qdumpfs.sh +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d0d2013cd5b52dcc99390e498ce0f749b3bf4d74d5229f734606b7b8a47b221f
|
|
4
|
+
data.tar.gz: e6f9d32055e67cc2b8beed5354befbf52f02ff06448cfa827673fc46a771bda1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eaed232b7e0803f065d6dde3373745bc7459b7c006ad5f20b2ddeb1431d5adc473c35df9045a913c0fcfd524a92f5d0319fed33e5fa2f645607a5bb0488d1d73
|
|
7
|
+
data.tar.gz: e434c372a596e239aa97564b4820e5d3c0fb31802f33c9f4b37d031009811819268893462f48c9c3e25728f2302cc56fcd9c5c990ba869dc209edeb1171d0cd8
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# Qdumpfs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
pdumpfsの個人的改良版です。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Gem化して最近のバージョンのバージョンのRubyに対応。コマンドの拡張などを行っています。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## インストール
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
gem install qdumpfs
|
|
10
10
|
|
|
11
|
+
## 使用方法
|
|
11
12
|
|
|
12
13
|
```
|
|
13
14
|
Usage: qdumpfs [options] <source> <dest>
|
|
@@ -19,48 +20,53 @@ Options
|
|
|
19
20
|
-e, --exclude=PATTERN exclude files/directories matching PATTERN
|
|
20
21
|
-s, --exclude-by-size=SIZE exclude files larger than SIZE
|
|
21
22
|
-w, --exclude-by-glob=GLOB exclude files matching GLOB
|
|
22
|
-
-c, --command=COMMAND backup|sync|list|expire|verify|
|
|
23
|
+
-c, --command=COMMAND backup|sync|list|expire|verify|delete
|
|
23
24
|
-l, --limit=HOURS limit hours
|
|
24
25
|
-k, --keep=KEEPARG ex: --keep 100Y12M12W30D (100years, 12months, 12weeks, 30days, default)
|
|
25
26
|
```
|
|
26
27
|
|
|
27
|
-
##
|
|
28
|
+
## 実行例
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
バックアップを実行する場合。
|
|
28
32
|
|
|
29
|
-
Backup your home directory, run the following command.
|
|
30
33
|
```
|
|
31
34
|
qdumpfs /home/foo /backup
|
|
32
35
|
```
|
|
33
36
|
|
|
34
|
-
|
|
37
|
+
"--command backup"オプションを明示することもできます。
|
|
38
|
+
|
|
35
39
|
```
|
|
36
40
|
qdumpfs --command=backup /home/foo /backup
|
|
37
41
|
```
|
|
38
42
|
|
|
39
|
-
|
|
43
|
+
"--command sync"でバックアップフォルダを同期できます。
|
|
40
44
|
```
|
|
41
45
|
qdumpfs --command=sync /backup1 /backup2
|
|
42
46
|
```
|
|
43
47
|
|
|
44
|
-
|
|
48
|
+
バックアップフォルダの同期には膨大な時間が必要な場合があるため、実行時間を制限できます。以下は例えば1時間に制限する場合です。
|
|
45
49
|
```
|
|
46
50
|
qdumpfs --command=sync --limit=1 /backup1 /backup2
|
|
47
51
|
```
|
|
48
52
|
|
|
49
|
-
|
|
53
|
+
バックアップフォルダの同期で、1時間でかつ"100Y12M12W30D"を保存する場合のオプションです。
|
|
50
54
|
```
|
|
51
|
-
qdumpfs --command=sync --limit=1 --keep=5Y6M7W10D
|
|
55
|
+
qdumpfs --command=sync --limit=1 --keep=5Y6M7W10D backup1 /backup2
|
|
52
56
|
```
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
"--command expire"で、"--keep="パターンに該当しないバックアップを削除できます。
|
|
55
59
|
```
|
|
56
|
-
qdumpfs --command=expire --limit=1 --keep=5Y6M7W10D
|
|
60
|
+
qdumpfs --command=expire --limit=1 --keep=5Y6M7W10D backup1 /backup2
|
|
57
61
|
```
|
|
58
62
|
|
|
63
|
+
"--command delete"で、バックアップに存在する指定したパスを削除できます(間違えてバックアップした内容を削除したい場合などに使用)。
|
|
64
|
+
```
|
|
65
|
+
qdumpfs --command=delete --delete-dir=backup1 --limit=1 r:/backup2
|
|
66
|
+
```
|
|
59
67
|
|
|
60
68
|
## License
|
|
61
69
|
|
|
62
70
|
qdumpfs is a free software with ABSOLUTELY NO WARRANTY under the terms of the GNU General Public License version 2.
|
|
63
71
|
|
|
64
72
|
|
|
65
|
-
|
|
66
|
-
|
data/lib/qdumpfs.rb
CHANGED
|
@@ -45,9 +45,13 @@ module Qdumpfs
|
|
|
45
45
|
opt.on('--delete-to=YYYYMMDD', 'delete backup to YYYY/MM/DD') {|v|
|
|
46
46
|
opts[:delete_to] = Date.parse(v)
|
|
47
47
|
}
|
|
48
|
+
opt.on('--delete-dir=DIRS', 'relative path from the snapshot root of the backup. ex: --delete-dir=foo,home/bar') {|v|
|
|
49
|
+
opts[:delete_dirs] = v.split(/,/)
|
|
50
|
+
}
|
|
48
51
|
opt.on('--backup-at=YYYYMMDD', 'backup at YYYY/MM/DD') {|v|
|
|
49
52
|
opts[:backup_at] = Date.parse(v)
|
|
50
53
|
}
|
|
54
|
+
opt.on('-d', '--debug', 'debug mode') {|v| opts[:d] = v }
|
|
51
55
|
opt.parse!(argv)
|
|
52
56
|
option = Option.new(opts, argv)
|
|
53
57
|
if opts[:v]
|
|
@@ -61,8 +65,10 @@ module Qdumpfs
|
|
|
61
65
|
command = Command.new(option)
|
|
62
66
|
command.run
|
|
63
67
|
rescue => e
|
|
64
|
-
|
|
65
|
-
|
|
68
|
+
if option.debug
|
|
69
|
+
p e.message
|
|
70
|
+
p e.backtrace
|
|
71
|
+
end
|
|
66
72
|
puts opt.help
|
|
67
73
|
exit
|
|
68
74
|
end
|
|
@@ -85,8 +91,6 @@ module Qdumpfs
|
|
|
85
91
|
verify
|
|
86
92
|
elsif @opt.cmd == 'delete'
|
|
87
93
|
delete('delete')
|
|
88
|
-
# elsif @opt.cmd == 'test'
|
|
89
|
-
# test
|
|
90
94
|
else
|
|
91
95
|
raise RuntimeError, "unknown command: #{@opt.cmd}"
|
|
92
96
|
end
|
|
@@ -96,9 +100,15 @@ module Qdumpfs
|
|
|
96
100
|
def log_result(src, today, elapsed)
|
|
97
101
|
time = Time.now.strftime("%Y-%m-%dT%H:%M:%S")
|
|
98
102
|
bytes = convert_bytes(@written_bytes)
|
|
99
|
-
msg = sprintf("%s: %s -> %s (in %.2f sec, %s written)\n",
|
|
100
|
-
time, src, today, elapsed, bytes)
|
|
103
|
+
msg = sprintf("%s: %s -> %s (in %.2f sec, %s written)\n", time, src, today, elapsed, bytes)
|
|
101
104
|
log(msg)
|
|
105
|
+
log("error files:\n")
|
|
106
|
+
i = 1
|
|
107
|
+
@error_files.each do |filename, reason|
|
|
108
|
+
msg = "#{i}. #{filename}\t#{reason}\n"
|
|
109
|
+
log(msg)
|
|
110
|
+
i += 1
|
|
111
|
+
end
|
|
102
112
|
end
|
|
103
113
|
|
|
104
114
|
def log(msg, console = true)
|
|
@@ -109,6 +119,10 @@ module Qdumpfs
|
|
|
109
119
|
@opt.report(type, file_name)
|
|
110
120
|
end
|
|
111
121
|
|
|
122
|
+
def report_error(file_name, reason)
|
|
123
|
+
@opt.report_error(file_name, reason)
|
|
124
|
+
end
|
|
125
|
+
|
|
112
126
|
def update_file(src, latest, today)
|
|
113
127
|
type = detect_type(src, latest)
|
|
114
128
|
report(type, src)
|
|
@@ -133,11 +147,17 @@ module Qdumpfs
|
|
|
133
147
|
end
|
|
134
148
|
|
|
135
149
|
def filecount(dir)
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
result =
|
|
150
|
+
result = '0'
|
|
151
|
+
if windows?
|
|
152
|
+
pscmd = 'Get-ChildItem -Recurse -File | Measure-Object | %{$_.Count}'
|
|
153
|
+
cmd = "powershell -Command \"#{pscmd}\""
|
|
154
|
+
result = nil
|
|
155
|
+
Dir.chdir(dir) do
|
|
156
|
+
result = `#{cmd}`
|
|
157
|
+
result.chomp!
|
|
158
|
+
end
|
|
159
|
+
else
|
|
160
|
+
result = `find #{dir} | wc -l`
|
|
141
161
|
result.chomp!
|
|
142
162
|
end
|
|
143
163
|
result.to_i
|
|
@@ -149,29 +169,6 @@ module Qdumpfs
|
|
|
149
169
|
return src_count, dst_count
|
|
150
170
|
end
|
|
151
171
|
|
|
152
|
-
# def get_snapshots(target_dir)
|
|
153
|
-
# # 指定したディレクトリに含まれるバックアップフォルダ(日付つき)を全て取得
|
|
154
|
-
# dd = "[0-9][0-9]"
|
|
155
|
-
# dddd = dd + dd
|
|
156
|
-
# # FIXME: Y10K problem.
|
|
157
|
-
# dirs = []
|
|
158
|
-
# glob_path = File.join(target_dir, dddd, dd, dd)
|
|
159
|
-
# Dir.glob(glob_path).sort.find {|dir|
|
|
160
|
-
# day, month, year = File.split_all(dir).reverse.map {|x| x.to_i }
|
|
161
|
-
# path = diro
|
|
162
|
-
# if File.directory?(path) and Date.valid_date?(year, month, day) and
|
|
163
|
-
# dirs << path
|
|
164
|
-
# end
|
|
165
|
-
# }
|
|
166
|
-
# dirs
|
|
167
|
-
# end
|
|
168
|
-
|
|
169
|
-
# def get_snapshot_date(snapshot)
|
|
170
|
-
# # バックアップディレクトリのパス(日付つき)から日付を取得して返す
|
|
171
|
-
# day, month, year = File.split_all(snapshot).reverse.map {|x| x.to_i }
|
|
172
|
-
# Time.new(year, month, day)
|
|
173
|
-
# end
|
|
174
|
-
|
|
175
172
|
def update_snapshot(src, latest, today)
|
|
176
173
|
# バックアップの差分コピーを実行
|
|
177
174
|
# src: コピー元ディレクトリ ex) i:/from/home
|
|
@@ -192,8 +189,9 @@ module Qdumpfs
|
|
|
192
189
|
# ファイルのアップデート
|
|
193
190
|
update_file(s, l, t)
|
|
194
191
|
dirs[t] = File.stat(s) if File.ftype(s) == "directory"
|
|
195
|
-
rescue
|
|
196
|
-
|
|
192
|
+
rescue => e
|
|
193
|
+
report_error(s, e.message)
|
|
194
|
+
@error_files << [s, e.message]
|
|
197
195
|
next
|
|
198
196
|
end
|
|
199
197
|
end
|
|
@@ -227,8 +225,9 @@ module Qdumpfs
|
|
|
227
225
|
end
|
|
228
226
|
chown_if_root(type, s, t)
|
|
229
227
|
dirs[t] = File.stat(s) if File.ftype(s) == "directory"
|
|
230
|
-
rescue
|
|
231
|
-
|
|
228
|
+
rescue => e
|
|
229
|
+
report_error(s, e.message)
|
|
230
|
+
@error_files << [s, e.message]
|
|
232
231
|
next
|
|
233
232
|
end
|
|
234
233
|
end
|
|
@@ -240,7 +239,7 @@ module Qdumpfs
|
|
|
240
239
|
|
|
241
240
|
#コピー元のスナップショット
|
|
242
241
|
src_snapshots = BackupDir.scan_backup_dirs(src)
|
|
243
|
-
@opt.
|
|
242
|
+
@opt.detect_expire_dirs(src_snapshots)
|
|
244
243
|
|
|
245
244
|
# コピー先の最新スナップショット
|
|
246
245
|
dst_snapshots = BackupDir.scan_backup_dirs(dst)
|
|
@@ -308,6 +307,7 @@ module Qdumpfs
|
|
|
308
307
|
log("##### backup start #####")
|
|
309
308
|
|
|
310
309
|
@written_bytes = 0
|
|
310
|
+
@error_files = []
|
|
311
311
|
start_time = Time.now
|
|
312
312
|
if @opt.backup_at
|
|
313
313
|
start_time = to_time(@opt.backup_at)
|
|
@@ -364,6 +364,7 @@ module Qdumpfs
|
|
|
364
364
|
|
|
365
365
|
start_time = Time.now
|
|
366
366
|
@written_bytes = 0
|
|
367
|
+
@error_files = []
|
|
367
368
|
src = @opt.src
|
|
368
369
|
dst = @opt.dst
|
|
369
370
|
|
|
@@ -410,6 +411,10 @@ module Qdumpfs
|
|
|
410
411
|
|
|
411
412
|
end_time = Time.now
|
|
412
413
|
diff = time_diff(start_time, end_time)
|
|
414
|
+
|
|
415
|
+
elapsed = Time.now - start_time
|
|
416
|
+
log_result(src, dst, elapsed)
|
|
417
|
+
|
|
413
418
|
log("##### sync end #{fmt(end_time)} diff=#{diff} last_sync_complete=#{last_sync_complete} #####")
|
|
414
419
|
end
|
|
415
420
|
|
|
@@ -457,9 +462,7 @@ module Qdumpfs
|
|
|
457
462
|
|
|
458
463
|
def delete(cmd)
|
|
459
464
|
@opt.validate_directories(1)
|
|
460
|
-
|
|
461
465
|
start_time = Time.now
|
|
462
|
-
p @opt.limit_sec
|
|
463
466
|
limit_time = start_time + (@opt.limit_sec)
|
|
464
467
|
log("##### #{cmd} delete-from=#{@opt.delete_from} delete-to=#{@opt.delete_to} start #{fmt(start_time)} => limit_time=#{fmt(limit_time)} #####")
|
|
465
468
|
@opt.dirs.each do |target_dir|
|
|
@@ -482,6 +485,29 @@ p @opt.limit_sec
|
|
|
482
485
|
log("##### #{cmd} end #####")
|
|
483
486
|
end
|
|
484
487
|
|
|
488
|
+
def rm_dir(path)
|
|
489
|
+
can_delete = true
|
|
490
|
+
if @opt.dry_run
|
|
491
|
+
can_delete = false
|
|
492
|
+
elsif !FileTest.directory?(path)
|
|
493
|
+
can_delete = false
|
|
494
|
+
end
|
|
495
|
+
msg = can_delete ? "...ok..." : "...ng..."
|
|
496
|
+
print "Deleting #{path} #{msg}"
|
|
497
|
+
|
|
498
|
+
return unless can_delete
|
|
499
|
+
|
|
500
|
+
#それ以外は日付バックアップディレクトリ全体を削除
|
|
501
|
+
if windows?
|
|
502
|
+
# Windowsの場合
|
|
503
|
+
win_backup_path = to_win_path(path)
|
|
504
|
+
system("rmdir /S /Q #{win_backup_path}")
|
|
505
|
+
else
|
|
506
|
+
# Linux/macOSの場合
|
|
507
|
+
system("rm -rf #{path}")
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
|
|
485
511
|
def delete_target_dir(cmd, target_dir)
|
|
486
512
|
target_dir = to_unix_path(target_dir)
|
|
487
513
|
puts "<<<<< Target dir: #{target_dir} >>>>>"
|
|
@@ -494,40 +520,20 @@ p @opt.limit_sec
|
|
|
494
520
|
else
|
|
495
521
|
raise RuntimeError, "unknown command: #{cmd}"
|
|
496
522
|
end
|
|
497
|
-
|
|
498
|
-
# p @opt.keep_year
|
|
499
|
-
# p @opt.keep_month
|
|
500
|
-
# p @opt.keep_day
|
|
501
|
-
|
|
523
|
+
|
|
502
524
|
snapshots.each do |snapshot|
|
|
503
525
|
next if snapshot.keep
|
|
504
526
|
t_start = Time.now
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
if windows?
|
|
513
|
-
# Windowsの場合
|
|
514
|
-
win_backup_path = to_win_path(snapshot.path)
|
|
515
|
-
|
|
516
|
-
# byenow = "byenow"
|
|
517
|
-
# if which(byenow)
|
|
518
|
-
# print " bynow"
|
|
519
|
-
# system("byenow -y --delete-ntapi --one-liner #{snapshot.path}")
|
|
520
|
-
# else
|
|
521
|
-
# print " pass1"
|
|
522
|
-
# system("del /F /S /Q #{win_backup_path} > nul")
|
|
523
|
-
# print " pass2"
|
|
524
|
-
# system("rmdir /S /Q #{win_backup_path}")
|
|
525
|
-
# end
|
|
526
|
-
system("rmdir /S /Q #{win_backup_path}")
|
|
527
|
-
else
|
|
528
|
-
# Linux/macOSの場合
|
|
529
|
-
system("rm -rf #{snapshot.path}")
|
|
527
|
+
|
|
528
|
+
if @opt.delete_dirs.size > 0
|
|
529
|
+
#削除するディレクトリが指定されている場合日付バックアップディレクトリの下そのディレクトリを削除
|
|
530
|
+
@opt.delete_dirs.each do |delete_dir|
|
|
531
|
+
delete_path = File.join(snapshot.path, delete_dir)
|
|
532
|
+
rm_dir(delete_path)
|
|
530
533
|
end
|
|
534
|
+
else
|
|
535
|
+
#それ以外はバックアップディレクトリ全体が対象
|
|
536
|
+
rm_dir(snapshot.path)
|
|
531
537
|
end
|
|
532
538
|
|
|
533
539
|
t_end = Time.now
|
|
@@ -551,60 +557,6 @@ p @opt.limit_sec
|
|
|
551
557
|
end
|
|
552
558
|
end
|
|
553
559
|
|
|
554
|
-
# def delete
|
|
555
|
-
# @opt.validate_directories(1)
|
|
556
|
-
|
|
557
|
-
# start_time = Time.now
|
|
558
|
-
# limit_time = start_time + (@opt.limit_sec)
|
|
559
|
-
# log("##### delete start #{fmt(start_time)} => limit_time=#{fmt(limit_time)} #####")
|
|
560
|
-
# @opt.dirs.each do |target_dir|
|
|
561
|
-
# target_start = Time.now
|
|
562
|
-
# delete_target_dir(target_dir)
|
|
563
|
-
# target_end = Time.now
|
|
564
|
-
|
|
565
|
-
# # 次回expireにかかる時間を最終expire時間の半分と予想
|
|
566
|
-
# next_expire = (target_end - target_start) / 2
|
|
567
|
-
|
|
568
|
-
# cur_time = Time.now
|
|
569
|
-
# in_imit = (cur_time + next_expire) < limit_time
|
|
570
|
-
|
|
571
|
-
# log("## cur_time=#{fmt(cur_time)} + next_expire=#{next_expire} < limit_time=#{fmt(limit_time)} in_limit=#{in_limit} ## ")
|
|
572
|
-
# unless in_limit
|
|
573
|
-
# break
|
|
574
|
-
# end
|
|
575
|
-
# end
|
|
576
|
-
# log("##### delete end #####")
|
|
577
|
-
# end
|
|
578
|
-
|
|
579
|
-
# def delete_target_dir(target_dir)
|
|
580
|
-
# target_dir = to_unix_path(target_dir)
|
|
581
|
-
# puts "<<<<< Target dir: #{target_dir} >>>>>"
|
|
582
|
-
|
|
583
|
-
# snapshots = BackupDir.scan_backup_dirs(target_dir)
|
|
584
|
-
# @opt.detect_delete_dirs(snapshots)
|
|
585
|
-
|
|
586
|
-
# snapshots.each do |snapshot|
|
|
587
|
-
# next if snapshot.keep
|
|
588
|
-
# t_start = Time.now
|
|
589
|
-
# print "Deleting #{snapshot.path} ..."
|
|
590
|
-
|
|
591
|
-
# unless @opt.dry_run
|
|
592
|
-
# if windows?
|
|
593
|
-
# # Windowsの場合
|
|
594
|
-
# win_backup_path = to_win_path(snapshot.path)
|
|
595
|
-
# system("rmdir /S /Q #{win_backup_path}")
|
|
596
|
-
# else
|
|
597
|
-
# # Linux/macOSの場合
|
|
598
|
-
# system("rm -rf #{snapshot.path}")
|
|
599
|
-
# end
|
|
600
|
-
# end
|
|
601
|
-
# end
|
|
602
|
-
|
|
603
|
-
# t_end = Time.now
|
|
604
|
-
# diff = (t_end - t_start).to_i
|
|
605
|
-
# diff_hours = diff / 3600
|
|
606
|
-
# puts " done[#{diff} seconds = #{diff_hours} hours]."
|
|
607
|
-
# end
|
|
608
560
|
|
|
609
561
|
end
|
|
610
562
|
|
data/lib/qdumpfs/option.rb
CHANGED
|
@@ -141,14 +141,17 @@ module Qdumpfs
|
|
|
141
141
|
@keep_day = $1.to_i if keep =~ /(\d+)D/
|
|
142
142
|
@delete_from = @opts[:delete_from]
|
|
143
143
|
@delete_to = @opts[:delete_to]
|
|
144
|
+
@delete_dirs = @opts[:delete_dirs] || []
|
|
144
145
|
@backup_at = @opts[:backup_at]
|
|
145
146
|
@today = Date.today
|
|
147
|
+
@debug = @opts[:d]
|
|
146
148
|
end
|
|
147
149
|
attr_reader :dirs, :src, :dst, :cmd
|
|
148
150
|
attr_reader :keep_year, :keep_month, :keep_week, :keep_day
|
|
149
151
|
attr_reader :logdir, :logpath, :verifypath
|
|
150
152
|
attr_reader :logger, :matcher, :reporter, :interval_proc
|
|
151
|
-
attr_reader :delete_from, :delete_to, :backup_at
|
|
153
|
+
attr_reader :delete_from, :delete_to, :delete_dirs, :backup_at
|
|
154
|
+
attr_reader :debug
|
|
152
155
|
|
|
153
156
|
def report(type, filename)
|
|
154
157
|
if @opts[:v]
|
|
@@ -173,6 +176,11 @@ module Qdumpfs
|
|
|
173
176
|
end
|
|
174
177
|
log(msg)
|
|
175
178
|
end
|
|
179
|
+
|
|
180
|
+
def report_error(filename, reason)
|
|
181
|
+
msg = sprintf("err_file\t%s\t%s\n", filename, reason)
|
|
182
|
+
log(msg)
|
|
183
|
+
end
|
|
176
184
|
|
|
177
185
|
def log(msg, console = true)
|
|
178
186
|
return if (msg.nil? || msg == '')
|
data/lib/qdumpfs/util.rb
CHANGED
|
@@ -73,14 +73,14 @@ module QdumpfsFind
|
|
|
73
73
|
yield file.dup.taint
|
|
74
74
|
begin
|
|
75
75
|
s = File.lstat(file)
|
|
76
|
-
rescue
|
|
76
|
+
rescue => e
|
|
77
77
|
logger.print("File.lstat path=#{file} error=#{e.message}")
|
|
78
78
|
next
|
|
79
79
|
end
|
|
80
80
|
if s.directory? then
|
|
81
81
|
begin
|
|
82
82
|
fs = Dir.entries(file, :encoding=>'UTF-8')
|
|
83
|
-
rescue
|
|
83
|
+
rescue => e
|
|
84
84
|
logger.print("Dir.entries path=#{file} error=#{e.message}")
|
|
85
85
|
next
|
|
86
86
|
end
|
|
@@ -107,23 +107,22 @@ module QdumpfsUtils
|
|
|
107
107
|
|
|
108
108
|
# We don't use File.copy for calling @interval_proc.
|
|
109
109
|
def copy_file(src, dest)
|
|
110
|
-
|
|
111
|
-
File.open(
|
|
112
|
-
|
|
113
|
-
|
|
110
|
+
begin
|
|
111
|
+
File.open(src, 'rb') {|r|
|
|
112
|
+
File.open(dest, 'wb') {|w|
|
|
113
|
+
block_size = (r.stat.blksize or 8192)
|
|
114
114
|
i = 0
|
|
115
115
|
while true
|
|
116
116
|
block = r.sysread(block_size)
|
|
117
117
|
w.syswrite(block)
|
|
118
118
|
i += 1
|
|
119
119
|
@written_bytes += block.size
|
|
120
|
-
# @interval_proc.call if i % 10 == 0
|
|
121
120
|
end
|
|
122
|
-
|
|
123
|
-
# puts e.message, e.backtrace
|
|
124
|
-
end
|
|
121
|
+
}
|
|
125
122
|
}
|
|
126
|
-
|
|
123
|
+
rescue EOFError => e
|
|
124
|
+
# puts e.message, e.backtrace
|
|
125
|
+
end
|
|
127
126
|
unless FileTest.file?(dest)
|
|
128
127
|
raise "copy_file fails #{dest}"
|
|
129
128
|
end
|
data/lib/qdumpfs/version.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
module Qdumpfs
|
|
2
|
-
VERSION = "
|
|
3
|
-
end
|
|
1
|
+
module Qdumpfs
|
|
2
|
+
VERSION = "1.1.0"
|
|
3
|
+
end
|
|
4
|
+
|
data/run_list.sh
ADDED
data/run_qdumpfs.sh
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: qdumpfs
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- src
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-04-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -86,6 +86,7 @@ files:
|
|
|
86
86
|
- qdumpfs.gemspec
|
|
87
87
|
- run2_qdumpfs.cmd
|
|
88
88
|
- run_list.cmd
|
|
89
|
+
- run_list.sh
|
|
89
90
|
- run_qdumpfs.cmd
|
|
90
91
|
- run_qdumpfs.sh
|
|
91
92
|
- run_sync.cmd
|