9 int use_proc_diskstats
;
11 void pstat_init(struct pstat
*pst
, long nslice
, float update_interval
) {
13 ALLOC_VEC(pst
->slices
, nslice
);
16 pst
->update_interval
= update_interval
;
19 float pstat_current(struct pstat
*pst
) {
20 long idx
= pst
->cur_slice
? pst
->cur_slice
-1 : pst
->nslice
-1;
21 return pst
->slices
[idx
]/pst
->update_interval
;
24 void pstat_add(struct pstat
*pst
, unsigned long v
) {
25 pst
->slices
[pst
->cur_slice
] += v
;
28 void pstat_advance(struct pstat
*pst
) {
29 unsigned long v
= pst
->slices
[pst
->cur_slice
];
31 pst
->slices
[pst
->cur_slice
] -= pst
->total
;
32 else pst
->slices
[pst
->cur_slice
] = 0;
34 if (++pst
->cur_slice
>= pst
->nslice
) pst
->cur_slice
= 0;
35 pst
->slices
[pst
->cur_slice
] = 0;
38 float pstat_meanval(struct pstat
*pst
) {
39 unsigned long sum
= 0;
41 for (i
= 0; i
< pst
->nslice
; ++i
) sum
+= pst
->slices
[i
];
42 return sum
/ pst
->update_interval
/ (pst
->nslice
-1);
45 float get_read_throughput() {
46 return pstat_current(&ps
.disk_read
) / 2048.; /* 2048 because we log sector counts */
49 float get_write_throughput() {
50 return pstat_current(&ps
.disk_write
) / 2048.;
53 float get_swapin_throughput() {
54 return pstat_current(&ps
.swap_in
) / 2048.;
57 float get_swapout_throughput() {
58 return pstat_current(&ps
.swap_out
) / 2048.;
61 float get_read_mean_throughput() {
62 return pstat_meanval(&ps
.disk_read
) / 2048.;
65 float get_write_mean_throughput() {
66 return pstat_meanval(&ps
.disk_write
) / 2048.;
74 const char *proc_fname
;
75 if (!use_proc_diskstats
) proc_fname
= "/proc/partitions";
76 else proc_fname
= "/proc/diskstats";
78 f
= fopen(proc_fname
, "r");
79 if (!f
) { perror(proc_fname
); return; }
80 while (fgets(line
, sizeof(line
), f
)) {
83 const char *fmt
= use_proc_diskstats
?
84 "%d %d %200s %*d %*d %lu %*d %*d %*d %lu" :
85 "%d %d %*u %200s %*d %*d %lu %*d %*d %*d %lu";
86 if (sscanf(line
, fmt
, &major
, &minor
, hdname
, &nr
, &nw
) == 5 ||
87 (use_proc_diskstats
&& is_partition(major
,minor
) &&
88 /* .. kernel 2.5 uses a different format for partitions and disc */
89 sscanf(line
, "%d %d %200s %*d %lu %*d %lu", &major
, &minor
, hdname
, &nr
, &nw
) == 5)) {
91 if (readok
== 0) readok
= 1;
92 if ((dl
=find_dev(major
,minor
))) {
93 dl
->touched_r
= (dl
->nr
- nr
) ? 10 : dl
->touched_r
;
94 dl
->touched_w
= (dl
->nw
- nw
) ? 10 : dl
->touched_w
;
95 dl
->nr
= nr
; dl
->nw
= nw
;
96 if (is_displayed(dl
->hd_id
,dl
->part_id
) &&
97 ((dl
->part_id
&& (!find_id(dl
->hd_id
, 0) || !is_displayed(dl
->hd_id
, 0))) || /* partition without host disk */
98 (dl
->part_id
== 0))) /* disk */
100 if (!Prefs
.debug_disk_rd
) {
101 pstat_add(&ps
.disk_read
, nr
);
103 static long cntr
= 0; cntr
+=(rand()%30) == 0 ? Prefs
.debug_disk_rd
: 0;
104 pstat_add(&ps
.disk_read
, nr
+ cntr
);
106 if (!Prefs
.debug_disk_wr
) {
107 pstat_add(&ps
.disk_write
, nw
);
109 static long cntw
= 0; cntw
+=(rand()%30) == 0 ? Prefs
.debug_disk_wr
: 0;
110 pstat_add(&ps
.disk_write
, nw
+ cntw
);
115 /* if (in_our_disk || find_dev(major,minor))*/ {
117 for (sl
= swap_list(); sl
; sl
=sl
->next
) {
118 if (strcmp(stripdev(hdname
), stripdev(sl
->s
)) == 0) {
119 if (!Prefs
.debug_swapio
) {
120 pstat_add(&ps
.swap_in
, nr
);
121 pstat_add(&ps
.swap_out
, nw
);
123 static long cnt
= 0; cnt
+=Prefs
.debug_swapio
;
124 pstat_add(&ps
.swap_in
, nr
+ cnt
);
125 pstat_add(&ps
.swap_out
, nw
+ cnt
);
133 pstat_advance(&ps
.disk_read
);pstat_advance(&ps
.disk_write
);
134 pstat_advance(&ps
.swap_in
);pstat_advance(&ps
.swap_out
);
135 if (readok
== 0) { fprintf(stderr
, "warning: could not find any info in %s (kernel too old?)\n", proc_fname
); exit(1); }
136 else if (readok
== 1) { ONLY_ONCE(fprintf(stderr
, "warning: could not find any monitored disc in %s\n", proc_fname
)); }
137 BLAHBLAH(1,printf("swap: %5.2f,%5.2f disc: %5.2f,%5.2f MB/s\n",
138 get_swapin_throughput(), get_swapout_throughput(),
139 get_read_throughput(), get_write_throughput()));
142 void init_stats(float update_interval
) {
146 pstat_init(&ps
.swap_in
, (long)(0.5/update_interval
)+1, update_interval
);
147 pstat_init(&ps
.swap_out
, (long)(0.5/update_interval
)+1, update_interval
);
148 pstat_init(&ps
.disk_read
, (long)(0.5/update_interval
)+1, update_interval
);
149 pstat_init(&ps
.disk_write
, (long)(0.5/update_interval
)+1, update_interval
);
150 f
= fopen("/proc/swaps","r");
151 //if (!f) { perror("/proc/swaps"); exit(1); }
153 while (fgets(s
, 512, f
)) {
154 char *s2
= strchr(s
,' ');
155 if (s2
&& s2
!= s
&& strncmp(s
, "/dev/", 5) == 0) {
158 BLAHBLAH(1,printf("found swap partition: %s\n", swap_list()->s
));
164 fprintf(stderr
, "Warning: no swap partition found in /proc/swaps !!\n");
166 if ((f
=fopen("/proc/diskstats","r"))) {
167 use_proc_diskstats
= 1; fclose(f
);
169 else { use_proc_diskstats
= 0; }
170 BLAHBLAH(1,printf("using %s for disc statistics\n", use_proc_diskstats
? "/proc/diskstats" : "/proc/partitions"));
175 /* hello I am brain-dead */
176 void scan_all_hd(int add_partitions
) {
179 /* find mounted partitions */
180 if (add_partitions
&& (f
= fopen("/etc/mtab","r"))) {
181 while (fgets(s
,512,f
)) {
182 char partname
[512], mountpoint
[512];
184 if (sscanf(s
,"%500s %500s", partname
, mountpoint
)>=1) {
185 char *p
= strchr(mountpoint
, '/');
186 //printf("add_device_by_name(%s, %s)\n", partname, p);
187 add_device_by_name(partname
, p
);
193 /* second try .. look for hard drives listed in proc/partitions (and only hard-drives .. their partitions
194 are supposed to be listed in mtab) */
195 if ((f
= fopen("/proc/partitions","r"))) {
196 while (fgets(s
,512,f
)) {
197 unsigned major
, minor
;
198 char name
[512]; name
[0] = 0;
199 if (sscanf(s
,"%d %d %*d %500s", &major
, &minor
, name
)==3) {
201 /* on n'ajoute que les disques dont au moins une partoche etait dans mtab */
202 if (device_info(major
,minor
,NULL
,&hd_id
,&part_id
) != 0 && part_id
== 0 && find_id(hd_id
,-1)) {
203 add_device_by_id(major
,minor
,NULL
);
210 /* for (c = 'a'; c <= 'z'; ++c) {
211 snprintf(s,512,"/proc/ide/hd%c/media",c);
212 if ((f = fopen(s,"r")) && fgets(s, 512, f) && strcmp(s, "disk\n")==0) {
213 snprintf(s, 512, "/dev/hd%c",c);