solaris-kstat 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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
+