그전에 포스팅한 내용은 /proc/stat과 /proc/meminfo 를 이용하여 CPU 사용률 과 메모리 사용률을 구하였다.
이번에는 sysinfo() 함수를 이용하여 proc 파일 시스템을 만들어본다.
(본 내용은 짧은 영어 실력으로 번역하여 이해한 것으로 틀린 부분이 있으면 지적 부탁드립니다)
sysinfo 함수는 유저 영역에서 동작하는 함수로 proc 파일 시스템으로 동작하기 위해서는 부적합하다고 보인다.
하지만 proc 파일 시스템으로 만들면 좀 더 있어 보인다(?)는 이유로 강행하게 되었다.
sysinfo의 설명을 살펴보면 다음과 같다.
NAMEsysinfo - returns information on overall system statisticsSYNOPSIS#include <sys/sysinfo.h>int sysinfo(struct sysinfo *info); DESCRIPTIONUntil Linux 2.3.16,sysinfoused to return information in the following structure:
|
loads[3]을 살펴보면 1분, 5분 15분간 평균적인 load를 나타낸다고 되어 있다. 이 수치는 /proc/stat과 다르게 평균적으로 로딩되어진 프로세스들의 갯수를 뜻한다. 그리고 하나의 단점은 멀티코어 프로세서에는 normalize 되지 않았다고 한다. load average 가 1 인경우에는 싱글프로세서 인경우 CPU사용률 100% 인것이고, 쿼드 코어인경우에는 25% 이라고 한다.(자세한것은 man 쳐보세요~)
어째든 이러한 정보를 토대로 코딩을 한 내용이다( 주석으로 설명을 대신하겠습니다)
1 #include <linux/init.h>
2 #include <linux/kernel.h>
3 #include <linux/proc_fs.h>
4 #include <asm/uaccess.h>
5
6 typedef struct sysinfo sysInfo_t;
7 struct proc_dir_entry *sysinfo_entry;
8
9 static int read_sysinfo(char *page, char **start, off_t off,
10 int count, int *eof, void *data) // cat /proc/sysinfo 라고 쳤을때 실행되는 함수(proc 파일 시스템 read 함수)
11 {
12 int len;
13 unsigned int cpuUsage, memUsage;
14 sysInfo_t getSysInfo;
15 mm_segment_t old_fs = get_fs(); // 지금 현재영역 데이터 세그먼트 영역 저장
16 set_fs(KERNEL_DS); //커널 데이터 세그먼트로 변경
17 sys_sysinfo(&getSysInfo); // sysinfo 함수 호출(해당 함수는 시스템 영역에서 호출된는 함수 - User영역은 sysinfo())
18 set_fs(old_fs);
19 cpuUsage = (getSysInfo.loads[0]*100)/(60*HZ); //CPU 사용율을 구한다.
20 memUsage = ((getSysInfo.totalram - getSysInfo.freeram)*100) / getSysInfo.totalram; //메모리 사용률을 구한다
21
22 len = sprintf(page, " CPU Usage : %d %% \n Memory Usage : %d %%\n", cpuU sage, memUsage); // 화면에 출력
23
24 if (len <= off+count)
25 *eof = 1;
26 *start = page + off;
27 len -= off;
28 if (len > count)
29 len = count;
30 if (len < 0)
31 len = 0;
32
33 return len;
34
35 }
36
37
38
39 int __init sysinfo_probe(void) // 모듈 시작 뿐
40 {
41
42 sysinfo_entry = create_proc_read_entry("sysinfo", 0644, NULL, read_sysinfo, NULL); //proc 파일 시스템을 만든다
43 if(sysinfo_entry)
44 printk(KERN_INFO "Proc entry for driv successfully created");
45
46
47 return 0;
48 }
49
50 static void __exit sysinfo_exit(void) // 모듈 종료 함수(해당 모듈을 unload 시)
51 {
52 // Remove the /proc entry
53 remove_proc_entry("sysinfo", NULL);
54
55 return;
56 }
57 module_init(sysinfo_probe);
58 module_exit(sysinfo_exit);
2 #include <linux/kernel.h>
3 #include <linux/proc_fs.h>
4 #include <asm/uaccess.h>
5
6 typedef struct sysinfo sysInfo_t;
7 struct proc_dir_entry *sysinfo_entry;
8
9 static int read_sysinfo(char *page, char **start, off_t off,
10 int count, int *eof, void *data) // cat /proc/sysinfo 라고 쳤을때 실행되는 함수(proc 파일 시스템 read 함수)
11 {
12 int len;
13 unsigned int cpuUsage, memUsage;
14 sysInfo_t getSysInfo;
15 mm_segment_t old_fs = get_fs(); // 지금 현재영역 데이터 세그먼트 영역 저장
16 set_fs(KERNEL_DS); //커널 데이터 세그먼트로 변경
17 sys_sysinfo(&getSysInfo); // sysinfo 함수 호출(해당 함수는 시스템 영역에서 호출된는 함수 - User영역은 sysinfo())
18 set_fs(old_fs);
19 cpuUsage = (getSysInfo.loads[0]*100)/(60*HZ); //CPU 사용율을 구한다.
20 memUsage = ((getSysInfo.totalram - getSysInfo.freeram)*100) / getSysInfo.totalram; //메모리 사용률을 구한다
21
22 len = sprintf(page, " CPU Usage : %d %% \n Memory Usage : %d %%\n", cpuU sage, memUsage); // 화면에 출력
23
24 if (len <= off+count)
25 *eof = 1;
26 *start = page + off;
27 len -= off;
28 if (len > count)
29 len = count;
30 if (len < 0)
31 len = 0;
32
33 return len;
34
35 }
36
37
38
39 int __init sysinfo_probe(void) // 모듈 시작 뿐
40 {
41
42 sysinfo_entry = create_proc_read_entry("sysinfo", 0644, NULL, read_sysinfo, NULL); //proc 파일 시스템을 만든다
43 if(sysinfo_entry)
44 printk(KERN_INFO "Proc entry for driv successfully created");
45
46
47 return 0;
48 }
49
50 static void __exit sysinfo_exit(void) // 모듈 종료 함수(해당 모듈을 unload 시)
51 {
52 // Remove the /proc entry
53 remove_proc_entry("sysinfo", NULL);
54
55 return;
56 }
57 module_init(sysinfo_probe);
58 module_exit(sysinfo_exit);
어떻게 보면 너무 간단하다..