components/net-snmp/patches/052.16824703.dyn_cpu.patch
changeset 2114 5a98d3204048
parent 2107 1cda4e19a209
equal deleted inserted replaced
2113:38667c45630e 2114:5a98d3204048
       
     1 --- a/include/net-snmp/agent/hardware/cpu.h	2014-06-09 04:44:56.766491669 -0700
       
     2 +++ b/include/net-snmp/agent/hardware/cpu.h	2014-06-09 04:45:47.845551969 -0700
       
     3 @@ -52,6 +52,11 @@
       
     4       netsnmp_cpu_info *next;
       
     5  };
       
     6  
       
     7 +    /* Auxilary structure used for updating the new cpu list */
       
     8 +struct cpu_idx {
       
     9 +	int idx;
       
    10 +	struct cpu_idx *next;
       
    11 +};
       
    12  
       
    13      /*
       
    14       * Possibly not all needed ??
       
    15 @@ -60,6 +65,7 @@
       
    16  netsnmp_cpu_info *netsnmp_cpu_get_next( netsnmp_cpu_info* );
       
    17  netsnmp_cpu_info *netsnmp_cpu_get_byIdx(  int,   int );
       
    18  netsnmp_cpu_info *netsnmp_cpu_get_byName( char*, int );
       
    19 +int netsnmp_update_cpu_list( struct cpu_idx * ); /* returns the number of deleted cpus */
       
    20  
       
    21  netsnmp_cache *netsnmp_cpu_get_cache( void );
       
    22  int netsnmp_cpu_load( void );
       
    23 --- a/agent/mibgroup/hardware/cpu/cpu.c	2014-06-09 04:44:56.766855758 -0700
       
    24 +++ b/agent/mibgroup/hardware/cpu/cpu.c	2014-06-19 05:07:54.648759853 -0700
       
    25 @@ -244,3 +244,59 @@
       
    26      cpu2->pageIn     = cpu->pageIn;
       
    27      cpu2->pageOut    = cpu->pageOut;
       
    28  }
       
    29 +
       
    30 +    /*
       
    31 +     * Updates the cpu list, keeping the cpus whose indices are passed
       
    32 +     * assumes the passed linked list of indices is sorted in ascending order
       
    33 +     * returns the number of deleted cpus
       
    34 +     */
       
    35 +int netsnmp_update_cpu_list( struct cpu_idx *new_cpu_list )
       
    36 +{
       
    37 +    netsnmp_cpu_info *prev, *current, *temp1, *temp2;
       
    38 +    int n=0;
       
    39 +    netsnmp_cpu_info *cpu;
       
    40 +
       
    41 +    for( prev=current=_cpu_head; current && new_cpu_list ;
       
    42 +        current=current->next, new_cpu_list=new_cpu_list->next ) {
       
    43 +        if ( current->idx == new_cpu_list->idx ) {
       
    44 +            prev=current;
       
    45 +        } else {
       
    46 +            current=current->next;
       
    47 +            while ( current && (current->idx != new_cpu_list->idx) )
       
    48 +                current = current->next;
       
    49 +            if ( !current ) {
       
    50 +                /*This shouldn't happen. Something went really wrong */
       
    51 +                return -1;
       
    52 +            }
       
    53 +
       
    54 +            temp1 = prev->next;
       
    55 +            prev->next = current;
       
    56 +            prev = current;
       
    57 +                /* remove the unassigned cpus */
       
    58 +            while ( temp1 != current ) {
       
    59 +                temp2 = temp1;
       
    60 +                temp1 = temp1->next;
       
    61 +                n++;
       
    62 +                SNMP_FREE(temp2->history);
       
    63 +                SNMP_FREE(temp2);
       
    64 +            }
       
    65 +        }
       
    66 +    } /*end of for */
       
    67 +
       
    68 +    if ( !current && new_cpu_list ) {
       
    69 +        /* This shouldn't happen. */
       
    70 +        return -1;
       
    71 +    }
       
    72 +
       
    73 +    /* Delete the unassigned trailing cpus from the list */
       
    74 +    while ( current ) {
       
    75 +        temp2 = current;
       
    76 +        current = current->next;
       
    77 +        n++;
       
    78 +        SNMP_FREE(temp2->history);
       
    79 +        SNMP_FREE(temp2);
       
    80 +     }
       
    81 +     prev->next = NULL;
       
    82 +     return n;
       
    83 +}
       
    84 +
       
    85 --- a/agent/mibgroup/hardware/cpu/cpu_kstat.c	2014-06-09 04:44:56.766680662 -0700
       
    86 +++ b/agent/mibgroup/hardware/cpu/cpu_kstat.c	2014-06-19 04:53:47.176189429 -0700
       
    87 @@ -17,16 +17,16 @@
       
    88  extern kstat_ctl_t  *kstat_fd;
       
    89  extern int           cpu_num;
       
    90  int _cpu_status(char *state);
       
    91 +static void add_new_kstat_cpu_entry(kstat_t *ksp);
       
    92 +static struct cpu_idx * add_cpu_idx(struct cpu_idx * head, int idx);
       
    93  
       
    94      /*
       
    95       * Initialise the list of CPUs on the system
       
    96       *   (including descriptions)
       
    97       */
       
    98  void init_cpu_kstat( void ) {
       
    99 -    int               i, n=0, clock, state_begin;
       
   100 -    char              ctype[15], ftype[15], state[10];
       
   101 +    int               n=0;
       
   102      kstat_t          *ksp;
       
   103 -    kstat_named_t    *ks_data;
       
   104      netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 1 );
       
   105      strcpy(cpu->name, "Overall CPU statistics");
       
   106  
       
   107 @@ -41,36 +41,50 @@
       
   108          if ((strcmp(ksp->ks_module, "cpu_info") == 0) &&
       
   109              (strcmp(ksp->ks_class,  "misc"    ) == 0)) {
       
   110              kstat_read(kstat_fd, ksp, NULL );
       
   111 +            add_new_kstat_cpu_entry(ksp);
       
   112              n++;
       
   113 -            clock = 999999;
       
   114 -            memset(ctype, 0, sizeof(ctype));
       
   115 -            memset(ftype, 0, sizeof(ftype));
       
   116 -            memset(state, 0, sizeof(state));
       
   117 -            for (i=0, ks_data = ksp->ks_data; i < ksp->ks_ndata; i++, ks_data++) {
       
   118 -                if ( strcmp( ks_data->name, "state" ) == 0 ) {
       
   119 -                    strncpy( state, ks_data->value.c, sizeof(state));
       
   120 -                    state[sizeof(state)-1] = '\0';
       
   121 -                } else if ( strcmp( ks_data->name, "state_begin" ) == 0 ) {
       
   122 -                    state_begin = ks_data->value.i32;
       
   123 -                } else if ( strcmp( ks_data->name, "cpu_type" ) == 0 ) {
       
   124 -                    strncpy( ctype, ks_data->value.c, sizeof(ctype));
       
   125 -                    state[sizeof(ctype)-1] = '\0';
       
   126 -                } else if ( strcmp( ks_data->name, "fpu_type" ) == 0 ) {
       
   127 -                    strncpy( ftype, ks_data->value.c, sizeof(ftype));
       
   128 -                    state[sizeof(ftype)-1] = '\0';
       
   129 -                } else if ( strcmp( ks_data->name, "clock_MHz" ) == 0 ) {
       
   130 -                    clock = ks_data->value.i32;
       
   131 -                }
       
   132 -            }
       
   133 -            i   = ksp->ks_instance;
       
   134 -            cpu = netsnmp_cpu_get_byIdx( i, 1 );
       
   135 -            sprintf( cpu->name,  "cpu%d", i );
       
   136 -            sprintf( cpu->descr, "CPU %d Sun %d MHz %s with %s FPU %s",
       
   137 -                                 i, clock, ctype, ftype, state  );
       
   138 -            cpu->status = _cpu_status(state); /* XXX - or in 'n_c_a_load' ? */
       
   139          }
       
   140      }
       
   141 -    cpu_num = i;
       
   142 +    cpu_num = n;
       
   143 +}
       
   144 +
       
   145 +
       
   146 +    /*
       
   147 +     * adds the new cpu entry to the exisitng list
       
   148 +     */
       
   149 +static void
       
   150 +add_new_kstat_cpu_entry( kstat_t *ksp ) {
       
   151 +    int i, clock, state_begin;
       
   152 +    char ctype[15], ftype[15], state[10];
       
   153 +    kstat_named_t    *ks_data;
       
   154 +    netsnmp_cpu_info *cpu;
       
   155 +
       
   156 +    clock = 999999;
       
   157 +    memset(ctype, 0, sizeof(ctype));
       
   158 +    memset(ftype, 0, sizeof(ftype));
       
   159 +    memset(state, 0, sizeof(state));
       
   160 +
       
   161 +    for (i=0, ks_data = ksp->ks_data; i < ksp->ks_ndata; i++, ks_data++) {
       
   162 +        if ( strcmp( ks_data->name, "state" ) == 0 ) {
       
   163 +            strncpy( state, ks_data->value.c, sizeof(state));
       
   164 +            state[sizeof(state)-1] = '\0';
       
   165 +        } else if ( strcmp( ks_data->name, "state_begin" ) == 0 ) {
       
   166 +            state_begin = ks_data->value.i32;
       
   167 +        } else if ( strcmp( ks_data->name, "cpu_type" ) == 0 ) {
       
   168 +            strncpy( ctype, ks_data->value.c, sizeof(ctype));
       
   169 +            ctype[sizeof(ctype)-1] = '\0';
       
   170 +        } else if ( strcmp( ks_data->name, "fpu_type" ) == 0 ) {
       
   171 +            strncpy( ftype, ks_data->value.c, sizeof(ftype));
       
   172 +            ftype[sizeof(ftype)-1] = '\0';
       
   173 +        } else if ( strcmp( ks_data->name, "clock_MHz" ) == 0 ) {
       
   174 +            clock = ks_data->value.i32;
       
   175 +        }
       
   176 +    }
       
   177 +    i   = ksp->ks_instance;
       
   178 +    cpu = netsnmp_cpu_get_byIdx( i, 1 );
       
   179 +    sprintf( cpu->name,  "cpu%d", i );
       
   180 +    sprintf( cpu->descr, "CPU %d Sun %d MHz %s with %s FPU %s", i, clock, ctype, ftype, state  );
       
   181 +    cpu->status = _cpu_status(state);
       
   182  }
       
   183  
       
   184  
       
   185 @@ -78,11 +92,12 @@
       
   186       * Load the latest CPU usage statistics
       
   187       */
       
   188  int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
       
   189 -    int               i=1;
       
   190 +    int               i=1, n=0;
       
   191      kstat_t          *ksp;
       
   192      cpu_stat_t        cs;
       
   193      netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 0 );
       
   194      netsnmp_cpu_info *cpu2;
       
   195 +    struct cpu_idx *new_cpu_list = NULL, *temp_cpu_idx;
       
   196  
       
   197          /* Clear overall stats, ready for summing individual CPUs */
       
   198      cpu->user_ticks = 0;
       
   199 @@ -97,6 +112,32 @@
       
   200  
       
   201      kstat_chain_update( kstat_fd );
       
   202      DEBUGMSGTL(("cpu", "cpu_kstat load\n "));
       
   203 +
       
   204 +    /*
       
   205 +     * The stats update is three step.
       
   206 +     * First - add in the new cpus' info to the linked list
       
   207 +     */
       
   208 +    for (ksp = kstat_fd->kc_chain; ksp != NULL; ksp = ksp->ks_next) {
       
   209 +        if (ksp->ks_flags & KSTAT_FLAG_INVALID)
       
   210 +            continue;
       
   211 +        if ((strcmp(ksp->ks_module, "cpu_info") == 0) &&
       
   212 +            (strcmp(ksp->ks_class,  "misc"    ) == 0)) {
       
   213 +            kstat_read(kstat_fd, ksp, NULL );
       
   214 +            i = ksp->ks_instance;
       
   215 +            new_cpu_list = add_cpu_idx( new_cpu_list, i);
       
   216 +            cpu2 = netsnmp_cpu_get_byIdx( i, 0 );
       
   217 +            if ( !cpu2 ) {
       
   218 +                add_new_kstat_cpu_entry(ksp);
       
   219 +                n++;
       
   220 +            }
       
   221 +        }
       
   222 +    }
       
   223 +
       
   224 +
       
   225 +    /* Second - update the CPU list to reflect new kernel structures */
       
   226 +    n -= netsnmp_update_cpu_list( new_cpu_list );
       
   227 +
       
   228 +    /* Third - for updating stats for the new CPU set */
       
   229      for (ksp = kstat_fd->kc_chain; ksp != NULL; ksp = ksp->ks_next) {
       
   230          if (ksp->ks_flags & KSTAT_FLAG_INVALID)
       
   231              continue;
       
   232 @@ -104,7 +145,7 @@
       
   233              i    = ksp->ks_instance;
       
   234              cpu2 = netsnmp_cpu_get_byIdx( i, 0 );
       
   235              if ( !cpu2 )
       
   236 -                    break;  /* or continue ?*/ /*Skip new CPUs */
       
   237 +                    continue;  /* This shouldn't happen. Inconsistency in kstat CPU data */
       
   238              if ((ksp->ks_type != KSTAT_TYPE_RAW) ||
       
   239                  (ksp->ks_data_size != sizeof(cs))||
       
   240                  (kstat_read(kstat_fd, ksp, &cs) == -1)) {
       
   241 @@ -138,9 +179,43 @@
       
   242              cpu->nCtxSwitches += (unsigned long)cs.cpu_sysinfo.pswitch;
       
   243          }
       
   244      }
       
   245 +    cpu_num += n;
       
   246 +    /* Clean up the temporary CPU index list */
       
   247 +    while(new_cpu_list) {
       
   248 +        temp_cpu_idx = new_cpu_list;
       
   249 +        new_cpu_list = new_cpu_list->next;
       
   250 +        SNMP_FREE(temp_cpu_idx);
       
   251 +    }
       
   252      return 0;
       
   253  }
       
   254  
       
   255 +    /* returns the new head */
       
   256 +static struct cpu_idx *
       
   257 +add_cpu_idx(struct cpu_idx * head, int idx)
       
   258 +{
       
   259 +    struct cpu_idx *cpu_idx, *current;
       
   260 +    cpu_idx = SNMP_MALLOC_TYPEDEF( struct cpu_idx );
       
   261 +    if ( !cpu_idx ) {
       
   262 +        DEBUGMSG(("cpu", "(cpu_idx creation failed)\n"));
       
   263 +        return head;
       
   264 +    }
       
   265 +
       
   266 +    cpu_idx->idx = idx;
       
   267 +    if ( !head || head->idx > idx ) {
       
   268 +        cpu_idx->next = head;
       
   269 +        return cpu_idx;
       
   270 +    }
       
   271 +
       
   272 +    for ( current=head; current; current=current->next ) {
       
   273 +        if ( !current->next || current->next->idx > idx ) {
       
   274 +            cpu_idx->next = current->next;
       
   275 +            current->next = cpu_idx;
       
   276 +            return head;
       
   277 +        }
       
   278 +    }
       
   279 +
       
   280 +}
       
   281 +
       
   282  int
       
   283  _cpu_status( char *state)
       
   284  {