Unix Linux

[펌] Solaris Kernel Statistics

_침묵_ 2006. 1. 26. 08:28
 
Solaris Developer Connection Technical Articles 중 libkstat를 이용한 C Programing에 대한 문서입니다. 번역이 엉망이니 양해해 주십시오. 원문은http://soldc.sun.com/articles/kstatc.html에서 찾을 수 있습니다. 의문이나 문의 사항은 차주현(zoo11 at hst.co.kr)로 부탁드립니다.


Solaris Developer Connection Technical Articles

SolarisKernel Statistics - Accessing libkstat with C#


By Peter Boothby

1Solaris?tm Kernel Statistics - Accessing libkstat with C
1.1Introduction
1.2Data Structure Overview
1.3Getting Started
1.4Data Types
1.5Kstat Names
1.6Functions
1.7Dealing with Chain Updates
1.8Putting It All Together
1.9Additional Information


1.1Introduction#


솔라리스 커널은 커널 모듈의 특정한 통계 정보를 외부에 보내기 위해서
디바이스 드라이버나 다른 커널 모듈을 위한 몇몇의 함수와 data 구조체를 제공
한다. kstat 라고 불리우는 이 것은 솔라리스 소프트웨어 개발자에게 다음과 같은
것들을 제공한다.

* 디아이스 드라이버나 커널 모듈을 위한 통계 정보를 제공하는 C 함수
* 어플리케이션이 직접 커널 메모리를 읽지 않고도 솔라리스의 통계를 얻을 수 있
는 C 함수
* 쉘 스크립트나 명령어 라인에서 통계 정보에 접근 할 수 있도록 하는 perl 기반의
명령어 /usr/bin/kstat (솔라리스 8부터)

솔라리스 libkstat 라이브러리는 어플리케이션이 kstat에 접근 할 수 있도록 C 함수
를 제공 한다. 이 함수들은 프로그램이 root setuid의 필요성을 없애므로서 커널
데이터로의 안전한 인터페이스를 제공하기 위해 가상의 디바이스인 /dev/kstat 를
이용한다.

많은 개발자들이 C 를 이용하여 커널 데이터에 접근하기를 원하므로 이 문서는
libkstat 를 이용하는데 촛점이 맞춰져있다. 이 문서에서는 libkstat 의 함수들과
커널 data 구조체를 설명하고 라이브러리를 이용하는 예제 코드를 제공 한다.

1.2Data Structure Overview#


솔라리스 커널 데이터 통계들은 kstat chain 이라 불리우는 linked-list에 유지된
다. 각 kstat 는 공통의 헤더 섹션과 type에 따른 데이터 섹션이 있다.
이 chain은 시스템이 boot 할 때 초기화 되지만 솔라리스는 동적인 OS이기 때문에
계속 변한다. kstat entry는 커널의 요구에 따라 시스템에서 더해지기도 하고 제거
되기도 한다. 예를 들어 I/O 보드와 그것의 components들이 DR(Dynamic
Reconfiguration)에 의해 운영중인 시스템에 더해지면 새로운 하드웨어와 동작하는
모든 디바이스 드라이버와 커널 모듈의 kstat entry가 kstat chain에 삽입 된다.

구조체의 한 멤버인 ks_data는 kstat의 데이터 섹션의 포인터이다. 여러개의 데이
터 타입이 raw, named, timer, interrupt, I/O 타입에서 지원된다. 이런 타입들은
Data Types 장에서 설명 된다.

Example 1. /usr/include/kstat.h 에 정의된 kstat 헤더 섹션

