oopsの日記: NTFSの件その3
再び、NTFSの圧縮によりファイルが壊れる件の続き。
Virtual PC で確認した限りは、Windows2000 Professional で、MS06-036(2006/07/12?)までの適用したものでは障害が発生しない。MS06-51(2006/08/09?)まで適用した場合に障害が発生する。
どの HOTFIX か調べるのは面倒だからやらなけど、08/09の HOTFIX をすべてアンインストールしても障害は残ったりする。アンインストールの仕方がまずかったかもしれないけど。
この障害では、圧縮ありのファイルが条件を満たした場合、ほぼ確実に壊れる。壊れない場合の方が少ない(壊れない場合もある)。
条件を再び記すると、
1)アロケーションユニットサイズ(例えば4096バイト)の整数倍より少し小さいサイズのファイルであること。
2)圧縮しにくいファイル(例えば、JPGやらGIFやらZIPやら)で圧縮時にアロケーションユニットサイズの整数倍を超える。
3)古いファイルは壊れない。
とにかく致命的なんだが、この話題出て来ないね。デフォルトで圧縮はチェックされてないから、わざわざ圧縮使ってる人ぐらいしか該当しないんだろうけど。
ファイルが壊れているかチェックするには、以下の check.rb を使って、ruby -Ks check.rb c:/ とかやれば見つかる。この障害によって壊れたファイル以外も出力されるけど、壊れたファイルは同じような壊れ方をするっぽいので、大体リストアップされるかと思う。
------------------ check.rb ----------------------
#!/usr/local/bin/ruby
require 'find'
def check_broken(path)
bsize = 1024
begin
File.open(path,'rb') do |f|
c0 = nil
buf = nil
while buf = f.read(bsize)
buf.each_byte do |c|
if c0 == nil
c0 = c
next
end
return :ok if c != c0
end
end
end
rescue
return :err
end
return :ng
end
def print2(buf,f1,f2,is_flush=true)
f1.print(buf) if f1 != nil
f2.print(buf) if f2 != nil
if is_flush
f1.flush if f1 != nil
f2.flush if f2 != nil
end
end
logfile = File.open("00check.log",'w')
$*.each do |root|
Find.find(root) do |path|
next if !test(?f,path)
st = File.stat(path)
next if st == nil
next if st.size < 32
result = check_broken(path)
if result == :ng
print2("Broken?:#{st.size}: #{path}\n",logfile,STDOUT,true)
next
end
end
end
logfile.close
--------------------------------------------------
NTFSの件その3 More ログイン