Annotation of embedaddon/bmon/src/bmon.c, revision 1.1
1.1 ! misho 1: /*
! 2: * src/bmon.c Bandwidth Monitor
! 3: *
! 4: * Copyright (c) 2001-2005 Thomas Graf <tgraf@suug.ch>
! 5: *
! 6: * Permission is hereby granted, free of charge, to any person obtaining a
! 7: * copy of this software and associated documentation files (the "Software"),
! 8: * to deal in the Software without restriction, including without limitation
! 9: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
! 10: * and/or sell copies of the Software, and to permit persons to whom the
! 11: * Software is furnished to do so, subject to the following conditions:
! 12: *
! 13: * The above copyright notice and this permission notice shall be included
! 14: * in all copies or substantial portions of the Software.
! 15: *
! 16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
! 17: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
! 18: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
! 19: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
! 20: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
! 21: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
! 22: * DEALINGS IN THE SOFTWARE.
! 23: */
! 24:
! 25: #include <bmon/bmon.h>
! 26: #include <bmon/conf.h>
! 27: #include <bmon/item.h>
! 28: #include <bmon/itemtab.h>
! 29: #include <bmon/input.h>
! 30: #include <bmon/output.h>
! 31: #include <bmon/signal.h>
! 32: #include <bmon/utils.h>
! 33:
! 34: int start_time;
! 35: int do_quit = 0;
! 36:
! 37: struct reader_timing rtiming;
! 38: static char *usage_text =
! 39: "Usage: bmon [OPTION]...\n" \
! 40: "\n" \
! 41: "Options:\n" \
! 42: " -i <modparm> Primary input module\n" \
! 43: " -o <modparm> Primary ouptut module\n" \
! 44: " -I <modparm> Secondary input modules\n" \
! 45: " -O <modparm> Secondary output modules\n" \
! 46: " -f <path> Alternative path to configuration file\n" \
! 47: " -p <policy> Interface acceptance policy\n" \
! 48: " -a Accept interfaces even if they are down\n" \
! 49: " -A <attrs> Attributes history configuration\n" \
! 50: " -r <float> Read interval in seconds\n" \
! 51: " -R <float> Rate interval in seconds\n" \
! 52: " -H <hbeat> Heartbeat factor (0..1)\n" \
! 53: " -L <lifetime> Lifetime of a item in seconds\n" \
! 54: " -c Use SI units\n" \
! 55: " -t <path> Alternative path to itemtab file\n" \
! 56: " -N <num> Number of graphs to draw\n" \
! 57: " -s <float> Sleep time in seconds\n" \
! 58: " -w Signal driven output intervals\n" \
! 59: " -S <pid> Send SIGUSR1 to a running bmon instance\n" \
! 60: " -u <uid> Drop privileges and change UID\n" \
! 61: " -g <gid> Drop privileges and change GID\n" \
! 62: " -h show this help text\n" \
! 63: " -V show version\n" \
! 64: "\n" \
! 65: "Module configuration:\n" \
! 66: " modparm := MODULE:optlist,MODULE:optlist,...\n" \
! 67: " optlist := option;option;...\n" \
! 68: " option := TYPE[=VALUE]\n" \
! 69: "\n" \
! 70: " Examples:\n" \
! 71: " -O html:path=/var/www/html,distribution:port=2444;debug\n" \
! 72: " -O list # Shows a list of available modules\n" \
! 73: " -O html:help # Shows a help text for html module\n" \
! 74: "\n" \
! 75: "Interface selection:\n" \
! 76: " policy := [!]simple_regexp,[!]simple_regexp,...\n" \
! 77: "\n" \
! 78: " Example: -p 'eth*,lo*,!eth1'\n" \
! 79: "\n" \
! 80: "Attributes selection:\n" \
! 81: " attrs := [!]name,[!]name,...\n" \
! 82: "\n" \
! 83: " Example: -A !hbeat_err\n" \
! 84: "\n" \
! 85: "Please see the bmon(1) man pages for full documentation.\n";
! 86:
! 87: static char *uid, *gid;
! 88:
! 89: static void do_shutdown(void)
! 90: {
! 91: static int done;
! 92:
! 93: if (!done) {
! 94: done = 1;
! 95: input_shutdown();
! 96: output_shutdown();
! 97: }
! 98: }
! 99:
! 100: RETSIGTYPE sig_int(int unused)
! 101: {
! 102: if (do_quit)
! 103: exit(-1);
! 104: do_quit = 1;
! 105: }
! 106:
! 107: void sig_exit(void)
! 108: {
! 109: do_shutdown();
! 110: }
! 111:
! 112: void quit(const char *fmt, ...)
! 113: {
! 114: static int done;
! 115: va_list args;
! 116:
! 117: if (!done) {
! 118: done = 1;
! 119: do_shutdown();
! 120: }
! 121:
! 122: va_start(args, fmt);
! 123: vfprintf(stderr, fmt, args);
! 124: va_end(args);
! 125:
! 126: exit(1);
! 127: }
! 128:
! 129: static void print_version(void)
! 130: {
! 131: printf("bmon %s\n", PACKAGE_VERSION);
! 132: printf("Copyright (C) 2001-2005 by Thomas Graf <tgraf@suug.ch>\n");
! 133: printf("bmon comes with ABSOLUTELY NO WARRANTY. This is free software, " \
! 134: "and you\nare welcome to redistribute it under certain conditions. " \
! 135: "See the source\ncode for details.\n");
! 136: }
! 137:
! 138: static void parse_args(int argc, char *argv[])
! 139: {
! 140: for (;;)
! 141: {
! 142: int c = getopt(argc, argv, "hVf:i:I:o:O:p:r:s:S:waA:cN" \
! 143: ":u:g:H:R:L:t:");
! 144:
! 145: if (c == -1)
! 146: break;
! 147:
! 148: switch (c)
! 149: {
! 150: case 'i':
! 151: set_input(optarg);
! 152: break;
! 153:
! 154: case 'I':
! 155: set_sec_input(optarg);
! 156: break;
! 157:
! 158: case 'o':
! 159: set_output(optarg);
! 160: break;
! 161:
! 162: case 'O':
! 163: set_sec_output(optarg);
! 164: break;
! 165:
! 166: case 'f':
! 167: set_configfile(optarg);
! 168: break;
! 169:
! 170: case 'p':
! 171: item_parse_policy(optarg);
! 172: break;
! 173:
! 174: case 'A':
! 175: parse_attr_policy(optarg);
! 176: break;
! 177:
! 178: case 'r':
! 179: set_read_interval(optarg);
! 180: break;
! 181:
! 182: case 'R':
! 183: set_rate_interval(optarg);
! 184: break;
! 185:
! 186: case 'L':
! 187: set_lifetime(optarg);
! 188: break;
! 189:
! 190: case 's':
! 191: set_sleep_time(optarg);
! 192: break;
! 193:
! 194: case 'S':
! 195: send_signal(optarg);
! 196: exit(0);
! 197:
! 198: case 'w':
! 199: set_signal_output(1);
! 200: break;
! 201:
! 202: case 'a':
! 203: set_show_only_running(0);
! 204: break;
! 205:
! 206: case 'h':
! 207: print_version();
! 208: printf("\n%s", usage_text);
! 209: exit(1);
! 210:
! 211: case 'N':
! 212: set_ngraphs(strtol(optarg, NULL, 0));
! 213: break;
! 214:
! 215: case 'c':
! 216: set_use_si();
! 217: break;
! 218:
! 219: case 'u':
! 220: uid = strdup(optarg);
! 221: break;
! 222:
! 223: case 'g':
! 224: gid = strdup(optarg);
! 225: break;
! 226:
! 227: case 'H':
! 228: set_hb_factor(optarg);
! 229: break;
! 230:
! 231: case 't':
! 232: set_itemtab(optarg);
! 233: break;
! 234:
! 235: case 'V':
! 236: case 'v':
! 237: print_version();
! 238: exit(0);
! 239:
! 240: default:
! 241: quit("Aborting...\n");
! 242: }
! 243: }
! 244: }
! 245:
! 246: static void calc_variance(timestamp_t *c, timestamp_t *ri)
! 247: {
! 248: float v = (ts_to_float(c) / ts_to_float(ri)) * 100.0f;
! 249:
! 250: rtiming.rt_variance.v_error = v;
! 251: rtiming.rt_variance.v_total += v;
! 252:
! 253: if (v > rtiming.rt_variance.v_max)
! 254: rtiming.rt_variance.v_max = v;
! 255:
! 256: if (v < rtiming.rt_variance.v_min)
! 257: rtiming.rt_variance.v_min = v;
! 258: }
! 259:
! 260: static void drop_privs(void)
! 261: {
! 262: struct passwd *uentry = NULL;
! 263: struct group *gentry = NULL;
! 264:
! 265: if (gid)
! 266: gentry = getgrnam(gid);
! 267:
! 268: if (uid)
! 269: uentry = getpwnam(uid);
! 270:
! 271: if (gentry)
! 272: if (setgid(gentry->gr_gid) < 0)
! 273: quit("Unable to set group id %d: %s\n",
! 274: gentry->gr_gid, strerror(errno));
! 275:
! 276: if (uentry)
! 277: if (setuid(uentry->pw_uid) < 0)
! 278: quit("Unable to set user id %d: %s\n",
! 279: uentry->pw_uid, strerror(errno));
! 280: }
! 281:
! 282: int main(int argc, char *argv[])
! 283: {
! 284: unsigned long c_sleep_time;
! 285: float read_interval;
! 286:
! 287: start_time = time(0);
! 288:
! 289: parse_args(argc, argv);
! 290: read_configfile();
! 291: read_itemtab();
! 292:
! 293: c_sleep_time = get_sleep_time();
! 294: read_interval = get_read_interval();
! 295:
! 296: if (((double) c_sleep_time/1000000.0f) > read_interval)
! 297: c_sleep_time = (unsigned long) (read_interval * 1000000.0f);
! 298:
! 299: input_init();
! 300: output_init();
! 301:
! 302: drop_privs();
! 303:
! 304: {
! 305: /*
! 306: * E := Elapsed time
! 307: * NR := Next Read
! 308: * LR := Last Read
! 309: * RI := Read Interval
! 310: * ST := Sleep Time
! 311: * C := Correction
! 312: */
! 313: timestamp_t e, ri, tmp;
! 314: unsigned long st;
! 315:
! 316: get_read_interval_as_ts(&ri);
! 317:
! 318: /*
! 319: * E := NOW()
! 320: */
! 321: update_ts(&e);
! 322:
! 323: /*
! 324: * NR := E
! 325: */
! 326: COPY_TS(&rtiming.rt_next_read, &e);
! 327:
! 328: for (;;) {
! 329: output_pre();
! 330:
! 331: /*
! 332: * E := NOW()
! 333: */
! 334: update_ts(&e);
! 335:
! 336: /*
! 337: * IF NR <= E THEN
! 338: */
! 339: if (ts_le(&rtiming.rt_next_read, &e)) {
! 340: timestamp_t c;
! 341:
! 342: /*
! 343: * C := (NR - E)
! 344: */
! 345: ts_sub(&c, &rtiming.rt_next_read, &e);
! 346:
! 347: calc_variance(&c, &ri);
! 348:
! 349: /*
! 350: * LR := E
! 351: */
! 352: COPY_TS(&rtiming.rt_last_read, &e);
! 353:
! 354: /*
! 355: * NR := E + RI + C
! 356: */
! 357: ts_add(&rtiming.rt_next_read, &e, &ri);
! 358: ts_add(&rtiming.rt_next_read, &rtiming.rt_next_read, &c);
! 359:
! 360: input_read();
! 361: output_draw();
! 362:
! 363: output_post();
! 364: }
! 365:
! 366: if (do_quit)
! 367: exit(0);
! 368:
! 369: if (got_resized())
! 370: output_resize();
! 371:
! 372: /*
! 373: * ST := Configured ST
! 374: */
! 375: st = c_sleep_time;
! 376:
! 377: /*
! 378: * IF (NR - E) < ST THEN
! 379: */
! 380: ts_sub(&tmp, &rtiming.rt_next_read, &e);
! 381:
! 382: if (tmp.tv_sec < 0)
! 383: continue;
! 384:
! 385: if (tmp.tv_sec == 0 && tmp.tv_usec < st) {
! 386: if (tmp.tv_usec < 0)
! 387: continue;
! 388: /*
! 389: * ST := (NR - E)
! 390: */
! 391: st = tmp.tv_usec;
! 392: }
! 393:
! 394: /*
! 395: * SLEEP(ST)
! 396: */
! 397: usleep(st);
! 398: }
! 399: }
! 400:
! 401: return 0; /* buddha says i'll never be reached */
! 402: }
! 403:
! 404: static void __init bmon_init(void)
! 405: {
! 406: memset(&rtiming, 0, sizeof(rtiming));
! 407: rtiming.rt_variance.v_min = 10000000.0f;
! 408: atexit(&sig_exit);
! 409: signal(SIGINT, &sig_int);
! 410: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>