typedefstructkstat {/** Fields relevant to both kernel and user*/hrtime_t       ks_crtime;/*creation time*/structkstat  *ks_next;/*kstat chain linkage*/kid_t          ks_kid;/*unique kstat ID*/charks_module[KSTAT_STRLEN];/*module name*/uchar_t        ks_resv;/*reserved*/intks_instance;/*module's instance*/charks_name[KSTAT_STRLEN];/*kstat name*/uchar_t        ks_type;/*kstat data type*/charks_class[KSTAT_STRLEN];/*kstat class*/uchar_t        ks_flags;/*kstat flags*/void*ks_data;/*kstat type-specific data*/uint_t         ks_ndata;/*# of data records*/size_tks_data_size;/*size of kstat data section*/hrtime_t       ks_snaptime;/*time of last data snapshot*//** Fields relevant to kernel only*/int(*ks_update)(structkstat *,int);void*ks_private;int(*ks_snapshot)(structkstat *,void*,int);void*ks_lock;     } kstat_t;
주요한 멤버들은 다음과 같다.

* ks_crtime
이 멤버는 kstat chain이 처음 생성 된 시각을 나타내고 이 것은 여러가지 커널
카운터들이 kstat 가 생성 된 시각부터의 빈도를 계산하는데 이용된다. (일반적
으로 boot 한 이후 부터 라는 말로 대신 할 수 있다.)

생성 시각, last snapshot 시각, kstat_timer_t나 kstat_io_t 타임 스탬프 등등
모든 kstat와 관련된 시각은 64bit nanosecond 값을 가진다.

kstat 타임 스탬프의 정확도는 기계에 따라 다르나 단위의 정밀도는 모든 플랫폼
에 걸쳐서 같다. 이 같은 high-resolution 타임스탬프에 관한 일반적인 정보는
gethrtime(3C) man page를 참조.

* ks_next
kstat는 chain(linked-list) 속에 NULL-termanated 된 상태로 존재한다. ks_next
는 chain안에 다음 kstat를 가르킨다.

* ks_kid
kstat를 구별하는 ID이다.

* ks_module, ks_instance
이들은 kstat를 생성한 무듈의 이름과 instance 번호를 나타낸다. 하나의 instance
만이 있을 때는 ks_instance 는 0이다. kstat Names를 참조.

* ks_name
kstat의 의미있는 이름을 나타낸다. kstat name space에 대해 더 알고 싶다면
kstat Names장을 참조

* ks_type
kstat가 갖고 있는 데이터의 타입. Data Types를 참조

* ks_class
각각의 kstat는 bus,net,vm 혹은 misc 등의 넓은 class로 구별 되어 진다. 이
필드는 연관된 kstat들을 뽑아내는 필터로 사용 될 수 있다.

다음의 값들이 현재 solaris에서 사용 되어 진다.
bus
controller
device_error
disk
hat
kmem_cache
kstat
misc
net
nfs
pages
partition
rpc
ufs
vm
vmem

* ks_data, ks_ndata, ks_data_size
ks_data는 kstat의 data section의 포인터이다. 그곳에 저장되어 있는 data의
type은 ks_type에 따라 달라진다. ks_ndata 는 data record 의 갯수를 나타낸다.
몇몇의 type만이 여러개의 data record를 허용한다.

다음의 kstat는 여러개의 data record를 지원한다.
- KSTAT_TYPE_RAW
- KSTAT_TYPE_NAMED
- KSTAT_TYPE_TIMER

다음의 kstat는 단 하나의 data record만을 지원한다.
- KSTAT_TYPE_INTR
- KSTAT_TYPE_IO

ks_data_size는 data section의 총 바이트수를 나타낸다.

* ks_snaptime
이것은 최종 data 의 snapshot 의 타임스탬프이다. 이 필드는 다음의 계산 방식으로
activity rates를 계산 할 수 있다.

rate = (new_count - old_count) / (new_snaptime - old_snaptime);


1.3Getting Started#


kstat를 사용하기 위해서는 프로그램은 처음에 kstat_open()이란 함수를 부르게 되
는데 이 것은 kstat control 구조체의 포인터를 반환 한다. Example 2는 kstat
chain control 구조체를 보여준다.

