5 module MogileFS::Bigfile
6 GZIP_HEADER = "\x1f\x8b".freeze # mogtool(1) has this
7 # VALID_TYPES = %w(file tarball partition).map { |x| x.freeze }.freeze
10 info = get_file_data(key)
14 # returns the big_info hash if successful, raises an exception if not
15 def bigfile_write(key, wr, opts = { :verify => false })
16 info = bigfile_stat(key)
18 md5 = opts[:verify] ? Digest::MD5.new : nil
21 # we only decode raw zlib deflated streams that mogtool (unfortunately)
22 # generates. tarballs and gzip(1) are up to to the application to decrypt.
23 filter = Proc.new do |buf|
25 if info[:compressed] && info[:type] == 'file' &&
26 buf.length >= 2 && buf[0,2] != GZIP_HEADER
27 zi = Zlib::Inflate.new
29 # mogtool(1) seems to have a bug that causes it to generate bogus
30 # MD5s if zlib deflate is used. Don't trust those MD5s for now...
43 end if (info[:compressed] || md5)
45 info[:parts].each_with_index do |part,part_nr|
46 next if part_nr == 0 # info[:parts][0] is always empty
47 uris = verify_uris(part[:paths].map { |path| URI.parse(path) })
49 # part[:paths] may not be valid anymore due to rebalancing, however we
50 # can get_keys on key,<part_nr> and retry paths if all paths fail
51 part[:paths] = get_paths("#{key.gsub(/^big_info:/, '')},#{part_nr}")
52 uris = verify_uris(part[:paths].map { |path| URI.parse(path) })
53 raise MogileFS::Backend::NoDevices if uris.empty?
56 sock = http_get_sock(uris[0])
58 w = sysrwloop(sock, wr, filter)
60 if md5 && md5.hexdigest != part[:md5]
61 raise MogileFS::ChecksumMismatchError, "#{md5} != #{part[:md5]}"
66 wr.syswrite(zi.finish) if zi
73 def parse_info(info = '')
75 info.each_line do |line|
78 when /^(des|type|filename)\s+(.+)$/
80 when /^compressed\s+([01])$/
81 rv[:compressed] = ($1 == '1')
82 when /^(chunks|size)\s+(\d+)$/
83 rv[$1.to_sym] = $2.to_i
84 when /^part\s+(\d+)\s+bytes=(\d+)\s+md5=(.+)\s+paths:\s+(.+)$/
85 rv[:parts][$1.to_i] = {
88 :paths => $4.split(/\s*,\s*/),
96 end # module MogileFS::Bigfile
99 # Copied from mogtool:
100 # http://code.sixapart.com/svn/mogilefs/utils/mogtool, r1221
102 # this is a temporary file that we delete when we're doing recording all chunks
106 starttime=UNIXTIMESTAMP
108 # when done, we write the _info file and delete the _pre.
112 des Cow's ljdb backup as of 2004-11-17
113 type { partition, file, tarball }
115 filename ljbinlog.305.gz
116 partblocks 234324324324
119 part 1 <bytes> <md5hex>
120 part 2 <bytes> <md5hex>
121 part 3 <bytes> <md5hex>
122 part 4 <bytes> <md5hex>
123 part 5 <bytes> <md5hex>
132 BEGIN MOGTOOL RECIEPT
137 part 1 bytes=23423432 md5=2349823948239423984 paths: http://dev5/2/23/23/.fid, http://dev6/23/423/4/324.fid
138 part 1 bytes=23423432 md5=2349823948239423984 paths: http://dev5/2/23/23/.fid, http://dev6/23/423/4/324.fid
139 part 1 bytes=23423432 md5=2349823948239423984 paths: http://dev5/2/23/23/.fid, http://dev6/23/423/4/324.fid
140 part 1 bytes=23423432 md5=2349823948239423984 paths: http://dev5/2/23/23/.fid, http://dev6/23/423/4/324.fid