class ICFS::Utils::Check
Check
a case for errors
Public Class Methods
new(store, log)
click to toggle source
Instance
@param store [Store] The store to check @param log [Logger] Where to log
# File lib/icfs/utils/check.rb, line 36 def initialize(store, log) @store = store @log = log end
Public Instance Methods
check(cid, cur_log, cur_hash, opts={})
click to toggle source
Check
a case
@param cur_log [Integer] The last log @param cur_hash [String] The hash of the last log
# File lib/icfs/utils/check.rb, line 100 def check(cid, cur_log, cur_hash, opts={}) @log.info('ICFS check: case %s' % cid) ent_cur = Set.new cse_cur = false idx_cur = Set.new act_cur = Set.new file_cur = Set.new # go thru the logs from most current lnum = cur_log hash_log = cur_hash time_log = Time.now.to_i while( lnum > 0 ) # log log = _item( 'log %d' % lnum, :log_read, [cid, lnum], false, hash_log, Items::ItemLog, [ ['caseid', 0].freeze, ['log', 1].freeze ].freeze, ) if !log hash_log = nil lnum = lnum - 1 next end # check that time decreases if log['time'] > time_log @log.warn('ICFS check: log %d time inconsistent' % lnum) end # entry if log['entry'] enum = log['entry']['num'] ent = _item( 'entry %d-%d' % [enum, lnum], :entry_read, [cid, enum, lnum], ent_cur.include?(enum), log['entry']['hash'], Items::ItemEntry, [ ['caseid', 0].freeze, ['entry', 1].freeze, ['log', 2].freeze ].freeze, ) # current entry unless ent_cur.include?(enum) ent_cur.add(enum) if ent['files'] ent['files'].each do |fd| file_cur.add( '%d-%d-%d' % [enum, fd['num'], fd['log']] ) end end end end # index if log['index'] xnum = log['index']['num'] idx = _item( 'index %d-%d'. freeze % [xnum, lnum], :index_read, [cid, xnum, lnum], idx_cur.include?(xnum), log['index']['hash'], Items::ItemIndex, [ ['caseid', 0].freeze, ['index', 1].freeze, ['log', 2].freeze ] ) idx_cur.add(xnum) end # action if log['action'] anum = log['action']['num'] act = _item( 'action %d-%d' % [anum, lnum], :action_read, [cid, anum, lnum], act_cur.include?(anum), log['action']['hash'], Items::ItemAction, [ ['caseid', 0].freeze, ['action', 1].freeze, ['log', 2].freeze ] ) act_cur.add(anum) end # case if log['case'] cse = _item( 'case %d' % lnum, :case_read, [cid, lnum], cse_cur, log['case']['hash'], Items::ItemCase, [ ['caseid', 0].freeze, ['log', 1].freeze ] ) cse_cur = true end # files if log['files_hash'] fnum = 0 log['files_hash'].each do |hash| fnum = fnum + 1 fn = '%d-%d-%d' % [enum, fnum, lnum] cur = file_cur.include?(fn) file_cur.delete(fn) if cur @log.debug('ICFS check: file %s' % fn) # read/size if opts[:hash_all] || (cur && opts[:hash_current]) fi = @store.file_read(cid, enum, lnum, fnum) elsif opts[:stat_all] || (cur && opts[:stat_current]) fi = @store.file_size(cur, enum, lnum, fnum) else fi = true end # missing if !fi if cur @log.error('ICFS check: file %s missing and current' % fn) else @log.warn('ICFS check: file %s missing and historical' % fn) end end # hash if fi.is_a?(File) # check if hash != ICFS.hash_temp(fi) @log.error('ICFS check: file %s hash bad' % fn) end # close if fi.respond_to?(:close!) fi.close! else fi.close end end end end # previous log lnum = lnum - 1 hash_log = log['prev'] end # check for any non-existant current files unless file_cur.empty? file_cur.each do |fn| @log.error('ICFS check: file %s current but not logged' % fn) end end @log.debug('ICFS check: case %s complete' % cid) end
Private Instance Methods
_item(title, read, read_args, hist, hash, val, con)
click to toggle source
check an object
# File lib/icfs/utils/check.rb, line 45 def _item(title, read, read_args, hist, hash, val, con) @log.debug('ICFS check: %s' % title) # read json = @store.send(read, *read_args) if !json if hist @log.warn('ICFS check: %s is missing and historical' % title) else @log.error('ICFS check: %s is missing and current' % title) end return nil end # hash if hash if hash != ICFS.hash(json) @log.error('ICFS check: %s hash bad' % title) end else @log.warn('ICFS check: %s hash unverified' % title) end # parse obj = JSON.parse(json) err = Validate.check(obj, val) if err @log.error('ICFS check: %s bad format' % title) return nil end # inconsistent con.each do |name, num| if obj[name] != read_args[num] @log.error('ICFS check: %s inconsistent' % title) return nil end end return obj rescue JSON::ParserError @log.error('ICFS check: %s bad JSON' % title) return nil end