[...]

> So here's an updated diff that uses a timer to purge the cache after
> 5 seconds:

LGTM except for...

> 
> Index: usr.sbin/snmpd/mib.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/snmpd/mib.c,v
> retrieving revision 1.86
> diff -u -p -u -p -r1.86 mib.c
> --- usr.sbin/snmpd/mib.c      9 May 2018 13:56:46 -0000       1.86
> +++ usr.sbin/snmpd/mib.c      22 May 2018 09:57:57 -0000
> @@ -414,6 +414,7 @@ int        mib_hrswrun(struct oid *, struct be
>  
>  int   kinfo_proc_comp(const void *, const void *);
>  int   kinfo_proc(u_int32_t, struct kinfo_proc **);
> +void  kinfo_proc_free(void);
>  int   kinfo_args(struct kinfo_proc *, char **);
>  
>  static struct oid hr_mib[] = {
> @@ -857,24 +858,29 @@ kinfo_proc_comp(const void *a, const voi
>       return (((*k1)->p_pid > (*k2)->p_pid) ? 1 : -1);
>  }
>  
> +static struct event    kinfo_timer;
> +static struct kinfo_proc *kp = NULL;
> +static struct kinfo_proc **klist = NULL;
> +static size_t                  nkp = 0, nklist = 0;
> +
>  int
>  kinfo_proc(u_int32_t idx, struct kinfo_proc **kinfo)
>  {
> -     static struct kinfo_proc *kp = NULL;
> -     static size_t            nkp = 0;
> -     int                      mib[] = { CTL_KERN, KERN_PROC,
> -                                 KERN_PROC_ALL, 0, sizeof(*kp), 0 };
> -     struct kinfo_proc       **klist;
> -     size_t                   size, count, i;
> +     int              mib[] = { CTL_KERN, KERN_PROC,
> +                         KERN_PROC_ALL, 0, sizeof(*kp), 0 };
> +     size_t           size, count, i;
> +     struct timeval   timer;
> +
> +     if (kp != NULL && klist != NULL)
> +             goto cached;
>  
> +     kinfo_proc_free();
>       for (;;) {
>               size = nkp * sizeof(*kp);
>               mib[5] = nkp;
>               if (sysctl(mib, sizeofa(mib), kp, &size, NULL, 0) == -1) {
>                       if (errno == ENOMEM) {
> -                             free(kp);
> -                             kp = NULL;
> -                             nkp = 0;
> +                             kinfo_proc_free();
>                               continue;
>                       }
>  
> @@ -887,30 +893,50 @@ kinfo_proc(u_int32_t idx, struct kinfo_p
>  
>               kp = malloc(size);
>               if (kp == NULL) {
> -                     nkp = 0;
> +                     kinfo_proc_free();
>                       return (-1);
>               }
>               nkp = count;
>       }
>  
>       klist = calloc(count, sizeof(*klist));
> -     if (klist == NULL)
> +     if (klist == NULL) {
> +             kinfo_proc_free();
>               return (-1);
> +     }
> +     nklist = count;
>  
> -     for (i = 0; i < count; i++)
> +     for (i = 0; i < nklist; i++)
>               klist[i] = &kp[i];
> -     qsort(klist, count, sizeof(*klist), kinfo_proc_comp);
> +     qsort(klist, nklist, sizeof(*klist), kinfo_proc_comp);
>  
> +     evtimer_set(&kinfo_timer, (void (*)(int, short, void *))kinfo_proc_free,

this cast which looks dubious.  Can you please add a function with
the appropriate signature?

        void
        kinfo_timer_cb(int fd, short event, void *arg)
        {
                kinfo_proc_free();
        }

With this point addressed, ok jca@


> +         NULL);
> +     timer.tv_sec = 5;
> +     timer.tv_usec = 0;
> +     evtimer_add(&kinfo_timer, &timer);
> +
> +cached:
>       *kinfo = NULL;
> -     for (i = 0; i < count; i++) {
> +     for (i = 0; i < nklist; i++) {
>               if (klist[i]->p_pid >= (int32_t)idx) {
>                       *kinfo = klist[i];
>                       break;
>               }
>       }
> -     free(klist);
>  
>       return (0);
> +}
> +
> +void
> +kinfo_proc_free(void)
> +{
> +     free(kp);
> +     kp = NULL;
> +     nkp = 0;
> +     free(klist);
> +     klist = NULL;
> +     nklist = 0;
>  }
>  
>  int



-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to