Example 2. kstat control 구조체

typedefstructkstat_ctl {         kid_t     kc_chain_id;/*current kstat chain ID*/kstat_t   *kc_chain;/*pointer to kstat chain*/intkc_kd;/*/dev/kstat descriptor*/} kstat_ctl_t;

kc_chain은 kstat chain의 복사본의 헤더를 가리키고 있다. 일반적으로 특정한
kstat를 찾아 처리 하기위해 kstat_lookup()을 사용하거나 chain을 walk하여야 한다.
kc_chain_id는 kstat chain 복사본의 kstat chain 구별자(KCID)이다. KCID의 사용
법은 kstat Names에서 설명 한다.

kstat data에 접근하는데 드는 쓸데없는 오버헤드를 피하기 위하여, 프로그램은
먼저 kstat chain에서 필요한 정보의 type을 찾고 그리고 나서 kstat_read()와
kstat_data_lookup()을 이용하여 커널로 부터 통계 정보를 얻는다.

Example 3은 disk I/O에 대한 모든 정보를 갖고 있는 kstat entry를 출력 하는 예를
보여준다. 코드는 chain의 처음부터 끝까지 훑으며 ks_type이 KSTAT_TYPE_IO인 kstat
entry 를 찾아 내어 data를 얻기 위해 kstat_read()를 호출하고 받은 데이터를 처리
하기 위해 my_io_display()라는 함수를 호출 했다. 이 함수의 구현에 대한 샘플코드
는 Example 9에 보인다.

Example 3. Disk I/O 정보를 갖고 있는 kstat entry 출력

kstat_ctl_t    *kc;     kstat_t       *ksp;     kstat_io_t     kio;     kc = kstat_open();for(ksp = kc->kc_chain; ksp !=NULL; ksp = ksp->ks_next) {if(ksp->ks_type == KSTAT_TYPE_IO) {          kstat_read(kc, ksp, &kio);          my_io_display(kio);       }     }

1.4Data Types#


kstat의 data section에는 ks_type 필드에 따라 5개 중에 하나의 type을 갖는다.
다음의 kstat type은 여러개의 data record를 가질수 있다. record의 갯수는
ks_ndata로 알 수 있다.

- KSTAT_TYPE_RAW
- KSTAT_TYPE_NAMED
- KSTAT_TYPE_TIMER

ks_data_size필드에 data section의 총 크기가 바이트 단위로 나와 있다.

* KSTAT_TYPE_RAW
"raw" kstat type은 data의 내용을 단순한 바이트의 나열로 취급 된다. 그리고 이
것은 vminfo(/usr/include/sys/sysinfo.h 에 정의 되어 있는) 같은 잘 알려진 구
조체를 담기 위해 사용 된다. Example 4는 이 정보를 출력하는 간단한 예를 보인다.

Example 4. Raw kstat 의 출력


staticvoidprint_vminfo(kstat_t *kp)  {       vminfo_t *vminfop;       vminfop = (vminfo_t *)(kp->ks_data);       printf("Free memory:%d\n", vminfop->freemem);       printf("Swap reserved:%d\n", vminfop->swap_resv);       printf("Swap allocated:%d\n", vminfop->swap_alloc);       printf("Swap available:%d\n", vminfop->swap_avail);       printf("Swap free:%d\n", vminfop->swap_free);  }

* KSTAT_TYPE_NAMED
이 type의 kstat의 data section에는 임의의 name=value 통계들을 갖고 있다.
Example 5는 named kstat를 담기 위한 구조체를 보여준다.

Example 5. /usr/include/kstat.h 에 정의된 named kstat

