slstatus-diskio-4bd78c9.patch - sites - public wiki contents of suckless.org | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
Refs | |
--- | |
slstatus-diskio-4bd78c9.patch (5402B) | |
--- | |
1 Author: K. Eugene Carlson <[email protected]> | |
2 Date: Fri Sep 3 01:09:02 2021 +0900 | |
3 | |
4 Get disk IO stats on Linux (read, write, %) | |
5 | |
6 This patch lets slstatus report on disk IO on Linux systems: reads | |
7 from disk, writes to disk and IO percentage. | |
8 | |
9 diff --git a/Makefile b/Makefile | |
10 index 3be46cc..1ecc8db 100644 | |
11 --- a/Makefile | |
12 +++ b/Makefile | |
13 @@ -12,6 +12,7 @@ COM =\ | |
14 components/disk\ | |
15 components/entropy\ | |
16 components/hostname\ | |
17 + components/iocheck\ | |
18 components/ip\ | |
19 components/kernel_release\ | |
20 components/keyboard_indicators\ | |
21 diff --git a/README b/README | |
22 index 4da0756..1a64914 100644 | |
23 --- a/README | |
24 +++ b/README | |
25 @@ -15,6 +15,7 @@ Features | |
26 - Available entropy | |
27 - Username/GID/UID | |
28 - Hostname | |
29 +- Disk IO (read, write and percentage) (Linux only) | |
30 - IP address (IPv4 and IPv6) | |
31 - Kernel version | |
32 - Keyboard indicators | |
33 diff --git a/components/iocheck.c b/components/iocheck.c | |
34 new file mode 100644 | |
35 index 0000000..7fa102d | |
36 --- /dev/null | |
37 +++ b/components/iocheck.c | |
38 @@ -0,0 +1,170 @@ | |
39 +/* See LICENSE file for copyright and license details. */ | |
40 +#include <stdio.h> | |
41 +#include <string.h> | |
42 +#include <stdint.h> | |
43 +#include <stdlib.h> | |
44 +#include <dirent.h> | |
45 +#include <unistd.h> | |
46 + | |
47 +#include "../util.h" | |
48 + | |
49 +#if defined(__linux__) | |
50 + static int | |
51 + get_io(uintmax_t *s_in, uintmax_t *s_out) | |
52 + { | |
53 + FILE *fp; | |
54 + struct { | |
55 + const char *name; | |
56 + const size_t len; | |
57 + uintmax_t *var; | |
58 + } ent[] = { | |
59 + { "pgpgin", sizeof("pgpgin") - 1, s_in }, | |
60 + { "pgpgout", sizeof("pgpgout") - 1, s_out }, | |
61 + }; | |
62 + size_t line_len = 0, i, left; | |
63 + char *line = NULL; | |
64 + | |
65 + /* get number of fields we want to extract */ | |
66 + for (i = 0, left = 0; i < LEN(ent); i++) { | |
67 + if (ent[i].var) { | |
68 + left++; | |
69 + } | |
70 + } | |
71 + | |
72 + if (!(fp = fopen("/proc/vmstat", "r"))) { | |
73 + warn("fopen '/proc/vmstat':"); | |
74 + return 1; | |
75 + } | |
76 + | |
77 + /* read file line by line and extract field information… | |
78 + while (left > 0 && getline(&line, &line_len, fp) >= 0) { | |
79 + for (i = 0; i < LEN(ent); i++) { | |
80 + if (ent[i].var && | |
81 + !strncmp(line,ent[i].name, ent[i].len))… | |
82 + sscanf(line + ent[i].len + 1, | |
83 + "%ju\n", ent[i].var); | |
84 + left--; | |
85 + break; | |
86 + } | |
87 + } | |
88 + } | |
89 + free(line); | |
90 + if(ferror(fp)) { | |
91 + warn("getline '/proc/vmstat':"); | |
92 + return 1; | |
93 + } | |
94 + | |
95 + fclose(fp); | |
96 + return 0; | |
97 + } | |
98 + | |
99 + const char * | |
100 + io_in(void) | |
101 + { | |
102 + uintmax_t oldin; | |
103 + static uintmax_t newin; | |
104 + | |
105 + oldin = newin; | |
106 + | |
107 + if (get_io(&newin, NULL)) { | |
108 + return NULL; | |
109 + } | |
110 + if (oldin == 0) { | |
111 + return NULL; | |
112 + } | |
113 + | |
114 + return fmt_human((newin-oldin) * 1024, 1024); | |
115 + } | |
116 + | |
117 + const char * | |
118 + io_out(void) | |
119 + { | |
120 + uintmax_t oldout; | |
121 + static uintmax_t newout; | |
122 + | |
123 + oldout = newout; | |
124 + | |
125 + if (get_io(NULL, &newout)) { | |
126 + return NULL; | |
127 + } | |
128 + if (oldout == 0) { | |
129 + return NULL; | |
130 + } | |
131 + | |
132 + return fmt_human((newout - oldout) * 1024, 1024); | |
133 + } | |
134 + | |
135 + const char * | |
136 + io_perc(void) | |
137 + { | |
138 + struct dirent *dp; | |
139 + DIR *bd; | |
140 + uintmax_t oldwait; | |
141 + static uintmax_t newwait; | |
142 + extern const unsigned int interval; | |
143 + | |
144 + oldwait = newwait; | |
145 + | |
146 + if (!(bd = opendir("/sys/block"))) { | |
147 + warn("opendir '%s':", "/sys/block"); | |
148 + return NULL; | |
149 + } | |
150 + | |
151 + newwait = 0; | |
152 + /* get IO wait stats from the /sys/block directories */ | |
153 + while ((dp = readdir(bd))) { | |
154 + if (strstr(dp->d_name, "loop") || | |
155 + strstr(dp->d_name, "ram")) { | |
156 + continue; | |
157 + } | |
158 + if (!strcmp(dp->d_name, ".") || | |
159 + !strcmp(dp->d_name, "..")) { | |
160 + continue; | |
161 + } | |
162 + /* virtual devices don't count */ | |
163 + char virtpath[50]; | |
164 + strcpy(virtpath, "/sys/devices/virtual/block/"); | |
165 + strcat(virtpath, dp->d_name); | |
166 + if (access(virtpath, R_OK) == 0) { | |
167 + continue; | |
168 + } | |
169 + char statpath[34]; | |
170 + strcpy(statpath, "/sys/block/"); | |
171 + strcat(statpath, dp->d_name); | |
172 + strcat(statpath, "/stat"); | |
173 + uintmax_t partwait; | |
174 + if (pscanf(statpath, | |
175 + "%*d %*d %*d %*d %*d %*d %*d %*d %*d %j… | |
176 + &partwait) != 1) { | |
177 + continue; | |
178 + } | |
179 + newwait += partwait; | |
180 + } | |
181 + closedir(bd); | |
182 + if (oldwait == 0 || newwait < oldwait) { | |
183 + return NULL; | |
184 + } | |
185 + | |
186 + return bprintf("%0.1f", 100 * | |
187 + (newwait - oldwait) / (float)interval); | |
188 + } | |
189 + | |
190 +#else | |
191 + const char * | |
192 + io_in(void) | |
193 + { | |
194 + return NULL; | |
195 + } | |
196 + | |
197 + const char * | |
198 + io_out(void) | |
199 + { | |
200 + return NULL; | |
201 + } | |
202 + | |
203 + const char * | |
204 + io_perc(void) | |
205 + { | |
206 + return NULL; | |
207 + } | |
208 +#endif | |
209 diff --git a/config.def.h b/config.def.h | |
210 index 5f6c114..4d49881 100644 | |
211 --- a/config.def.h | |
212 +++ b/config.def.h | |
213 @@ -28,6 +28,9 @@ static const char unknown_str[] = "n/a"; | |
214 * entropy available entropy NULL | |
215 * gid GID of current user NULL | |
216 * hostname hostname NULL | |
217 + * io_in disk IO (read) NULL | |
218 + * io_out disk IO (write) NULL | |
219 + * io_perc disk IO (percentage) NULL | |
220 * ipv4 IPv4 address interface name (… | |
221 * ipv6 IPv6 address interface name (… | |
222 * kernel_release `uname -r` NULL | |
223 diff --git a/slstatus.h b/slstatus.h | |
224 index f3b4979..8b14b75 100644 | |
225 --- a/slstatus.h | |
226 +++ b/slstatus.h | |
227 @@ -24,6 +24,11 @@ const char *entropy(const char *unused); | |
228 /* hostname */ | |
229 const char *hostname(const char *unused); | |
230 | |
231 +/* iocheck */ | |
232 +const char *io_in(void); | |
233 +const char *io_out(void); | |
234 +const char *io_perc(void); | |
235 + | |
236 /* ip */ | |
237 const char *ipv4(const char *interface); | |
238 const char *ipv6(const char *interface); |