Diff for /embedaddon/bmon/src/bmon.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 22:19:56 version 1.1.1.2, 2014/07/30 07:55:27
Line 1 Line 1
 /*  /*
  * src/bmon.c              Bandwidth Monitor   * src/bmon.c              Bandwidth Monitor
  *   *
 * Copyright (c) 2001-2005 Thomas Graf <tgraf@suug.ch> * Copyright (c) 2001-2013 Thomas Graf <tgraf@suug.ch>
  * Copyright (c) 2013 Red Hat, Inc.
  *   *
  * Permission is hereby granted, free of charge, to any person obtaining a   * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),   * copy of this software and associated documentation files (the "Software"),
Line 24 Line 25
   
 #include <bmon/bmon.h>  #include <bmon/bmon.h>
 #include <bmon/conf.h>  #include <bmon/conf.h>
#include <bmon/item.h>#include <bmon/attr.h>
#include <bmon/itemtab.h>#include <bmon/utils.h>
 #include <bmon/input.h>  #include <bmon/input.h>
 #include <bmon/output.h>  #include <bmon/output.h>
#include <bmon/signal.h>#include <bmon/module.h>
#include <bmon/utils.h>#include <bmon/group.h>
   
 int start_time;  int start_time;
 int do_quit = 0;  int do_quit = 0;
   int is_daemon = 0;
   
 struct reader_timing rtiming;  struct reader_timing rtiming;
   
 static char *usage_text =  static char *usage_text =
 "Usage: bmon [OPTION]...\n" \  "Usage: bmon [OPTION]...\n" \
 "\n" \  "\n" \
 "Options:\n" \  "Options:\n" \
"   -i <modparm>    Primary input module\n" \"Startup:\n" \
"   -o <modparm>    Primary ouptut module\n" \"   -i, --input=MODPARM             Input module(s)\n" \
"   -I <modparm>    Secondary input modules\n" \"   -o, --output=MODPARM            Output module(s)\n" \
"   -O <modparm>    Secondary output modules\n" \"   -f, --configfile=PATH           Alternative path to configuration file\n" \
"   -f <path>       Alternative path to configuration file\n" \"   -h, --help                      Show this help text\n" \
"   -p <policy>     Interface acceptance policy\n" \"   -V, --version                   Show version\n" \
"   -a              Accept interfaces even if they are down\n" \ 
"   -A <attrs>      Attributes history configuration\n" \ 
"   -r <float>      Read interval in seconds\n" \ 
"   -R <float>      Rate interval in seconds\n" \ 
"   -H <hbeat>      Heartbeat factor (0..1)\n" \ 
"   -L <lifetime>   Lifetime of a item in seconds\n" \ 
"   -c              Use SI units\n" \ 
"   -t <path>       Alternative path to itemtab file\n" \ 
"   -N <num>        Number of graphs to draw\n" \ 
"   -s <float>      Sleep time in seconds\n" \ 
"   -w              Signal driven output intervals\n" \ 
"   -S <pid>        Send SIGUSR1 to a running bmon instance\n" \ 
"   -u <uid>        Drop privileges and change UID\n" \ 
"   -g <gid>        Drop privileges and change GID\n" \ 
"   -h              show this help text\n" \ 
"   -V              show version\n" \ 
 "\n" \  "\n" \
   "Input:\n" \
   "   -p, --policy=POLICY             Element display policy (see below)\n" \
   "   -a, --show-all                  Show all elements (even disabled elements)\n" \
   "   -r, --read-interval=FLOAT       Read interval in seconds (float)\n" \
   "   -R, --rate-interval=FLOAT       Rate interval in seconds (float)\n" \
   "   -s, --sleep-interval=FLOAT      Sleep time in seconds (float)\n" \
   "   -L, --lifetime=LIFETIME         Lifetime of an element in seconds (float)\n" \
   "\n" \
   "Output:\n" \
   "   -U, --use-si                    Use SI units\n" \
   "   -b, --use-bit                   Display in bits instead of bytes\n" \
   "\n" \
 "Module configuration:\n" \  "Module configuration:\n" \
 "   modparm := MODULE:optlist,MODULE:optlist,...\n" \  "   modparm := MODULE:optlist,MODULE:optlist,...\n" \
 "   optlist := option;option;...\n" \  "   optlist := option;option;...\n" \
 "   option  := TYPE[=VALUE]\n" \  "   option  := TYPE[=VALUE]\n" \
 "\n" \  "\n" \
 "   Examples:\n" \  "   Examples:\n" \
"       -O html:path=/var/www/html,distribution:port=2444;debug\n" \"       -o curses:ngraph=2\n" \
"       -O list          # Shows a list of available modules\n" \"       -o list            # Shows a list of available modules\n" \
"       -O html:help     # Shows a help text for html module\n" \"       -o curses:help     # Shows a help text for html module\n" \
 "\n" \  "\n" \
 "Interface selection:\n" \  "Interface selection:\n" \
 "   policy  := [!]simple_regexp,[!]simple_regexp,...\n" \  "   policy  := [!]simple_regexp,[!]simple_regexp,...\n" \
 "\n" \  "\n" \
 "   Example: -p 'eth*,lo*,!eth1'\n" \  "   Example: -p 'eth*,lo*,!eth1'\n" \
 "\n" \  "\n" \
 "Attributes selection:\n" \  
 "   attrs   := [!]name,[!]name,...\n" \  
 "\n" \  
 "   Example: -A !hbeat_err\n" \  
 "\n" \  
 "Please see the bmon(1) man pages for full documentation.\n";  "Please see the bmon(1) man pages for full documentation.\n";
   
 static char *uid, *gid;  
   
 static void do_shutdown(void)  static void do_shutdown(void)
 {  {
         static int done;          static int done;
                   
         if (!done) {          if (!done) {
                 done = 1;                  done = 1;
                input_shutdown();                module_shutdown();
                output_shutdown(); 
         }          }
 }  }
   
Line 114  void quit(const char *fmt, ...) Line 105  void quit(const char *fmt, ...)
         static int done;          static int done;
         va_list args;          va_list args;
   
           va_start(args, fmt);
           vfprintf(stderr, fmt, args);
           va_end(args);
   
         if (!done) {          if (!done) {
                 done = 1;                  done = 1;
                 do_shutdown();                  do_shutdown();
         }          }
   
         va_start(args, fmt);  
         vfprintf(stderr, fmt, args);  
         va_end(args);  
   
         exit(1);          exit(1);
 }  }
   
static void print_version(void)static inline void print_version(void)
 {  {
         printf("bmon %s\n", PACKAGE_VERSION);          printf("bmon %s\n", PACKAGE_VERSION);
        printf("Copyright (C) 2001-2005 by Thomas Graf <tgraf@suug.ch>\n");        printf("Copyright (C) 2001-2013 by Thomas Graf <tgraf@suug.ch>\n");
        printf("bmon comes with ABSOLUTELY NO WARRANTY. This is free software, " \        printf("Copyright (C) 2013 Red Hat, Inc.\n");
                "and you\nare welcome to redistribute it under certain conditions. " \        printf("bmon comes with ABSOLUTELY NO WARRANTY. This is free " \
                "See the source\ncode for details.\n");               "software, and you\nare welcome to redistribute it under " \
                "certain conditions. See the source\ncode for details.\n");
 }  }
   
static void parse_args(int argc, char *argv[])static void parse_args_pre(int argc, char *argv[])
 {  {
           DBG("Parsing arguments pre state");
   
         for (;;)          for (;;)
         {          {
                int c = getopt(argc, argv, "hVf:i:I:o:O:p:r:s:S:waA:cN" \                char *gostr = "+:hvVf:";
                    ":u:g:H:R:L:t:"); 
   
                   struct option long_opts[] = {
                           {"help", 0, 0, 'h'},
                           {"version", 0, 0, 'v'},
                           {"configfile", 1, 0, 'f'},
                           {0, 0, 0, 0},
                   };
                   int c = getopt_long(argc, argv, gostr, long_opts, NULL);
                 if (c == -1)                  if (c == -1)
                         break;                          break;
                                   
                 switch (c)                  switch (c)
                 {                  {
                        case 'i':                        case 'f':
                                set_input(optarg);                                set_configfile(optarg);
                                 break;                                  break;
   
                        case 'I':                        case 'h':
                                set_sec_input(optarg);                                print_version();
                                 printf("\n%s", usage_text);
                                 exit(1);
                         case 'V':
                         case 'v':
                                 print_version();
                                 exit(0);
                 }
         }
 }
 
 static int parse_args_post(int argc, char *argv[])
 {
         DBG("Parsing arguments post state");
 
         optind = 1;
 
         for (;;)
         {
                 char *gostr = "i:o:p:r:R:s:aUb" \
                               "L:hvVf:";
 
                 struct option long_opts[] = {
                         {"input", 1, 0, 'i'},
                         {"output", 1, 0, 'o'},
                         {"policy", 1, 0, 'p'},
                         {"read-interval", 1, 0, 'r'},
                         {"rate-interval", 1, 0, 'R'},
                         {"sleep-interval", 1, 0, 's'},
                         {"show-all", 0, 0, 'a'},
                         {"use-si", 0, 0, 'U'},
                         {"use-bit", 0, 0, 'b'},
                         {"lifetime", 1, 0, 'L'},
                         {0, 0, 0, 0},
                 };
                 int c = getopt_long(argc, argv, gostr, long_opts, NULL);
                 if (c == -1)
                         break;
                 
                 switch (c)
                 {
                         case 'i':
                                 if (input_set(optarg))
                                         return 1;
                                 break;                                  break;
   
                         case 'o':                          case 'o':
                                set_output(optarg);                                if (output_set(optarg))
                                         return 1;
                                 break;                                  break;
   
                         case 'O':  
                                 set_sec_output(optarg);  
                                 break;  
                                   
                         case 'f':  
                                 set_configfile(optarg);  
                                 break;  
   
                         case 'p':                          case 'p':
                                item_parse_policy(optarg);                                cfg_setstr(cfg, "policy", optarg);
                                 break;                                  break;
   
                         case 'A':  
                                 parse_attr_policy(optarg);  
                                 break;  
   
                         case 'r':                          case 'r':
                                set_read_interval(optarg);                                cfg_setfloat(cfg, "read_interval", strtod(optarg, NULL));
                                 break;                                  break;
   
                         case 'R':                          case 'R':
                                set_rate_interval(optarg);                                cfg_setfloat(cfg, "rate_interval", strtod(optarg, NULL));
                                 break;                                  break;
   
                         case 'L':  
                                 set_lifetime(optarg);  
                                 break;  
   
                         case 's':                          case 's':
                                set_sleep_time(optarg);                                cfg_setint(cfg, "sleep_time", strtoul(optarg, NULL, 0));
                                 break;                                  break;
   
                         case 'S':  
                                 send_signal(optarg);  
                                 exit(0);  
   
                         case 'w':  
                                 set_signal_output(1);  
                                 break;  
   
                         case 'a':                          case 'a':
                                set_show_only_running(0);                                cfg_setint(cfg, "show_all", 1);
                                 break;                                  break;
   
                        case 'h':                        case 'U':
                                print_version();                                cfg_setbool(cfg, "use_si", cfg_true);
                                printf("\n%s", usage_text); 
                                exit(1); 
 
                        case 'N': 
                                set_ngraphs(strtol(optarg, NULL, 0)); 
                                 break;                                  break;
   
                        case 'c':                        case 'b':
                                set_use_si();                                cfg_setbool(cfg, "use_bit", cfg_true);
                                 break;                                  break;
                           
                         case 'u':  
                                 uid = strdup(optarg);  
                                 break;  
   
                        case 'g':                        case 'L':
                                gid = strdup(optarg);                                cfg_setint(cfg, "lifetime", strtoul(optarg, NULL, 0));
                                 break;                                  break;
   
                        case 'H':                        case 'f':
                                set_hb_factor(optarg);                                /* Already handled in pre getopt loop */
                                 break;                                  break;
   
                         case 't':  
                                 set_itemtab(optarg);  
                                 break;  
   
                         case 'V':  
                         case 'v':  
                                 print_version();  
                                 exit(0);  
   
                         default:                          default:
                                 quit("Aborting...\n");                                  quit("Aborting...\n");
                                   break;
   
                 }                  }
         }          }
   
           return 0;
 }  }
   
   #if 0
 static void calc_variance(timestamp_t *c, timestamp_t *ri)  static void calc_variance(timestamp_t *c, timestamp_t *ri)
 {  {
         float v = (ts_to_float(c) / ts_to_float(ri)) * 100.0f;          float v = (ts_to_float(c) / ts_to_float(ri)) * 100.0f;
Line 256  static void calc_variance(timestamp_t *c, timestamp_t  Line 263  static void calc_variance(timestamp_t *c, timestamp_t 
         if (v < rtiming.rt_variance.v_min)          if (v < rtiming.rt_variance.v_min)
                 rtiming.rt_variance.v_min = v;                  rtiming.rt_variance.v_min = v;
 }  }
   #endif
   
 static void drop_privs(void)  
 {  
         struct passwd *uentry = NULL;  
         struct group *gentry = NULL;  
   
         if (gid)  
                 gentry = getgrnam(gid);  
   
         if (uid)  
                 uentry = getpwnam(uid);  
   
         if (gentry)  
                 if (setgid(gentry->gr_gid) < 0)  
                         quit("Unable to set group id %d: %s\n",  
                             gentry->gr_gid, strerror(errno));  
   
         if (uentry)  
                 if (setuid(uentry->pw_uid) < 0)  
                         quit("Unable to set user id %d: %s\n",  
                             uentry->pw_uid, strerror(errno));  
 }  
   
 int main(int argc, char *argv[])  int main(int argc, char *argv[])
 {  {
        unsigned long c_sleep_time;        unsigned long sleep_time;
        float read_interval;        double read_interval;
        
         start_time = time(0);          start_time = time(0);
           memset(&rtiming, 0, sizeof(rtiming));
           rtiming.rt_variance.v_min = FLT_MAX;
   
        parse_args(argc, argv);        /*
        read_configfile();         * Early initialization before reading config
        read_itemtab();         */
         conf_init_pre();
         parse_args_pre(argc, argv);
   
        c_sleep_time = get_sleep_time();        /*
        read_interval = get_read_interval();         * Reading the configuration file */
         configfile_read();
   
        if (((double) c_sleep_time/1000000.0f) > read_interval)        /*
                c_sleep_time = (unsigned long) (read_interval * 1000000.0f);         * Late initialization after reading config
          */
         if (parse_args_post(argc, argv))
                 return 1;
         conf_init_post();
   
        input_init();        module_init();
        output_init(); 
   
        drop_privs();        read_interval = cfg_read_interval;
         sleep_time = cfg_getint(cfg, "sleep_time");
   
        {        if (((double) sleep_time / 1000000.0f) > read_interval)
                 sleep_time = (unsigned long) (read_interval * 1000000.0f);
 
         DBG("Entering mainloop...");
 
         do {
                 /*                  /*
                  * E  := Elapsed time                   * E  := Elapsed time
                  * NR := Next Read                   * NR := Next Read
Line 313  int main(int argc, char *argv[]) Line 313  int main(int argc, char *argv[])
                 timestamp_t e, ri, tmp;                  timestamp_t e, ri, tmp;
                 unsigned long st;                  unsigned long st;
   
                get_read_interval_as_ts(&ri);                float_to_timestamp(&ri, read_interval);
   
                 /*                  /*
                 * E := NOW()                 * NR := NOW
                  */                   */
                update_ts(&e);                update_timestamp(&rtiming.rt_next_read);
                                   
                 /*  
                  * NR := E  
                  */  
                 COPY_TS(&rtiming.rt_next_read, &e);  
                   
                 for (;;) {                  for (;;) {
                         output_pre();                          output_pre();
   
                         /*                          /*
                         * E := NOW()                         * E := NOW
                          */                           */
                        update_ts(&e);                        update_timestamp(&e);
   
                         /*                          /*
                          * IF NR <= E THEN                           * IF NR <= E THEN
                          */                           */
                        if (ts_le(&rtiming.rt_next_read, &e)) {                        if (timestamp_le(&rtiming.rt_next_read, &e)) {
                                 timestamp_t c;                                  timestamp_t c;
   
                                 /*                                  /*
                                  * C :=  (NR - E)                                   * C :=  (NR - E)
                                  */                                   */
                                ts_sub(&c, &rtiming.rt_next_read, &e);                                timestamp_sub(&c, &rtiming.rt_next_read, &e);
   
                                calc_variance(&c, &ri);                                //calc_variance(&c, &ri);
   
                                 /*                                  /*
                                  * LR := E                                   * LR := E
                                  */                                   */
                                COPY_TS(&rtiming.rt_last_read, &e);                                copy_timestamp(&rtiming.rt_last_read, &e);
   
                                 /*                                  /*
                                  * NR := E + RI + C                                   * NR := E + RI + C
                                  */                                   */
                                ts_add(&rtiming.rt_next_read, &e, &ri);                                timestamp_add(&rtiming.rt_next_read, &e, &ri);
                                ts_add(&rtiming.rt_next_read, &rtiming.rt_next_read, &c);                                timestamp_add(&rtiming.rt_next_read,
                                        &rtiming.rt_next_read, &c);
   
   
                                   reset_update_flags();
                                 input_read();                                  input_read();
                                   free_unused_elements();
                                 output_draw();                                  output_draw();
   
                                 output_post();                                  output_post();
                         }                          }
   
                         if (do_quit)                          if (do_quit)
                                 exit(0);                                  exit(0);
   
                         if (got_resized())  
                                 output_resize();  
   
                         /*                          /*
                          * ST := Configured ST                           * ST := Configured ST
                          */                           */
                        st = c_sleep_time;                        st = sleep_time;
   
                         /*                          /*
                          * IF (NR - E) < ST THEN                           * IF (NR - E) < ST THEN
                          */                           */
                        ts_sub(&tmp, &rtiming.rt_next_read, &e);                        timestamp_sub(&tmp, &rtiming.rt_next_read, &e);
   
                         if (tmp.tv_sec < 0)                          if (tmp.tv_sec < 0)
                                 continue;                                  continue;
Line 396  int main(int argc, char *argv[]) Line 391  int main(int argc, char *argv[])
                          */                           */
                         usleep(st);                          usleep(st);
                 }                  }
        }        } while (0);
        
         return 0; /* buddha says i'll never be reached */          return 0; /* buddha says i'll never be reached */
 }  }
   
 static void __init bmon_init(void)  static void __init bmon_init(void)
 {  {
         memset(&rtiming, 0, sizeof(rtiming));  
         rtiming.rt_variance.v_min = 10000000.0f;  
         atexit(&sig_exit);          atexit(&sig_exit);
        signal(SIGINT, &sig_int);        //signal(SIGINT, &sig_int);
 }  }

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>