typedefstructkstat_named {charname[KSTAT_STRLEN];/*name of counter*/uchar_t data_type;/*data type*/union{charc[16];/*enough for 128-bit ints*/int32_ti32;uint32_tui32;int64_ti64;uint64_tui64;/*These structure members are obsolete*/int32_tl;uint32_tul;int64_tll;uint64_tull;      } value;/*value of counter*/} kstat_named_t;#define KSTAT_DATA_CHAR0#define KSTAT_DATA_INT321#define KSTAT_DATA_UINT322#define KSTAT_DATA_INT643#define KSTAT_DATA_UINT644/*These types are obsolete*/#define KSTAT_DATA_LONG1#define KSTAT_DATA_ULONG2#define KSTAT_DATA_LONGLONG3#define KSTAT_DATA_ULONGLONG4#define KSTAT_DATA_FLOAT5#define KSTAT_DATA_DOUBLE6
Example 9에 사용된 my_named_display()는 어떻게 named kstat를 출력하는지 보여
준다.
data_type이 KSTAT_DATA_CHAR가 쓰여도 16바이트의 char 배열이 NULL-terminated
된다는 보장이 없다는 것을 기억하라. 이 사실은 printf()같은 함수로 출력할 때
중요하다.

* KSTAT_TYPE_TIMER
이 kstat는 event timer의 통계를 갖고 있다. 이들은 어떠한 event에 대한 count
정보와 timing 정보를 제공 한다.

Example 6. /usr/include/kstat.h에 정의된 timer kstat

typedefstructkstat_timer {charname[KSTAT_STRLEN];/*event name*/uchar_t resv;/*reserved*/u_longlong_t num_events;/*number of events*/hrtime_t elapsed_time;/*cumulative elapsed time*/hrtime_t min_time;/*shortest event duration*/hrtime_t max_time;/*longest event duration*/hrtime_t start_time;/*previous event start time*/hrtime_t stop_time;/*previous event stop time*/} kstat_timer_t;
* KSTAT_TYPE_INTR
이 type의 kstat는 인터럽트 통계 정보를 제공한다. 인터럽트는 크게 다음과 같이
나뉜다.

Interrupt Type Definition
----------------------------------------------------------------------------
Hard 하드웨어 장치 자체에서 발생
Soft 시스템 인터럽트에 의한 시스템 자체가 발생
Watchdog 주기적 timer call에 의해 발생
Spurious 인터럽트 entry point에는 들어갔지만 처리 할 인터럽트 없음
Multiple Service 다른 인터럽트 처리를 마치기 전에 인터럽트가 감지 되고 처리됨

Example 7. /usr/include/kstat.h 에 정의된 interrupt kstat

#define KSTAT_INTR_HARD0#define KSTAT_INTR_SOFT1#define KSTAT_INTR_WATCHDOG2#define KSTAT_INTR_SPURIOUS3#define KSTAT_INTR_MULTSVC4#define KSTAT_NUM_INTRS5typedefstructkstat_intr {      uint_t intrs[KSTAT_NUM_INTRS];/*interrupt counters*/} kstat_intr_t;
* KSTAT_TYPE_IO

Example 8. /usr/include/kstat.h 에 정의된 I/O kstat

typedefstructkstat_io {/** Basic counters.*/u_longlong_t nread;/*number of bytes read*/u_longlong_t nwritten;/*number of bytes written*/uint_t       reads;/*number of read operations*/uint_t       writes;/*number of write operations*/hrtime_t wtime;/*cumulative wait (pre-service) time*/hrtime_t wlentime;/*cumulative wait length*time product*/hrtime_t wlastupdate;/*last time wait queue changed*/hrtime_t rtime;/*cumulative run (service) time*/hrtime_t rlentime;/*cumulative run length*time product*/hrtime_t rlastupdate;/*last time run queue changed*/uint_t wcnt;/*count of elements in wait state*/uint_t rcnt;/*count of elements in run state*/} kstat_io_t

