]> git.ipfire.org Git - thirdparty/util-linux.git/blob - sys-utils/cytune.c
Imported from util-linux-2.7.1 tarball.
[thirdparty/util-linux.git] / sys-utils / cytune.c
1 /* cytune.c -- Tune Cyclades driver
2 *
3 * Copyright 1995 Nick Simicich (njs@scifi.emi.net)
4 *
5 * Modifications by Rik Faith (faith@cs.unc.edu)
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the Nick Simicich
18 * 4. Neither the name of the Nick Simicich nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY NICK SIMICICH AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL NICK SIMICICH OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 */
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <sys/types.h>
39 #include <sys/time.h>
40 #include <sys/ioctl.h>
41 #include <unistd.h>
42 #include <string.h>
43 #include <fcntl.h>
44 #include <errno.h>
45 #include <linux/tty.h>
46 #include <termios.h>
47 #include <linux/tqueue.h>
48 #include <linux/cyclades.h>
49 #include <signal.h>
50
51 #if 0
52 #ifndef XMIT
53 # include <linux/version.h>
54 # if LINUX_VERSION_CODE > 66056
55 # define XMIT
56 # endif
57 #endif
58 #endif
59 /* Until it gets put in the kernel,
60 toggle by hand. */
61 #undef XMIT
62
63 struct cyclades_control {
64 struct cyclades_monitor c;
65 int cfile;
66 int maxmax;
67 double maxtran;
68 double maxxmit;
69 unsigned long threshold_value;
70 unsigned long timeout_value;
71 };
72 struct cyclades_control *cmon;
73 int cmon_index;
74
75 #define mvtime(tvpto, tvpfrom) (((tvpto)->tv_sec = (tvpfrom)->tv_sec),(tvpto)->tv_usec = (tvpfrom)->tv_usec)
76
77
78 inline double dtime(struct timeval * tvpnew, struct timeval * tvpold) {
79 double diff;
80 diff = (double)tvpnew->tv_sec - (double)tvpold->tv_sec;
81 diff += ((double)tvpnew->tv_usec - (double)tvpold->tv_usec)/1000000;
82 return diff;
83 }
84
85 static int global_argc, global_optind;
86 static char ***global_argv;
87
88 void summary(int signal) {
89 struct cyclades_control *cc;
90
91 int argc, optind;
92 char **argv;
93
94 int i,j;
95
96 argc = global_argc;
97 argv = *global_argv;
98 optind = global_optind;
99
100 if (signal > 0) {
101 for(i = optind; i < argc; i ++) {
102 j = i - optind;
103 cc = &cmon[cmon_index];
104 fprintf(stderr, "File %s, For threshold value %lu, Maximum characters "
105 "in fifo were %d,\nand the maximum transfer rate in "
106 "characters/second was %f\n",
107 argv[i],
108 cc->threshold_value,
109 cc->maxmax,
110 cc->maxtran);
111 }
112
113 exit(0);
114 }
115 cc = &cmon[cmon_index];
116 if (cc->threshold_value > 0 && signal != -1) {
117 fprintf(stderr, "File %s, For threshold value %lu and timrout value %lu,"
118 " Maximum characters "
119 "in fifo were %d,\nand the maximum transfer rate in "
120 "characters/second was %f\n",
121 argv[cmon_index+optind],
122 cc->threshold_value,
123 cc->timeout_value,
124 cc->maxmax,
125 cc->maxtran);
126 }
127 cc->maxmax = 0;
128 cc->maxtran = 0.0;
129 cc->threshold_value = 0;
130 cc->timeout_value = 0;
131 }
132
133 static int query = 0;
134 static int interval = 1;
135
136 static int set = 0;
137 static int set_val = -1;
138 static int get = 0;
139
140 static int set_def = 0;
141 static int set_def_val = -1;
142 static int get_def = 0;
143
144 static int set_time = 0;
145 static int set_time_val = -1;
146
147 static int set_def_time = 0;
148 static int set_def_time_val = -1;
149
150
151 int main(int argc, char *argv[]) {
152
153 struct timeval lasttime, thistime;
154 struct timezone tz = {0,0};
155 double diff;
156 int errflg = 0;
157 int file;
158 int numfiles;
159 struct cyclades_monitor cywork;
160
161 int i;
162 extern char *optarg;
163 extern int optind;
164 unsigned long threshold_value;
165 unsigned long timeout_value;
166 double xfer_rate;
167 #ifdef XMIT
168 double xmit_rate;
169 #endif
170
171 global_argc = argc; /* For signal routine. */
172 global_argv = &argv; /* For signal routine. */
173
174 while (EOF != (i = getopt(argc, argv,
175 "qs:S:t:T:gGi:"))) {
176 switch (i) {
177 case 'q':
178 query = 1;
179 break;
180 case 'i':
181 interval = atoi(optarg);
182 if(interval <= 0) {
183 fprintf(stderr, "Invalid interval value: %s\n",optarg);
184 errflg ++;
185 }
186 break;
187 case 's':
188 ++set;
189 set_val = atoi(optarg);
190 if(set_val <= 0 || set_val > 12) {
191 fprintf(stderr, "Invalid set value: %s\n",optarg);
192 errflg ++;
193 }
194 break;
195 case 'S':
196 ++set_def;
197 set_def_val = atoi(optarg);
198 if(set_def_val < 0 || set_def_val > 12) {
199 fprintf(stderr, "Invalid default value: %s\n",optarg);
200 errflg ++;
201 }
202 break;
203 case 't':
204 ++set_time;
205 set_time_val = atoi(optarg);
206 if(set_time_val <= 0 || set_time_val > 255) {
207 fprintf(stderr, "Invalid set time value: %s\n",optarg);
208 errflg ++;
209 }
210 break;
211 case 'T':
212 ++set_def_time;
213 set_def_time_val = atoi(optarg);
214 if(set_def_time_val < 0 || set_def_time_val > 255) {
215 fprintf(stderr, "Invalid default time value: %s\n",optarg);
216 errflg ++;
217 }
218 break;
219 case 'g': ++get; break;
220 case 'G': ++get_def; break;
221 default:
222 errflg ++;
223 }
224 }
225 numfiles = argc - optind;
226 if(errflg || (numfiles == 0)
227 || (!query && !set && !set_def &&
228 !get && !get_def && !set_time && !set_def_time) ||
229 (set && set_def) || (set_time && set_def_time) ||
230 (get && get_def)) {
231 fprintf(stderr,
232 "Usage: %s [-q [-i interval]]"
233 " ([-s value]|[-S value]) ([-t value]|[-T value])"
234 " [-g|-G] file [file...]\n",
235 argv[0]);
236 exit(1);
237 }
238
239 global_optind = optind; /* For signal routine. */
240
241 if (set || set_def) {
242 for(i = optind;i < argc;i ++) {
243 file = open(argv[i],O_RDONLY);
244 if(file == -1) {
245 fprintf(stderr, "Can't open %s: %s\n",argv[i],strerror(errno));
246 exit(1);
247 }
248 if(ioctl(file,
249 set ? CYSETTHRESH : CYSETDEFTHRESH,
250 set ? set_val : set_def_val)) {
251 fprintf(stderr, "Can't set %s to threshold %d: %s\n",
252 argv[i],set?set_val:set_def_val,strerror(errno));
253 exit(1);
254 }
255 }
256 }
257 if (set_time || set_def_time) {
258 for(i = optind;i < argc;i ++) {
259 file = open(argv[i],O_RDONLY);
260 if(file == -1) {
261 fprintf(stderr, "Can't open %s: %s\n",argv[i],strerror(errno));
262 exit(1);
263 }
264 if(ioctl(file,
265 set_time ? CYSETTIMEOUT : CYSETDEFTIMEOUT,
266 set_time ? set_time_val : set_def_time_val)) {
267 fprintf(stderr, "Can't set %s to time threshold %d: %s\n",
268 argv[i],set_time?set_time_val:set_def_time_val,strerror(errno));
269 exit(1);
270 }
271 }
272 }
273
274 if (get || get_def) {
275 for(i = optind;i < argc;i ++) {
276 file = open(argv[i],O_RDONLY);
277 if(file == -1) {
278 fprintf(stderr, "Can't open %s: %s\n",argv[i],strerror(errno));
279 exit(1);
280 }
281 if(ioctl(file, get ? CYGETTHRESH : CYGETDEFTHRESH, &threshold_value)) {
282 fprintf(stderr, "Can't get threshold for %s: %s\n",
283 argv[i],strerror(errno));
284 exit(1);
285 }
286 if(ioctl(file, get ? CYGETTIMEOUT : CYGETDEFTIMEOUT, &timeout_value)) {
287 fprintf(stderr, "Can't get timeout for %s: %s\n",
288 argv[i],strerror(errno));
289 exit(1);
290 }
291 printf("%s: %ld %s threshold and %ld %s timeout\n",
292 argv[i], threshold_value,
293 get?"current":"default",
294 timeout_value,
295 get?"current":"default");
296 }
297 }
298
299 if(!query) return 0; /* must have been something earlier */
300
301 /* query stuff after this line */
302
303 cmon = (struct cyclades_control *) malloc(sizeof (struct cyclades_control)
304 * numfiles);
305 if(!cmon) {
306 perror("malloc failed");
307 exit(1);
308 }
309 if(signal(SIGINT, summary)||
310 signal(SIGQUIT, summary)||
311 signal(SIGTERM, summary)) {
312 perror("Can't set signal handler");
313 exit(1);
314 }
315 if(gettimeofday(&lasttime,&tz)) {
316 perror("gettimeofday failed");
317 exit(1);
318 }
319 for(i = optind; i < argc; i ++) {
320 cmon_index = i - optind;
321 cmon[cmon_index].cfile = open(argv[i], O_RDONLY);
322 if(-1 == cmon[cmon_index].cfile) {
323 fprintf(stderr, "Can't open %s: %s\n",argv[i],strerror(errno));
324 exit(1);
325 }
326 if(ioctl(cmon[cmon_index].cfile, CYGETMON, &cmon[cmon_index].c)) {
327 fprintf(stderr, "Can't issue CYGETMON on %s: %s\n",
328 argv[i],strerror(errno));
329 exit(1);
330 }
331 summary(-1);
332 if(ioctl(cmon[cmon_index].cfile, CYGETTHRESH, &threshold_value)) {
333 fprintf(stderr, "Can't get threshold for %s: %s\n",
334 argv[i],strerror(errno));
335 exit(1);
336 }
337 if(ioctl(cmon[cmon_index].cfile, CYGETTIMEOUT, &timeout_value)) {
338 fprintf(stderr, "Can't get timeout for %s: %s\n",
339 argv[i],strerror(errno));
340 exit(1);
341 }
342 }
343 while(1) {
344 sleep(interval);
345
346 if(gettimeofday(&thistime,&tz)) {
347 perror("gettimeofday failed");
348 exit(1);
349 }
350 diff = dtime(&thistime, &lasttime);
351 mvtime(&lasttime, &thistime);
352
353 for(i = optind; i < argc; i ++) {
354 cmon_index = i - optind;
355 if(ioctl(cmon[cmon_index].cfile, CYGETMON, &cywork)) {
356 fprintf(stderr, "Can't issue CYGETMON on %s: %s\n",
357 argv[i],strerror(errno));
358 exit(1);
359 }
360 if(ioctl(cmon[cmon_index].cfile, CYGETTHRESH, &threshold_value)) {
361 fprintf(stderr, "Can't get threshold for %s: %s\n",
362 argv[i],strerror(errno));
363 exit(1);
364 }
365 if(ioctl(cmon[cmon_index].cfile, CYGETTIMEOUT, &timeout_value)) {
366 fprintf(stderr, "Can't get timeout for %s: %s\n",
367 argv[i],strerror(errno));
368 exit(1);
369 }
370
371 xfer_rate = cywork.char_count/diff;
372 #ifdef XMIT
373 xmit_rate = cywork.send_count/diff;
374 #endif
375
376 if(threshold_value != cmon[cmon_index].threshold_value ||
377 timeout_value != cmon[cmon_index].timeout_value) {
378 summary(-2);
379 /* Note that the summary must come before the setting of */
380 /* threshold_value */
381 cmon[cmon_index].threshold_value = threshold_value;
382 cmon[cmon_index].timeout_value = timeout_value;
383 } else {
384 /* Don't record this first cycle after change */
385 if(xfer_rate > cmon[cmon_index].maxtran)
386 cmon[cmon_index].maxtran = xfer_rate;
387 #ifdef XMIT
388 if(xmit_rate > cmon[cmon_index].maxxmit)
389 cmon[cmon_index].maxxmit = xmit_rate;
390 #endif
391 if(cywork.char_max > cmon[cmon_index].maxmax)
392 cmon[cmon_index].maxmax = cywork.char_max;
393 }
394
395 #ifdef XMIT
396 printf("%s: %lu ints, %lu/%lu chars; "
397 "fifo: %lu thresh, %lu tmout, "
398 "%lu max, %lu now\n",
399 argv[i],
400 cywork.int_count,cywork.char_count,cywork.send_count,
401 threshold_value,timeout_value,
402 cywork.char_max,cywork.char_last);
403 printf(" %f int/sec; %f rec, %f send (char/sec)\n",
404 cywork.int_count/diff,
405 xfer_rate,
406 xmit_rate);
407 #else
408 printf("%s: %lu ints, %lu chars; "
409 "fifo: %lu thresh, %lu tmout, "
410 "%lu max, %lu now\n",
411 argv[i],
412 cywork.int_count,cywork.char_count,
413 threshold_value,timeout_value,
414 cywork.char_max,cywork.char_last);
415 printf(" %f int/sec; %f rec (char/sec)\n",
416 cywork.int_count/diff,
417 xfer_rate);
418 #endif
419 memcpy(&cmon[cmon_index].c, &cywork, sizeof (struct cyclades_monitor));
420 }
421 }
422
423 return 0;
424 }