Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Patch to exclude duplicated disk/net devices

Help
2013-04-15
2013-05-28
  • Denis Cerkvin
    Denis Cerkvin
    2013-04-15

    Hi All,

    Using NMon on my servers more intensively, I noticed that same disk's io request can be accounted up to 3x times. Assuming I have device sda with partition sda1 which is part of LUKS devise md-0, overall totals for my disks will show 3x of throughput and requests.

    Also if I use VirtualBox, for example, of 10Gbps ethernet, I would like to exclude some of those devices out of the reports, to see only the interfaces I am interested in.

    Also I needed the ability to show different pages with different sets of devices to various users.

    Therefore I came up with these changes, allowing me to set environment variables "NMON_EXCLUDE_DISKS" and "NMON_EXCLUDE_IFS" in profile files for different users, so they will see right reports when calling the same executable, even with same disk group files.

    Patch is below, will be glad if it will be useful.

    =================================================
    С уважением,
    Денис

    Библия для людей, работающих с командной строкой.
    http://www.read-and-think.org/ 
    =================================================

    $ cat excluding.disk.netifs.patch
    -- lmon14g.c 2013-04-15 08:54:09.000000000 +1000
    +++ lmon.c 2013-04-15 18:38:06.621858846 +1000
    @@ -652,8 +652,9 @@
    };

    #define ulong unsigned long
    +#define DK_NAME_MAX_LEN 32
    struct dsk_stat {
    - char dk_name;
    + char dk_name;
    int dk_major;
    int dk_minor;
    long dk_noinfo;
    @@ -794,8 +795,9 @@
    };

    #define NETMAX 32
    +#define IF_NAME_MAX_LEN 17
    struct net_stat {
    - unsigned long if_name;
    + unsigned long if_name;
    unsigned long long if_ibytes;
    unsigned long long if_obytes;
    unsigned long long if_ipackets;
    @@ -1535,7 +1537,8 @@
    p->cpu_total.uptime=atof(proc.line);
    for(i=0;i<strlen(proc.line);i++) {
    if(proc.line_ == ' ') {
    - p->cpu_total.idletime=atof(&proc.line);
    +// Used to be p->cpu_total.idletime=atof(&proc.line);
    + p->cpu_total.idletime=atof(&proc.line)/cpus;
    break;
    }
    }
    @@ -1617,6 +1620,7 @@
    {
    static FILE *fp = (FILE *)-1;
    char buf;
    +char *envp; // Env. Var with names of disks.
    int i;
    int ret;

    @@ -1639,7 +1643,15 @@
        8    0 sda 990 2325 4764 6860 9 3 12 417 0 6003 7277
        8    1 sda1 3264 4356 12 12
    */
    +
    + // Getting the pointer to the string with names of excluded disks.
    + envp=getenv("NMON_EXCLUDE_DISKS");
    + // Here we account for space separated list of quoted DISKMAX devices.
    + if (envp && (strlen(envp) > (DK_NAME_MAX_LEN+3)*DISKMAX-2) ) // Something is wrong with Env. Var.
    + envp=NULL;
    +
    for(i=0;i<DISKMAX;) {
    +
    if(fgets(buf,1024,fp) == NULL)
    break;
    /* zero the data ready for reading */
    @@ -1673,6 +1685,7 @@
    &p->dk.dk_inflight,
    &p->dk.dk_time,
    &p->dk.dk_11 );
    +
    if(ret == 7) { /* shuffle the data around due to missing columns for partitions */
    p->dk.dk_partition = 1;
    p->dk.dk_wkb = p->dk.dk_rmsec;
    @@ -1686,6 +1699,19 @@
    else fprintf(stderr,"disk sscanf wanted 14 but returned=%d line=%s\n",
    ret,buf);

    + if(envp) { // Got disks to exclude!
    +                // export NMON_EXCLUDE_DISKS="'dm-0' 'dm-1' 'sda1' 'sda2' 'sda'"
    +                // export NMON_EXCLUDE_DISKS="'cciss/c0d0p1' 'cciss/c0d0'"
    +                 sprintf(buf, "'%s'", &p->dk.dk_name); // 'sda'
    +                 // Is this disk one of them?
    +                  if ( strstr(envp, buf) ) {
    +                   // DEBUG fprintf(stderr,"skipping disk '%s' found in %s\n",
    +                   //  &p->dk.dk_name, envp);
    +                   continue;
    +    // No need to decrement "i" here, see loop condition and below.
    +                  }
    +                } // No excluded disks.
    +
    p->dk.dk_rkb /= 2; /* sectors = 512 bytes */
    p->dk.dk_wkb /= 2;
    p->dk.dk_xfers = p->dk.dk_reads + p->dk.dk_writes;
    @@ -3007,6 +3033,7 @@
    {
    static FILE *fp = (FILE *)-1;
    char buf;
    +char *envp; // Env. Var with names of net.interfaces.
    int i=0;
    int ret;
    unsigned long junk;
    @@ -3028,7 +3055,15 @@
       sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0
       eth1:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0
    */
    +
    + // Getting the pointer to the string with names of excluded network interfaces.
    +        envp=getenv("NMON_EXCLUDE_IFS");
    +        // Here we account for space separated list of quoted NETMAX devices.
    +        if (envp && (strlen(envp) > (IF_NAME_MAX_LEN+3)*NETMAX-2) ) // Something is wrong with Env. Var.
    +           envp=NULL;
    +
    for(i=0;i<NETMAX;i++) {
    +
    if(fgets(buf,1024,fp) == NULL)
    break;
    strip_spaces(buf);
    @@ -3053,6 +3088,18 @@
    );
    if(ret != 16)
    fprintf(stderr,"sscanf wanted 16 returned = %d line=%s\n", ret, (char *)buf);
    +
    + if(envp) { // Got interfaces to exclude!
    +                // export NMON_EXCLUDE_IFS="'wlan0' 'lo' 'vboxnet0' 'vboxnet2'"
    +                // export NMON_EXCLUDE_IFS="'bond0' 'ib0' 'ib1'"
    +                 sprintf(buf, "'%s'", (char *) &p->ifnets.if_name); // 'wlan0'
    +                 // Is this disk one of them?
    +                  if ( strstr(envp, buf) ) {
    +    i-; // "i" is incremented in the loop condition, so need to decrease to re-use.
    +                   continue;
    +                  }
    +                } // No excluded interfaces.
    +
    }
    end:
    if(reread) {
    @@ -4854,13 +4901,15 @@
    (float)p->cpu_total.mins5,
    updays, uphours, upmins);

    - mvwprintw(padker,4, 1, "Interrupts     %8.1f   15 mins %5.2f    Average CPU use=%6.2f%%",
    + mvwprintw(padker,4, 1, "Interrupts     %8.1f   15 mins %5.2f    Average CPU use=%6.2f%% (%d CPUs)",
    (float)(p->cpu_total.intr - q->cpu_total.intr)/elapsed,
    (float)p->cpu_total.mins15,
    (float)(
    (p->cpu_total.uptime -
    p->cpu_total.idletime)/
    - p->cpu_total.uptime *100.0));
    + p->cpu_total.uptime *100.0),
    + cpus
    + );
    DISPLAY(padker,5);
    } else {
    if(proc_first_time) {
    $ _