- Accumulated Time and Queue Length Statistics
time 정보는 "active" time 의 총합을 구함으로써 얻어진다. 큐 길이 정보는
경과한 시간과 큐의 길이의 곱의 총합을 구함으로써 얻어진다. 즉, 큐 길이를
시간에 대해 적분한 리만 합(Riemann sum)에 이다. Figure 1는 queue/time 에
대한 샘플 그래프를 보여준다.

Figure 1.           ^           |                       _________           8                       | i4    |           |                       |       |   Queue   6                       |       |   Length  |       _________       |       |           4       | i2    |_______|       |           |       |       i3              |           2_______|                       |           |    i1                         |           |_______________________________|           Time->  t1      t2      t3      t4
매번 상태가 변할 때 마다 (큐에 들어가거나 나가거나) 그 전의 상태 변화 부터
경과된 시간이 active time에 더해 진다. (그 동안 큐의 길이가 0이 아니라면)
경과된 시간과 큐 길이의 곱이 길이에 시간이 곱해진 합에 더해진다. (vlentime
혹은 rlentime)
프로그래밍적으로 말하자면

if(queue length !=0) {      time += elapsed time since last state change;      lentime +=  (elapsed time since last state change * queue length);  }
이 방법은 어떤 정의된 시스템의 residency측정 하는 일반 적인 방법이다. 큐 길이
대신에 "outstanding RPC calls to server X." 를 생각 하자.

많은 수의 I/O 서브 시스템이 적어도 2개의 기본적인 트랜잭션 리스트를 갖고 있
다.
  1. 처리가 아직 시작 되진 않았지만, 처리 되길 대기 하고 있는 트랜잭션 리스트
  2. 아직 처리가 끝나지 않았지만 현재 처리되고 있는 트랜잭션 리스트

이러한 이유에서 두개의 누적 time 통계가 정의 된다.
  1. Pre-service (wait) time
  2. Service (run) time
각 누적된 시간은 nanosecond가 기본 단위이다.

1.5Kstat Names#


kstat namespace는 kstat 구조체에 의해서 3개의 필드로 정의 된다.
- ks_module
- ks_instance
- ks_name

이 세개의 조합은 namespace에서 유일하도록 보장 된다.

예를 들어 4개의?FastEthernet 인터페이스를 갖고 있는 시스템을 상상해 보자. Sun의
?FastEthernet 컨트롤러를 위한 디바이스 드라이버는 "hme"라고 불린다. 첫번째
ethernet 인터페이스는 instance 0 이고 두번째는 instance 1이다. "hme" 디바이스
드라이버는 각 인터페이스 마다 두 type의 kstat를 제공 한다. 첫번째는 성능 통계를
갖고있는 named kstat이고 두번째는 인터럽트 정보를 갖는다.

첫번째 인터페이스의 network 통계는 ks_module == "hme", ks_instance == 0,
ks_name == "hme0" 에서 찾을 수 있다. 인터럽트 정보는 ks_module == "hme",
ks_instance == 0, ks_name == "hmec0" 로 정의되는 kstat에서 찾을 수 있다.

이 예에서는 ks_name을 만드는 module name과 instance name의 조합이 이 드라이버의
이름 명명 규칙이 된다. 다른 디바이스 드라이버들도 여러개의 kstat를 만들기 위해
비슷한 명명 규칙을 사용하지만 반드시 요구 되는 것은 아니다. 다만 이 세개의 조합
이 unique 해야 한다.

커널이 어떤 kstat를 제공하는지 어떻게 알 수 있을까? 솔라리스 8에서 가장 쉬운
방법은 아무 인자 없이 /usr/bin/kstat를 실행 해 보는 것이다. 이 명령은 현재의
거의 모든 kstat data를 출력 한다. 솔라리스 kstat명령어는 거의 모든 알려진
KSTAT_TYPE_RAW kstat를 출력한다.

1.6Functions#


다음의 함수들이 C 프로그래밍에서 kstat에 접근하기 위해 사용 가능 하다.

