Class: Solaris::Kstat

Inherits:
Object
  • Object
show all
Extended by:
FFI::Library
Includes:
Functions, Structs
Defined in:
lib/solaris/kstat.rb

Constant Summary collapse

VERSION =

The version of the solaris-kstat library

'1.1.1'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mod = nil, instance = -1,, name = nil) ⇒ Kstat

Creates and returns a Kstat object. This does NOT traverse the kstat chain. The Kstat#record method uses the values passed to actually retrieve data.

You may specify a module, an instance and a name. The module defaults to nil (all modules), the instance defaults to -1 (all instances) and the name defaults to nil (all names).

Examples:

require 'solaris/kstat'
include Kstat

k1 = Kstat.new                    # Everything
k2 = Kstat.new('cpu')             # Just CPU info
k3 = Kstat.new('cpu', 0)          # Just CPU info for instance 0
k4 = Kstat.new('cpu', 0, 'sys')   # CPU info for instance 0 named 'sys'

Raises:

  • (TypeError)


40
41
42
43
44
45
46
47
48
49
# File 'lib/solaris/kstat.rb', line 40

def initialize(mod=nil, instance=-1, name=nil)
  # Type checking added since invalid values could cause a segfault later on.
  raise TypeError unless mod.is_a?(String) if mod
  raise TypeError unless instance.is_a?(Fixnum)
  raise TypeError unless name.is_a?(String) if name

  @module   = mod
  @instance = instance
  @name     = name
end

Instance Attribute Details

#instanceObject

The kstat instance number



17
18
19
# File 'lib/solaris/kstat.rb', line 17

def instance
  @instance
end

#moduleObject

The kstat module



14
15
16
# File 'lib/solaris/kstat.rb', line 14

def module
  @module
end

#nameObject

The kstat name



20
21
22
# File 'lib/solaris/kstat.rb', line 20

def name
  @name
end

Instance Method Details

#recordObject

Returns a nested hash based on the values passed to the constructor. How deeply that hash is nested depends on the values passed to the constructor. The more specific your criterion, the less data you will receive.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/solaris/kstat.rb', line 55

def record
  kptr = kstat_open()

  if kptr.null?
    raise SystemCallError.new('kstat_open', FFI.errno)
  end

  kstat = kstat_lookup(kptr, @module, @instance, @name)

  if kstat.null?
    kstat_close(kptr)
    raise SystemCallError.new('kstat_lookup', FFI.errno)
  end

  mhash = {} # Holds modules
  ihash = {} # Holds instances
  nhash = {} # Holds names
  shash = {} # Subhash for names

  # Sync the chain with the kernel
  if kstat_chain_update(kptr) < 0
    raise SystemCallError.new('kstat_chain_update', FFI.errno)
  end

  begin
    while !kstat.null?
      break if kstat[:ks_next].null?

      if @module && @module != kstat[:ks_module].to_s
        kstat = KstatStruct.new(kstat[:ks_next])
        next
      end

      if @instance != -1 && @instance != kstat[:ks_instance]
        kstat = KstatStruct.new(kstat[:ks_next])
        next
      end

      if @name && @name != kstat[:ks_name].to_s
        kstat = KstatStruct.new(kstat[:ks_next])
        next
      end

      if kstat_read(kptr, kstat, nil) < 0
        raise SystemCallError.new('kstat_read', FFI.errno)
      end

      case kstat[:ks_type]
        when 0 # KSTAT_TYPE_RAW
          shash = map_raw_data_type(kstat)
        when 1 # KS_TYPE_NAMED
          shash = map_named_data_type(kstat)
        when 2 # KS_TYPE_INTR
          shash = map_intr_data_type(kstat)
        when 3 # KS_TYPE_IO
          shash = map_io_data_type(kstat)
        when 4 # KS_TYPE_TIMER
          shash = map_timer_data_type(kstat)
        else
          raise ArgumentError, 'unknown data record type'
      end

      # The various calls to .to_s here and elsewhere are necessary
      # to convert FFI's CharArray to Ruby strings.

      shash['class'] = kstat[:ks_class].to_s

      ks_name = kstat[:ks_name].to_s
      ks_instance = kstat[:ks_instance]
      ks_module = kstat[:ks_module].to_s

      nhash[ks_name]     = shash
      ihash[ks_instance] = nhash
      mhash[ks_module]   = ihash

      kstat = KstatStruct.new(kstat[:ks_next])
    end
  ensure
    kstat_close(kptr)
  end

  mhash
end