パスワードを忘れた? アカウント作成
518923 journal

oopsの日記: NTFSの件その3

日記 by oops

再び、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
 
--------------------------------------------------

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

計算機科学者とは、壊れていないものを修理する人々のことである

読み込み中...