* kstat_ctl_t * kstat_open(void);
커널 통계 라이브러리에 접근 할 수있는 kstat control structure를 초기화 한다.
이 함수는 일련의 libkstat 함수안에 kc 인자로 들어가야 하는 control 구조체의
포인터를 돌려 준다.

* kstat_t * kstat_lookup(kstat_ctl_t *kc, char *ks_module, int ks_instance,
char *ks_name);
인자로 주어진 ks_module이나 ks_instance, ks_name을 찾기 위해 kstat chain을
훑는다. ks_module이 NULL이거나 ks_instance가 -1 혹은 ks_name이 NULL이라면
이 들은 무시된다. 예를 들면 kstat_lookup(kc, NULL, -1, "foo")는 단순하게
kstat chain 중 name이 "foo"인 것을 찾는다.

* void * kstat_data_lookup(kstat_t *ksp, char *name);
kstat data section에서 주어진 name으로 data record를 찾는다. 이 함수는 named
data record를 갖는 kstat type에서만 유효 하다. 현재는 KSTAT_TYPE_NAMED와
KSTAT_TYPE_TIMER만이 named data record를 갖는다. 커널로 부터 data를 얻기 위해
서는 먼저 kstat_read()를 호출 해야 한다. 그리고 나서 이 함수로 data section
에서 특정한 data record를 찾는다.

* kid_t kstat_read(kstat_ctl_t *kc, kstat_t *ksp, void *buf);
특정한 kstat의 data를 커널로 부터 얻기 위해 사용된다.

* kid_t kstat_write(kstat_ctl_t *kc, kstat_t *ksp, void *buf);
특정한 kstat에 data를 쓰기 위해 사용된다. superuser만이 사용가능

* kid_t kstat_chain_update(kstat_ctl_t *kc);
사용자의 kstat 복사본을 (kstat header) 커널과 동기화 한다.

* int kstat_close(kstat_ctl_t *kc);
kstat control 구조체와 관계된 모든 자원을 해체한다. exit(2)나 execve()를 하면
자동으로 수행 된다.


1.7Dealing with Chain Updates#


Data Structure Overview에서 언급 했듯이 kstat chain은 동적으로 변화한다.
libkstat 라이브러리의 kstat_open()은 커널의 kstat chain의 복사본을 돌려준다. 커
널의 kstat chain의 내용은 계속 바뀌므로 사용자 프로그램은 적당한 때에 사용자
프로그램의 kstat chain 복사본의 내용이 커널의 kstat chain과 같은지를 확인하기
위하여 kstat_chain_update()를 수행 해야 한다. 이 것이 kstat control 구조체의
kc_chain_id에 있는 KCID의 목적이다.

커널 모듈이 시스템의 chain에 kstat를 더하거나 제거 할 때마다 KCID는 증가한다.
사용자 프로그램이 kstat_chain_update()를 하면 이 함수는 사용자의 KCID와 커널의
KCID가 일치하는지 검사하고 일치하지 않는다면 kstat_chain_update()는 사용자 프로
그램의 kstat chain을 커널의 것과 일치 하도록 rebuild한 후 다음의 값을 돌려준다.

- 만약 chain이 update되었다면 새로운 KCID의 값
- 아무런 변화도 없다면 0
- error가 발생 하면 -1

만약 사용자 프로그램이 libkstat라이브러리의 이전 함수 호출에 의한 값들을 cache
하고 있었다면 새로운 KCID는 up-to-date된 정보를 갖고 있다는 flag로써 인식된다.
프로그램은 chain을 다시 한번 검색 해서 프로그램이 필요한 정보가 더해 졌는지
제거 되었는지 알 수 있다.

이러한 것의 실질적인 예를 시스템 명령어인 iostat이다. iostat는 시스템에 부착된
디스크에 대한 내부적인 정보를 cache하고 있다가 새롭게 디스크가 online 되었는지
offline 되었는지 인식 할 필요가 있다. iostat가 interval을 인자로 갖고 실행되면
iostat는 주어진 interval마다 I/O 통계를 출력한다.

