# Onering Collector - Disk Statistics plugin # provides data on disks, mounts, and RAID configuration # report do # ------------------------------------------------------------------------------ # block devices # blocks = [] Facter.value('blockdevices').split(/\W+/).each do |dev| block = { :vendor => Facter.value("blockdevice_#{dev}_vendor"), :model => Facter.value("blockdevice_#{dev}_model"), :size => (Integer(Facter.value("blockdevice_#{dev}_size")) rescue nil) } if File.directory?("/sys/block/#{dev}") block[:removable] = (File.read("/sys/block/#{dev}/removable").to_s.chomp.strip == '1' rescue nil) block[:readonly] = (File.read("/sys/block/#{dev}/ro").to_s.chomp.strip == '1' rescue nil) block[:solidstate] = (File.read("/sys/block/#{dev}/queue/rotational").to_s.chomp.strip == '0' rescue nil) block[:sectorsize] = {} %w{ logical physical }.each do |s| block[:sectorsize][s.to_sym] = (Integer(File.read("/sys/block/#{dev}/queue/#{s}_block_size").chomp.strip) rescue nil) end end blocks << block.compact end # ------------------------------------------------------------------------------ # partitions # # partitions = [] # begin # File.read("/proc/partitions").lines.each do |line| # next if line == line.first # line = line.chomp.strip # next if line.empty? # line = line.split(/\s+/) # # for the moment, just interested in sd devices # # numbers sources from /proc/devices # # # next unless [ # 8,65,66,67,68,69,70,71,128,129,130,131,132,133,134,135 # ].include?(line[0].to_i) # # only get numbered partitions (not whole-device entries) # next unless line[-1] =~ /^\D+\d+$/ # partition = { # :name => line[-1], # } # end # rescue # nil # end # ------------------------------------------------------------------------------ # mounts # mounts = {} current_dev = nil uuids = Hash[Dir["/dev/disk/by-uuid/*"].collect{|i| [File.expand_path(File.readlink(i), File.dirname(i)), File.basename(i)] }] File.read("/etc/mtab").lines.each do |line| dev,mount,fstype,flags,dump,pass = line.split(/\s+/) mounts[dev] = { :mount => mount, :device => dev, :filesystem => fstype, :flags => flags.split(/\s*,\s*/), :uuid => uuids[dev] }.compact end # logical space utilization Facter::Util::Resolution.exec("df 2> /dev/null").to_s.lines.each do |line| next if line =~ /^Filesystem/ parts = line.split(/\s+/) if parts.length == 1 current_dev = parts.first next else dev,kblk,used,free,percent,mount = parts dev = current_dev if dev.empty? next unless mounts[dev] and mounts[dev].is_a?(Hash) mounts[dev][:used] = (used.to_i * 1024) mounts[dev][:available] = (free.to_i * 1024) mounts[dev][:total] = (mounts[dev][:available] + mounts[dev][:used]) mounts[dev][:percent_used] = percent.delete('%').to_i end end # ------------------------------------------------------------------------------ # LVM # vg = {} # volume groups Facter::Util::Resolution.exec("vgdisplay -c 2> /dev/null").to_s.lines.each do |line| line = line.strip.chomp.split(':') vg[line[0]] = { :name => line[0], :uuid => line[16], :size => (line[11].to_i*1024), :extents => { :size => (line[12].to_i * 1024), :total => line[13].to_i, :allocated => line[14].to_i, :free => line[15].to_i }, :volumes => [], :disks => [] } end # logical volumes Facter::Util::Resolution.exec("lvdisplay -c 2> /dev/null").to_s.lines.each do |line| line = line.strip.chomp.split(':') unless vg[line[1]].nil? vg[line[1]][:volumes] << { :name => line[0], :sectors => line[6].to_i, :extents => line[7].to_i, :size => (vg[line[1]][:extents][:size] * line[7].to_i) } end end # physical volumes Facter::Util::Resolution.exec("pvdisplay -c 2> /dev/null").to_s.lines.each do |line| line = line.strip.chomp.split(':') unless vg[line[1]].nil? vg[line[1]][:disks] << { :name => line[0], :uuid => line[11], :size => (line[8].to_i * (line[7].to_i * 1024)), # See Note 1 below :extents => { :size => (line[7].to_i * 1024), :total => line[8].to_i, :allocated => line[10].to_i, :free => line[9].to_i } } # the output of certain versions of pvdisplay -c reports a blatantly incorrect # physical volume total size. the workaround is to calculate the actual total size # via (total extents * extent size) # # this may or may not be GPT related # end end d = {} d[:@mounts] = (Hash[mounts.select{|k,v| k =~ /^\/dev\/((h|s|xv|v)d|mapper|vgc)/ }].values rescue nil) d[:lvm] = { :@groups => vg.values } unless vg.values.empty? d[:@smart] = Facter.value('smart') d[:@block] = blocks unless blocks.empty? stat :disk, d.compact end