solaris-kstat 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGES ADDED
@@ -0,0 +1,29 @@
1
+ == 0.2.2 - 10-Jul-2006
2
+ * Updated the gemspec (and put a gem out on RubyForge).
3
+
4
+ == 0.2.1 - 31-Mar-2005
5
+ * Added some taint checking for string arguments.
6
+ * Added better error messages for various kstat related C function failures.
7
+ * Made this document rdoc friendly.
8
+ * Modified the test suite slightly because the "ifb" module is not, in fact,
9
+ found on all Solaris systems.
10
+ * Added a gemspec.
11
+ * Added more tests.
12
+ * Added an acknowledgement.
13
+ * Removed the kstat.txt and kstat.rd files. The documentation is now
14
+ located in the README file, though the source files are still rdoc friendly.
15
+
16
+ == 0.2.0 - 18-Jan-2005
17
+ * Altered the API to accept a module, instance and name. This release is
18
+ still backwards compatable with the 0.1.x version.
19
+ * Added Kstat#module, Kstat#instance and Kstat#name.
20
+ * Documentation updates
21
+ * More tests added
22
+
23
+ == 0.1.1 - 9-Nov-2004
24
+ * Added support for the cpu_stat module.
25
+ * Moved 'examples' to toplevel directory.
26
+ * Some attempts made to make documentation more rdoc friendly.
27
+
28
+ == 0.1.0 - 6-Oct-2004
29
+ * Initial release
data/MANIFEST ADDED
@@ -0,0 +1,12 @@
1
+ CHANGES
2
+ MANIFEST
3
+ README
4
+ extconf.rb
5
+ solaris-kstat.gemspec
6
+
7
+ examples/test.rb
8
+
9
+ lib/solaris/rkstat.c
10
+ lib/solaris/rkstat.h
11
+
12
+ test/tc_kstat.rb
data/README ADDED
@@ -0,0 +1,100 @@
1
+ == Description
2
+ Ruby extension for the Solaris kstat library.
3
+
4
+ == Prerequisites
5
+ Solaris 8 or later.
6
+ Ruby 1.8.x
7
+
8
+ == Installation
9
+ ruby extconf.rb
10
+ make
11
+ ruby test/tc_kstat.rb (optional)
12
+ make site-install
13
+
14
+ == Synopsis
15
+ require "solaris/kstat"
16
+ require "pp"
17
+ include Solaris
18
+
19
+ k = Kstat.new("cpu_info",0,"cpu_info0")
20
+ pp k
21
+
22
+ {"cpu_info"=>
23
+ {0=>
24
+ {"cpu_info0"=>
25
+ {"chip_id"=>0,
26
+ "fpu_type"=>"sparcv9",
27
+ "device_ID"=>0,
28
+ "cpu_type"=>"sparcv9",
29
+ "implementation"=>"Unknown",
30
+ "clock_MHz"=>502,
31
+ "state_begin"=>1105974702,
32
+ "state"=>"on-line"}}}}
33
+
34
+ == Class Methods
35
+ Kstat.new(module=nil, instance=-1, name=nil)
36
+ Creates and returns a Kstat object. This does not traverse the kstat
37
+ chain. The Kstat#record method uses the values passed to actually
38
+ retrieve data.
39
+
40
+ You may specify a module, an instance and a name. The module defaults to
41
+ nil (all modules), the instance defaults to -1 (all instances) and the
42
+ name defaults to nil (all names).
43
+
44
+ == Instance Methods
45
+ Kstat#record
46
+ Returns a nested hash based on the values passed to the constructor. How
47
+ deeply that hash is nested depends on the values passed to the constructor.
48
+ The more specific your criterion, the less data you will receive.
49
+
50
+ == Error Classes
51
+ KstatError < StandardError
52
+ Raised if anything goes wrong. Typically, this will only occur if you
53
+ pass bad arguments to the constructor (e.g. a module name that doesn't
54
+ exist, etc).
55
+
56
+ == Unsupported names
57
+ The following names will not return any meaningful value:
58
+
59
+ * kstat_headers
60
+ * sfmmu_global_stat
61
+ * sfmmu_percpu_stat
62
+
63
+ == Known Bugs
64
+ You will receive a couple warnings during the build process. You
65
+ can ignore these.
66
+
67
+ == Designer's Notes
68
+ I have noticed that results from the cpu_stat module differ from the output
69
+ of the 'kstat' command line tool. I am convinced that my code is correct and
70
+ that there is a bug in the Solaris::Kstat Perl module. Unfortunately, the
71
+ source for the version of Solaris::Kstat that works on Solaris 8 and later is
72
+ not available (the version on CPAN only works on Solaris 6 and 7).
73
+
74
+ See http://tinyurl.com/karxw for more details.
75
+
76
+ == Acknowledgements
77
+ Thanks go to Charlie Mills for help with the 'volatile' issue.
78
+
79
+ == Future Plans
80
+ Eliminate warnings that occur during the build process.
81
+
82
+ == License
83
+ Ruby's
84
+
85
+ == Copyright
86
+ (C) 2003-2006 Daniel J. Berger
87
+ All Rights Reserved
88
+
89
+ == Warranty
90
+ This package is provided "as is" and without any express or
91
+ implied warranties, including, without limitation, the implied
92
+ warranties of merchantability and fitness for a particular purpose.
93
+
94
+ == Author
95
+ Daniel J. Berger
96
+ djberg96 at gmail dot com
97
+ imperator on IRC (freenode)
98
+
99
+ == See Also
100
+ kstat(1M)
data/examples/test.rb ADDED
@@ -0,0 +1,43 @@
1
+ ########################################################
2
+ # test_kstat.rb
3
+ #
4
+ # Sample script for general futzing.
5
+ ########################################################
6
+ base = File.basename(Dir.pwd)
7
+
8
+ if base == "examples" || base =~ /solaris-kstat.*/
9
+ require "ftools"
10
+ Dir.chdir ".." if base == "examples"
11
+ Dir.mkdir("solaris") unless File.exists?("solaris")
12
+ File.copy("kstat.so","solaris")
13
+ $LOAD_PATH.unshift Dir.pwd
14
+ end
15
+
16
+ require "solaris/kstat"
17
+ require "pp"
18
+ include Solaris
19
+
20
+ puts "VERSION: " + Kstat::VERSION
21
+ puts
22
+
23
+ k1 = Kstat.new("cpu_info",0)
24
+ pp k1.record
25
+
26
+ puts "=" * 40
27
+
28
+ k2 = Kstat.new("unix",0,"flushmeter")
29
+ pp k2
30
+
31
+ # Print all modules
32
+ k = Kstat.new
33
+ k.record.each{ |k,v|
34
+ p k
35
+ }
36
+
37
+ =begin
38
+ pp k.record["cpu_info"][0]["cpu_info0"]
39
+ puts "=" * 40
40
+ pp k.record["unix"][0]["flushmeter"]
41
+ puts "=" * 40
42
+ pp k.record["cpu_stat"][0]["cpu_stat0"]
43
+ =end
data/extconf.rb ADDED
@@ -0,0 +1,14 @@
1
+ require "mkmf"
2
+ require "ftools"
3
+
4
+ File.copy("lib/solaris/rkstat.c",".")
5
+ File.copy("lib/solaris/rkstat.h",".")
6
+
7
+ # This package requires Solaris 2.8 or later
8
+ unless have_header("kstat.h")
9
+ STDERR.puts "The kstat.h header file was not found. Exiting."
10
+ exit
11
+ end
12
+
13
+ have_library("kstat")
14
+ create_makefile("solaris/kstat")
@@ -0,0 +1,208 @@
1
+ #ifdef __cplusplus
2
+ extern "C" {
3
+ #endif
4
+
5
+ #include <kstat.h>
6
+ #include <nfs/nfs.h>
7
+ #include <nfs/nfs_clnt.h>
8
+ #include <sys/utsname.h>
9
+ #include <sys/sysinfo.h>
10
+ #include <sys/inttypes.h>
11
+ #include <sys/dnlc.h>
12
+ #include <sys/vmmeter.h>
13
+ #include <sys/var.h>
14
+ #include <errno.h>
15
+ #include <string.h>
16
+
17
+ #include "ruby.h"
18
+ #include "rkstat.h"
19
+
20
+ VALUE cKstatError;
21
+
22
+ static VALUE ks_allocate(VALUE klass){
23
+ KstatStruct* ptr;
24
+ return Data_Make_Struct(klass,KstatStruct,0,ks_free,ptr);
25
+ }
26
+
27
+ /*
28
+ * call-seq:
29
+ * Kstat.new(module=nil, instance=-1, name=nil)
30
+ *
31
+ * Creates and returns a Kstat object. This does not traverse the kstat
32
+ * chain. The Kstat#record method uses the values passed to actually
33
+ * retrieve data.
34
+ *
35
+ * You may specify a module, an instance and a name. The module defaults to
36
+ * nil (all modules), the instance defaults to -1 (all instances) and the
37
+ * name defaults to nil (all names).
38
+ */
39
+ VALUE ks_init(int argc, VALUE* argv, VALUE self){
40
+ KstatStruct* ptr;
41
+ VALUE rbModule, rbInstance, rbName;
42
+
43
+ Data_Get_Struct(self,KstatStruct,ptr);
44
+
45
+ rb_scan_args(argc,argv,"03",&rbModule,&rbInstance,&rbName);
46
+
47
+ if(!NIL_P(rbModule)){
48
+ SafeStringValue(rbModule);
49
+ rb_iv_set(self,"@module",rbModule);
50
+ }
51
+
52
+ if(!NIL_P(rbName)){
53
+ SafeStringValue(rbName);
54
+ rb_iv_set(self,"@name",rbName);
55
+ }
56
+
57
+ if(!NIL_P(rbInstance))
58
+ rb_iv_set(self,"@instance",rbInstance);
59
+
60
+ return self;
61
+ }
62
+
63
+ /*
64
+ * Returns a nested hash based on the values passed to the constructor. How
65
+ * deeply that hash is nested depends on the values passed to the constructor.
66
+ * The more specific your criterion, the less data you will receive.
67
+ */
68
+ VALUE ks_record(VALUE self){
69
+ volatile VALUE rbMHash, rbIHash, rbNHash, rbSHash;
70
+ KstatStruct* ptr;
71
+ kstat_io_t kio;
72
+ kstat_timer_t kt;
73
+
74
+ char* module;
75
+ char* name;
76
+ int instance = -1; /* -1 represents all instances (the default) */
77
+
78
+ VALUE rbModule, rbInstance, rbName;
79
+
80
+ Data_Get_Struct(self,KstatStruct,ptr);
81
+
82
+ rbMHash = rb_hash_new(); /* Module name is key, holds rbIHashes */
83
+ rbIHash = rb_hash_new(); /* Instance name is key, holds rbNHashes */
84
+ rbNHash = rb_hash_new(); /* Name is key, holds rbSHashes */
85
+
86
+ rbModule = rb_iv_get(self,"@module");
87
+ rbInstance = rb_iv_get(self,"@instance");
88
+ rbName = rb_iv_get(self,"@name");
89
+
90
+ /* Module is NULL by default (i.e. all modules are returned) */
91
+ if(NIL_P(rbModule)){
92
+ module = NULL;
93
+ }
94
+ else{
95
+ module = StringValuePtr(rbModule);
96
+ }
97
+
98
+ /* Instance defaults to -1 (i.e. all instances are returned) */
99
+ if(!NIL_P(rbInstance)){
100
+ instance = NUM2INT(rbInstance);
101
+ }
102
+
103
+ /* Name is NULL by default (i.e. all names are returned) */
104
+ if(NIL_P(rbName)){
105
+ name = NULL;
106
+ }
107
+ else{
108
+ name = StringValuePtr(rbName);
109
+ }
110
+
111
+ /* A failure probably means the module, instance or name doesn't exist */
112
+ if((ptr->kc = kstat_open()) == NULL)
113
+ rb_raise(cKstatError,"kstat_open() failure: %s", strerror(errno));
114
+
115
+ /*
116
+ * Traverse the kstat chain, looking for matches based on supplied data.
117
+ * A failure likely means a non-existant module or name was provided.
118
+ */
119
+ if((ptr->ksp = kstat_lookup(ptr->kc, module, instance, name)) == NULL)
120
+ rb_raise(cKstatError,"kstat_lookup() failure: %s", strerror(errno));
121
+
122
+ /* Sync the chain with the kernel */
123
+ kstat_chain_update(ptr->kc);
124
+
125
+ while(ptr->ksp){
126
+
127
+ /* If a module is specified, ignore modules that don't match */
128
+ if( (module) && (strcmp(module,ptr->ksp->ks_module)) ){
129
+ ptr->ksp = ptr->ksp->ks_next;
130
+ continue;
131
+ }
132
+
133
+ /* If an instance is specified, ignore instances that don't match */
134
+ if( (instance != -1) && (instance != ptr->ksp->ks_instance) ){
135
+ ptr->ksp = ptr->ksp->ks_next;
136
+ continue;
137
+ }
138
+
139
+ /* If a name is specified, ignore names that don't match */
140
+ if( (name) && (strcmp(name,ptr->ksp->ks_name)) ){
141
+ ptr->ksp = ptr->ksp->ks_next;
142
+ continue;
143
+ }
144
+
145
+ /* Call the appropriate data mapper based on ks_type */
146
+ switch(ptr->ksp->ks_type){
147
+ case KSTAT_TYPE_NAMED:
148
+ kstat_read(ptr->kc,ptr->ksp,NULL);
149
+ rbSHash = map_named_data_type(ptr->ksp);
150
+ break;
151
+ case KSTAT_TYPE_IO:
152
+ kstat_read(ptr->kc,ptr->ksp,&kio);
153
+ rbSHash = map_io_data_type(&kio);
154
+ break;
155
+ case KSTAT_TYPE_TIMER:
156
+ kstat_read(ptr->kc,ptr->ksp,&kt);
157
+ rbSHash = map_timer_data_type(&kt);
158
+ case KSTAT_TYPE_INTR:
159
+ kstat_read(ptr->kc,ptr->ksp,NULL);
160
+ rbSHash = map_intr_data_type(ptr->ksp);
161
+ break;
162
+ case KSTAT_TYPE_RAW:
163
+ kstat_read(ptr->kc,ptr->ksp,NULL);
164
+ rbSHash = map_raw_data_type(ptr->ksp);
165
+ break;
166
+ default:
167
+ rb_raise(cKstatError,"Unknown data record type");
168
+ }
169
+
170
+ rb_hash_aset(rbNHash,rb_str_new2(ptr->ksp->ks_name),rbSHash);
171
+ rb_hash_aset(rbIHash,INT2FIX(ptr->ksp->ks_instance), rbNHash);
172
+ rb_hash_aset(rbMHash,rb_str_new2(ptr->ksp->ks_module),rbIHash);
173
+
174
+ ptr->ksp = ptr->ksp->ks_next;
175
+ }
176
+
177
+ return rbMHash;
178
+ }
179
+
180
+ /*
181
+ * Interface for Solaris kstat data.
182
+ */
183
+ void Init_kstat(){
184
+ VALUE mSolaris, cKstat;
185
+
186
+ /* Module and Class declarations */
187
+ mSolaris = rb_define_module("Solaris");
188
+ cKstat = rb_define_class_under(mSolaris,"Kstat",rb_cObject);
189
+ cKstatError = rb_define_class_under(mSolaris,"KstatError",rb_eStandardError);
190
+
191
+ rb_define_alloc_func(cKstat,ks_allocate);
192
+
193
+ /* Instance Methods */
194
+ rb_define_method(cKstat,"initialize",ks_init,-1);
195
+ rb_define_method(cKstat,"record",ks_record,0);
196
+
197
+ /* Attributes */
198
+ rb_define_attr(cKstat,"module",1,1);
199
+ rb_define_attr(cKstat,"instance",1,1);
200
+ rb_define_attr(cKstat,"name",1,1);
201
+
202
+ /* Constants */
203
+ rb_define_const(cKstat,"VERSION",rb_str_new2(SOLARIS_KSTAT_VERSION));
204
+ }
205
+
206
+ #ifdef __cplusplus
207
+ }
208
+ #endif
@@ -0,0 +1,365 @@
1
+ #ifdef __cplusplus
2
+ extern "C" {
3
+ #endif
4
+
5
+ #define SOLARIS_KSTAT_VERSION "0.2.2"
6
+
7
+ /* Function prototypes */
8
+ static VALUE map_named_data_type(kstat_t* ksp);
9
+ static VALUE map_io_data_type(kstat_io_t* kio);
10
+ static VALUE map_intr_data_type(kstat_t* ksp);
11
+ static VALUE map_timer_data_type(kstat_timer_t* kt);
12
+ static VALUE map_raw_data_type(kstat_t* ksp);
13
+ static VALUE map_raw_vminfo(kstat_t* ksp);
14
+ static VALUE map_raw_flushmeter(kstat_t* ksp);
15
+ static VALUE map_raw_var(kstat_t* ksp);
16
+ static VALUE map_raw_ncstats(kstat_t* ksp);
17
+ static VALUE map_raw_sysinfo(kstat_t* ksp);
18
+ static VALUE map_raw_cpu_sysinfo(kstat_t* ksp);
19
+ static VALUE map_raw_mntinfo(kstat_t* ksp);
20
+
21
+ /* Structure wrapped as our Kstat class */
22
+ struct kstruct{
23
+ kstat_ctl_t* kc;
24
+ kstat_t* ksp;
25
+ };
26
+
27
+ typedef struct kstruct KstatStruct;
28
+
29
+ static void ks_free(KstatStruct* p){
30
+ if(p->kc){
31
+ kstat_close(p->kc);
32
+ }
33
+ free(p);
34
+ }
35
+
36
+ /* Helps reduce GC for String key/value pairs in a hash */
37
+ void hash_add_pair(VALUE rbHash, const char *key, const char *value)
38
+ {
39
+ volatile VALUE key_obj = rb_str_new2(key);
40
+ rb_hash_aset(rbHash, key_obj, rb_str_new2(value));
41
+ }
42
+
43
+ /* Helper functions */
44
+
45
+ static VALUE map_raw_mntinfo(kstat_t* ksp){
46
+ struct mntinfo_kstat *mptr;
47
+ mptr = (struct mntinfo_kstat*)(ksp->ks_data);
48
+ volatile VALUE rbHash = rb_hash_new();
49
+
50
+ rb_hash_aset(rbHash,rb_str_new2("mik_proto"),rb_str_new2(mptr->mik_proto));
51
+ rb_hash_aset(rbHash,rb_str_new2("mik_vers"),UINT2NUM(mptr->mik_vers));
52
+ rb_hash_aset(rbHash,rb_str_new2("mik_flags"),UINT2NUM(mptr->mik_flags));
53
+ rb_hash_aset(rbHash,rb_str_new2("mik_secmod"),UINT2NUM(mptr->mik_secmod));
54
+ rb_hash_aset(rbHash,rb_str_new2("mik_curread"),UINT2NUM(mptr->mik_curread));
55
+ rb_hash_aset(rbHash,rb_str_new2("mik_curwrite"),
56
+ UINT2NUM(mptr->mik_curwrite));
57
+ rb_hash_aset(rbHash,rb_str_new2("mik_timeo"),UINT2NUM(mptr->mik_timeo));
58
+ rb_hash_aset(rbHash,rb_str_new2("mik_retrans"),UINT2NUM(mptr->mik_retrans));
59
+ rb_hash_aset(rbHash,rb_str_new2("mik_acregmin"),
60
+ UINT2NUM(mptr->mik_acregmin));
61
+ rb_hash_aset(rbHash,rb_str_new2("mik_acregmax"),
62
+ UINT2NUM(mptr->mik_acregmax));
63
+ rb_hash_aset(rbHash,rb_str_new2("mik_acdirmin"),
64
+ UINT2NUM(mptr->mik_acdirmin));
65
+ rb_hash_aset(rbHash,rb_str_new2("mik_acdirmax"),
66
+ UINT2NUM(mptr->mik_acdirmax));
67
+ rb_hash_aset(rbHash,rb_str_new2("mik_noresponse"),
68
+ UINT2NUM(mptr->mik_noresponse));
69
+ rb_hash_aset(rbHash,rb_str_new2("mik_failover"),
70
+ UINT2NUM(mptr->mik_failover));
71
+ rb_hash_aset(rbHash,rb_str_new2("mik_remap"), UINT2NUM(mptr->mik_remap));
72
+ rb_hash_aset(rbHash,rb_str_new2("mik_curserver"),
73
+ rb_str_new2(mptr->mik_curserver));
74
+
75
+ return rbHash;
76
+ }
77
+
78
+ static VALUE map_raw_vminfo(kstat_t* ksp){
79
+ vminfo_t *vminfop;
80
+ vminfop = (vminfo_t *)ksp->ks_data;
81
+ volatile VALUE rbHash = rb_hash_new();
82
+
83
+ rb_hash_aset(rbHash,rb_str_new2("freemem"),ULL2NUM(vminfop->freemem));
84
+ rb_hash_aset(rbHash,rb_str_new2("swap_resv"),ULL2NUM(vminfop->swap_resv));
85
+ rb_hash_aset(rbHash,rb_str_new2("swap_alloc"),ULL2NUM(vminfop->swap_alloc));
86
+ rb_hash_aset(rbHash,rb_str_new2("swap_avail"),ULL2NUM(vminfop->swap_avail));
87
+ rb_hash_aset(rbHash,rb_str_new2("swap_free"),ULL2NUM(vminfop->swap_free));
88
+
89
+ return rbHash;
90
+ }
91
+
92
+ static VALUE map_raw_var(kstat_t* ksp){
93
+ struct var* v;
94
+ v = (struct var *)ksp->ks_data;
95
+ volatile VALUE rbHash = rb_hash_new();
96
+
97
+ rb_hash_aset(rbHash,rb_str_new2("v_buf"),INT2NUM(v->v_buf));
98
+ rb_hash_aset(rbHash,rb_str_new2("v_call"),INT2NUM(v->v_call));
99
+ rb_hash_aset(rbHash,rb_str_new2("v_proc"),INT2NUM(v->v_proc));
100
+ rb_hash_aset(rbHash,rb_str_new2("v_maxupttl"),INT2NUM(v->v_maxupttl));
101
+ rb_hash_aset(rbHash,rb_str_new2("v_nglobpris"),INT2NUM(v->v_nglobpris));
102
+ rb_hash_aset(rbHash,rb_str_new2("v_maxsyspri"),INT2NUM(v->v_maxsyspri));
103
+ rb_hash_aset(rbHash,rb_str_new2("v_clist"),INT2NUM(v->v_clist));
104
+ rb_hash_aset(rbHash,rb_str_new2("v_maxup"),INT2NUM(v->v_maxup));
105
+ rb_hash_aset(rbHash,rb_str_new2("v_hbuf"),INT2NUM(v->v_hbuf));
106
+ rb_hash_aset(rbHash,rb_str_new2("v_hmask"),INT2NUM(v->v_hmask));
107
+ rb_hash_aset(rbHash,rb_str_new2("v_pbuf"),INT2NUM(v->v_pbuf));
108
+ rb_hash_aset(rbHash,rb_str_new2("v_sptmap"),INT2NUM(v->v_sptmap));
109
+ rb_hash_aset(rbHash,rb_str_new2("v_maxpmem"),INT2NUM(v->v_maxpmem));
110
+ rb_hash_aset(rbHash,rb_str_new2("v_autoup"),INT2NUM(v->v_autoup));
111
+ rb_hash_aset(rbHash,rb_str_new2("v_bufhwm"),INT2NUM(v->v_bufhwm));
112
+
113
+ return rbHash;
114
+ }
115
+
116
+ static VALUE map_raw_flushmeter(kstat_t* ksp){
117
+ struct flushmeter* fp;
118
+ fp = (struct flushmeter *)ksp->ks_data;
119
+ volatile VALUE rbHash = rb_hash_new();
120
+
121
+ rb_hash_aset(rbHash,rb_str_new2("f_ctx"),ULL2NUM(fp->f_ctx));
122
+ rb_hash_aset(rbHash,rb_str_new2("f_segment"),ULL2NUM(fp->f_segment));
123
+ rb_hash_aset(rbHash,rb_str_new2("f_page"),ULL2NUM(fp->f_page));
124
+ rb_hash_aset(rbHash,rb_str_new2("f_partial"),ULL2NUM(fp->f_partial));
125
+ rb_hash_aset(rbHash,rb_str_new2("f_usr"),ULL2NUM(fp->f_usr));
126
+ rb_hash_aset(rbHash,rb_str_new2("f_region"),ULL2NUM(fp->f_region));
127
+
128
+ return rbHash;
129
+ }
130
+
131
+ static VALUE map_raw_ncstats(kstat_t* ksp){
132
+ struct ncstats* np;
133
+ np = (struct ncstats *)ksp->ks_data;
134
+ volatile VALUE rbHash = rb_hash_new();
135
+
136
+ rb_hash_aset(rbHash,rb_str_new2("hits"),INT2NUM(np->hits));
137
+ rb_hash_aset(rbHash,rb_str_new2("misses"),INT2NUM(np->misses));
138
+ rb_hash_aset(rbHash,rb_str_new2("enters"),INT2NUM(np->enters));
139
+ rb_hash_aset(rbHash,rb_str_new2("dbl_enters"),INT2NUM(np->dbl_enters));
140
+ rb_hash_aset(rbHash,rb_str_new2("long_enter"),INT2NUM(np->long_enter));
141
+ rb_hash_aset(rbHash,rb_str_new2("long_look"),INT2NUM(np->long_look));
142
+ rb_hash_aset(rbHash,rb_str_new2("move_to_front"),INT2NUM(np->move_to_front));
143
+ rb_hash_aset(rbHash,rb_str_new2("purges"),INT2NUM(np->purges));
144
+
145
+ return rbHash;
146
+ }
147
+
148
+ static VALUE map_raw_sysinfo(kstat_t* ksp){
149
+ sysinfo_t* sp;
150
+ sp = (sysinfo_t *)ksp->ks_data;
151
+ volatile VALUE rbHash = rb_hash_new();
152
+
153
+ rb_hash_aset(rbHash,rb_str_new2("updates"),UINT2NUM(sp->updates));
154
+ rb_hash_aset(rbHash,rb_str_new2("runque"),UINT2NUM(sp->runque));
155
+ rb_hash_aset(rbHash,rb_str_new2("runocc"),UINT2NUM(sp->runocc));
156
+ rb_hash_aset(rbHash,rb_str_new2("swpque"),UINT2NUM(sp->swpque));
157
+ rb_hash_aset(rbHash,rb_str_new2("swpocc"),UINT2NUM(sp->swpocc));
158
+ rb_hash_aset(rbHash,rb_str_new2("waiting"),UINT2NUM(sp->waiting));
159
+
160
+ return rbHash;
161
+ }
162
+
163
+
164
+ /*
165
+ * Maps the cpu_sysinfo struct from sys/sysinfo.h into a hash.
166
+ */
167
+ static VALUE map_raw_cpu_sysinfo(kstat_t* ksp){
168
+ cpu_sysinfo_t* cptr;
169
+ cptr = (cpu_sysinfo_t *)ksp->ks_data;
170
+ volatile VALUE rbHash = rb_hash_new();
171
+
172
+ rb_hash_aset(rbHash,rb_str_new2("cpu_idle"),UINT2NUM(cptr->cpu[CPU_IDLE]));
173
+ rb_hash_aset(rbHash,rb_str_new2("cpu_user"),UINT2NUM(cptr->cpu[CPU_USER]));
174
+ rb_hash_aset(rbHash,rb_str_new2("cpu_kernel"),UINT2NUM(cptr->cpu[CPU_KERNEL]));
175
+ rb_hash_aset(rbHash,rb_str_new2("cpu_wait"),UINT2NUM(cptr->cpu[CPU_WAIT]));
176
+ rb_hash_aset(rbHash,rb_str_new2("wait_io"),UINT2NUM(cptr->wait[W_IO]));
177
+ rb_hash_aset(rbHash,rb_str_new2("wait_swap"),UINT2NUM(cptr->wait[W_SWAP]));
178
+ rb_hash_aset(rbHash,rb_str_new2("wait_pio"),UINT2NUM(cptr->wait[W_PIO]));
179
+ rb_hash_aset(rbHash,rb_str_new2("bread"),UINT2NUM(cptr->bread));
180
+ rb_hash_aset(rbHash,rb_str_new2("bwrite"),UINT2NUM(cptr->bwrite));
181
+ rb_hash_aset(rbHash,rb_str_new2("lread"),UINT2NUM(cptr->lread));
182
+ rb_hash_aset(rbHash,rb_str_new2("lwrite"),UINT2NUM(cptr->lwrite));
183
+ rb_hash_aset(rbHash,rb_str_new2("phread"),UINT2NUM(cptr->phread));
184
+ rb_hash_aset(rbHash,rb_str_new2("phwrite"),UINT2NUM(cptr->phwrite));
185
+ rb_hash_aset(rbHash,rb_str_new2("pswitch"),UINT2NUM(cptr->pswitch));
186
+ rb_hash_aset(rbHash,rb_str_new2("trap"),UINT2NUM(cptr->trap));
187
+ rb_hash_aset(rbHash,rb_str_new2("intr"),UINT2NUM(cptr->intr));
188
+ rb_hash_aset(rbHash,rb_str_new2("syscall"),UINT2NUM(cptr->syscall));
189
+ rb_hash_aset(rbHash,rb_str_new2("sysread"),UINT2NUM(cptr->sysread));
190
+ rb_hash_aset(rbHash,rb_str_new2("syswrite"),UINT2NUM(cptr->syswrite));
191
+ rb_hash_aset(rbHash,rb_str_new2("sysfork"),UINT2NUM(cptr->sysfork));
192
+ rb_hash_aset(rbHash,rb_str_new2("sysvfork"),UINT2NUM(cptr->sysvfork));
193
+ rb_hash_aset(rbHash,rb_str_new2("sysexec"),UINT2NUM(cptr->sysexec));
194
+ rb_hash_aset(rbHash,rb_str_new2("readch"),UINT2NUM(cptr->readch));
195
+ rb_hash_aset(rbHash,rb_str_new2("writech"),UINT2NUM(cptr->writech));
196
+ rb_hash_aset(rbHash,rb_str_new2("rcvint"),UINT2NUM(cptr->rcvint));
197
+ rb_hash_aset(rbHash,rb_str_new2("xmtint"),UINT2NUM(cptr->xmtint));
198
+ rb_hash_aset(rbHash,rb_str_new2("mdmint"),UINT2NUM(cptr->mdmint));
199
+ rb_hash_aset(rbHash,rb_str_new2("rawch"),UINT2NUM(cptr->rawch));
200
+ rb_hash_aset(rbHash,rb_str_new2("canch"),UINT2NUM(cptr->canch));
201
+ rb_hash_aset(rbHash,rb_str_new2("outch"),UINT2NUM(cptr->outch));
202
+ rb_hash_aset(rbHash,rb_str_new2("msg"),UINT2NUM(cptr->msg));
203
+ rb_hash_aset(rbHash,rb_str_new2("sema"),UINT2NUM(cptr->sema));
204
+ rb_hash_aset(rbHash,rb_str_new2("namei"),UINT2NUM(cptr->namei));
205
+ rb_hash_aset(rbHash,rb_str_new2("ufsiget"),UINT2NUM(cptr->ufsiget));
206
+ rb_hash_aset(rbHash,rb_str_new2("ufsdirblk"),UINT2NUM(cptr->ufsdirblk));
207
+ rb_hash_aset(rbHash,rb_str_new2("ufsipage"),UINT2NUM(cptr->ufsipage));
208
+ rb_hash_aset(rbHash,rb_str_new2("ufsinopage"),UINT2NUM(cptr->ufsinopage));
209
+ rb_hash_aset(rbHash,rb_str_new2("inodeovf"),UINT2NUM(cptr->inodeovf));
210
+ rb_hash_aset(rbHash,rb_str_new2("fileovf"),UINT2NUM(cptr->fileovf));
211
+ rb_hash_aset(rbHash,rb_str_new2("procovf"),UINT2NUM(cptr->procovf));
212
+ rb_hash_aset(rbHash,rb_str_new2("intrthread"),UINT2NUM(cptr->intrthread));
213
+ rb_hash_aset(rbHash,rb_str_new2("intrblk"),UINT2NUM(cptr->intrblk));
214
+ rb_hash_aset(rbHash,rb_str_new2("idlethread"),UINT2NUM(cptr->idlethread));
215
+ rb_hash_aset(rbHash,rb_str_new2("inv_swtch"),UINT2NUM(cptr->inv_swtch));
216
+ rb_hash_aset(rbHash,rb_str_new2("nthreads"),UINT2NUM(cptr->nthreads));
217
+ rb_hash_aset(rbHash,rb_str_new2("cpumigrate"),UINT2NUM(cptr->cpumigrate));
218
+ rb_hash_aset(rbHash,rb_str_new2("xcalls"),UINT2NUM(cptr->xcalls));
219
+ rb_hash_aset(rbHash,rb_str_new2("mutex_adenters"),
220
+ UINT2NUM(cptr->mutex_adenters));
221
+ rb_hash_aset(rbHash,rb_str_new2("rw_rdfails"),UINT2NUM(cptr->rw_rdfails));
222
+ rb_hash_aset(rbHash,rb_str_new2("rw_wrfails"),UINT2NUM(cptr->rw_wrfails));
223
+ rb_hash_aset(rbHash,rb_str_new2("modload"),UINT2NUM(cptr->modload));
224
+ rb_hash_aset(rbHash,rb_str_new2("modunload"),UINT2NUM(cptr->modunload));
225
+ rb_hash_aset(rbHash,rb_str_new2("bawrite"),UINT2NUM(cptr->bawrite));
226
+ #ifdef STATISTICS
227
+ rb_hash_aset(rbHash,rb_str_new2("rw_enters"),UINT2NUM(cptr->rw_enters));
228
+ rb_hash_aset(rbHash,rb_str_new2("win_uo_cnt"),UINT2NUM(cptr->win_uo_cnt));
229
+ rb_hash_aset(rbHash,rb_str_new2("win_uu_cnt"),UINT2NUM(cptr->win_uu_cnt));
230
+ rb_hash_aset(rbHash,rb_str_new2("win_so_cnt"),UINT2NUM(cptr->win_so_cnt));
231
+ rb_hash_aset(rbHash,rb_str_new2("win_su_cnt"),UINT2NUM(cptr->win_su_cnt));
232
+ rb_hash_aset(rbHash,rb_str_new2("win_suo_cnt"),UINT2NUM(cptr->win_suo_cnt));
233
+ #endif
234
+
235
+ return rbHash;
236
+ }
237
+
238
+ /* There are several different structs possible here. We'll forward this
239
+ * call to the appropriate mapper based on the module and name.
240
+ *
241
+ * A few names are not yet being handled.
242
+ */
243
+ static VALUE map_raw_data_type(kstat_t* ksp){
244
+ VALUE rbHash = rb_hash_new();
245
+
246
+ if(!strcmp(ksp->ks_module,"unix")){
247
+ if(!strcmp(ksp->ks_name,"vminfo")){
248
+ rbHash = map_raw_vminfo(ksp);
249
+ }
250
+ else if(!strcmp(ksp->ks_name,"flushmeter")){
251
+ rbHash = map_raw_flushmeter(ksp);
252
+ }
253
+ else if(!strcmp(ksp->ks_name,"ncstats")){
254
+ rbHash = map_raw_ncstats(ksp);
255
+ }
256
+ else if(!strcmp(ksp->ks_name,"sysinfo")){
257
+ rbHash = map_raw_sysinfo(ksp);
258
+ }
259
+ else if(!strcmp(ksp->ks_name,"var")){
260
+ rbHash = map_raw_var(ksp);
261
+ }
262
+ else{
263
+ /* Return an empty hash for unhandled names for now */
264
+ rbHash = rb_hash_new();
265
+ }
266
+ }
267
+
268
+ if(!strcmp(ksp->ks_module,"cpu_stat")){
269
+ rbHash = map_raw_cpu_sysinfo(ksp);
270
+ }
271
+
272
+ if(!strcmp(ksp->ks_module,"nfs")){
273
+ if(!strcmp(ksp->ks_name,"mntinfo")){
274
+ rbHash = map_raw_mntinfo(ksp);
275
+ }
276
+ }
277
+ return rbHash;
278
+ }
279
+
280
+ static VALUE map_timer_data_type(kstat_timer_t* t){
281
+ volatile VALUE rbHash = rb_hash_new();
282
+
283
+ rb_hash_aset(rbHash,rb_str_new2("name"),rb_str_new2(t->name));
284
+ rb_hash_aset(rbHash,rb_str_new2("num_events"),ULL2NUM(t->num_events));
285
+ rb_hash_aset(rbHash,rb_str_new2("elapsed_time"),ULL2NUM(t->elapsed_time));
286
+ rb_hash_aset(rbHash,rb_str_new2("min_time"),ULL2NUM(t->min_time));
287
+ rb_hash_aset(rbHash,rb_str_new2("max_time"),ULL2NUM(t->max_time));
288
+ rb_hash_aset(rbHash,rb_str_new2("start_time"),ULL2NUM(t->start_time));
289
+ rb_hash_aset(rbHash,rb_str_new2("stop_time"),ULL2NUM(t->stop_time));
290
+
291
+ return rbHash;
292
+ }
293
+
294
+ static VALUE map_intr_data_type(kstat_t* ksp){
295
+ int i;
296
+ kstat_intr_t* kp;
297
+ kp = (kstat_intr_t *)ksp->ks_data;
298
+ VALUE rbHash = rb_hash_new();
299
+ static char* intr_names[] =
300
+ {"hard", "soft", "watchdog", "spurious", "multiple_service"};
301
+
302
+ for(i = 0; i < KSTAT_NUM_INTRS; i++){
303
+ rb_hash_aset(rbHash,rb_str_new2(intr_names[i]),UINT2NUM(kp->intrs[i]));
304
+ }
305
+
306
+ return rbHash;
307
+ }
308
+
309
+ static VALUE map_io_data_type(kstat_io_t* k){
310
+ volatile VALUE rbHash = rb_hash_new();
311
+
312
+ rb_hash_aset(rbHash,rb_str_new2("nread"),ULL2NUM(k->nread));
313
+ rb_hash_aset(rbHash,rb_str_new2("nwritten"),ULL2NUM(k->nwritten));
314
+ rb_hash_aset(rbHash,rb_str_new2("reads"),UINT2NUM(k->reads));
315
+ rb_hash_aset(rbHash,rb_str_new2("writes"),UINT2NUM(k->writes));
316
+ rb_hash_aset(rbHash,rb_str_new2("wtime"),ULL2NUM(k->wtime));
317
+ rb_hash_aset(rbHash,rb_str_new2("wlentime"),ULL2NUM(k->wlentime));
318
+ rb_hash_aset(rbHash,rb_str_new2("wlastupdate"),ULL2NUM(k->wlastupdate));
319
+ rb_hash_aset(rbHash,rb_str_new2("rtime"),ULL2NUM(k->rtime));
320
+ rb_hash_aset(rbHash,rb_str_new2("rlentime"),ULL2NUM(k->rlentime));
321
+ rb_hash_aset(rbHash,rb_str_new2("rlastupdate"),ULL2NUM(k->rlastupdate));
322
+ rb_hash_aset(rbHash,rb_str_new2("wcnt"),UINT2NUM(k->wcnt));
323
+ rb_hash_aset(rbHash,rb_str_new2("rcnt"),UINT2NUM(k->rcnt));
324
+
325
+ return rbHash;
326
+ }
327
+
328
+ static VALUE map_named_data_type(kstat_t* ksp){
329
+ volatile VALUE rbHash;
330
+ kstat_named_t* knp;
331
+ knp = (kstat_named_t *)ksp->ks_data;
332
+ int i;
333
+
334
+ rbHash = rb_hash_new();
335
+
336
+ for(i = 0; i < ksp->ks_ndata; i++, knp++)
337
+ {
338
+ switch (knp->data_type)
339
+ {
340
+ case KSTAT_DATA_CHAR:
341
+ hash_add_pair(rbHash,knp->name,knp->value.c);
342
+ break;
343
+ case KSTAT_DATA_INT32:
344
+ rb_hash_aset(rbHash,rb_str_new2(knp->name),INT2NUM(knp->value.i32));
345
+ break;
346
+ case KSTAT_DATA_UINT32:
347
+ rb_hash_aset(rbHash,rb_str_new2(knp->name),UINT2NUM(knp->value.ui32));
348
+ break;
349
+ case KSTAT_DATA_INT64:
350
+ rb_hash_aset(rbHash,rb_str_new2(knp->name),LL2NUM(knp->value.i64));
351
+ break;
352
+ case KSTAT_DATA_UINT64:
353
+ rb_hash_aset(rbHash,rb_str_new2(knp->name),ULL2NUM(knp->value.ui64));
354
+ break;
355
+ default:
356
+ hash_add_pair(rbHash,knp->name,"Unknown");
357
+ break;
358
+ }
359
+ }
360
+ return rbHash;
361
+ }
362
+
363
+ #ifdef __cplusplus
364
+ }
365
+ #endif
data/test/tc_kstat.rb ADDED
@@ -0,0 +1,155 @@
1
+ ###############################################################################
2
+ # tc_kstat.rb
3
+ #
4
+ # Test suite for the solaris-kstat Ruby package.
5
+ ###############################################################################
6
+ base = File.basename(Dir.pwd)
7
+ if base == "test" || base =~ /solaris-kstat.*/
8
+ require "ftools"
9
+ Dir.chdir("..") if base == "test"
10
+ Dir.mkdir("solaris") unless File.exists?("solaris")
11
+ File.copy("kstat.so","solaris")
12
+ $LOAD_PATH.unshift Dir.pwd
13
+ end
14
+
15
+ require "solaris/kstat"
16
+ require "test/unit"
17
+ require "set"
18
+ include Solaris
19
+
20
+ class TC_Kstat < Test::Unit::TestCase
21
+ def setup
22
+ @k = Kstat.new
23
+ end
24
+
25
+ def test_version
26
+ assert_equal("0.2.2", Kstat::VERSION)
27
+ end
28
+
29
+ def test_name
30
+ assert_respond_to(@k, :name)
31
+ assert_respond_to(@k, :name=)
32
+ assert_nil(@k.name)
33
+ assert_nothing_raised{ @k.name }
34
+ assert_nothing_raised{ @k.name = "foo" }
35
+ end
36
+
37
+ def test_module
38
+ assert_respond_to(@k, :module)
39
+ assert_respond_to(@k, :module=)
40
+ assert_nil(@k.module)
41
+ assert_nothing_raised{ @k.module }
42
+ assert_nothing_raised{ @k.module = "bar" }
43
+ end
44
+
45
+ def test_instance
46
+ assert_respond_to(@k, :instance)
47
+ assert_respond_to(@k, :instance=)
48
+ assert_nil(@k.instance)
49
+ assert_nothing_raised{ @k.instance }
50
+ assert_nothing_raised{ @k.instance = 0 }
51
+ end
52
+
53
+ def test_constructor_valid_values
54
+ assert_nothing_raised{ Kstat.new("cpu_info",0,"cpu_info0").record }
55
+ assert_nothing_raised{ Kstat.new(nil,0,"cpu_info0").record }
56
+ assert_nothing_raised{ Kstat.new("cpu_info",0,nil).record }
57
+ end
58
+
59
+ def test_constructor_invalid_values
60
+ assert_raises(KstatError){ Kstat.new("bogus").record }
61
+ assert_raises(KstatError){ Kstat.new("cpu_info",99).record }
62
+ assert_raises(KstatError){ Kstat.new("cpu_info",0,"bogus").record }
63
+ assert_raises(TypeError){ Kstat.new("cpu_info","x").record }
64
+ end
65
+
66
+ def test_record_basic
67
+ assert_respond_to(@k, :record)
68
+ end
69
+
70
+ def test_record_named
71
+ assert_nothing_raised{ @k.record["cpu_info"][0]["cpu_info0"] }
72
+ assert_kind_of(Hash, @k.record["cpu_info"][0]["cpu_info0"])
73
+ end
74
+
75
+ def test_record_io
76
+ assert_nothing_raised{ @k.record["nfs"][1]["nfs1"] }
77
+ assert_kind_of(Hash, @k.record["nfs"][1]["nfs1"])
78
+ end
79
+
80
+ def test_record_intr
81
+ assert_nothing_raised{ @k.record["fd"][0]["fd0"] }
82
+ assert_kind_of(Hash, @k.record["fd"][0]["fd0"])
83
+ end
84
+
85
+ def test_record_raw_vminfo
86
+ keys = %w/freemem swap_alloc swap_avail swap_free swap_resv/
87
+
88
+ assert_nothing_raised{ @k.record["unix"][0]["vminfo"] }
89
+ assert_kind_of(Hash, @k.record["unix"][0]["vminfo"])
90
+ assert_equal(keys, @k.record["unix"][0]["vminfo"].keys.sort)
91
+ end
92
+
93
+ def test_record_raw_var
94
+ keys = %w/v_autoup v_buf v_bufhwm v_call v_clist v_hbuf v_hmask/
95
+ keys.push %w/v_maxpmem v_maxsyspri v_maxup v_maxupttl v_nglobpris v_pbuf/
96
+ keys.push %w/v_proc v_sptmap/
97
+ keys.flatten!
98
+
99
+ assert_nothing_raised{ @k.record["unix"][0]["var"] }
100
+ assert_kind_of(Hash, @k.record["unix"][0]["var"])
101
+ assert_equal(keys, @k.record["unix"][0]["var"].keys.sort)
102
+ end
103
+
104
+ def test_record_raw_flushmeter
105
+ keys = %w/f_ctx f_page f_partial f_region f_segment f_usr/
106
+
107
+ assert_nothing_raised{ @k.record["unix"][0]["flushmeter"] }
108
+ assert_kind_of(Hash, @k.record["unix"][0]["flushmeter"])
109
+ assert_equal(keys, @k.record["unix"][0]["flushmeter"].keys.sort)
110
+ end
111
+
112
+ def test_record_raw_cpu_stat
113
+ keys = %w/cpu_idle cpu_user cpu_kernel cpu_wait wait_io wait_swap/
114
+ keys << %w/wait_pio bread bwrite lread lwrite phread phwrite pswitch/
115
+ keys << %w/trap intr syscall sysread syswrite sysfork sysvfork sysexec/
116
+ keys << %w/readch writech rcvint xmtint mdmint rawch canch outch msg/
117
+ keys << %w/sema namei ufsiget ufsdirblk ufsipage ufsinopage inodeovf/
118
+ keys << %w/fileovf procovf intrthread intrblk idlethread inv_swtch/
119
+ keys << %w/nthreads cpumigrate xcalls mutex_adenters rw_rdfails/
120
+ keys << %w/rw_wrfails modload modunload bawrite/
121
+ keys.flatten!
122
+
123
+ assert_nothing_raised{ @k.record["cpu_stat"][0]["cpu_stat0"] }
124
+ assert_kind_of(Hash, @k.record["cpu_stat"][0]["cpu_stat0"])
125
+
126
+ # Too big and difficult to sort manually - so use a Set
127
+ set1 = Set.new(keys)
128
+ set2 = Set.new(@k.record["cpu_stat"][0]["cpu_stat0"].keys)
129
+ diff = set1 - set2
130
+
131
+ assert_equal(set1,set2,"Diff was: #{diff.to_a}")
132
+ end
133
+
134
+ def test_record_ncstats
135
+ keys = %w/dbl_enters enters hits long_enter long_look misses/
136
+ keys.push %w/move_to_front purges/
137
+ keys.flatten!
138
+
139
+ assert_nothing_raised{ @k.record["unix"][0]["ncstats"] }
140
+ assert_kind_of(Hash, @k.record["unix"][0]["ncstats"])
141
+ assert_equal(keys, @k.record["unix"][0]["ncstats"].keys.sort)
142
+ end
143
+
144
+ def test_record_sysinfo
145
+ keys = %w/runocc runque swpocc swpque updates waiting/
146
+
147
+ assert_nothing_raised{ @k.record["unix"][0]["sysinfo"] }
148
+ assert_kind_of(Hash, @k.record["unix"][0]["sysinfo"])
149
+ assert_equal(keys, @k.record["unix"][0]["sysinfo"].keys.sort)
150
+ end
151
+
152
+ def teardown
153
+ @k = nil
154
+ end
155
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: solaris-kstat
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.2.2
7
+ date: 2006-07-11 00:00:00 -06:00
8
+ summary: Interface for the Solaris kstat library
9
+ require_paths:
10
+ - lib
11
+ email: djberg96@gmail.com
12
+ homepage: http://www.rubyforge.org/projects/solarisutils
13
+ rubyforge_project: solarisutils
14
+ description: Interface for the Solaris kstat library
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.8.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Daniel J. Berger
31
+ files:
32
+ - CHANGES
33
+ - README
34
+ - MANIFEST
35
+ - extconf.rb
36
+ - lib/solaris/rkstat.c
37
+ - lib/solaris/rkstat.h
38
+ - test/tc_kstat.rb
39
+ - examples/test.rb
40
+ test_files:
41
+ - test/tc_kstat.rb
42
+ rdoc_options: []
43
+
44
+ extra_rdoc_files:
45
+ - README
46
+ - CHANGES
47
+ executables: []
48
+
49
+ extensions:
50
+ - extconf.rb
51
+ requirements: []
52
+
53
+ dependencies: []
54
+