diff options
| -rw-r--r-- | src/lib/CMakeLists.txt | 10 | ||||
| -rw-r--r-- | src/lib/config.h.in | 1 | ||||
| -rw-r--r-- | src/lib/dev.c | 20 | ||||
| -rw-r--r-- | src/lib/frct.c | 141 | ||||
| -rw-r--r-- | src/lib/rib.c | 18 | 
5 files changed, 173 insertions, 17 deletions
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 76d0530d..022c5cca 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -219,6 +219,16 @@ set(ACK_WHEEL_SLOTS 128 CACHE STRING  set(ACK_WHEEL_RESOLUTION 20 CACHE STRING    "Minimum acknowledgment delay (ns), as a power to 2") +if (HAVE_FUSE) +  set(PROC_FLOW_STATS TRUE CACHE BOOL +    "Enable flow statistics tracking for application flows") +    if (PROC_FLOW_STATS) +       message(STATUS "Application flow statistics enabled") +    else () +       message(STATUS "Application flow statistics disabled") +    endif () +endif () +  set(SOURCE_FILES_DEV    # Add source files here    cacep.c diff --git a/src/lib/config.h.in b/src/lib/config.h.in index 17213a57..5c5b6caf 100644 --- a/src/lib/config.h.in +++ b/src/lib/config.h.in @@ -56,6 +56,7 @@  #cmakedefine HAVE_FUSE  #ifdef HAVE_FUSE  #define FUSE_PREFIX         "@FUSE_PREFIX@" +#cmakedefine PROC_FLOW_STATS  #endif  #define PTHREAD_COND_CLOCK  @PTHREAD_COND_CLOCK@ diff --git a/src/lib/dev.c b/src/lib/dev.c index ec4561b2..fbbc096d 100644 --- a/src/lib/dev.c +++ b/src/lib/dev.c @@ -44,6 +44,9 @@  #include <ouroboros/shm_rbuff.h>  #include <ouroboros/utils.h>  #include <ouroboros/fqueue.h> +#ifdef PROC_FLOW_STATS +#include <ouroboros/rib.h> +#endif  #include <stdlib.h>  #include <string.h> @@ -361,7 +364,9 @@ static void init(int     argc,  {          const char * prog = argv[0];          int          i; - +#ifdef PROC_FLOW_STATS +        char         procstr[32]; +#endif          (void) argc;          (void) envp; @@ -437,6 +442,11 @@ static void init(int     argc,          if (timerwheel_init() < 0)                  goto fail_timerwheel; +#if defined PROC_FLOW_STATS +        sprintf(procstr, "proc.%d", getpid()); +        /* Don't bail, it just won't show metrics */ +        rib_init(procstr); +#endif          return;   fail_timerwheel: @@ -470,7 +480,13 @@ static void init(int     argc,  static void fini(void)  { -        int i = 0; +        int  i = 0; +#ifdef PROC_FLOW_STATS +        char procstr[32]; + +        sprintf(procstr, "proc.%d", getpid()); +        rib_fini(); +#endif          if (ai.fds == NULL)                  return; diff --git a/src/lib/frct.c b/src/lib/frct.c index 7aaf037c..5313e4da 100644 --- a/src/lib/frct.c +++ b/src/lib/frct.c @@ -20,10 +20,12 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#define DELT_RDV      (100 * MILLION) /* ns */ -#define MAX_RDV         (1 * BILLION) /* ns */ +#define DELT_RDV         (100 * MILLION) /* ns */ +#define MAX_RDV            (1 * BILLION) /* ns */ -#define FRCT_PCILEN    (sizeof(struct frct_pci)) +#define FRCT             "frct" +#define FRCT_PCILEN      (sizeof(struct frct_pci)) +#define FRCT_NAME_STRLEN 32  struct frct_cr {          uint32_t        lwe;     /* Left window edge               */ @@ -84,6 +86,103 @@ struct frct_pci {          uint32_t ackno;  } __attribute__((packed)); +#ifdef PROC_FLOW_STATS + +static int frct_rib_read(const char * path, +                         char *       buf, +                         size_t       len) +{ +        struct timespec now; +        char *          entry; +        struct flow *   flow; +        struct frcti *  frcti; +        int             fd; + +        (void) len; + +        entry = strstr(path, RIB_SEPARATOR); +        assert(entry); +        *entry = '\0'; + +        fd = atoi(path); + +        flow = &ai.flows[fd]; + +        clock_gettime(PTHREAD_COND_CLOCK, &now); + +        pthread_rwlock_rdlock(&ai.lock); + +        frcti = flow->frcti; + +        pthread_rwlock_rdlock(&frcti->lock); + +        sprintf(buf, +                "Maximum packet lifetime (ns):    %20ld\n" +                "Max time to Ack (ns):            %20ld\n" +                "Max time to Retransmit (ns):     %20ld\n" +                "Smoothed rtt (ns):               %20ld\n" +                "RTT standard deviation (ns):     %20ld\n" +                "Retransmit timeout RTO (ns):     %20ld\n" +                "Sender left window edge:         %20u\n" +                "Sender right window edge:        %20u\n" +                "Sender inactive (ns):            %20ld\n" +                "Sender current sequence number:  %20u\n" +                "Receiver left window edge:       %20u\n" +                "Receiver right window edge:      %20u\n" +                "Receiver inactive (ns):          %20ld\n" +                "Receiver last ack:               %20u\n", +                frcti->mpl, +                frcti->a, +                frcti->r, +                frcti->srtt, +                frcti->mdev, +                frcti->rto, +                frcti->snd_cr.lwe, +                frcti->snd_cr.rwe, +                ts_diff_ns(&frcti->snd_cr.act, &now), +                frcti->snd_cr.seqno, +                frcti->rcv_cr.lwe, +                frcti->rcv_cr.rwe, +                ts_diff_ns(&frcti->rcv_cr.act, &now), +                frcti->rcv_cr.seqno); + +        pthread_rwlock_unlock(&flow->frcti->lock); + +        pthread_rwlock_unlock(&ai.lock); + +        return strlen(buf); +} + +static int frct_rib_readdir(char *** buf) +{ +        *buf = malloc(sizeof(**buf)); + +        (*buf)[0] = strdup("frct"); + +        return 1; +} + +static int frct_rib_getattr(const char *      path, +                            struct rib_attr * attr) +{ +        (void) path; +        (void) attr; + +        attr->size  = 1024; +        attr->mtime = 0; + +        return 0; +} + + +static struct rib_ops r_ops = { +        .read    = frct_rib_read, +        .readdir = frct_rib_readdir, +        .getattr = frct_rib_getattr +}; + +#endif /* PROC_FLOW_STATS */ +  static bool before(uint32_t seq1,                     uint32_t seq2)  { @@ -205,14 +304,16 @@ static void __send_rdv(int fd)  static struct frcti * frcti_create(int fd)  { -        struct frcti *     frcti; -        ssize_t            idx; -        struct timespec    now; -        time_t             mpl; -        time_t             a; -        time_t             r; -        pthread_condattr_t cattr; - +        struct frcti *      frcti; +        ssize_t             idx; +        struct timespec     now; +        time_t              mpl; +        time_t              a; +        time_t              r; +        pthread_condattr_t  cattr; +#ifdef PROC_FLOW_STATS +        char                frctstr[FRCT_NAME_STRLEN + 1]; +#endif          frcti = malloc(sizeof(*frcti));          if (frcti == NULL)                  goto fail_malloc; @@ -233,6 +334,13 @@ static struct frcti * frcti_create(int fd)          if (pthread_cond_init(&frcti->cond, &cattr))                  goto fail_cond; +#ifdef PROC_FLOW_STATS +        sprintf(frctstr, "%d", fd); +        if (rib_reg(frctstr, &r_ops)) +                goto fail_rib_reg; +#endif +        pthread_condattr_destroy(&cattr); +          for (idx = 0; idx < RQ_SIZE; ++idx)                  frcti->rq[idx] = -1; @@ -269,9 +377,13 @@ static struct frcti * frcti_create(int fd)          return frcti; +#ifdef PROC_FLOW_STATS + fail_rib_reg: +        pthread_cond_destroy(&frcti->cond); +#endif   fail_cond:          pthread_condattr_destroy(&cattr); -fail_cattr: + fail_cattr:          pthread_mutex_destroy(&frcti->mtx);   fail_mutex:          pthread_rwlock_destroy(&frcti->lock); @@ -283,6 +395,11 @@ fail_cattr:  static void frcti_destroy(struct frcti * frcti)  { +#ifdef PROC_FLOW_STATS +        char frctstr[FRCT_NAME_STRLEN + 1]; +        sprintf(frctstr, "%d", frcti->fd); +        rib_unreg(frctstr); +#endif          pthread_cond_destroy(&frcti->cond);          pthread_mutex_destroy(&frcti->mtx);          pthread_rwlock_destroy(&frcti->lock); diff --git a/src/lib/rib.c b/src/lib/rib.c index dfac69d7..8fda19d4 100644 --- a/src/lib/rib.c +++ b/src/lib/rib.c @@ -286,8 +286,17 @@ int rib_init(const char * mountpt)                                     NULL};          struct fuse_args args = FUSE_ARGS_INIT(3, argv); +        if (access("/dev/fuse", R_OK)) +                goto fail; +          if (stat(FUSE_PREFIX, &st) == -1) -                return -1; +                goto fail; + +        /* This is crap to allow IPCP RIB to remount to a different name */ +        if (strlen(rib.mnt) > 0) { +                fuse_unmount(rib.mnt, rib.ch); +                rmdir(rib.mnt); +        }          sprintf(rib.mnt, FUSE_PREFIX "/%s", mountpt); @@ -295,13 +304,13 @@ int rib_init(const char * mountpt)                  switch(errno) {                  case ENOENT:                          if (mkdir(rib.mnt, 0777)) -                                return -1; +                                goto fail_mnt;                          break;                  case ENOTCONN:                          fuse_unmount(rib.mnt, rib.ch);                          break;                  default: -                        return -1; +                        goto fail_mnt;                  }          fuse_opt_parse(&args, NULL, NULL, NULL); @@ -335,6 +344,9 @@ int rib_init(const char * mountpt)   fail_mount:          fuse_opt_free_args(&args);          rmdir(rib.mnt); + fail_mnt: +        memset(rib.mnt, 0, RIB_PATH_LEN + 1); + fail:          return -1;  #else          (void) mountpt;  | 
