Hi,
a snmpwalk of HOST-RESOURCES-MIB::hrSWRunTable doesn't scale very well
with an increasing number of running processes.
For every process and each of the 7 elements of the table, mib_hrswrun()
would call kinfo_proc() which queried all the processes running on the
system and sort them by pid.
The patch below keeps the results cached and updates the list of processes
at maximum once every 5 seconds.
Gerhard
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 08:17:16 -0000
@@ -861,11 +861,18 @@ int
kinfo_proc(u_int32_t idx, struct kinfo_proc **kinfo)
{
static struct kinfo_proc *kp = NULL;
- static size_t nkp = 0;
+ static struct kinfo_proc **klist = NULL;
+ static size_t nkp = 0, nklist = 0;
+ static time_t tinfo = 0;
int mib[] = { CTL_KERN, KERN_PROC,
KERN_PROC_ALL, 0, sizeof(*kp), 0 };
- struct kinfo_proc **klist;
+ struct kinfo_proc **knew;
size_t size, count, i;
+ time_t now;
+
+ (void)time(&now);
+ if (now - tinfo < 5 && kp != NULL && klist != NULL)
+ goto cached;
for (;;) {
size = nkp * sizeof(*kp);
@@ -892,23 +899,26 @@ kinfo_proc(u_int32_t idx, struct kinfo_p
}
nkp = count;
}
+ tinfo = now;
- klist = calloc(count, sizeof(*klist));
- if (klist == NULL)
+ knew = recallocarray(klist, nklist, count, sizeof(*klist));
+ if (knew == NULL)
return (-1);
+ klist = knew;
+ 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);
+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);
}