1.8Putting It All Together#


당신의 C program은 다음을 포함 해야 한다.

#include

프로그램이 링킹 될 때에는 컴파일러 명령행은 -lkstat를 포함 해야 한다.

cc -o print_some_kstats -lkstat print_some_kstats.c

다음은 짧은 예제 프로그램이다. 우선 프로그램은 kstat_lookup()과 kstat_read()를
이용하여 시스템의 CPU 속도를 알아 낸다. 그리고 나서 무한 루프를 돌면서 모든
KSTAT_TYPE_IO인 kstat에 대한 얼마간의 정보를 출력한다. 루프의 첫 머리에 현재의
kstat chain이 current한지 알아보기 위해 kstat_chain_update()를 호출함을 주목하
라. 만약 kstat chain이 변화했다면 stderr를 통해 메세지를 출력 한다.

Example 9. Sample Program to Print kstats of Different Types

/*print_some_kstats.c:*  print out a couple of interesting things*/#include#include#include#define SLEEPTIME10voidmy_named_display(char*,char*, kstat_named_t *);voidmy_io_display(char*,char*, kstat_io_t);main(intargc,char**argv){     kstat_ctl_t   *kc;     kstat_t       *ksp;     kstat_io_t     kio;     kstat_named_t *knp;     kc = kstat_open();/** Print out the CPU speed. We make two assumptions here:* 1) All CPUs are the same speed, so we'll just search for the*    first one;* 2) At least one CPU is online, so our search will always*    find something. :)*/ksp = kstat_lookup(kc,"cpu_info", -1,NULL);     kstat_read(kc, ksp,NULL);/*lookup the CPU speed data record*/knp = kstat_data_lookup(ksp,"clock_MHz");     printf("CPU speed of system is ");     my_named_display(ksp->ks_name, ksp->ks_class, knp);     printf("\n");/*dump some info about all I/O kstats everySLEEPTIME seconds*/while(1) {/*make sure we have current data*/if(kstat_chain_update(kc))             fprintf(stderr,"<>\n");for(ksp = kc->kc_chain; ksp !=NULL; ksp = ksp->ks_next) {if(ksp->ks_type == KSTAT_TYPE_IO) {              kstat_read(kc, ksp, &kio);              my_io_display(ksp->ks_name, ksp->ks_class, kio);           }         }         sleep(SLEEPTIME);     }/*while(1)*/}voidmy_io_display(char*devname,char*class, kstat_io_t k){     printf("Name:%sClass:%s\n",devname,class);     printf("\tnumber of bytes read%lld\n", k.nread);     printf("\tnumber of bytes written%lld\n", k.nwritten);     printf("\tnumber of read operations%d\n", k.reads);     printf("\tnumber of write operations%d\n\n", k.writes);}voidmy_named_display(char*devname,char*class, kstat_named_t *knp){switch(knp->data_type) {caseKSTAT_DATA_CHAR:          printf("%.16s",knp->value.c);break;caseKSTAT_DATA_INT32:          printf("%"PRId32,knp->value.i32);break;caseKSTAT_DATA_UINT32:          printf("%"PRIu32,knp->value.ui32);break;caseKSTAT_DATA_INT64:          printf("%"PRId64,knp->value.i64);break;caseKSTAT_DATA_UINT64:          printf("%"PRIu64,knp->value.ui64);    }}

1.9Additional Information#


이 문서에 포함되어 있는 정보중 대다수는?SunSolve?InfoDoc, Solaris white paper,
Solaris man page(section 3 kstat)에서 빌려 왔다. API에 대한 자세한 정보를 알고
싶다면 the Solaris 8 Reference Manual Collection 과 Writing Device Drivers를
참조 하라. 이 문서들은 docs.sun.com에서 구할 수 있다.