Introduction
Introduction Statistics Contact Development Disclaimer Help
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);
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.