1 1.3 peter /* $NetBSD: qdisc_jobs.c,v 1.3 2006/10/28 11:43:02 peter Exp $ */ 2 1.2 peter /* $KAME: qdisc_jobs.c,v 1.2 2002/10/27 03:19:36 kjc Exp $ */ 3 1.2 peter /* 4 1.2 peter * Copyright (c) 2001-2002, by the Rector and Board of Visitors of the 5 1.2 peter * University of Virginia. 6 1.2 peter * All rights reserved. 7 1.2 peter * 8 1.2 peter * Redistribution and use in source and binary forms, 9 1.2 peter * with or without modification, are permitted provided 10 1.2 peter * that the following conditions are met: 11 1.2 peter * 12 1.2 peter * Redistributions of source code must retain the above 13 1.2 peter * copyright notice, this list of conditions and the following 14 1.2 peter * disclaimer. 15 1.2 peter * 16 1.2 peter * Redistributions in binary form must reproduce the above 17 1.2 peter * copyright notice, this list of conditions and the following 18 1.2 peter * disclaimer in the documentation and/or other materials provided 19 1.2 peter * with the distribution. 20 1.2 peter * 21 1.2 peter * Neither the name of the University of Virginia nor the names 22 1.2 peter * of its contributors may be used to endorse or promote products 23 1.2 peter * derived from this software without specific prior written 24 1.2 peter * permission. 25 1.2 peter * 26 1.2 peter * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 27 1.2 peter * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 28 1.2 peter * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 29 1.2 peter * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 30 1.2 peter * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE 31 1.2 peter * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 32 1.2 peter * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 33 1.2 peter * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34 1.2 peter * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 35 1.2 peter * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 1.2 peter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 37 1.2 peter * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 38 1.2 peter * THE POSSIBILITY OF SUCH DAMAGE. 39 1.2 peter */ 40 1.2 peter /* 41 1.2 peter * JoBS - altq prototype implementation 42 1.2 peter * 43 1.2 peter * Author: Nicolas Christin <nicolas (at) cs.virginia.edu> 44 1.2 peter * 45 1.2 peter * JoBS algorithms originally devised and proposed by 46 1.2 peter * Nicolas Christin and Jorg Liebeherr. 47 1.2 peter * Grateful Acknowledgments to Tarek Abdelzaher for his help and 48 1.2 peter * comments, and to Kenjiro Cho for some helpful advice. 49 1.2 peter * Contributed by the Multimedia Networks Group at the University 50 1.2 peter * of Virginia. 51 1.2 peter * 52 1.2 peter * http://qosbox.cs.virginia.edu 53 1.2 peter * 54 1.2 peter */ 55 1.2 peter 56 1.2 peter #include <sys/param.h> 57 1.2 peter #include <sys/ioctl.h> 58 1.2 peter #include <sys/time.h> 59 1.2 peter #include <sys/socket.h> 60 1.2 peter #include <net/if.h> 61 1.2 peter #include <netinet/in.h> 62 1.2 peter #include <altq/altq.h> 63 1.2 peter #include <altq/altq_jobs.h> 64 1.2 peter 65 1.2 peter #include <stdio.h> 66 1.2 peter #include <stdlib.h> 67 1.2 peter #include <unistd.h> 68 1.2 peter #include <string.h> 69 1.2 peter #include <signal.h> 70 1.2 peter #include <math.h> 71 1.2 peter #include <errno.h> 72 1.2 peter #include <err.h> 73 1.2 peter 74 1.2 peter #include "quip_client.h" 75 1.2 peter #include "altqstat.h" 76 1.2 peter 77 1.2 peter void 78 1.2 peter jobs_stat_loop(int fd, const char *ifname, int count, int interval) 79 1.2 peter { 80 1.2 peter struct class_stats stats1[JOBS_MAXPRI], stats2[JOBS_MAXPRI]; 81 1.2 peter char clnames[JOBS_MAXPRI][128]; 82 1.2 peter struct jobs_class_stats get_stats; 83 1.2 peter struct class_stats *sp, *lp, *new, *last, *tmp; 84 1.2 peter struct timeval cur_time, last_time; 85 1.2 peter int i; 86 1.2 peter double sec; 87 1.2 peter int cnt = count; 88 1.2 peter sigset_t omask; 89 1.2 peter 90 1.2 peter strlcpy(get_stats.iface.jobs_ifname, ifname, 91 1.2 peter sizeof(get_stats.iface.jobs_ifname)); 92 1.2 peter new = &stats1[0]; 93 1.2 peter last = &stats2[0]; 94 1.2 peter 95 1.2 peter /* invalidate class handles */ 96 1.2 peter for (i=0; i<JOBS_MAXPRI; i++) 97 1.2 peter last[i].class_handle = JOBS_NULLCLASS_HANDLE; 98 1.2 peter 99 1.3 peter for (;;) { 100 1.2 peter get_stats.stats = new; 101 1.2 peter get_stats.maxpri = JOBS_MAXPRI; 102 1.2 peter if (ioctl(fd, JOBS_GETSTATS, &get_stats) < 0) 103 1.2 peter err(1, "ioctl JOBS_GETSTATS"); 104 1.2 peter 105 1.2 peter gettimeofday(&cur_time, NULL); 106 1.2 peter sec = calc_interval(&cur_time, &last_time); 107 1.2 peter 108 1.2 peter printf("\n%s:\n", ifname); 109 1.2 peter printf("pri\tdel\trdc\tviol\tp_i\trlc\tthru\toff_ld\tbc_e\tavg_e\tstdev_e\twc_e\tbc_d\tavg_d\tstdev_d\twc_d\tnr_en\tnr_de\n"); 110 1.2 peter 111 1.2 peter for (i = get_stats.maxpri; i >= 0; i--) { 112 1.2 peter sp = &new[i]; 113 1.2 peter lp = &last[i]; 114 1.2 peter 115 1.2 peter if (sp->class_handle == JOBS_NULLCLASS_HANDLE) 116 1.2 peter continue; 117 1.2 peter 118 1.2 peter if (sp->class_handle != lp->class_handle) { 119 1.2 peter quip_chandle2name(ifname, sp->class_handle, 120 1.2 peter clnames[i], sizeof(clnames[0])); 121 1.2 peter continue; 122 1.2 peter } 123 1.2 peter 124 1.2 peter printf("%d\t%.0f\t%.2f\t%.3f\t%.2f\t%.2f\t%.3f\t%.2f\t%llu\t%.0f\t%.0f\t%llu\t%llu\t%.0f\t%.0f\t%llu\t%u\t%u\n", 125 1.2 peter i, 126 1.2 peter (sp->rout.packets == 0)? 127 1.2 peter -1.:(double)sp->avgdel/(double)sp->rout.packets, 128 1.2 peter (i > 0)?((sp->rout.packets > 0 && (&new[i-1])->rout.packets > 0)? 129 1.2 peter (double)(sp->avgdel*(&new[i-1])->rout.packets)/((double)sp->rout.packets*(&new[i-1])->avgdel):0):-1.0, 130 1.2 peter (sp->arrival.packets == 0)? 131 1.2 peter 0:(double)100.*sp->adc_violations/(double)sp->arrival.packets, 132 1.2 peter (sp->arrivalbusy.bytes == 0)? 133 1.2 peter 0:(double)(100.*sp->dropcnt.bytes/(double)(sp->arrivalbusy.bytes)), 134 1.2 peter (i > 0)?( 135 1.2 peter (sp->arrivalbusy.bytes == 0 || (&new[i-1])->dropcnt.bytes == 0)? 136 1.2 peter 0:(double)(sp->dropcnt.bytes*(&new[i-1])->arrivalbusy.bytes) 137 1.2 peter /(double)(sp->arrivalbusy.bytes*(&new[i-1])->dropcnt.bytes)):-1.0, 138 1.2 peter (sp->rout.bytes > 0)? 139 1.2 peter (double)calc_rate(sp->rout.bytes, 140 1.2 peter 0, sec)/1000000.:0, 141 1.2 peter (sp->arrival.bytes-lp->arrival.bytes > 0)? 142 1.2 peter (double)calc_rate(sp->arrival.bytes-lp->arrival.bytes, 143 1.2 peter 0, sec)/1000000.:0, 144 1.2 peter (ull)sp->bc_cycles_enqueue, 145 1.2 peter (sp->total_enqueued == 0)? 146 1.2 peter -1:(double)sp->avg_cycles_enqueue/sp->total_enqueued, 147 1.2 peter (sp->total_enqueued == 0)? 148 1.2 peter -1.: 149 1.2 peter sqrt((double)((u_int)((sp->avg_cycles2_enqueue/sp->total_enqueued) 150 1.2 peter -(sp->avg_cycles_enqueue/sp->total_enqueued*sp->avg_cycles_enqueue/sp->total_enqueued)))), 151 1.2 peter (ull)sp->wc_cycles_enqueue, 152 1.2 peter (ull)sp->bc_cycles_dequeue, 153 1.2 peter (sp->total_dequeued == 0)? 154 1.2 peter -1:(double)sp->avg_cycles_dequeue/sp->total_dequeued, 155 1.2 peter (sp->total_dequeued == 0)? 156 1.2 peter -1.: 157 1.2 peter sqrt((double)((u_int)((sp->avg_cycles2_dequeue/sp->total_dequeued) 158 1.2 peter -(sp->avg_cycles_dequeue/sp->total_dequeued*sp->avg_cycles_dequeue/sp->total_dequeued)))), 159 1.2 peter (ull)sp->wc_cycles_dequeue, 160 1.2 peter (u_int)sp->total_enqueued, 161 1.2 peter (u_int)sp->total_dequeued 162 1.2 peter ); 163 1.2 peter } 164 1.2 peter 165 1.2 peter /* swap the buffer pointers */ 166 1.2 peter tmp = last; 167 1.2 peter last = new; 168 1.2 peter new = tmp; 169 1.2 peter 170 1.2 peter last_time = cur_time; 171 1.2 peter 172 1.3 peter if (count != 0 && --cnt == 0) 173 1.3 peter break; 174 1.3 peter 175 1.2 peter /* wait for alarm signal */ 176 1.2 peter if (sigprocmask(SIG_BLOCK, NULL, &omask) == 0) 177 1.2 peter sigsuspend(&omask); 178 1.2 peter } 179 1.2 peter } 180